Skip to content

Commit 16e8292

Browse files
committed
Merge branch 'mlxsw-Add-VXLAN-support-for-Spectrum-2'
Ido Schimmel says: ==================== mlxsw: Add VXLAN support for Spectrum-2 This patchset adds support for VXLAN tunneling on the Spectrum-2 ASIC. Spectrum-1 and Spectrum-2 are largely backward compatible in this area, so not too many changes are required. Patches #1-#2 expose a function and perform small refactoring towards the actual Spectrum-2 implementation in patches #3-#4. Patch #3 adds the required initialization steps on Spectrum-2. Patch #4 finally enables VXLAN on Spectrum-2. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 482dcf7 + 02d21b5 commit 16e8292

File tree

4 files changed

+162
-21
lines changed

4 files changed

+162
-21
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,9 @@ void mlxsw_sp_router_nve_demote_decap(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id,
507507
const union mlxsw_sp_l3addr *ul_sip);
508508
int mlxsw_sp_router_tb_id_vr_id(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
509509
u16 *vr_id);
510+
int mlxsw_sp_router_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id,
511+
u16 *ul_rif_index);
512+
void mlxsw_sp_router_ul_rif_put(struct mlxsw_sp *mlxsw_sp, u16 ul_rif_index);
510513

511514
/* spectrum_kvdl.c */
512515
enum mlxsw_sp_kvdl_entry_type {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct mlxsw_sp_nve {
2828
unsigned int num_nve_tunnels; /* Protected by RTNL */
2929
unsigned int num_max_mc_entries[MLXSW_SP_L3_PROTO_MAX];
3030
u32 tunnel_index;
31+
u16 ul_rif_index; /* Reserved for Spectrum */
3132
};
3233

3334
struct mlxsw_sp_nve_ops {

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

Lines changed: 130 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <net/vxlan.h>
88

99
#include "reg.h"
10+
#include "spectrum.h"
1011
#include "spectrum_nve.h"
1112

1213
/* Eth (18B) | IPv6 (40B) | UDP (8B) | VxLAN (8B) | Eth (14B) | IPv6 (40B)
@@ -20,9 +21,9 @@
2021
#define MLXSW_SP_NVE_VXLAN_SUPPORTED_FLAGS (VXLAN_F_UDP_ZERO_CSUM_TX | \
2122
VXLAN_F_LEARN)
2223

23-
static bool mlxsw_sp1_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
24-
const struct net_device *dev,
25-
struct netlink_ext_ack *extack)
24+
static bool mlxsw_sp_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
25+
const struct net_device *dev,
26+
struct netlink_ext_ack *extack)
2627
{
2728
struct vxlan_dev *vxlan = netdev_priv(dev);
2829
struct vxlan_config *cfg = &vxlan->cfg;
@@ -112,32 +113,40 @@ static int mlxsw_sp_nve_parsing_set(struct mlxsw_sp *mlxsw_sp,
112113
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl);
113114
}
114115

116+
static void
117+
mlxsw_sp_nve_vxlan_config_prepare(char *tngcr_pl,
118+
const struct mlxsw_sp_nve_config *config)
119+
{
120+
u8 udp_sport;
121+
122+
mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, true,
123+
config->ttl);
124+
/* VxLAN driver's default UDP source port range is 32768 (0x8000)
125+
* to 60999 (0xee47). Set the upper 8 bits of the UDP source port
126+
* to a random number between 0x80 and 0xee
127+
*/
128+
get_random_bytes(&udp_sport, sizeof(udp_sport));
129+
udp_sport = (udp_sport % (0xee - 0x80 + 1)) + 0x80;
130+
mlxsw_reg_tngcr_nve_udp_sport_prefix_set(tngcr_pl, udp_sport);
131+
mlxsw_reg_tngcr_usipv4_set(tngcr_pl, be32_to_cpu(config->ul_sip.addr4));
132+
}
133+
115134
static int
116135
mlxsw_sp1_nve_vxlan_config_set(struct mlxsw_sp *mlxsw_sp,
117136
const struct mlxsw_sp_nve_config *config)
118137
{
119138
char tngcr_pl[MLXSW_REG_TNGCR_LEN];
120139
u16 ul_vr_id;
121-
u8 udp_sport;
122140
int err;
123141

124142
err = mlxsw_sp_router_tb_id_vr_id(mlxsw_sp, config->ul_tb_id,
125143
&ul_vr_id);
126144
if (err)
127145
return err;
128146

129-
mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, true,
130-
config->ttl);
131-
/* VxLAN driver's default UDP source port range is 32768 (0x8000)
132-
* to 60999 (0xee47). Set the upper 8 bits of the UDP source port
133-
* to a random number between 0x80 and 0xee
134-
*/
135-
get_random_bytes(&udp_sport, sizeof(udp_sport));
136-
udp_sport = (udp_sport % (0xee - 0x80 + 1)) + 0x80;
137-
mlxsw_reg_tngcr_nve_udp_sport_prefix_set(tngcr_pl, udp_sport);
147+
mlxsw_sp_nve_vxlan_config_prepare(tngcr_pl, config);
138148
mlxsw_reg_tngcr_learn_enable_set(tngcr_pl, config->learning_en);
139149
mlxsw_reg_tngcr_underlay_virtual_router_set(tngcr_pl, ul_vr_id);
140-
mlxsw_reg_tngcr_usipv4_set(tngcr_pl, be32_to_cpu(config->ul_sip.addr4));
141150

142151
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
143152
}
@@ -231,34 +240,134 @@ mlxsw_sp_nve_vxlan_clear_offload(const struct net_device *nve_dev, __be32 vni)
231240

232241
const struct mlxsw_sp_nve_ops mlxsw_sp1_nve_vxlan_ops = {
233242
.type = MLXSW_SP_NVE_TYPE_VXLAN,
234-
.can_offload = mlxsw_sp1_nve_vxlan_can_offload,
243+
.can_offload = mlxsw_sp_nve_vxlan_can_offload,
235244
.nve_config = mlxsw_sp_nve_vxlan_config,
236245
.init = mlxsw_sp1_nve_vxlan_init,
237246
.fini = mlxsw_sp1_nve_vxlan_fini,
238247
.fdb_replay = mlxsw_sp_nve_vxlan_fdb_replay,
239248
.fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload,
240249
};
241250

242-
static bool mlxsw_sp2_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
243-
const struct net_device *dev,
244-
struct netlink_ext_ack *extack)
251+
static bool mlxsw_sp2_nve_vxlan_learning_set(struct mlxsw_sp *mlxsw_sp,
252+
bool learning_en)
245253
{
246-
return false;
254+
char tnpc_pl[MLXSW_REG_TNPC_LEN];
255+
256+
mlxsw_reg_tnpc_pack(tnpc_pl, MLXSW_REG_TNPC_TUNNEL_PORT_NVE,
257+
learning_en);
258+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tnpc), tnpc_pl);
259+
}
260+
261+
static int
262+
mlxsw_sp2_nve_vxlan_config_set(struct mlxsw_sp *mlxsw_sp,
263+
const struct mlxsw_sp_nve_config *config)
264+
{
265+
char tngcr_pl[MLXSW_REG_TNGCR_LEN];
266+
u16 ul_rif_index;
267+
int err;
268+
269+
err = mlxsw_sp_router_ul_rif_get(mlxsw_sp, config->ul_tb_id,
270+
&ul_rif_index);
271+
if (err)
272+
return err;
273+
mlxsw_sp->nve->ul_rif_index = ul_rif_index;
274+
275+
err = mlxsw_sp2_nve_vxlan_learning_set(mlxsw_sp, config->learning_en);
276+
if (err)
277+
goto err_vxlan_learning_set;
278+
279+
mlxsw_sp_nve_vxlan_config_prepare(tngcr_pl, config);
280+
mlxsw_reg_tngcr_underlay_rif_set(tngcr_pl, ul_rif_index);
281+
282+
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
283+
if (err)
284+
goto err_tngcr_write;
285+
286+
return 0;
287+
288+
err_tngcr_write:
289+
mlxsw_sp2_nve_vxlan_learning_set(mlxsw_sp, false);
290+
err_vxlan_learning_set:
291+
mlxsw_sp_router_ul_rif_put(mlxsw_sp, ul_rif_index);
292+
return err;
293+
}
294+
295+
static void mlxsw_sp2_nve_vxlan_config_clear(struct mlxsw_sp *mlxsw_sp)
296+
{
297+
char tngcr_pl[MLXSW_REG_TNGCR_LEN];
298+
299+
mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, false, 0);
300+
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
301+
mlxsw_sp2_nve_vxlan_learning_set(mlxsw_sp, false);
302+
mlxsw_sp_router_ul_rif_put(mlxsw_sp, mlxsw_sp->nve->ul_rif_index);
303+
}
304+
305+
static int mlxsw_sp2_nve_vxlan_rtdp_set(struct mlxsw_sp *mlxsw_sp,
306+
unsigned int tunnel_index,
307+
u16 ul_rif_index)
308+
{
309+
char rtdp_pl[MLXSW_REG_RTDP_LEN];
310+
311+
mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_NVE, tunnel_index);
312+
mlxsw_reg_rtdp_egress_router_interface_set(rtdp_pl, ul_rif_index);
313+
314+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl);
247315
}
248316

249317
static int mlxsw_sp2_nve_vxlan_init(struct mlxsw_sp_nve *nve,
250318
const struct mlxsw_sp_nve_config *config)
251319
{
252-
return -EOPNOTSUPP;
320+
struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
321+
int err;
322+
323+
err = mlxsw_sp_nve_parsing_set(mlxsw_sp,
324+
MLXSW_SP_NVE_VXLAN_PARSING_DEPTH,
325+
config->udp_dport);
326+
if (err)
327+
return err;
328+
329+
err = mlxsw_sp2_nve_vxlan_config_set(mlxsw_sp, config);
330+
if (err)
331+
goto err_config_set;
332+
333+
err = mlxsw_sp2_nve_vxlan_rtdp_set(mlxsw_sp, nve->tunnel_index,
334+
nve->ul_rif_index);
335+
if (err)
336+
goto err_rtdp_set;
337+
338+
err = mlxsw_sp_router_nve_promote_decap(mlxsw_sp, config->ul_tb_id,
339+
config->ul_proto,
340+
&config->ul_sip,
341+
nve->tunnel_index);
342+
if (err)
343+
goto err_promote_decap;
344+
345+
return 0;
346+
347+
err_promote_decap:
348+
err_rtdp_set:
349+
mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp);
350+
err_config_set:
351+
mlxsw_sp_nve_parsing_set(mlxsw_sp, MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH,
352+
config->udp_dport);
353+
return err;
253354
}
254355

255356
static void mlxsw_sp2_nve_vxlan_fini(struct mlxsw_sp_nve *nve)
256357
{
358+
struct mlxsw_sp_nve_config *config = &nve->config;
359+
struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
360+
361+
mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id,
362+
config->ul_proto, &config->ul_sip);
363+
mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp);
364+
mlxsw_sp_nve_parsing_set(mlxsw_sp, MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH,
365+
config->udp_dport);
257366
}
258367

259368
const struct mlxsw_sp_nve_ops mlxsw_sp2_nve_vxlan_ops = {
260369
.type = MLXSW_SP_NVE_TYPE_VXLAN,
261-
.can_offload = mlxsw_sp2_nve_vxlan_can_offload,
370+
.can_offload = mlxsw_sp_nve_vxlan_can_offload,
262371
.nve_config = mlxsw_sp_nve_vxlan_config,
263372
.init = mlxsw_sp2_nve_vxlan_init,
264373
.fini = mlxsw_sp2_nve_vxlan_fini,

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7595,6 +7595,34 @@ static void mlxsw_sp_ul_rif_put(struct mlxsw_sp_rif *ul_rif)
75957595
mlxsw_sp_vr_put(mlxsw_sp, vr);
75967596
}
75977597

7598+
int mlxsw_sp_router_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id,
7599+
u16 *ul_rif_index)
7600+
{
7601+
struct mlxsw_sp_rif *ul_rif;
7602+
7603+
ASSERT_RTNL();
7604+
7605+
ul_rif = mlxsw_sp_ul_rif_get(mlxsw_sp, ul_tb_id, NULL);
7606+
if (IS_ERR(ul_rif))
7607+
return PTR_ERR(ul_rif);
7608+
*ul_rif_index = ul_rif->rif_index;
7609+
7610+
return 0;
7611+
}
7612+
7613+
void mlxsw_sp_router_ul_rif_put(struct mlxsw_sp *mlxsw_sp, u16 ul_rif_index)
7614+
{
7615+
struct mlxsw_sp_rif *ul_rif;
7616+
7617+
ASSERT_RTNL();
7618+
7619+
ul_rif = mlxsw_sp->router->rifs[ul_rif_index];
7620+
if (WARN_ON(!ul_rif))
7621+
return;
7622+
7623+
mlxsw_sp_ul_rif_put(ul_rif);
7624+
}
7625+
75987626
static int
75997627
mlxsw_sp2_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif)
76007628
{

0 commit comments

Comments
 (0)