.. | .. |
---|
3 | 3 | |
---|
4 | 4 | #include <net/ip_tunnels.h> |
---|
5 | 5 | #include <net/ip6_tunnel.h> |
---|
| 6 | +#include <net/inet_ecn.h> |
---|
6 | 7 | |
---|
7 | 8 | #include "spectrum_ipip.h" |
---|
| 9 | +#include "reg.h" |
---|
8 | 10 | |
---|
9 | 11 | struct ip_tunnel_parm |
---|
10 | 12 | mlxsw_sp_ipip_netdev_parms4(const struct net_device *ol_dev) |
---|
.. | .. |
---|
145 | 147 | struct mlxsw_sp_ipip_entry *ipip_entry) |
---|
146 | 148 | { |
---|
147 | 149 | u16 rif_index = mlxsw_sp_ipip_lb_rif_index(ipip_entry->ol_lb); |
---|
| 150 | + u16 ul_rif_id = mlxsw_sp_ipip_lb_ul_rif_id(ipip_entry->ol_lb); |
---|
148 | 151 | char rtdp_pl[MLXSW_REG_RTDP_LEN]; |
---|
149 | 152 | struct ip_tunnel_parm parms; |
---|
150 | 153 | unsigned int type_check; |
---|
.. | .. |
---|
157 | 160 | ikey = mlxsw_sp_ipip_parms4_ikey(parms); |
---|
158 | 161 | |
---|
159 | 162 | mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_IPIP, tunnel_index); |
---|
| 163 | + mlxsw_reg_rtdp_egress_router_interface_set(rtdp_pl, ul_rif_id); |
---|
160 | 164 | |
---|
161 | 165 | type_check = has_ikey ? |
---|
162 | 166 | MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE_KEY : |
---|
.. | .. |
---|
336 | 340 | const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[] = { |
---|
337 | 341 | [MLXSW_SP_IPIP_TYPE_GRE4] = &mlxsw_sp_ipip_gre4_ops, |
---|
338 | 342 | }; |
---|
| 343 | + |
---|
| 344 | +static int mlxsw_sp_ipip_ecn_encap_init_one(struct mlxsw_sp *mlxsw_sp, |
---|
| 345 | + u8 inner_ecn, u8 outer_ecn) |
---|
| 346 | +{ |
---|
| 347 | + char tieem_pl[MLXSW_REG_TIEEM_LEN]; |
---|
| 348 | + |
---|
| 349 | + mlxsw_reg_tieem_pack(tieem_pl, inner_ecn, outer_ecn); |
---|
| 350 | + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tieem), tieem_pl); |
---|
| 351 | +} |
---|
| 352 | + |
---|
| 353 | +int mlxsw_sp_ipip_ecn_encap_init(struct mlxsw_sp *mlxsw_sp) |
---|
| 354 | +{ |
---|
| 355 | + int i; |
---|
| 356 | + |
---|
| 357 | + /* Iterate over inner ECN values */ |
---|
| 358 | + for (i = INET_ECN_NOT_ECT; i <= INET_ECN_CE; i++) { |
---|
| 359 | + u8 outer_ecn = INET_ECN_encapsulate(0, i); |
---|
| 360 | + int err; |
---|
| 361 | + |
---|
| 362 | + err = mlxsw_sp_ipip_ecn_encap_init_one(mlxsw_sp, i, outer_ecn); |
---|
| 363 | + if (err) |
---|
| 364 | + return err; |
---|
| 365 | + } |
---|
| 366 | + |
---|
| 367 | + return 0; |
---|
| 368 | +} |
---|
| 369 | + |
---|
| 370 | +static int mlxsw_sp_ipip_ecn_decap_init_one(struct mlxsw_sp *mlxsw_sp, |
---|
| 371 | + u8 inner_ecn, u8 outer_ecn) |
---|
| 372 | +{ |
---|
| 373 | + char tidem_pl[MLXSW_REG_TIDEM_LEN]; |
---|
| 374 | + u8 new_inner_ecn; |
---|
| 375 | + bool trap_en; |
---|
| 376 | + |
---|
| 377 | + new_inner_ecn = mlxsw_sp_tunnel_ecn_decap(outer_ecn, inner_ecn, |
---|
| 378 | + &trap_en); |
---|
| 379 | + mlxsw_reg_tidem_pack(tidem_pl, outer_ecn, inner_ecn, new_inner_ecn, |
---|
| 380 | + trap_en, trap_en ? MLXSW_TRAP_ID_DECAP_ECN0 : 0); |
---|
| 381 | + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tidem), tidem_pl); |
---|
| 382 | +} |
---|
| 383 | + |
---|
| 384 | +int mlxsw_sp_ipip_ecn_decap_init(struct mlxsw_sp *mlxsw_sp) |
---|
| 385 | +{ |
---|
| 386 | + int i, j, err; |
---|
| 387 | + |
---|
| 388 | + /* Iterate over inner ECN values */ |
---|
| 389 | + for (i = INET_ECN_NOT_ECT; i <= INET_ECN_CE; i++) { |
---|
| 390 | + /* Iterate over outer ECN values */ |
---|
| 391 | + for (j = INET_ECN_NOT_ECT; j <= INET_ECN_CE; j++) { |
---|
| 392 | + err = mlxsw_sp_ipip_ecn_decap_init_one(mlxsw_sp, i, j); |
---|
| 393 | + if (err) |
---|
| 394 | + return err; |
---|
| 395 | + } |
---|
| 396 | + } |
---|
| 397 | + |
---|
| 398 | + return 0; |
---|
| 399 | +} |
---|