Skip to content

Commit 41a6351

Browse files
committed
Merge branch 'mlxsw-Add-support-for-Q-in-VNI'
Ido Schimmel says: ==================== mlxsw: Add support for Q-in-VNI This patch set adds support for Q-in-VNI over Spectrum-{2,3} ASICs. Q-in-VNI is like regular VxLAN encapsulation with the sole difference that overlay packets can contain a VLAN tag. In Linux, this is achieved by adding the VxLAN device to a 802.1ad bridge instead of a 802.1q bridge. From mlxsw perspective, Q-in-VNI support entails two main changes: 1. An outer VLAN tag should always be pushed to the overlay packet during decapsulation 2. The EtherType used during decapsulation should be 802.1ad (0x88a8) instead of the default 802.1q (0x8100) Patch set overview: Patches #1-#3 add required device registers and fields Patch #4 performs small refactoring to allow code re-use Patches #5-#7 make the EtherType used during decapsulation a property of the tunnel port (i.e., VxLAN). This leads to the driver vetoing configurations in which VxLAN devices are member in both 802.1ad and 802.1q/802.1d bridges. Will be handled in the future by determining the overlay EtherType on the egress port instead Patch #8 adds support for Q-in-VNI for Spectrum-2 and newer ASICs Patches #9-#10 veto Q-in-VNI for Spectrum-1 ASICs due to some hardware limitations. Can be worked around, but decided not to support it for now Patch #11 adjusts mlxsw to stop vetoing addition of VXLAN devices to 802.1ad bridges Patch #12 adds a generic forwarding test that can be used with both veth pairs and physical ports with a loopback Patch #13 adds a test to make sure mlxsw vetoes unsupported Q-in-VNI configurations ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents a8d5dd1 + 477ce6d commit 41a6351

File tree

10 files changed

+703
-47
lines changed

10 files changed

+703
-47
lines changed

drivers/net/ethernet/mellanox/mlxsw/reg.h

Lines changed: 122 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,13 @@ mlxsw_reg_sfd_uc_tunnel_pack(char *payload, int rec_index,
581581
mlxsw_reg_sfd_uc_tunnel_protocol_set(payload, rec_index, proto);
582582
}
583583

584+
enum mlxsw_reg_tunnel_port {
585+
MLXSW_REG_TUNNEL_PORT_NVE,
586+
MLXSW_REG_TUNNEL_PORT_VPLS,
587+
MLXSW_REG_TUNNEL_PORT_FLEX_TUNNEL0,
588+
MLXSW_REG_TUNNEL_PORT_FLEX_TUNNEL1,
589+
};
590+
584591
/* SFN - Switch FDB Notification Register
585592
* -------------------------------------------
586593
* The switch provides notifications on newly learned FDB entries and
@@ -738,13 +745,6 @@ MLXSW_ITEM32_INDEXED(reg, sfn, uc_tunnel_protocol, MLXSW_REG_SFN_BASE_LEN, 27,
738745
MLXSW_ITEM32_INDEXED(reg, sfn, uc_tunnel_uip_lsb, MLXSW_REG_SFN_BASE_LEN, 0,
739746
24, MLXSW_REG_SFN_REC_LEN, 0x0C, false);
740747

741-
enum mlxsw_reg_sfn_tunnel_port {
742-
MLXSW_REG_SFN_TUNNEL_PORT_NVE,
743-
MLXSW_REG_SFN_TUNNEL_PORT_VPLS,
744-
MLXSW_REG_SFN_TUNNEL_FLEX_TUNNEL0,
745-
MLXSW_REG_SFN_TUNNEL_FLEX_TUNNEL1,
746-
};
747-
748748
/* reg_sfn_uc_tunnel_port
749749
* Tunnel port.
750750
* Reserved on Spectrum.
@@ -821,8 +821,16 @@ static inline void mlxsw_reg_spms_vid_pack(char *payload, u16 vid,
821821

822822
MLXSW_REG_DEFINE(spvid, MLXSW_REG_SPVID_ID, MLXSW_REG_SPVID_LEN);
823823

824+
/* reg_spvid_tport
825+
* Port is tunnel port.
826+
* Reserved when SwitchX/-2 or Spectrum-1.
827+
* Access: Index
828+
*/
829+
MLXSW_ITEM32(reg, spvid, tport, 0x00, 24, 1);
830+
824831
/* reg_spvid_local_port
825-
* Local port number.
832+
* When tport = 0: Local port number. Not supported for CPU port.
833+
* When tport = 1: Tunnel port.
826834
* Access: Index
827835
*/
828836
MLXSW_ITEM32(reg, spvid, local_port, 0x00, 16, 8);
@@ -1693,6 +1701,109 @@ static inline void mlxsw_reg_svfa_pack(char *payload, u8 local_port,
16931701
mlxsw_reg_svfa_vid_set(payload, vid);
16941702
}
16951703

1704+
/* SPVTR - Switch Port VLAN Stacking Register
1705+
* ------------------------------------------
1706+
* The Switch Port VLAN Stacking register configures the VLAN mode of the port
1707+
* to enable VLAN stacking.
1708+
*/
1709+
#define MLXSW_REG_SPVTR_ID 0x201D
1710+
#define MLXSW_REG_SPVTR_LEN 0x10
1711+
1712+
MLXSW_REG_DEFINE(spvtr, MLXSW_REG_SPVTR_ID, MLXSW_REG_SPVTR_LEN);
1713+
1714+
/* reg_spvtr_tport
1715+
* Port is tunnel port.
1716+
* Access: Index
1717+
*
1718+
* Note: Reserved when SwitchX/-2 or Spectrum-1.
1719+
*/
1720+
MLXSW_ITEM32(reg, spvtr, tport, 0x00, 24, 1);
1721+
1722+
/* reg_spvtr_local_port
1723+
* When tport = 0: local port number (Not supported from/to CPU).
1724+
* When tport = 1: tunnel port.
1725+
* Access: Index
1726+
*/
1727+
MLXSW_ITEM32(reg, spvtr, local_port, 0x00, 16, 8);
1728+
1729+
/* reg_spvtr_ippe
1730+
* Ingress Port Prio Mode Update Enable.
1731+
* When set, the Port Prio Mode is updated with the provided ipprio_mode field.
1732+
* Reserved on Get operations.
1733+
* Access: OP
1734+
*/
1735+
MLXSW_ITEM32(reg, spvtr, ippe, 0x04, 31, 1);
1736+
1737+
/* reg_spvtr_ipve
1738+
* Ingress Port VID Mode Update Enable.
1739+
* When set, the Ingress Port VID Mode is updated with the provided ipvid_mode
1740+
* field.
1741+
* Reserved on Get operations.
1742+
* Access: OP
1743+
*/
1744+
MLXSW_ITEM32(reg, spvtr, ipve, 0x04, 30, 1);
1745+
1746+
/* reg_spvtr_epve
1747+
* Egress Port VID Mode Update Enable.
1748+
* When set, the Egress Port VID Mode is updated with the provided epvid_mode
1749+
* field.
1750+
* Access: OP
1751+
*/
1752+
MLXSW_ITEM32(reg, spvtr, epve, 0x04, 29, 1);
1753+
1754+
/* reg_spvtr_ipprio_mode
1755+
* Ingress Port Priority Mode.
1756+
* This controls the PCP and DEI of the new outer VLAN
1757+
* Note: for SwitchX/-2 the DEI is not affected.
1758+
* 0: use port default PCP and DEI (configured by QPDPC).
1759+
* 1: use C-VLAN PCP and DEI.
1760+
* Has no effect when ipvid_mode = 0.
1761+
* Reserved when tport = 1.
1762+
* Access: RW
1763+
*/
1764+
MLXSW_ITEM32(reg, spvtr, ipprio_mode, 0x04, 20, 4);
1765+
1766+
enum mlxsw_reg_spvtr_ipvid_mode {
1767+
/* IEEE Compliant PVID (default) */
1768+
MLXSW_REG_SPVTR_IPVID_MODE_IEEE_COMPLIANT_PVID,
1769+
/* Push VLAN (for VLAN stacking, except prio tagged packets) */
1770+
MLXSW_REG_SPVTR_IPVID_MODE_PUSH_VLAN_FOR_UNTAGGED_PACKET,
1771+
/* Always push VLAN (also for prio tagged packets) */
1772+
MLXSW_REG_SPVTR_IPVID_MODE_ALWAYS_PUSH_VLAN,
1773+
};
1774+
1775+
/* reg_spvtr_ipvid_mode
1776+
* Ingress Port VLAN-ID Mode.
1777+
* For Spectrum family, this affects the values of SPVM.i
1778+
* Access: RW
1779+
*/
1780+
MLXSW_ITEM32(reg, spvtr, ipvid_mode, 0x04, 16, 4);
1781+
1782+
enum mlxsw_reg_spvtr_epvid_mode {
1783+
/* IEEE Compliant VLAN membership */
1784+
MLXSW_REG_SPVTR_EPVID_MODE_IEEE_COMPLIANT_VLAN_MEMBERSHIP,
1785+
/* Pop VLAN (for VLAN stacking) */
1786+
MLXSW_REG_SPVTR_EPVID_MODE_POP_VLAN,
1787+
};
1788+
1789+
/* reg_spvtr_epvid_mode
1790+
* Egress Port VLAN-ID Mode.
1791+
* For Spectrum family, this affects the values of SPVM.e,u,pt.
1792+
* Access: WO
1793+
*/
1794+
MLXSW_ITEM32(reg, spvtr, epvid_mode, 0x04, 0, 4);
1795+
1796+
static inline void mlxsw_reg_spvtr_pack(char *payload, bool tport,
1797+
u8 local_port,
1798+
enum mlxsw_reg_spvtr_ipvid_mode ipvid_mode)
1799+
{
1800+
MLXSW_REG_ZERO(spvtr, payload);
1801+
mlxsw_reg_spvtr_tport_set(payload, tport);
1802+
mlxsw_reg_spvtr_local_port_set(payload, local_port);
1803+
mlxsw_reg_spvtr_ipvid_mode_set(payload, ipvid_mode);
1804+
mlxsw_reg_spvtr_ipve_set(payload, true);
1805+
}
1806+
16961807
/* SVPE - Switch Virtual-Port Enabling Register
16971808
* --------------------------------------------
16981809
* Enables port virtualization.
@@ -10507,13 +10618,6 @@ enum mlxsw_reg_tnumt_record_type {
1050710618
*/
1050810619
MLXSW_ITEM32(reg, tnumt, record_type, 0x00, 28, 4);
1050910620

10510-
enum mlxsw_reg_tnumt_tunnel_port {
10511-
MLXSW_REG_TNUMT_TUNNEL_PORT_NVE,
10512-
MLXSW_REG_TNUMT_TUNNEL_PORT_VPLS,
10513-
MLXSW_REG_TNUMT_TUNNEL_FLEX_TUNNEL0,
10514-
MLXSW_REG_TNUMT_TUNNEL_FLEX_TUNNEL1,
10515-
};
10516-
1051710621
/* reg_tnumt_tunnel_port
1051810622
* Tunnel port.
1051910623
* Access: RW
@@ -10561,7 +10665,7 @@ MLXSW_ITEM32_INDEXED(reg, tnumt, udip_ptr, 0x0C, 0, 24, 0x04, 0x00, false);
1056110665

1056210666
static inline void mlxsw_reg_tnumt_pack(char *payload,
1056310667
enum mlxsw_reg_tnumt_record_type type,
10564-
enum mlxsw_reg_tnumt_tunnel_port tport,
10668+
enum mlxsw_reg_tunnel_port tport,
1056510669
u32 underlay_mc_ptr, bool vnext,
1056610670
u32 next_underlay_mc_ptr,
1056710671
u8 record_size)
@@ -10725,13 +10829,6 @@ static inline void mlxsw_reg_tndem_pack(char *payload, u8 underlay_ecn,
1072510829

1072610830
MLXSW_REG_DEFINE(tnpc, MLXSW_REG_TNPC_ID, MLXSW_REG_TNPC_LEN);
1072710831

10728-
enum mlxsw_reg_tnpc_tunnel_port {
10729-
MLXSW_REG_TNPC_TUNNEL_PORT_NVE,
10730-
MLXSW_REG_TNPC_TUNNEL_PORT_VPLS,
10731-
MLXSW_REG_TNPC_TUNNEL_FLEX_TUNNEL0,
10732-
MLXSW_REG_TNPC_TUNNEL_FLEX_TUNNEL1,
10733-
};
10734-
1073510832
/* reg_tnpc_tunnel_port
1073610833
* Tunnel port.
1073710834
* Access: Index
@@ -10751,7 +10848,7 @@ MLXSW_ITEM32(reg, tnpc, learn_enable_v6, 0x04, 1, 1);
1075110848
MLXSW_ITEM32(reg, tnpc, learn_enable_v4, 0x04, 0, 1);
1075210849

1075310850
static inline void mlxsw_reg_tnpc_pack(char *payload,
10754-
enum mlxsw_reg_tnpc_tunnel_port tport,
10851+
enum mlxsw_reg_tunnel_port tport,
1075510852
bool learn_enable)
1075610853
{
1075710854
MLXSW_REG_ZERO(tnpc, payload);
@@ -11320,6 +11417,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
1132011417
MLXSW_REG(slcor),
1132111418
MLXSW_REG(spmlr),
1132211419
MLXSW_REG(svfa),
11420+
MLXSW_REG(spvtr),
1132311421
MLXSW_REG(svpe),
1132411422
MLXSW_REG(sfmr),
1132511423
MLXSW_REG(spvmlr),

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
384384
return err;
385385
}
386386

387-
static int mlxsw_sp_ethtype_to_sver_type(u16 ethtype, u8 *p_sver_type)
387+
int mlxsw_sp_ethtype_to_sver_type(u16 ethtype, u8 *p_sver_type)
388388
{
389389
switch (ethtype) {
390390
case ETH_P_8021Q:

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ int mlxsw_sp_port_vid_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
584584
int mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port *mlxsw_sp_port, bool enable);
585585
int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
586586
bool learn_enable);
587+
int mlxsw_sp_ethtype_to_sver_type(u16 ethtype, u8 *p_sver_type);
587588
int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
588589
u16 ethtype);
589590
struct mlxsw_sp_port_vlan *
@@ -1202,6 +1203,7 @@ struct mlxsw_sp_nve_params {
12021203
enum mlxsw_sp_nve_type type;
12031204
__be32 vni;
12041205
const struct net_device *dev;
1206+
u16 ethertype;
12051207
};
12061208

12071209
extern const struct mlxsw_sp_nve_ops *mlxsw_sp1_nve_ops_arr[];

drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ mlxsw_sp_nve_mc_record_refresh(struct mlxsw_sp_nve_mc_record *mc_record)
368368
next_valid = true;
369369
}
370370

371-
mlxsw_reg_tnumt_pack(tnumt_pl, type, MLXSW_REG_TNUMT_TUNNEL_PORT_NVE,
371+
mlxsw_reg_tnumt_pack(tnumt_pl, type, MLXSW_REG_TUNNEL_PORT_NVE,
372372
mc_record->kvdl_index, next_valid,
373373
next_kvdl_index, mc_record->num_entries);
374374

@@ -798,11 +798,11 @@ int mlxsw_sp_nve_fid_enable(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *fid,
798798

799799
ops = nve->nve_ops_arr[params->type];
800800

801-
if (!ops->can_offload(nve, params->dev, extack))
801+
if (!ops->can_offload(nve, params, extack))
802802
return -EINVAL;
803803

804804
memset(&config, 0, sizeof(config));
805-
ops->nve_config(nve, params->dev, &config);
805+
ops->nve_config(nve, params, &config);
806806
if (nve->num_nve_tunnels &&
807807
memcmp(&config, &nve->config, sizeof(config))) {
808808
NL_SET_ERR_MSG_MOD(extack, "Conflicting NVE tunnels configuration");

drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct mlxsw_sp_nve_config {
1818
u32 ul_tb_id;
1919
enum mlxsw_sp_l3proto ul_proto;
2020
union mlxsw_sp_l3addr ul_sip;
21+
u16 ethertype;
2122
};
2223

2324
struct mlxsw_sp_nve {
@@ -35,10 +36,10 @@ struct mlxsw_sp_nve {
3536
struct mlxsw_sp_nve_ops {
3637
enum mlxsw_sp_nve_type type;
3738
bool (*can_offload)(const struct mlxsw_sp_nve *nve,
38-
const struct net_device *dev,
39+
const struct mlxsw_sp_nve_params *params,
3940
struct netlink_ext_ack *extack);
4041
void (*nve_config)(const struct mlxsw_sp_nve *nve,
41-
const struct net_device *dev,
42+
const struct mlxsw_sp_nve_params *params,
4243
struct mlxsw_sp_nve_config *config);
4344
int (*init)(struct mlxsw_sp_nve *nve,
4445
const struct mlxsw_sp_nve_config *config);

0 commit comments

Comments
 (0)