提交 a38b2fa3 编写于 作者: D David S. Miller

Merge branch 'mlxsw-Prepare-for-multicast-router-offload'

Jiri Pirko says:

====================
mlxsw: Prepare for multicast router offload

Yotam says:

This patch-set makes various preparations needed for the multicast router
offloading, which include:
 - Add the needed registers.
 - Add needed ACL actions.
 - Add new traps and trap groups.
 - Exporting needed private structs and enums.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -17,7 +17,7 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \ ...@@ -17,7 +17,7 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
spectrum_kvdl.o spectrum_acl_tcam.o \ spectrum_kvdl.o spectrum_acl_tcam.o \
spectrum_acl.o spectrum_flower.o \ spectrum_acl.o spectrum_flower.o \
spectrum_cnt.o spectrum_fid.o \ spectrum_cnt.o spectrum_fid.o \
spectrum_ipip.o spectrum_ipip.o spectrum_acl_flex_actions.o
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o
obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o
......
...@@ -712,7 +712,7 @@ int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block) ...@@ -712,7 +712,7 @@ int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block)
} }
EXPORT_SYMBOL(mlxsw_afa_block_append_drop); EXPORT_SYMBOL(mlxsw_afa_block_append_drop);
int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block) int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id)
{ {
char *act = mlxsw_afa_block_append_action(block, char *act = mlxsw_afa_block_append_action(block,
MLXSW_AFA_TRAPDISC_CODE, MLXSW_AFA_TRAPDISC_CODE,
...@@ -722,7 +722,7 @@ int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block) ...@@ -722,7 +722,7 @@ int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block)
return -ENOBUFS; return -ENOBUFS;
mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_TRAP, mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_TRAP,
MLXSW_AFA_TRAPDISC_FORWARD_ACTION_DISCARD, MLXSW_AFA_TRAPDISC_FORWARD_ACTION_DISCARD,
MLXSW_TRAP_ID_ACL0); trap_id);
return 0; return 0;
} }
EXPORT_SYMBOL(mlxsw_afa_block_append_trap); EXPORT_SYMBOL(mlxsw_afa_block_append_trap);
...@@ -891,3 +891,74 @@ int mlxsw_afa_block_append_fid_set(struct mlxsw_afa_block *block, u16 fid) ...@@ -891,3 +891,74 @@ int mlxsw_afa_block_append_fid_set(struct mlxsw_afa_block *block, u16 fid)
return 0; return 0;
} }
EXPORT_SYMBOL(mlxsw_afa_block_append_fid_set); EXPORT_SYMBOL(mlxsw_afa_block_append_fid_set);
/* MC Routing Action
* -----------------
* The Multicast router action. Can be used by RMFT_V2 - Router Multicast
* Forwarding Table Version 2 Register.
*/
#define MLXSW_AFA_MCROUTER_CODE 0x10
#define MLXSW_AFA_MCROUTER_SIZE 2
enum mlxsw_afa_mcrouter_rpf_action {
MLXSW_AFA_MCROUTER_RPF_ACTION_NOP,
MLXSW_AFA_MCROUTER_RPF_ACTION_TRAP,
MLXSW_AFA_MCROUTER_RPF_ACTION_DISCARD_ERROR,
};
/* afa_mcrouter_rpf_action */
MLXSW_ITEM32(afa, mcrouter, rpf_action, 0x00, 28, 3);
/* afa_mcrouter_expected_irif */
MLXSW_ITEM32(afa, mcrouter, expected_irif, 0x00, 0, 16);
/* afa_mcrouter_min_mtu */
MLXSW_ITEM32(afa, mcrouter, min_mtu, 0x08, 0, 16);
enum mlxsw_afa_mrouter_vrmid {
MLXSW_AFA_MCROUTER_VRMID_INVALID,
MLXSW_AFA_MCROUTER_VRMID_VALID
};
/* afa_mcrouter_vrmid
* Valid RMID: rigr_rmid_index is used as RMID
*/
MLXSW_ITEM32(afa, mcrouter, vrmid, 0x0C, 31, 1);
/* afa_mcrouter_rigr_rmid_index
* When the vrmid field is set to invalid, the field is used as pointer to
* Router Interface Group (RIGR) Table in the KVD linear.
* When the vrmid is set to valid, the field is used as RMID index, ranged
* from 0 to max_mid - 1. The index is to the Port Group Table.
*/
MLXSW_ITEM32(afa, mcrouter, rigr_rmid_index, 0x0C, 0, 24);
static inline void
mlxsw_afa_mcrouter_pack(char *payload,
enum mlxsw_afa_mcrouter_rpf_action rpf_action,
u16 expected_irif, u16 min_mtu,
enum mlxsw_afa_mrouter_vrmid vrmid, u32 rigr_rmid_index)
{
mlxsw_afa_mcrouter_rpf_action_set(payload, rpf_action);
mlxsw_afa_mcrouter_expected_irif_set(payload, expected_irif);
mlxsw_afa_mcrouter_min_mtu_set(payload, min_mtu);
mlxsw_afa_mcrouter_vrmid_set(payload, vrmid);
mlxsw_afa_mcrouter_rigr_rmid_index_set(payload, rigr_rmid_index);
}
int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
u16 expected_irif, u16 min_mtu,
bool rmid_valid, u32 kvdl_index)
{
char *act = mlxsw_afa_block_append_action(block,
MLXSW_AFA_MCROUTER_CODE,
MLXSW_AFA_MCROUTER_SIZE);
if (!act)
return -ENOBUFS;
mlxsw_afa_mcrouter_pack(act, MLXSW_AFA_MCROUTER_RPF_ACTION_TRAP,
expected_irif, min_mtu, rmid_valid, kvdl_index);
return 0;
}
EXPORT_SYMBOL(mlxsw_afa_block_append_mcrouter);
...@@ -60,7 +60,7 @@ u32 mlxsw_afa_block_first_set_kvdl_index(struct mlxsw_afa_block *block); ...@@ -60,7 +60,7 @@ u32 mlxsw_afa_block_first_set_kvdl_index(struct mlxsw_afa_block *block);
void mlxsw_afa_block_continue(struct mlxsw_afa_block *block); void mlxsw_afa_block_continue(struct mlxsw_afa_block *block);
void mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id); void mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id);
int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block); int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block);
int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block); int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id);
int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block, int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block,
u8 local_port, bool in_port); u8 local_port, bool in_port);
int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block, int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block,
...@@ -68,5 +68,8 @@ int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block, ...@@ -68,5 +68,8 @@ int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block,
int mlxsw_afa_block_append_counter(struct mlxsw_afa_block *block, int mlxsw_afa_block_append_counter(struct mlxsw_afa_block *block,
u32 counter_index); u32 counter_index);
int mlxsw_afa_block_append_fid_set(struct mlxsw_afa_block *block, u16 fid); int mlxsw_afa_block_append_fid_set(struct mlxsw_afa_block *block, u16 fid);
int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
u16 expected_irif, u16 min_mtu,
bool rmid_valid, u32 kvdl_index);
#endif #endif
...@@ -2142,15 +2142,14 @@ MLXSW_REG_DEFINE(pefa, MLXSW_REG_PEFA_ID, MLXSW_REG_PEFA_LEN); ...@@ -2142,15 +2142,14 @@ MLXSW_REG_DEFINE(pefa, MLXSW_REG_PEFA_ID, MLXSW_REG_PEFA_LEN);
*/ */
MLXSW_ITEM32(reg, pefa, index, 0x00, 0, 24); MLXSW_ITEM32(reg, pefa, index, 0x00, 0, 24);
#define MLXSW_REG_PXXX_FLEX_ACTION_SET_LEN 0xA8 #define MLXSW_REG_FLEX_ACTION_SET_LEN 0xA8
/* reg_pefa_flex_action_set /* reg_pefa_flex_action_set
* Action-set to perform when rule is matched. * Action-set to perform when rule is matched.
* Must be zero padded if action set is shorter. * Must be zero padded if action set is shorter.
* Access: RW * Access: RW
*/ */
MLXSW_ITEM_BUF(reg, pefa, flex_action_set, 0x08, MLXSW_ITEM_BUF(reg, pefa, flex_action_set, 0x08, MLXSW_REG_FLEX_ACTION_SET_LEN);
MLXSW_REG_PXXX_FLEX_ACTION_SET_LEN);
static inline void mlxsw_reg_pefa_pack(char *payload, u32 index, static inline void mlxsw_reg_pefa_pack(char *payload, u32 index,
const char *flex_action_set) const char *flex_action_set)
...@@ -2243,7 +2242,7 @@ MLXSW_ITEM_BUF(reg, ptce2, mask, 0x80, ...@@ -2243,7 +2242,7 @@ MLXSW_ITEM_BUF(reg, ptce2, mask, 0x80,
* Access: RW * Access: RW
*/ */
MLXSW_ITEM_BUF(reg, ptce2, flex_action_set, 0xE0, MLXSW_ITEM_BUF(reg, ptce2, flex_action_set, 0xE0,
MLXSW_REG_PXXX_FLEX_ACTION_SET_LEN); MLXSW_REG_FLEX_ACTION_SET_LEN);
static inline void mlxsw_reg_ptce2_pack(char *payload, bool valid, static inline void mlxsw_reg_ptce2_pack(char *payload, bool valid,
enum mlxsw_reg_ptce2_op op, enum mlxsw_reg_ptce2_op op,
...@@ -3682,12 +3681,15 @@ enum mlxsw_reg_htgt_trap_group { ...@@ -3682,12 +3681,15 @@ enum mlxsw_reg_htgt_trap_group {
MLXSW_REG_HTGT_TRAP_GROUP_SP_IGMP, MLXSW_REG_HTGT_TRAP_GROUP_SP_IGMP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP, MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF, MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF,
MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM,
MLXSW_REG_HTGT_TRAP_GROUP_SP_MULTICAST,
MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP, MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_HOST_MISS, MLXSW_REG_HTGT_TRAP_GROUP_SP_HOST_MISS,
MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP, MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE, MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE,
MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME, MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME,
MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP, MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP,
MLXSW_REG_HTGT_TRAP_GROUP_SP_RPF,
MLXSW_REG_HTGT_TRAP_GROUP_SP_EVENT, MLXSW_REG_HTGT_TRAP_GROUP_SP_EVENT,
MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_MLD, MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_MLD,
MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_ND, MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_ND,
...@@ -3992,6 +3994,12 @@ MLXSW_ITEM32(reg, ritr, ipv4, 0x00, 29, 1); ...@@ -3992,6 +3994,12 @@ MLXSW_ITEM32(reg, ritr, ipv4, 0x00, 29, 1);
*/ */
MLXSW_ITEM32(reg, ritr, ipv6, 0x00, 28, 1); MLXSW_ITEM32(reg, ritr, ipv6, 0x00, 28, 1);
/* reg_ritr_ipv4_mc
* IPv4 multicast routing enable.
* Access: RW
*/
MLXSW_ITEM32(reg, ritr, ipv4_mc, 0x00, 27, 1);
enum mlxsw_reg_ritr_if_type { enum mlxsw_reg_ritr_if_type {
/* VLAN interface. */ /* VLAN interface. */
MLXSW_REG_RITR_VLAN_IF, MLXSW_REG_RITR_VLAN_IF,
...@@ -4049,6 +4057,14 @@ MLXSW_ITEM32(reg, ritr, ipv4_fe, 0x04, 29, 1); ...@@ -4049,6 +4057,14 @@ MLXSW_ITEM32(reg, ritr, ipv4_fe, 0x04, 29, 1);
*/ */
MLXSW_ITEM32(reg, ritr, ipv6_fe, 0x04, 28, 1); MLXSW_ITEM32(reg, ritr, ipv6_fe, 0x04, 28, 1);
/* reg_ritr_ipv4_mc_fe
* IPv4 Multicast Forwarding Enable.
* When disabled, forwarding is blocked but local traffic (traps and IP to me)
* will be enabled.
* Access: RW
*/
MLXSW_ITEM32(reg, ritr, ipv4_mc_fe, 0x04, 27, 1);
/* reg_ritr_lb_en /* reg_ritr_lb_en
* Loop-back filter enable for unicast packets. * Loop-back filter enable for unicast packets.
* If the flag is set then loop-back filter for unicast packets is * If the flag is set then loop-back filter for unicast packets is
...@@ -4271,11 +4287,13 @@ static inline void mlxsw_reg_ritr_pack(char *payload, bool enable, ...@@ -4271,11 +4287,13 @@ static inline void mlxsw_reg_ritr_pack(char *payload, bool enable,
mlxsw_reg_ritr_enable_set(payload, enable); mlxsw_reg_ritr_enable_set(payload, enable);
mlxsw_reg_ritr_ipv4_set(payload, 1); mlxsw_reg_ritr_ipv4_set(payload, 1);
mlxsw_reg_ritr_ipv6_set(payload, 1); mlxsw_reg_ritr_ipv6_set(payload, 1);
mlxsw_reg_ritr_ipv4_mc_set(payload, 1);
mlxsw_reg_ritr_type_set(payload, type); mlxsw_reg_ritr_type_set(payload, type);
mlxsw_reg_ritr_op_set(payload, op); mlxsw_reg_ritr_op_set(payload, op);
mlxsw_reg_ritr_rif_set(payload, rif); mlxsw_reg_ritr_rif_set(payload, rif);
mlxsw_reg_ritr_ipv4_fe_set(payload, 1); mlxsw_reg_ritr_ipv4_fe_set(payload, 1);
mlxsw_reg_ritr_ipv6_fe_set(payload, 1); mlxsw_reg_ritr_ipv6_fe_set(payload, 1);
mlxsw_reg_ritr_ipv4_mc_fe_set(payload, 1);
mlxsw_reg_ritr_lb_en_set(payload, 1); mlxsw_reg_ritr_lb_en_set(payload, 1);
mlxsw_reg_ritr_virtual_router_set(payload, vr_id); mlxsw_reg_ritr_virtual_router_set(payload, vr_id);
mlxsw_reg_ritr_mtu_set(payload, mtu); mlxsw_reg_ritr_mtu_set(payload, mtu);
...@@ -4311,6 +4329,57 @@ mlxsw_reg_ritr_loopback_ipip4_pack(char *payload, ...@@ -4311,6 +4329,57 @@ mlxsw_reg_ritr_loopback_ipip4_pack(char *payload,
mlxsw_reg_ritr_loopback_ipip_usip4_set(payload, usip); mlxsw_reg_ritr_loopback_ipip_usip4_set(payload, usip);
} }
/* RTAR - Router TCAM Allocation Register
* --------------------------------------
* This register is used for allocation of regions in the TCAM table.
*/
#define MLXSW_REG_RTAR_ID 0x8004
#define MLXSW_REG_RTAR_LEN 0x20
MLXSW_REG_DEFINE(rtar, MLXSW_REG_RTAR_ID, MLXSW_REG_RTAR_LEN);
enum mlxsw_reg_rtar_op {
MLXSW_REG_RTAR_OP_ALLOCATE,
MLXSW_REG_RTAR_OP_RESIZE,
MLXSW_REG_RTAR_OP_DEALLOCATE,
};
/* reg_rtar_op
* Access: WO
*/
MLXSW_ITEM32(reg, rtar, op, 0x00, 28, 4);
enum mlxsw_reg_rtar_key_type {
MLXSW_REG_RTAR_KEY_TYPE_IPV4_MULTICAST = 1,
MLXSW_REG_RTAR_KEY_TYPE_IPV6_MULTICAST = 3
};
/* reg_rtar_key_type
* TCAM key type for the region.
* Access: WO
*/
MLXSW_ITEM32(reg, rtar, key_type, 0x00, 0, 8);
/* reg_rtar_region_size
* TCAM region size. When allocating/resizing this is the requested
* size, the response is the actual size.
* Note: Actual size may be larger than requested.
* Reserved for op = Deallocate
* Access: WO
*/
MLXSW_ITEM32(reg, rtar, region_size, 0x04, 0, 16);
static inline void mlxsw_reg_rtar_pack(char *payload,
enum mlxsw_reg_rtar_op op,
enum mlxsw_reg_rtar_key_type key_type,
u16 region_size)
{
MLXSW_REG_ZERO(rtar, payload);
mlxsw_reg_rtar_op_set(payload, op);
mlxsw_reg_rtar_key_type_set(payload, key_type);
mlxsw_reg_rtar_region_size_set(payload, region_size);
}
/* RATR - Router Adjacency Table Register /* RATR - Router Adjacency Table Register
* -------------------------------------- * --------------------------------------
* The RATR register is used to configure the Router Adjacency (next-hop) * The RATR register is used to configure the Router Adjacency (next-hop)
...@@ -4630,6 +4699,65 @@ static inline void mlxsw_reg_ricnt_pack(char *payload, u32 index, ...@@ -4630,6 +4699,65 @@ static inline void mlxsw_reg_ricnt_pack(char *payload, u32 index,
MLXSW_REG_RICNT_COUNTER_SET_TYPE_BASIC); MLXSW_REG_RICNT_COUNTER_SET_TYPE_BASIC);
} }
/* RRCR - Router Rules Copy Register Layout
* ----------------------------------------
* This register is used for moving and copying route entry rules.
*/
#define MLXSW_REG_RRCR_ID 0x800F
#define MLXSW_REG_RRCR_LEN 0x24
MLXSW_REG_DEFINE(rrcr, MLXSW_REG_RRCR_ID, MLXSW_REG_RRCR_LEN);
enum mlxsw_reg_rrcr_op {
/* Move rules */
MLXSW_REG_RRCR_OP_MOVE,
/* Copy rules */
MLXSW_REG_RRCR_OP_COPY,
};
/* reg_rrcr_op
* Access: WO
*/
MLXSW_ITEM32(reg, rrcr, op, 0x00, 28, 4);
/* reg_rrcr_offset
* Offset within the region from which to copy/move.
* Access: Index
*/
MLXSW_ITEM32(reg, rrcr, offset, 0x00, 0, 16);
/* reg_rrcr_size
* The number of rules to copy/move.
* Access: WO
*/
MLXSW_ITEM32(reg, rrcr, size, 0x04, 0, 16);
/* reg_rrcr_table_id
* Identifier of the table on which to perform the operation. Encoding is the
* same as in RTAR.key_type
* Access: Index
*/
MLXSW_ITEM32(reg, rrcr, table_id, 0x10, 0, 4);
/* reg_rrcr_dest_offset
* Offset within the region to which to copy/move
* Access: Index
*/
MLXSW_ITEM32(reg, rrcr, dest_offset, 0x20, 0, 16);
static inline void mlxsw_reg_rrcr_pack(char *payload, enum mlxsw_reg_rrcr_op op,
u16 offset, u16 size,
enum mlxsw_reg_rtar_key_type table_id,
u16 dest_offset)
{
MLXSW_REG_ZERO(rrcr, payload);
mlxsw_reg_rrcr_op_set(payload, op);
mlxsw_reg_rrcr_offset_set(payload, offset);
mlxsw_reg_rrcr_size_set(payload, size);
mlxsw_reg_rrcr_table_id_set(payload, table_id);
mlxsw_reg_rrcr_dest_offset_set(payload, dest_offset);
}
/* RALTA - Router Algorithmic LPM Tree Allocation Register /* RALTA - Router Algorithmic LPM Tree Allocation Register
* ------------------------------------------------------- * -------------------------------------------------------
* RALTA is used to allocate the LPM trees of the SHSPM method. * RALTA is used to allocate the LPM trees of the SHSPM method.
...@@ -5596,6 +5724,229 @@ mlxsw_reg_rtdp_ipip4_pack(char *payload, u16 irif, ...@@ -5596,6 +5724,229 @@ mlxsw_reg_rtdp_ipip4_pack(char *payload, u16 irif,
mlxsw_reg_rtdp_ipip_expected_gre_key_set(payload, expected_gre_key); mlxsw_reg_rtdp_ipip_expected_gre_key_set(payload, expected_gre_key);
} }
/* RIGR-V2 - Router Interface Group Register Version 2
* ---------------------------------------------------
* The RIGR_V2 register is used to add, remove and query egress interface list
* of a multicast forwarding entry.
*/
#define MLXSW_REG_RIGR2_ID 0x8023
#define MLXSW_REG_RIGR2_LEN 0xB0
#define MLXSW_REG_RIGR2_MAX_ERIFS 32
MLXSW_REG_DEFINE(rigr2, MLXSW_REG_RIGR2_ID, MLXSW_REG_RIGR2_LEN);
/* reg_rigr2_rigr_index
* KVD Linear index.
* Access: Index
*/
MLXSW_ITEM32(reg, rigr2, rigr_index, 0x04, 0, 24);
/* reg_rigr2_vnext
* Next RIGR Index is valid.
* Access: RW
*/
MLXSW_ITEM32(reg, rigr2, vnext, 0x08, 31, 1);
/* reg_rigr2_next_rigr_index
* Next RIGR Index. The index is to the KVD linear.
* Reserved when vnxet = '0'.
* Access: RW
*/
MLXSW_ITEM32(reg, rigr2, next_rigr_index, 0x08, 0, 24);
/* reg_rigr2_vrmid
* RMID Index is valid.
* Access: RW
*/
MLXSW_ITEM32(reg, rigr2, vrmid, 0x20, 31, 1);
/* reg_rigr2_rmid_index
* RMID Index.
* Range 0 .. max_mid - 1
* Reserved when vrmid = '0'.
* The index is to the Port Group Table (PGT)
* Access: RW
*/
MLXSW_ITEM32(reg, rigr2, rmid_index, 0x20, 0, 16);
/* reg_rigr2_erif_entry_v
* Egress Router Interface is valid.
* Note that low-entries must be set if high-entries are set. For
* example: if erif_entry[2].v is set then erif_entry[1].v and
* erif_entry[0].v must be set.
* Index can be from 0 to cap_mc_erif_list_entries-1
* Access: RW
*/
MLXSW_ITEM32_INDEXED(reg, rigr2, erif_entry_v, 0x24, 31, 1, 4, 0, false);
/* reg_rigr2_erif_entry_erif
* Egress Router Interface.
* Valid range is from 0 to cap_max_router_interfaces - 1
* Index can be from 0 to MLXSW_REG_RIGR2_MAX_ERIFS - 1
* Access: RW
*/
MLXSW_ITEM32_INDEXED(reg, rigr2, erif_entry_erif, 0x24, 0, 16, 4, 0, false);
static inline void mlxsw_reg_rigr2_pack(char *payload, u32 rigr_index,
bool vnext, u32 next_rigr_index)
{
MLXSW_REG_ZERO(rigr2, payload);
mlxsw_reg_rigr2_rigr_index_set(payload, rigr_index);
mlxsw_reg_rigr2_vnext_set(payload, vnext);
mlxsw_reg_rigr2_next_rigr_index_set(payload, next_rigr_index);
mlxsw_reg_rigr2_vrmid_set(payload, 0);
mlxsw_reg_rigr2_rmid_index_set(payload, 0);
}
static inline void mlxsw_reg_rigr2_erif_entry_pack(char *payload, int index,
bool v, u16 erif)
{
mlxsw_reg_rigr2_erif_entry_v_set(payload, index, v);
mlxsw_reg_rigr2_erif_entry_erif_set(payload, index, erif);
}
/* RMFT-V2 - Router Multicast Forwarding Table Version 2 Register
* --------------------------------------------------------------
* The RMFT_V2 register is used to configure and query the multicast table.
*/
#define MLXSW_REG_RMFT2_ID 0x8027
#define MLXSW_REG_RMFT2_LEN 0x174
MLXSW_REG_DEFINE(rmft2, MLXSW_REG_RMFT2_ID, MLXSW_REG_RMFT2_LEN);
/* reg_rmft2_v
* Valid
* Access: RW
*/
MLXSW_ITEM32(reg, rmft2, v, 0x00, 31, 1);
enum mlxsw_reg_rmft2_type {
MLXSW_REG_RMFT2_TYPE_IPV4,
MLXSW_REG_RMFT2_TYPE_IPV6
};
/* reg_rmft2_type
* Access: Index
*/
MLXSW_ITEM32(reg, rmft2, type, 0x00, 28, 2);
enum mlxsw_sp_reg_rmft2_op {
/* For Write:
* Write operation. Used to write a new entry to the table. All RW
* fields are relevant for new entry. Activity bit is set for new
* entries - Note write with v (Valid) 0 will delete the entry.
* For Query:
* Read operation
*/
MLXSW_REG_RMFT2_OP_READ_WRITE,
};
/* reg_rmft2_op
* Operation.
* Access: OP
*/
MLXSW_ITEM32(reg, rmft2, op, 0x00, 20, 2);
/* reg_rmft2_a
* Activity. Set for new entries. Set if a packet lookup has hit on the specific
* entry.
* Access: RO
*/
MLXSW_ITEM32(reg, rmft2, a, 0x00, 16, 1);
/* reg_rmft2_offset
* Offset within the multicast forwarding table to write to.
* Access: Index
*/
MLXSW_ITEM32(reg, rmft2, offset, 0x00, 0, 16);
/* reg_rmft2_virtual_router
* Virtual Router ID. Range from 0..cap_max_virtual_routers-1
* Access: RW
*/
MLXSW_ITEM32(reg, rmft2, virtual_router, 0x04, 0, 16);
enum mlxsw_reg_rmft2_irif_mask {
MLXSW_REG_RMFT2_IRIF_MASK_IGNORE,
MLXSW_REG_RMFT2_IRIF_MASK_COMPARE
};
/* reg_rmft2_irif_mask
* Ingress RIF mask.
* Access: RW
*/
MLXSW_ITEM32(reg, rmft2, irif_mask, 0x08, 24, 1);
/* reg_rmft2_irif
* Ingress RIF index.
* Access: RW
*/
MLXSW_ITEM32(reg, rmft2, irif, 0x08, 0, 16);
/* reg_rmft2_dip4
* Destination IPv4 address
* Access: RW
*/
MLXSW_ITEM32(reg, rmft2, dip4, 0x1C, 0, 32);
/* reg_rmft2_dip4_mask
* A bit that is set directs the TCAM to compare the corresponding bit in key. A
* bit that is clear directs the TCAM to ignore the corresponding bit in key.
* Access: RW
*/
MLXSW_ITEM32(reg, rmft2, dip4_mask, 0x2C, 0, 32);
/* reg_rmft2_sip4
* Source IPv4 address
* Access: RW
*/
MLXSW_ITEM32(reg, rmft2, sip4, 0x3C, 0, 32);
/* reg_rmft2_sip4_mask
* A bit that is set directs the TCAM to compare the corresponding bit in key. A
* bit that is clear directs the TCAM to ignore the corresponding bit in key.
* Access: RW
*/
MLXSW_ITEM32(reg, rmft2, sip4_mask, 0x4C, 0, 32);
/* reg_rmft2_flexible_action_set
* ACL action set. The only supported action types in this field and in any
* action-set pointed from here are as follows:
* 00h: ACTION_NULL
* 01h: ACTION_MAC_TTL, only TTL configuration is supported.
* 03h: ACTION_TRAP
* 06h: ACTION_QOS
* 08h: ACTION_POLICING_MONITORING
* 10h: ACTION_ROUTER_MC
* Access: RW
*/
MLXSW_ITEM_BUF(reg, rmft2, flexible_action_set, 0x80,
MLXSW_REG_FLEX_ACTION_SET_LEN);
static inline void
mlxsw_reg_rmft2_ipv4_pack(char *payload, bool v, u16 offset, u16 virtual_router,
enum mlxsw_reg_rmft2_irif_mask irif_mask, u16 irif,
u32 dip4, u32 dip4_mask, u32 sip4, u32 sip4_mask,
const char *flexible_action_set)
{
MLXSW_REG_ZERO(rmft2, payload);
mlxsw_reg_rmft2_v_set(payload, v);
mlxsw_reg_rmft2_type_set(payload, MLXSW_REG_RMFT2_TYPE_IPV4);
mlxsw_reg_rmft2_op_set(payload, MLXSW_REG_RMFT2_OP_READ_WRITE);
mlxsw_reg_rmft2_offset_set(payload, offset);
mlxsw_reg_rmft2_virtual_router_set(payload, virtual_router);
mlxsw_reg_rmft2_irif_mask_set(payload, irif_mask);
mlxsw_reg_rmft2_irif_set(payload, irif);
mlxsw_reg_rmft2_dip4_set(payload, dip4);
mlxsw_reg_rmft2_dip4_mask_set(payload, dip4_mask);
mlxsw_reg_rmft2_sip4_set(payload, sip4);
mlxsw_reg_rmft2_sip4_mask_set(payload, sip4_mask);
if (flexible_action_set)
mlxsw_reg_rmft2_flexible_action_set_memcpy_to(payload,
flexible_action_set);
}
/* MFCR - Management Fan Control Register /* MFCR - Management Fan Control Register
* -------------------------------------- * --------------------------------------
* This register controls the settings of the Fan Speed PWM mechanism. * This register controls the settings of the Fan Speed PWM mechanism.
...@@ -6856,9 +7207,11 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = { ...@@ -6856,9 +7207,11 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(hpkt), MLXSW_REG(hpkt),
MLXSW_REG(rgcr), MLXSW_REG(rgcr),
MLXSW_REG(ritr), MLXSW_REG(ritr),
MLXSW_REG(rtar),
MLXSW_REG(ratr), MLXSW_REG(ratr),
MLXSW_REG(rtdp), MLXSW_REG(rtdp),
MLXSW_REG(ricnt), MLXSW_REG(ricnt),
MLXSW_REG(rrcr),
MLXSW_REG(ralta), MLXSW_REG(ralta),
MLXSW_REG(ralst), MLXSW_REG(ralst),
MLXSW_REG(raltb), MLXSW_REG(raltb),
...@@ -6866,6 +7219,8 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = { ...@@ -6866,6 +7219,8 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(rauht), MLXSW_REG(rauht),
MLXSW_REG(raleu), MLXSW_REG(raleu),
MLXSW_REG(rauhtd), MLXSW_REG(rauhtd),
MLXSW_REG(rigr2),
MLXSW_REG(rmft2),
MLXSW_REG(mfcr), MLXSW_REG(mfcr),
MLXSW_REG(mfsc), MLXSW_REG(mfsc),
MLXSW_REG(mfsm), MLXSW_REG(mfsm),
......
...@@ -63,6 +63,7 @@ enum mlxsw_res_id { ...@@ -63,6 +63,7 @@ enum mlxsw_res_id {
MLXSW_RES_ID_MAX_CPU_POLICERS, MLXSW_RES_ID_MAX_CPU_POLICERS,
MLXSW_RES_ID_MAX_VRS, MLXSW_RES_ID_MAX_VRS,
MLXSW_RES_ID_MAX_RIFS, MLXSW_RES_ID_MAX_RIFS,
MLXSW_RES_ID_MC_ERIF_LIST_ENTRIES,
MLXSW_RES_ID_MAX_LPM_TREES, MLXSW_RES_ID_MAX_LPM_TREES,
/* Internal resources. /* Internal resources.
...@@ -100,6 +101,7 @@ static u16 mlxsw_res_ids[] = { ...@@ -100,6 +101,7 @@ static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_MAX_CPU_POLICERS] = 0x2A13, [MLXSW_RES_ID_MAX_CPU_POLICERS] = 0x2A13,
[MLXSW_RES_ID_MAX_VRS] = 0x2C01, [MLXSW_RES_ID_MAX_VRS] = 0x2C01,
[MLXSW_RES_ID_MAX_RIFS] = 0x2C02, [MLXSW_RES_ID_MAX_RIFS] = 0x2C02,
[MLXSW_RES_ID_MC_ERIF_LIST_ENTRIES] = 0x2C10,
[MLXSW_RES_ID_MAX_LPM_TREES] = 0x2C30, [MLXSW_RES_ID_MAX_LPM_TREES] = 0x2C30,
}; };
......
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
#include "txheader.h" #include "txheader.h"
#include "spectrum_cnt.h" #include "spectrum_cnt.h"
#include "spectrum_dpipe.h" #include "spectrum_dpipe.h"
#include "spectrum_acl_flex_actions.h"
#include "../mlxfw/mlxfw.h" #include "../mlxfw/mlxfw.h"
#define MLXSW_FWREV_MAJOR 13 #define MLXSW_FWREV_MAJOR 13
...@@ -3420,6 +3421,10 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = { ...@@ -3420,6 +3421,10 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {
false, SP_IP2ME, DISCARD), false, SP_IP2ME, DISCARD),
/* ACL trap */ /* ACL trap */
MLXSW_SP_RXL_NO_MARK(ACL0, TRAP_TO_CPU, IP2ME, false), MLXSW_SP_RXL_NO_MARK(ACL0, TRAP_TO_CPU, IP2ME, false),
/* Multicast Router Traps */
MLXSW_SP_RXL_MARK(IPV4_PIM, TRAP_TO_CPU, PIM, false),
MLXSW_SP_RXL_MARK(RPF, TRAP_TO_CPU, RPF, false),
MLXSW_SP_RXL_MARK(ACL1, TRAP_TO_CPU, MULTICAST, false),
}; };
static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core) static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
...@@ -3445,6 +3450,8 @@ static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core) ...@@ -3445,6 +3450,8 @@ static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP: case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP: case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF: case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_RPF:
rate = 128; rate = 128;
burst_size = 7; burst_size = 7;
break; break;
...@@ -3460,6 +3467,7 @@ static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core) ...@@ -3460,6 +3467,7 @@ static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP: case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE: case MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_ND: case MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_ND:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_MULTICAST:
rate = 1024; rate = 1024;
burst_size = 7; burst_size = 7;
break; break;
...@@ -3505,6 +3513,7 @@ static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core) ...@@ -3505,6 +3513,7 @@ static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core)
case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP: case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP: case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF: case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM:
priority = 5; priority = 5;
tc = 5; tc = 5;
break; break;
...@@ -3521,12 +3530,14 @@ static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core) ...@@ -3521,12 +3530,14 @@ static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core)
break; break;
case MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP: case MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_ND: case MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_ND:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_RPF:
priority = 2; priority = 2;
tc = 2; tc = 2;
break; break;
case MLXSW_REG_HTGT_TRAP_GROUP_SP_HOST_MISS: case MLXSW_REG_HTGT_TRAP_GROUP_SP_HOST_MISS:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP: case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE: case MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE:
case MLXSW_REG_HTGT_TRAP_GROUP_SP_MULTICAST:
priority = 1; priority = 1;
tc = 1; tc = 1;
break; break;
...@@ -3693,6 +3704,18 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core, ...@@ -3693,6 +3704,18 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
goto err_switchdev_init; goto err_switchdev_init;
} }
err = mlxsw_sp_counter_pool_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to init counter pool\n");
goto err_counter_pool_init;
}
err = mlxsw_sp_afa_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL actions\n");
goto err_afa_init;
}
err = mlxsw_sp_router_init(mlxsw_sp); err = mlxsw_sp_router_init(mlxsw_sp);
if (err) { if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n"); dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n");
...@@ -3711,12 +3734,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core, ...@@ -3711,12 +3734,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
goto err_acl_init; goto err_acl_init;
} }
err = mlxsw_sp_counter_pool_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to init counter pool\n");
goto err_counter_pool_init;
}
err = mlxsw_sp_dpipe_init(mlxsw_sp); err = mlxsw_sp_dpipe_init(mlxsw_sp);
if (err) { if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to init pipeline debug\n"); dev_err(mlxsw_sp->bus_info->dev, "Failed to init pipeline debug\n");
...@@ -3734,14 +3751,16 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core, ...@@ -3734,14 +3751,16 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
err_ports_create: err_ports_create:
mlxsw_sp_dpipe_fini(mlxsw_sp); mlxsw_sp_dpipe_fini(mlxsw_sp);
err_dpipe_init: err_dpipe_init:
mlxsw_sp_counter_pool_fini(mlxsw_sp);
err_counter_pool_init:
mlxsw_sp_acl_fini(mlxsw_sp); mlxsw_sp_acl_fini(mlxsw_sp);
err_acl_init: err_acl_init:
mlxsw_sp_span_fini(mlxsw_sp); mlxsw_sp_span_fini(mlxsw_sp);
err_span_init: err_span_init:
mlxsw_sp_router_fini(mlxsw_sp); mlxsw_sp_router_fini(mlxsw_sp);
err_router_init: err_router_init:
mlxsw_sp_afa_fini(mlxsw_sp);
err_afa_init:
mlxsw_sp_counter_pool_fini(mlxsw_sp);
err_counter_pool_init:
mlxsw_sp_switchdev_fini(mlxsw_sp); mlxsw_sp_switchdev_fini(mlxsw_sp);
err_switchdev_init: err_switchdev_init:
mlxsw_sp_lag_fini(mlxsw_sp); mlxsw_sp_lag_fini(mlxsw_sp);
...@@ -3760,10 +3779,11 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core) ...@@ -3760,10 +3779,11 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
mlxsw_sp_ports_remove(mlxsw_sp); mlxsw_sp_ports_remove(mlxsw_sp);
mlxsw_sp_dpipe_fini(mlxsw_sp); mlxsw_sp_dpipe_fini(mlxsw_sp);
mlxsw_sp_counter_pool_fini(mlxsw_sp);
mlxsw_sp_acl_fini(mlxsw_sp); mlxsw_sp_acl_fini(mlxsw_sp);
mlxsw_sp_span_fini(mlxsw_sp); mlxsw_sp_span_fini(mlxsw_sp);
mlxsw_sp_router_fini(mlxsw_sp); mlxsw_sp_router_fini(mlxsw_sp);
mlxsw_sp_afa_fini(mlxsw_sp);
mlxsw_sp_counter_pool_fini(mlxsw_sp);
mlxsw_sp_switchdev_fini(mlxsw_sp); mlxsw_sp_switchdev_fini(mlxsw_sp);
mlxsw_sp_lag_fini(mlxsw_sp); mlxsw_sp_lag_fini(mlxsw_sp);
mlxsw_sp_buffers_fini(mlxsw_sp); mlxsw_sp_buffers_fini(mlxsw_sp);
......
...@@ -152,6 +152,7 @@ struct mlxsw_sp { ...@@ -152,6 +152,7 @@ struct mlxsw_sp {
struct mlxsw_sp_sb *sb; struct mlxsw_sp_sb *sb;
struct mlxsw_sp_bridge *bridge; struct mlxsw_sp_bridge *bridge;
struct mlxsw_sp_router *router; struct mlxsw_sp_router *router;
struct mlxsw_afa *afa;
struct mlxsw_sp_acl *acl; struct mlxsw_sp_acl *acl;
struct mlxsw_sp_fid_core *fid_core; struct mlxsw_sp_fid_core *fid_core;
struct { struct {
......
...@@ -52,7 +52,6 @@ ...@@ -52,7 +52,6 @@
struct mlxsw_sp_acl { struct mlxsw_sp_acl {
struct mlxsw_sp *mlxsw_sp; struct mlxsw_sp *mlxsw_sp;
struct mlxsw_afk *afk; struct mlxsw_afk *afk;
struct mlxsw_afa *afa;
struct mlxsw_sp_fid *dummy_fid; struct mlxsw_sp_fid *dummy_fid;
const struct mlxsw_sp_acl_ops *ops; const struct mlxsw_sp_acl_ops *ops;
struct rhashtable ruleset_ht; struct rhashtable ruleset_ht;
...@@ -333,7 +332,7 @@ mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl) ...@@ -333,7 +332,7 @@ mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl)
rulei = kzalloc(sizeof(*rulei), GFP_KERNEL); rulei = kzalloc(sizeof(*rulei), GFP_KERNEL);
if (!rulei) if (!rulei)
return NULL; return NULL;
rulei->act_block = mlxsw_afa_block_create(acl->afa); rulei->act_block = mlxsw_afa_block_create(acl->mlxsw_sp->afa);
if (IS_ERR(rulei->act_block)) { if (IS_ERR(rulei->act_block)) {
err = PTR_ERR(rulei->act_block); err = PTR_ERR(rulei->act_block);
goto err_afa_block_create; goto err_afa_block_create;
...@@ -397,7 +396,8 @@ int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei) ...@@ -397,7 +396,8 @@ int mlxsw_sp_acl_rulei_act_drop(struct mlxsw_sp_acl_rule_info *rulei)
int mlxsw_sp_acl_rulei_act_trap(struct mlxsw_sp_acl_rule_info *rulei) int mlxsw_sp_acl_rulei_act_trap(struct mlxsw_sp_acl_rule_info *rulei)
{ {
return mlxsw_afa_block_append_trap(rulei->act_block); return mlxsw_afa_block_append_trap(rulei->act_block,
MLXSW_TRAP_ID_ACL0);
} }
int mlxsw_sp_acl_rulei_act_fwd(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_acl_rulei_act_fwd(struct mlxsw_sp *mlxsw_sp,
...@@ -653,85 +653,6 @@ int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp, ...@@ -653,85 +653,6 @@ int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
return 0; return 0;
} }
#define MLXSW_SP_KDVL_ACT_EXT_SIZE 1
static int mlxsw_sp_act_kvdl_set_add(void *priv, u32 *p_kvdl_index,
char *enc_actions, bool is_first)
{
struct mlxsw_sp *mlxsw_sp = priv;
char pefa_pl[MLXSW_REG_PEFA_LEN];
u32 kvdl_index;
int err;
/* The first action set of a TCAM entry is stored directly in TCAM,
* not KVD linear area.
*/
if (is_first)
return 0;
err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KDVL_ACT_EXT_SIZE,
&kvdl_index);
if (err)
return err;
mlxsw_reg_pefa_pack(pefa_pl, kvdl_index, enc_actions);
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pefa), pefa_pl);
if (err)
goto err_pefa_write;
*p_kvdl_index = kvdl_index;
return 0;
err_pefa_write:
mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
return err;
}
static void mlxsw_sp_act_kvdl_set_del(void *priv, u32 kvdl_index,
bool is_first)
{
struct mlxsw_sp *mlxsw_sp = priv;
if (is_first)
return;
mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
}
static int mlxsw_sp_act_kvdl_fwd_entry_add(void *priv, u32 *p_kvdl_index,
u8 local_port)
{
struct mlxsw_sp *mlxsw_sp = priv;
char ppbs_pl[MLXSW_REG_PPBS_LEN];
u32 kvdl_index;
int err;
err = mlxsw_sp_kvdl_alloc(mlxsw_sp, 1, &kvdl_index);
if (err)
return err;
mlxsw_reg_ppbs_pack(ppbs_pl, kvdl_index, local_port);
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ppbs), ppbs_pl);
if (err)
goto err_ppbs_write;
*p_kvdl_index = kvdl_index;
return 0;
err_ppbs_write:
mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
return err;
}
static void mlxsw_sp_act_kvdl_fwd_entry_del(void *priv, u32 kvdl_index)
{
struct mlxsw_sp *mlxsw_sp = priv;
mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
}
static const struct mlxsw_afa_ops mlxsw_sp_act_afa_ops = {
.kvdl_set_add = mlxsw_sp_act_kvdl_set_add,
.kvdl_set_del = mlxsw_sp_act_kvdl_set_del,
.kvdl_fwd_entry_add = mlxsw_sp_act_kvdl_fwd_entry_add,
.kvdl_fwd_entry_del = mlxsw_sp_act_kvdl_fwd_entry_del,
};
int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp) int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
{ {
const struct mlxsw_sp_acl_ops *acl_ops = &mlxsw_sp_acl_tcam_ops; const struct mlxsw_sp_acl_ops *acl_ops = &mlxsw_sp_acl_tcam_ops;
...@@ -753,14 +674,6 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp) ...@@ -753,14 +674,6 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
goto err_afk_create; goto err_afk_create;
} }
acl->afa = mlxsw_afa_create(MLXSW_CORE_RES_GET(mlxsw_sp->core,
ACL_ACTIONS_PER_SET),
&mlxsw_sp_act_afa_ops, mlxsw_sp);
if (IS_ERR(acl->afa)) {
err = PTR_ERR(acl->afa);
goto err_afa_create;
}
err = rhashtable_init(&acl->ruleset_ht, err = rhashtable_init(&acl->ruleset_ht,
&mlxsw_sp_acl_ruleset_ht_params); &mlxsw_sp_acl_ruleset_ht_params);
if (err) if (err)
...@@ -792,8 +705,6 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp) ...@@ -792,8 +705,6 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
err_fid_get: err_fid_get:
rhashtable_destroy(&acl->ruleset_ht); rhashtable_destroy(&acl->ruleset_ht);
err_rhashtable_init: err_rhashtable_init:
mlxsw_afa_destroy(acl->afa);
err_afa_create:
mlxsw_afk_destroy(acl->afk); mlxsw_afk_destroy(acl->afk);
err_afk_create: err_afk_create:
kfree(acl); kfree(acl);
...@@ -810,7 +721,6 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp) ...@@ -810,7 +721,6 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp)
WARN_ON(!list_empty(&acl->rules)); WARN_ON(!list_empty(&acl->rules));
mlxsw_sp_fid_put(acl->dummy_fid); mlxsw_sp_fid_put(acl->dummy_fid);
rhashtable_destroy(&acl->ruleset_ht); rhashtable_destroy(&acl->ruleset_ht);
mlxsw_afa_destroy(acl->afa);
mlxsw_afk_destroy(acl->afk); mlxsw_afk_destroy(acl->afk);
kfree(acl); kfree(acl);
} }
/*
* drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c
* Copyright (c) 2017 Mellanox Technologies. All rights reserved.
* Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
* Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
*
* 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.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "spectrum_acl_flex_actions.h"
#include "core_acl_flex_actions.h"
#define MLXSW_SP_KVDL_ACT_EXT_SIZE 1
static int mlxsw_sp_act_kvdl_set_add(void *priv, u32 *p_kvdl_index,
char *enc_actions, bool is_first)
{
struct mlxsw_sp *mlxsw_sp = priv;
char pefa_pl[MLXSW_REG_PEFA_LEN];
u32 kvdl_index;
int err;
/* The first action set of a TCAM entry is stored directly in TCAM,
* not KVD linear area.
*/
if (is_first)
return 0;
err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ACT_EXT_SIZE,
&kvdl_index);
if (err)
return err;
mlxsw_reg_pefa_pack(pefa_pl, kvdl_index, enc_actions);
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pefa), pefa_pl);
if (err)
goto err_pefa_write;
*p_kvdl_index = kvdl_index;
return 0;
err_pefa_write:
mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
return err;
}
static void mlxsw_sp_act_kvdl_set_del(void *priv, u32 kvdl_index,
bool is_first)
{
struct mlxsw_sp *mlxsw_sp = priv;
if (is_first)
return;
mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
}
static int mlxsw_sp_act_kvdl_fwd_entry_add(void *priv, u32 *p_kvdl_index,
u8 local_port)
{
struct mlxsw_sp *mlxsw_sp = priv;
char ppbs_pl[MLXSW_REG_PPBS_LEN];
u32 kvdl_index;
int err;
err = mlxsw_sp_kvdl_alloc(mlxsw_sp, 1, &kvdl_index);
if (err)
return err;
mlxsw_reg_ppbs_pack(ppbs_pl, kvdl_index, local_port);
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ppbs), ppbs_pl);
if (err)
goto err_ppbs_write;
*p_kvdl_index = kvdl_index;
return 0;
err_ppbs_write:
mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
return err;
}
static void mlxsw_sp_act_kvdl_fwd_entry_del(void *priv, u32 kvdl_index)
{
struct mlxsw_sp *mlxsw_sp = priv;
mlxsw_sp_kvdl_free(mlxsw_sp, kvdl_index);
}
static const struct mlxsw_afa_ops mlxsw_sp_act_afa_ops = {
.kvdl_set_add = mlxsw_sp_act_kvdl_set_add,
.kvdl_set_del = mlxsw_sp_act_kvdl_set_del,
.kvdl_fwd_entry_add = mlxsw_sp_act_kvdl_fwd_entry_add,
.kvdl_fwd_entry_del = mlxsw_sp_act_kvdl_fwd_entry_del,
};
int mlxsw_sp_afa_init(struct mlxsw_sp *mlxsw_sp)
{
mlxsw_sp->afa = mlxsw_afa_create(MLXSW_CORE_RES_GET(mlxsw_sp->core,
ACL_ACTIONS_PER_SET),
&mlxsw_sp_act_afa_ops, mlxsw_sp);
return PTR_ERR_OR_ZERO(mlxsw_sp->afa);
}
void mlxsw_sp_afa_fini(struct mlxsw_sp *mlxsw_sp)
{
mlxsw_afa_destroy(mlxsw_sp->afa);
}
/*
* drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.h
* Copyright (c) 2017 Mellanox Technologies. All rights reserved.
* Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
* Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
*
* 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.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MLXSW_SPECTRUM_ACL_FLEX_KEYS_H
#define _MLXSW_SPECTRUM_ACL_FLEX_KEYS_H
#include "spectrum.h"
int mlxsw_sp_afa_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_afa_fini(struct mlxsw_sp *mlxsw_sp);
#endif
...@@ -5049,6 +5049,11 @@ int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif) ...@@ -5049,6 +5049,11 @@ int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif)
return rif->dev->ifindex; return rif->dev->ifindex;
} }
const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif)
{
return rif->dev;
}
static struct mlxsw_sp_rif * static struct mlxsw_sp_rif *
mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_rif_params *params) const struct mlxsw_sp_rif_params *params)
......
...@@ -69,6 +69,7 @@ u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif); ...@@ -69,6 +69,7 @@ u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif);
u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif); u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif);
u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif); u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif);
int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif); int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif);
const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif);
int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif, struct mlxsw_sp_rif *rif,
enum mlxsw_sp_rif_counter_dir dir, enum mlxsw_sp_rif_counter_dir dir,
......
...@@ -62,6 +62,8 @@ enum { ...@@ -62,6 +62,8 @@ enum {
MLXSW_TRAP_ID_TTLERROR = 0x53, MLXSW_TRAP_ID_TTLERROR = 0x53,
MLXSW_TRAP_ID_LBERROR = 0x54, MLXSW_TRAP_ID_LBERROR = 0x54,
MLXSW_TRAP_ID_IPV4_OSPF = 0x55, MLXSW_TRAP_ID_IPV4_OSPF = 0x55,
MLXSW_TRAP_ID_IPV4_PIM = 0x58,
MLXSW_TRAP_ID_RPF = 0x5C,
MLXSW_TRAP_ID_IP2ME = 0x5F, MLXSW_TRAP_ID_IP2ME = 0x5F,
MLXSW_TRAP_ID_IPV6_UNSPECIFIED_ADDRESS = 0x60, MLXSW_TRAP_ID_IPV6_UNSPECIFIED_ADDRESS = 0x60,
MLXSW_TRAP_ID_IPV6_LINK_LOCAL_DEST = 0x61, MLXSW_TRAP_ID_IPV6_LINK_LOCAL_DEST = 0x61,
...@@ -89,6 +91,8 @@ enum { ...@@ -89,6 +91,8 @@ enum {
MLXSW_TRAP_ID_ROUTER_ALERT_IPV4 = 0xD6, MLXSW_TRAP_ID_ROUTER_ALERT_IPV4 = 0xD6,
MLXSW_TRAP_ID_ROUTER_ALERT_IPV6 = 0xD7, MLXSW_TRAP_ID_ROUTER_ALERT_IPV6 = 0xD7,
MLXSW_TRAP_ID_ACL0 = 0x1C0, MLXSW_TRAP_ID_ACL0 = 0x1C0,
/* Multicast trap used for routes with trap action */
MLXSW_TRAP_ID_ACL1 = 0x1C1,
MLXSW_TRAP_ID_MAX = 0x1FF MLXSW_TRAP_ID_MAX = 0x1FF
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册