Skip to content

Commit

Permalink
Merge tag 'mlx5-updates-2019-11-22' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-updates-2019-11-22

1) Misc Cleanups
2) Software steering support for Geneve
====================

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
  • Loading branch information
Jakub Kicinski committed Nov 24, 2019
2 parents d46b7e4 + 90ac245 commit 9520aea
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 93 deletions.
26 changes: 10 additions & 16 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
struct dst_entry *dst;
struct neighbour *n;

#if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6)
int ret;

ret = ipv6_stub->ipv6_dst_lookup(dev_net(mirred_dev), NULL, &dst,
Expand All @@ -157,9 +156,6 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
dst_release(dst);
return ret;
}
#else
return -EOPNOTSUPP;
#endif

n = dst_neigh_lookup(dst, &fl6->daddr);
dst_release(dst);
Expand Down Expand Up @@ -240,13 +236,13 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
mlx5_core_warn(priv->mdev, "encap size %d too big, max supported is %d\n",
ipv4_encap_size, max_encap_size);
err = -EOPNOTSUPP;
goto out;
goto release_neigh;
}

encap_header = kzalloc(ipv4_encap_size, GFP_KERNEL);
if (!encap_header) {
err = -ENOMEM;
goto out;
goto release_neigh;
}

/* used by mlx5e_detach_encap to lookup a neigh hash table
Expand Down Expand Up @@ -298,7 +294,7 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
/* the encap entry will be made valid on neigh update event
* and not used before that.
*/
goto out;
goto release_neigh;
}
e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev,
e->reformat_type,
Expand All @@ -318,9 +314,8 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e);
free_encap:
kfree(encap_header);
out:
if (n)
neigh_release(n);
release_neigh:
neigh_release(n);
return err;
}

Expand Down Expand Up @@ -359,13 +354,13 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
mlx5_core_warn(priv->mdev, "encap size %d too big, max supported is %d\n",
ipv6_encap_size, max_encap_size);
err = -EOPNOTSUPP;
goto out;
goto release_neigh;
}

encap_header = kzalloc(ipv6_encap_size, GFP_KERNEL);
if (!encap_header) {
err = -ENOMEM;
goto out;
goto release_neigh;
}

/* used by mlx5e_detach_encap to lookup a neigh hash table
Expand Down Expand Up @@ -416,7 +411,7 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
/* the encap entry will be made valid on neigh update event
* and not used before that.
*/
goto out;
goto release_neigh;
}

e->pkt_reformat = mlx5_packet_reformat_alloc(priv->mdev,
Expand All @@ -437,9 +432,8 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e);
free_encap:
kfree(encap_header);
out:
if (n)
neigh_release(n);
release_neigh:
neigh_release(n);
return err;
}

Expand Down
7 changes: 7 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,16 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv,
struct net_device *mirred_dev,
struct mlx5e_encap_entry *e);

#if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6)
int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
struct net_device *mirred_dev,
struct mlx5e_encap_entry *e);
#else
static inline int
mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv,
struct net_device *mirred_dev,
struct mlx5e_encap_entry *e) { return -EOPNOTSUPP; }
#endif

bool mlx5e_tc_tun_device_to_offload(struct mlx5e_priv *priv,
struct net_device *netdev);
Expand Down
60 changes: 48 additions & 12 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,52 @@ static bool dr_mask_is_gre_set(struct mlx5dr_match_misc *misc)
DR_MASK_IS_OUTER_MPLS_OVER_GRE_UDP_SET((_misc2), gre) || \
DR_MASK_IS_OUTER_MPLS_OVER_GRE_UDP_SET((_misc2), udp))

static bool dr_mask_is_flex_parser_tnl_set(struct mlx5dr_match_misc3 *misc3)
static bool
dr_mask_is_misc3_vxlan_gpe_set(struct mlx5dr_match_misc3 *misc3)
{
return (misc3->outer_vxlan_gpe_vni ||
misc3->outer_vxlan_gpe_next_protocol ||
misc3->outer_vxlan_gpe_flags);
}

static bool
dr_matcher_supp_flex_parser_vxlan_gpe(struct mlx5dr_cmd_caps *caps)
{
return caps->flex_protocols &
MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED;
}

static bool
dr_mask_is_flex_parser_tnl_vxlan_gpe_set(struct mlx5dr_match_param *mask,
struct mlx5dr_domain *dmn)
{
return dr_mask_is_misc3_vxlan_gpe_set(&mask->misc3) &&
dr_matcher_supp_flex_parser_vxlan_gpe(&dmn->info.caps);
}

static bool dr_mask_is_misc_geneve_set(struct mlx5dr_match_misc *misc)
{
return misc->geneve_vni ||
misc->geneve_oam ||
misc->geneve_protocol_type ||
misc->geneve_opt_len;
}

static bool
dr_matcher_supp_flex_parser_geneve(struct mlx5dr_cmd_caps *caps)
{
return caps->flex_protocols &
MLX5_FLEX_PARSER_GENEVE_ENABLED;
}

static bool
dr_mask_is_flex_parser_tnl_geneve_set(struct mlx5dr_match_param *mask,
struct mlx5dr_domain *dmn)
{
return dr_mask_is_misc_geneve_set(&mask->misc) &&
dr_matcher_supp_flex_parser_geneve(&dmn->info.caps);
}

static bool dr_mask_is_flex_parser_icmpv6_set(struct mlx5dr_match_misc3 *misc3)
{
return (misc3->icmpv6_type || misc3->icmpv6_code ||
Expand Down Expand Up @@ -137,13 +176,6 @@ static bool dr_mask_is_gvmi_or_qpn_set(struct mlx5dr_match_misc *misc)
return (misc->source_sqn || misc->source_port);
}

static bool
dr_matcher_supp_flex_parser_vxlan_gpe(struct mlx5dr_domain *dmn)
{
return dmn->info.caps.flex_protocols &
MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED;
}

int mlx5dr_matcher_select_builders(struct mlx5dr_matcher *matcher,
struct mlx5dr_matcher_rx_tx *nic_matcher,
enum mlx5dr_ipv outer_ipv,
Expand Down Expand Up @@ -262,10 +294,14 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher,
inner, rx);
}

if (dr_mask_is_flex_parser_tnl_set(&mask.misc3) &&
dr_matcher_supp_flex_parser_vxlan_gpe(dmn))
mlx5dr_ste_build_flex_parser_tnl(&sb[idx++], &mask,
inner, rx);
if (dr_mask_is_flex_parser_tnl_vxlan_gpe_set(&mask, dmn))
mlx5dr_ste_build_flex_parser_tnl_vxlan_gpe(&sb[idx++],
&mask,
inner, rx);
else if (dr_mask_is_flex_parser_tnl_geneve_set(&mask, dmn))
mlx5dr_ste_build_flex_parser_tnl_geneve(&sb[idx++],
&mask,
inner, rx);

if (DR_MASK_IS_ETH_L4_MISC_SET(mask.misc3, outer))
mlx5dr_ste_build_eth_l4_misc(&sb[idx++], &mask, inner, rx);
Expand Down
126 changes: 84 additions & 42 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
Original file line number Diff line number Diff line change
Expand Up @@ -2083,68 +2083,110 @@ void mlx5dr_ste_build_eth_l4_misc(struct mlx5dr_ste_build *sb,
sb->ste_build_tag_func = &dr_ste_build_eth_l4_misc_tag;
}

static void dr_ste_build_flex_parser_tnl_bit_mask(struct mlx5dr_match_param *value,
bool inner, u8 *bit_mask)
static void
dr_ste_build_flex_parser_tnl_vxlan_gpe_bit_mask(struct mlx5dr_match_param *value,
bool inner, u8 *bit_mask)
{
struct mlx5dr_match_misc3 *misc_3_mask = &value->misc3;

if (misc_3_mask->outer_vxlan_gpe_flags ||
misc_3_mask->outer_vxlan_gpe_next_protocol) {
MLX5_SET(ste_flex_parser_tnl, bit_mask,
flex_parser_tunneling_header_63_32,
(misc_3_mask->outer_vxlan_gpe_flags << 24) |
(misc_3_mask->outer_vxlan_gpe_next_protocol));
misc_3_mask->outer_vxlan_gpe_flags = 0;
misc_3_mask->outer_vxlan_gpe_next_protocol = 0;
}

if (misc_3_mask->outer_vxlan_gpe_vni) {
MLX5_SET(ste_flex_parser_tnl, bit_mask,
flex_parser_tunneling_header_31_0,
misc_3_mask->outer_vxlan_gpe_vni << 8);
misc_3_mask->outer_vxlan_gpe_vni = 0;
}
DR_STE_SET_MASK_V(flex_parser_tnl_vxlan_gpe, bit_mask,
outer_vxlan_gpe_flags,
misc_3_mask, outer_vxlan_gpe_flags);
DR_STE_SET_MASK_V(flex_parser_tnl_vxlan_gpe, bit_mask,
outer_vxlan_gpe_next_protocol,
misc_3_mask, outer_vxlan_gpe_next_protocol);
DR_STE_SET_MASK_V(flex_parser_tnl_vxlan_gpe, bit_mask,
outer_vxlan_gpe_vni,
misc_3_mask, outer_vxlan_gpe_vni);
}

static int dr_ste_build_flex_parser_tnl_tag(struct mlx5dr_match_param *value,
struct mlx5dr_ste_build *sb,
u8 *hw_ste_p)
static int
dr_ste_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value,
struct mlx5dr_ste_build *sb,
u8 *hw_ste_p)
{
struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
struct mlx5dr_match_misc3 *misc3 = &value->misc3;
u8 *tag = hw_ste->tag;

if (misc3->outer_vxlan_gpe_flags ||
misc3->outer_vxlan_gpe_next_protocol) {
MLX5_SET(ste_flex_parser_tnl, tag,
flex_parser_tunneling_header_63_32,
(misc3->outer_vxlan_gpe_flags << 24) |
(misc3->outer_vxlan_gpe_next_protocol));
misc3->outer_vxlan_gpe_flags = 0;
misc3->outer_vxlan_gpe_next_protocol = 0;
}

if (misc3->outer_vxlan_gpe_vni) {
MLX5_SET(ste_flex_parser_tnl, tag,
flex_parser_tunneling_header_31_0,
misc3->outer_vxlan_gpe_vni << 8);
misc3->outer_vxlan_gpe_vni = 0;
}
DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
outer_vxlan_gpe_flags, misc3,
outer_vxlan_gpe_flags);
DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
outer_vxlan_gpe_next_protocol, misc3,
outer_vxlan_gpe_next_protocol);
DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
outer_vxlan_gpe_vni, misc3,
outer_vxlan_gpe_vni);

return 0;
}

void mlx5dr_ste_build_flex_parser_tnl(struct mlx5dr_ste_build *sb,
struct mlx5dr_match_param *mask,
bool inner, bool rx)
void mlx5dr_ste_build_flex_parser_tnl_vxlan_gpe(struct mlx5dr_ste_build *sb,
struct mlx5dr_match_param *mask,
bool inner, bool rx)
{
dr_ste_build_flex_parser_tnl_vxlan_gpe_bit_mask(mask, inner,
sb->bit_mask);

sb->rx = rx;
sb->inner = inner;
sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER;
sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_vxlan_gpe_tag;
}

static void
dr_ste_build_flex_parser_tnl_geneve_bit_mask(struct mlx5dr_match_param *value,
u8 *bit_mask)
{
dr_ste_build_flex_parser_tnl_bit_mask(mask, inner, sb->bit_mask);
struct mlx5dr_match_misc *misc_mask = &value->misc;

DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask,
geneve_protocol_type,
misc_mask, geneve_protocol_type);
DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask,
geneve_oam,
misc_mask, geneve_oam);
DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask,
geneve_opt_len,
misc_mask, geneve_opt_len);
DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask,
geneve_vni,
misc_mask, geneve_vni);
}

static int
dr_ste_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value,
struct mlx5dr_ste_build *sb,
u8 *hw_ste_p)
{
struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
struct mlx5dr_match_misc *misc = &value->misc;
u8 *tag = hw_ste->tag;

DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
geneve_protocol_type, misc, geneve_protocol_type);
DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
geneve_oam, misc, geneve_oam);
DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
geneve_opt_len, misc, geneve_opt_len);
DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
geneve_vni, misc, geneve_vni);

return 0;
}

void mlx5dr_ste_build_flex_parser_tnl_geneve(struct mlx5dr_ste_build *sb,
struct mlx5dr_match_param *mask,
bool inner, bool rx)
{
dr_ste_build_flex_parser_tnl_geneve_bit_mask(mask, sb->bit_mask);
sb->rx = rx;
sb->inner = inner;
sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER;
sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_tag;
sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_geneve_tag;
}

static void dr_ste_build_register_0_bit_mask(struct mlx5dr_match_param *value,
Expand Down
9 changes: 6 additions & 3 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,12 @@ int mlx5dr_ste_build_flex_parser_1(struct mlx5dr_ste_build *sb,
struct mlx5dr_match_param *mask,
struct mlx5dr_cmd_caps *caps,
bool inner, bool rx);
void mlx5dr_ste_build_flex_parser_tnl(struct mlx5dr_ste_build *sb,
struct mlx5dr_match_param *mask,
bool inner, bool rx);
void mlx5dr_ste_build_flex_parser_tnl_vxlan_gpe(struct mlx5dr_ste_build *sb,
struct mlx5dr_match_param *mask,
bool inner, bool rx);
void mlx5dr_ste_build_flex_parser_tnl_geneve(struct mlx5dr_ste_build *sb,
struct mlx5dr_match_param *mask,
bool inner, bool rx);
void mlx5dr_ste_build_general_purpose(struct mlx5dr_ste_build *sb,
struct mlx5dr_match_param *mask,
bool inner, bool rx);
Expand Down
24 changes: 24 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5_ifc_dr.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,30 @@ struct mlx5_ifc_ste_flex_parser_tnl_bits {
u8 reserved_at_40[0x40];
};

struct mlx5_ifc_ste_flex_parser_tnl_vxlan_gpe_bits {
u8 outer_vxlan_gpe_flags[0x8];
u8 reserved_at_8[0x10];
u8 outer_vxlan_gpe_next_protocol[0x8];

u8 outer_vxlan_gpe_vni[0x18];
u8 reserved_at_38[0x8];

u8 reserved_at_40[0x40];
};

struct mlx5_ifc_ste_flex_parser_tnl_geneve_bits {
u8 reserved_at_0[0x2];
u8 geneve_opt_len[0x6];
u8 geneve_oam[0x1];
u8 reserved_at_9[0x7];
u8 geneve_protocol_type[0x10];

u8 geneve_vni[0x18];
u8 reserved_at_38[0x8];

u8 reserved_at_40[0x40];
};

struct mlx5_ifc_ste_general_purpose_bits {
u8 general_purpose_lookup_field[0x20];

Expand Down
Loading

0 comments on commit 9520aea

Please sign in to comment.