Commit fa6d61e9 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-various-updates'

Ido Schimmel says:

====================
mlxsw: Various updates

This patchset contains various updates for mlxsw. The most significant
change is the long overdue removal of the abort mechanism in the first
two patches.

Patches #1-#2 remove the route abort mechanism. This change is long
overdue and explained in detail in the commit message.

Patch #3 sets ports down in a few selftests that forgot to do so.
Discovered using a BPF tool (WIP) that monitors ASIC resources.

Patch #4 fixes an issue introduced by commit 557c4d2f ("selftests:
devlink_lib: add check for devlink device existence").

Patches #5-#8 modify the driver to read transceiver module's temperature
thresholds using MTMP register (when supported) instead of directly from
the module's EEPROM using MCIA register. This is both more reliable and
more efficient as now the module's temperature and thresholds are read
using one transaction instead of three.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fd5f5ab0 72a64c2f
...@@ -125,6 +125,7 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module, ...@@ -125,6 +125,7 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module,
int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module, int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
int off, int *temp) int off, int *temp)
{ {
unsigned int module_temp, module_crit, module_emerg;
char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE]; char eeprom_tmp[MLXSW_REG_MCIA_EEPROM_SIZE];
union { union {
u8 buf[MLXSW_REG_MCIA_TH_ITEM_SIZE]; u8 buf[MLXSW_REG_MCIA_TH_ITEM_SIZE];
...@@ -132,7 +133,6 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module, ...@@ -132,7 +133,6 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
} temp_thresh; } temp_thresh;
char mcia_pl[MLXSW_REG_MCIA_LEN] = {0}; char mcia_pl[MLXSW_REG_MCIA_LEN] = {0};
char mtmp_pl[MLXSW_REG_MTMP_LEN]; char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int module_temp;
bool qsfp, cmis; bool qsfp, cmis;
int page; int page;
int err; int err;
...@@ -142,12 +142,21 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module, ...@@ -142,12 +142,21 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl); err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl);
if (err) if (err)
return err; return err;
mlxsw_reg_mtmp_unpack(mtmp_pl, &module_temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, &module_temp, NULL, &module_crit,
&module_emerg, NULL);
if (!module_temp) { if (!module_temp) {
*temp = 0; *temp = 0;
return 0; return 0;
} }
/* Validate if threshold reading is available through MTMP register,
* otherwise fallback to read through MCIA.
*/
if (module_emerg) {
*temp = off == SFP_TEMP_HIGH_WARN ? module_crit : module_emerg;
return 0;
}
/* Read Free Side Device Temperature Thresholds from page 03h /* Read Free Side Device Temperature Thresholds from page 03h
* (MSB at lower byte address). * (MSB at lower byte address).
* Bytes: * Bytes:
......
...@@ -72,7 +72,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev, ...@@ -72,7 +72,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n"); dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
return err; return err;
} }
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL);
return sprintf(buf, "%d\n", temp); return sprintf(buf, "%d\n", temp);
} }
...@@ -95,7 +95,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev, ...@@ -95,7 +95,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n"); dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
return err; return err;
} }
mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL, NULL, NULL);
return sprintf(buf, "%d\n", temp_max); return sprintf(buf, "%d\n", temp_max);
} }
...@@ -239,7 +239,7 @@ static int mlxsw_hwmon_module_temp_get(struct device *dev, ...@@ -239,7 +239,7 @@ static int mlxsw_hwmon_module_temp_get(struct device *dev,
dev_err(dev, "Failed to query module temperature\n"); dev_err(dev, "Failed to query module temperature\n");
return err; return err;
} }
mlxsw_reg_mtmp_unpack(mtmp_pl, p_temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, p_temp, NULL, NULL, NULL, NULL);
return 0; return 0;
} }
......
...@@ -149,22 +149,27 @@ mlxsw_thermal_module_trips_reset(struct mlxsw_thermal_module *tz) ...@@ -149,22 +149,27 @@ mlxsw_thermal_module_trips_reset(struct mlxsw_thermal_module *tz)
static int static int
mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core, mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
struct mlxsw_thermal_module *tz) struct mlxsw_thermal_module *tz,
int crit_temp, int emerg_temp)
{ {
int crit_temp, emerg_temp;
int err; int err;
err = mlxsw_env_module_temp_thresholds_get(core, tz->module, /* Do not try to query temperature thresholds directly from the module's
SFP_TEMP_HIGH_WARN, * EEPROM if we got valid thresholds from MTMP.
&crit_temp); */
if (err) if (!emerg_temp || !crit_temp) {
return err; err = mlxsw_env_module_temp_thresholds_get(core, tz->module,
SFP_TEMP_HIGH_WARN,
&crit_temp);
if (err)
return err;
err = mlxsw_env_module_temp_thresholds_get(core, tz->module, err = mlxsw_env_module_temp_thresholds_get(core, tz->module,
SFP_TEMP_HIGH_ALARM, SFP_TEMP_HIGH_ALARM,
&emerg_temp); &emerg_temp);
if (err) if (err)
return err; return err;
}
if (crit_temp > emerg_temp) { if (crit_temp > emerg_temp) {
dev_warn(dev, "%s : Critical threshold %d is above emergency threshold %d\n", dev_warn(dev, "%s : Critical threshold %d is above emergency threshold %d\n",
...@@ -281,7 +286,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev, ...@@ -281,7 +286,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
dev_err(dev, "Failed to query temp sensor\n"); dev_err(dev, "Failed to query temp sensor\n");
return err; return err;
} }
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL);
if (temp > 0) if (temp > 0)
mlxsw_thermal_tz_score_update(thermal, tzdev, thermal->trips, mlxsw_thermal_tz_score_update(thermal, tzdev, thermal->trips,
temp); temp);
...@@ -420,36 +425,57 @@ static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev, ...@@ -420,36 +425,57 @@ static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev,
return err; return err;
} }
static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev, static void
int *p_temp) mlxsw_thermal_module_temp_and_thresholds_get(struct mlxsw_core *core,
u16 sensor_index, int *p_temp,
int *p_crit_temp,
int *p_emerg_temp)
{ {
struct mlxsw_thermal_module *tz = tzdev->devdata;
struct mlxsw_thermal *thermal = tz->parent;
struct device *dev = thermal->bus_info->dev;
char mtmp_pl[MLXSW_REG_MTMP_LEN]; char mtmp_pl[MLXSW_REG_MTMP_LEN];
int temp;
int err; int err;
/* Read module temperature. */ /* Read module temperature and thresholds. */
mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + mlxsw_reg_mtmp_pack(mtmp_pl, sensor_index, false, false);
tz->module, false, false); err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl);
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
if (err) { if (err) {
/* Do not return error - in case of broken module's sensor /* Set temperature and thresholds to zero to avoid passing
* it will cause error message flooding. * uninitialized data back to the caller.
*/ */
temp = 0; *p_temp = 0;
*p_temp = (int) temp; *p_crit_temp = 0;
return 0; *p_emerg_temp = 0;
return;
} }
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, p_temp, NULL, p_crit_temp, p_emerg_temp,
NULL);
}
static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
int *p_temp)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
struct mlxsw_thermal *thermal = tz->parent;
int temp, crit_temp, emerg_temp;
struct device *dev;
u16 sensor_index;
int err;
dev = thermal->bus_info->dev;
sensor_index = MLXSW_REG_MTMP_MODULE_INDEX_MIN + tz->module;
/* Read module temperature and thresholds. */
mlxsw_thermal_module_temp_and_thresholds_get(thermal->core,
sensor_index, &temp,
&crit_temp, &emerg_temp);
*p_temp = temp; *p_temp = temp;
if (!temp) if (!temp)
return 0; return 0;
/* Update trip points. */ /* Update trip points. */
err = mlxsw_thermal_module_trips_update(dev, thermal->core, tz); err = mlxsw_thermal_module_trips_update(dev, thermal->core, tz,
crit_temp, emerg_temp);
if (!err && temp > 0) if (!err && temp > 0)
mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp); mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
...@@ -560,7 +586,7 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev, ...@@ -560,7 +586,7 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
if (err) if (err)
return err; return err;
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL); mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL, NULL, NULL);
if (temp > 0) if (temp > 0)
mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp); mlxsw_thermal_tz_score_update(thermal, tzdev, tz->trips, temp);
...@@ -716,7 +742,10 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core, ...@@ -716,7 +742,10 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
struct mlxsw_thermal *thermal, u8 module) struct mlxsw_thermal *thermal, u8 module)
{ {
struct mlxsw_thermal_module *module_tz; struct mlxsw_thermal_module *module_tz;
int crit_temp, emerg_temp;
u16 sensor_index;
sensor_index = MLXSW_REG_MTMP_MODULE_INDEX_MIN + module;
module_tz = &thermal->tz_module_arr[module]; module_tz = &thermal->tz_module_arr[module];
/* Skip if parent is already set (case of port split). */ /* Skip if parent is already set (case of port split). */
if (module_tz->parent) if (module_tz->parent)
...@@ -727,8 +756,12 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core, ...@@ -727,8 +756,12 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
sizeof(thermal->trips)); sizeof(thermal->trips));
/* Initialize all trip point. */ /* Initialize all trip point. */
mlxsw_thermal_module_trips_reset(module_tz); mlxsw_thermal_module_trips_reset(module_tz);
/* Read module temperature and thresholds. */
mlxsw_thermal_module_temp_and_thresholds_get(core, sensor_index, NULL,
&crit_temp, &emerg_temp);
/* Update trip point according to the module data. */ /* Update trip point according to the module data. */
return mlxsw_thermal_module_trips_update(dev, core, module_tz); return mlxsw_thermal_module_trips_update(dev, core, module_tz,
crit_temp, emerg_temp);
} }
static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz) static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz)
......
...@@ -9463,6 +9463,14 @@ MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 12); ...@@ -9463,6 +9463,14 @@ MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 12);
((s16)((GENMASK(15, 0) + (v_) + 1) \ ((s16)((GENMASK(15, 0) + (v_) + 1) \
* 125)); }) * 125)); })
/* reg_mtmp_max_operational_temperature
* The highest temperature in the nominal operational range. Reading is in
* 0.125 Celsius degrees units.
* In case of module this is SFF critical temperature threshold.
* Access: RO
*/
MLXSW_ITEM32(reg, mtmp, max_operational_temperature, 0x04, 16, 16);
/* reg_mtmp_temperature /* reg_mtmp_temperature
* Temperature reading from the sensor. Reading is in 0.125 Celsius * Temperature reading from the sensor. Reading is in 0.125 Celsius
* degrees units. * degrees units.
...@@ -9541,7 +9549,9 @@ static inline void mlxsw_reg_mtmp_pack(char *payload, u16 sensor_index, ...@@ -9541,7 +9549,9 @@ static inline void mlxsw_reg_mtmp_pack(char *payload, u16 sensor_index,
} }
static inline void mlxsw_reg_mtmp_unpack(char *payload, int *p_temp, static inline void mlxsw_reg_mtmp_unpack(char *payload, int *p_temp,
int *p_max_temp, char *sensor_name) int *p_max_temp, int *p_temp_hi,
int *p_max_oper_temp,
char *sensor_name)
{ {
s16 temp; s16 temp;
...@@ -9553,6 +9563,14 @@ static inline void mlxsw_reg_mtmp_unpack(char *payload, int *p_temp, ...@@ -9553,6 +9563,14 @@ static inline void mlxsw_reg_mtmp_unpack(char *payload, int *p_temp,
temp = mlxsw_reg_mtmp_max_temperature_get(payload); temp = mlxsw_reg_mtmp_max_temperature_get(payload);
*p_max_temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp); *p_max_temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp);
} }
if (p_temp_hi) {
temp = mlxsw_reg_mtmp_temperature_threshold_hi_get(payload);
*p_temp_hi = MLXSW_REG_MTMP_TEMP_TO_MC(temp);
}
if (p_max_oper_temp) {
temp = mlxsw_reg_mtmp_max_operational_temperature_get(payload);
*p_max_oper_temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp);
}
if (sensor_name) if (sensor_name)
mlxsw_reg_mtmp_sensor_name_memcpy_from(payload, sensor_name); mlxsw_reg_mtmp_sensor_name_memcpy_from(payload, sensor_name);
} }
......
...@@ -4312,9 +4312,6 @@ static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp, ...@@ -4312,9 +4312,6 @@ static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop_key key; struct mlxsw_sp_nexthop_key key;
struct mlxsw_sp_nexthop *nh; struct mlxsw_sp_nexthop *nh;
if (mlxsw_sp->router->aborted)
return;
key.fib_nh = fib_nh; key.fib_nh = fib_nh;
nh = mlxsw_sp_nexthop_lookup(mlxsw_sp, key); nh = mlxsw_sp_nexthop_lookup(mlxsw_sp, key);
if (!nh) if (!nh)
...@@ -6422,9 +6419,6 @@ mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp, ...@@ -6422,9 +6419,6 @@ mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node; struct mlxsw_sp_fib_node *fib_node;
int err; int err;
if (mlxsw_sp->router->aborted)
return 0;
if (fen_info->fi->nh && if (fen_info->fi->nh &&
!mlxsw_sp_nexthop_obj_group_lookup(mlxsw_sp, fen_info->fi->nh->id)) !mlxsw_sp_nexthop_obj_group_lookup(mlxsw_sp, fen_info->fi->nh->id))
return 0; return 0;
...@@ -6485,9 +6479,6 @@ static int mlxsw_sp_router_fib4_del(struct mlxsw_sp *mlxsw_sp, ...@@ -6485,9 +6479,6 @@ static int mlxsw_sp_router_fib4_del(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node; struct mlxsw_sp_fib_node *fib_node;
int err; int err;
if (mlxsw_sp->router->aborted)
return 0;
fib4_entry = mlxsw_sp_fib4_entry_lookup(mlxsw_sp, fen_info); fib4_entry = mlxsw_sp_fib4_entry_lookup(mlxsw_sp, fen_info);
if (!fib4_entry) if (!fib4_entry)
return 0; return 0;
...@@ -7070,9 +7061,6 @@ static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp, ...@@ -7070,9 +7061,6 @@ static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
struct fib6_info *rt = rt_arr[0]; struct fib6_info *rt = rt_arr[0];
int err; int err;
if (mlxsw_sp->router->aborted)
return 0;
if (rt->fib6_src.plen) if (rt->fib6_src.plen)
return -EINVAL; return -EINVAL;
...@@ -7136,9 +7124,6 @@ static int mlxsw_sp_router_fib6_append(struct mlxsw_sp *mlxsw_sp, ...@@ -7136,9 +7124,6 @@ static int mlxsw_sp_router_fib6_append(struct mlxsw_sp *mlxsw_sp,
struct fib6_info *rt = rt_arr[0]; struct fib6_info *rt = rt_arr[0];
int err; int err;
if (mlxsw_sp->router->aborted)
return 0;
if (rt->fib6_src.plen) if (rt->fib6_src.plen)
return -EINVAL; return -EINVAL;
...@@ -7180,9 +7165,6 @@ static int mlxsw_sp_router_fib6_del(struct mlxsw_sp *mlxsw_sp, ...@@ -7180,9 +7165,6 @@ static int mlxsw_sp_router_fib6_del(struct mlxsw_sp *mlxsw_sp,
struct fib6_info *rt = rt_arr[0]; struct fib6_info *rt = rt_arr[0];
int err; int err;
if (mlxsw_sp->router->aborted)
return 0;
if (mlxsw_sp_fib6_rt_should_ignore(rt)) if (mlxsw_sp_fib6_rt_should_ignore(rt))
return 0; return 0;
...@@ -7211,55 +7193,6 @@ static int mlxsw_sp_router_fib6_del(struct mlxsw_sp *mlxsw_sp, ...@@ -7211,55 +7193,6 @@ static int mlxsw_sp_router_fib6_del(struct mlxsw_sp *mlxsw_sp,
return err; return err;
} }
static int __mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_l3proto proto,
u8 tree_id)
{
const struct mlxsw_sp_router_ll_ops *ll_ops = mlxsw_sp->router->proto_ll_ops[proto];
enum mlxsw_reg_ralxx_protocol ralxx_proto =
(enum mlxsw_reg_ralxx_protocol) proto;
struct mlxsw_sp_fib_entry_priv *priv;
char xralta_pl[MLXSW_REG_XRALTA_LEN];
char xralst_pl[MLXSW_REG_XRALST_LEN];
int i, err;
mlxsw_reg_xralta_pack(xralta_pl, true, ralxx_proto, tree_id);
err = ll_ops->ralta_write(mlxsw_sp, xralta_pl);
if (err)
return err;
mlxsw_reg_xralst_pack(xralst_pl, 0xff, tree_id);
err = ll_ops->ralst_write(mlxsw_sp, xralst_pl);
if (err)
return err;
for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
struct mlxsw_sp_fib_entry_op_ctx *op_ctx = mlxsw_sp->router->ll_op_ctx;
struct mlxsw_sp_vr *vr = &mlxsw_sp->router->vrs[i];
char xraltb_pl[MLXSW_REG_XRALTB_LEN];
mlxsw_sp_fib_entry_op_ctx_clear(op_ctx);
mlxsw_reg_xraltb_pack(xraltb_pl, vr->id, ralxx_proto, tree_id);
err = ll_ops->raltb_write(mlxsw_sp, xraltb_pl);
if (err)
return err;
priv = mlxsw_sp_fib_entry_priv_create(ll_ops);
if (IS_ERR(priv))
return PTR_ERR(priv);
ll_ops->fib_entry_pack(op_ctx, proto, MLXSW_SP_FIB_ENTRY_OP_WRITE,
vr->id, 0, NULL, priv);
ll_ops->fib_entry_act_ip2me_pack(op_ctx);
err = ll_ops->fib_entry_commit(mlxsw_sp, op_ctx, NULL);
mlxsw_sp_fib_entry_priv_put(priv);
if (err)
return err;
}
return 0;
}
static struct mlxsw_sp_mr_table * static struct mlxsw_sp_mr_table *
mlxsw_sp_router_fibmr_family_to_table(struct mlxsw_sp_vr *vr, int family) mlxsw_sp_router_fibmr_family_to_table(struct mlxsw_sp_vr *vr, int family)
{ {
...@@ -7276,9 +7209,6 @@ static int mlxsw_sp_router_fibmr_add(struct mlxsw_sp *mlxsw_sp, ...@@ -7276,9 +7209,6 @@ static int mlxsw_sp_router_fibmr_add(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mr_table *mrt; struct mlxsw_sp_mr_table *mrt;
struct mlxsw_sp_vr *vr; struct mlxsw_sp_vr *vr;
if (mlxsw_sp->router->aborted)
return 0;
vr = mlxsw_sp_vr_get(mlxsw_sp, men_info->tb_id, NULL); vr = mlxsw_sp_vr_get(mlxsw_sp, men_info->tb_id, NULL);
if (IS_ERR(vr)) if (IS_ERR(vr))
return PTR_ERR(vr); return PTR_ERR(vr);
...@@ -7293,9 +7223,6 @@ static void mlxsw_sp_router_fibmr_del(struct mlxsw_sp *mlxsw_sp, ...@@ -7293,9 +7223,6 @@ static void mlxsw_sp_router_fibmr_del(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mr_table *mrt; struct mlxsw_sp_mr_table *mrt;
struct mlxsw_sp_vr *vr; struct mlxsw_sp_vr *vr;
if (mlxsw_sp->router->aborted)
return;
vr = mlxsw_sp_vr_find(mlxsw_sp, men_info->tb_id); vr = mlxsw_sp_vr_find(mlxsw_sp, men_info->tb_id);
if (WARN_ON(!vr)) if (WARN_ON(!vr))
return; return;
...@@ -7313,9 +7240,6 @@ mlxsw_sp_router_fibmr_vif_add(struct mlxsw_sp *mlxsw_sp, ...@@ -7313,9 +7240,6 @@ mlxsw_sp_router_fibmr_vif_add(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif; struct mlxsw_sp_rif *rif;
struct mlxsw_sp_vr *vr; struct mlxsw_sp_vr *vr;
if (mlxsw_sp->router->aborted)
return 0;
vr = mlxsw_sp_vr_get(mlxsw_sp, ven_info->tb_id, NULL); vr = mlxsw_sp_vr_get(mlxsw_sp, ven_info->tb_id, NULL);
if (IS_ERR(vr)) if (IS_ERR(vr))
return PTR_ERR(vr); return PTR_ERR(vr);
...@@ -7334,9 +7258,6 @@ mlxsw_sp_router_fibmr_vif_del(struct mlxsw_sp *mlxsw_sp, ...@@ -7334,9 +7258,6 @@ mlxsw_sp_router_fibmr_vif_del(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mr_table *mrt; struct mlxsw_sp_mr_table *mrt;
struct mlxsw_sp_vr *vr; struct mlxsw_sp_vr *vr;
if (mlxsw_sp->router->aborted)
return;
vr = mlxsw_sp_vr_find(mlxsw_sp, ven_info->tb_id); vr = mlxsw_sp_vr_find(mlxsw_sp, ven_info->tb_id);
if (WARN_ON(!vr)) if (WARN_ON(!vr))
return; return;
...@@ -7346,25 +7267,6 @@ mlxsw_sp_router_fibmr_vif_del(struct mlxsw_sp *mlxsw_sp, ...@@ -7346,25 +7267,6 @@ mlxsw_sp_router_fibmr_vif_del(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_vr_put(mlxsw_sp, vr); mlxsw_sp_vr_put(mlxsw_sp, vr);
} }
static int mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp)
{
enum mlxsw_sp_l3proto proto = MLXSW_SP_L3_PROTO_IPV4;
int err;
err = __mlxsw_sp_router_set_abort_trap(mlxsw_sp, proto,
MLXSW_SP_LPM_TREE_MIN);
if (err)
return err;
/* The multicast router code does not need an abort trap as by default,
* packets that don't match any routes are trapped to the CPU.
*/
proto = MLXSW_SP_L3_PROTO_IPV6;
return __mlxsw_sp_router_set_abort_trap(mlxsw_sp, proto,
MLXSW_SP_LPM_TREE_MIN + 1);
}
static void mlxsw_sp_fib4_node_flush(struct mlxsw_sp *mlxsw_sp, static void mlxsw_sp_fib4_node_flush(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_node *fib_node) struct mlxsw_sp_fib_node *fib_node)
{ {
...@@ -7451,20 +7353,6 @@ static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp) ...@@ -7451,20 +7353,6 @@ static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp)
mlxsw_sp->router->adj_discard_index_valid = false; mlxsw_sp->router->adj_discard_index_valid = false;
} }
static void mlxsw_sp_router_fib_abort(struct mlxsw_sp *mlxsw_sp)
{
int err;
if (mlxsw_sp->router->aborted)
return;
dev_warn(mlxsw_sp->bus_info->dev, "FIB abort triggered. Note that FIB entries are no longer being offloaded to this device.\n");
mlxsw_sp_router_fib_flush(mlxsw_sp);
mlxsw_sp->router->aborted = true;
err = mlxsw_sp_router_set_abort_trap(mlxsw_sp);
if (err)
dev_warn(mlxsw_sp->bus_info->dev, "Failed to set abort trap.\n");
}
struct mlxsw_sp_fib6_event { struct mlxsw_sp_fib6_event {
struct fib6_info **rt_arr; struct fib6_info **rt_arr;
unsigned int nrt6; unsigned int nrt6;
...@@ -7546,7 +7434,7 @@ static void mlxsw_sp_router_fib4_event_process(struct mlxsw_sp *mlxsw_sp, ...@@ -7546,7 +7434,7 @@ static void mlxsw_sp_router_fib4_event_process(struct mlxsw_sp *mlxsw_sp,
err = mlxsw_sp_router_fib4_replace(mlxsw_sp, op_ctx, &fib_event->fen_info); err = mlxsw_sp_router_fib4_replace(mlxsw_sp, op_ctx, &fib_event->fen_info);
if (err) { if (err) {
mlxsw_sp_fib_entry_op_ctx_priv_put_all(op_ctx); mlxsw_sp_fib_entry_op_ctx_priv_put_all(op_ctx);
mlxsw_sp_router_fib_abort(mlxsw_sp); dev_warn(mlxsw_sp->bus_info->dev, "FIB replace failed.\n");
mlxsw_sp_fib4_offload_failed_flag_set(mlxsw_sp, mlxsw_sp_fib4_offload_failed_flag_set(mlxsw_sp,
&fib_event->fen_info); &fib_event->fen_info);
} }
...@@ -7581,7 +7469,7 @@ static void mlxsw_sp_router_fib6_event_process(struct mlxsw_sp *mlxsw_sp, ...@@ -7581,7 +7469,7 @@ static void mlxsw_sp_router_fib6_event_process(struct mlxsw_sp *mlxsw_sp,
fib_event->fib6_event.nrt6); fib_event->fib6_event.nrt6);
if (err) { if (err) {
mlxsw_sp_fib_entry_op_ctx_priv_put_all(op_ctx); mlxsw_sp_fib_entry_op_ctx_priv_put_all(op_ctx);
mlxsw_sp_router_fib_abort(mlxsw_sp); dev_warn(mlxsw_sp->bus_info->dev, "FIB replace failed.\n");
mlxsw_sp_fib6_offload_failed_flag_set(mlxsw_sp, mlxsw_sp_fib6_offload_failed_flag_set(mlxsw_sp,
fib6_event->rt_arr, fib6_event->rt_arr,
fib6_event->nrt6); fib6_event->nrt6);
...@@ -7593,7 +7481,7 @@ static void mlxsw_sp_router_fib6_event_process(struct mlxsw_sp *mlxsw_sp, ...@@ -7593,7 +7481,7 @@ static void mlxsw_sp_router_fib6_event_process(struct mlxsw_sp *mlxsw_sp,
fib_event->fib6_event.nrt6); fib_event->fib6_event.nrt6);
if (err) { if (err) {
mlxsw_sp_fib_entry_op_ctx_priv_put_all(op_ctx); mlxsw_sp_fib_entry_op_ctx_priv_put_all(op_ctx);
mlxsw_sp_router_fib_abort(mlxsw_sp); dev_warn(mlxsw_sp->bus_info->dev, "FIB append failed.\n");
mlxsw_sp_fib6_offload_failed_flag_set(mlxsw_sp, mlxsw_sp_fib6_offload_failed_flag_set(mlxsw_sp,
fib6_event->rt_arr, fib6_event->rt_arr,
fib6_event->nrt6); fib6_event->nrt6);
...@@ -7625,7 +7513,7 @@ static void mlxsw_sp_router_fibmr_event_process(struct mlxsw_sp *mlxsw_sp, ...@@ -7625,7 +7513,7 @@ static void mlxsw_sp_router_fibmr_event_process(struct mlxsw_sp *mlxsw_sp,
err = mlxsw_sp_router_fibmr_add(mlxsw_sp, &fib_event->men_info, replace); err = mlxsw_sp_router_fibmr_add(mlxsw_sp, &fib_event->men_info, replace);
if (err) if (err)
mlxsw_sp_router_fib_abort(mlxsw_sp); dev_warn(mlxsw_sp->bus_info->dev, "MR entry add failed.\n");
mr_cache_put(fib_event->men_info.mfc); mr_cache_put(fib_event->men_info.mfc);
break; break;
case FIB_EVENT_ENTRY_DEL: case FIB_EVENT_ENTRY_DEL:
...@@ -7636,7 +7524,7 @@ static void mlxsw_sp_router_fibmr_event_process(struct mlxsw_sp *mlxsw_sp, ...@@ -7636,7 +7524,7 @@ static void mlxsw_sp_router_fibmr_event_process(struct mlxsw_sp *mlxsw_sp,
err = mlxsw_sp_router_fibmr_vif_add(mlxsw_sp, err = mlxsw_sp_router_fibmr_vif_add(mlxsw_sp,
&fib_event->ven_info); &fib_event->ven_info);
if (err) if (err)
mlxsw_sp_router_fib_abort(mlxsw_sp); dev_warn(mlxsw_sp->bus_info->dev, "MR VIF add failed.\n");
dev_put(fib_event->ven_info.dev); dev_put(fib_event->ven_info.dev);
break; break;
case FIB_EVENT_VIF_DEL: case FIB_EVENT_VIF_DEL:
...@@ -7800,9 +7688,6 @@ static int mlxsw_sp_router_fib_rule_event(unsigned long event, ...@@ -7800,9 +7688,6 @@ static int mlxsw_sp_router_fib_rule_event(unsigned long event,
if (event == FIB_EVENT_RULE_DEL) if (event == FIB_EVENT_RULE_DEL)
return 0; return 0;
if (mlxsw_sp->router->aborted)
return 0;
fr_info = container_of(info, struct fib_rule_notifier_info, info); fr_info = container_of(info, struct fib_rule_notifier_info, info);
rule = fr_info->rule; rule = fr_info->rule;
...@@ -7860,10 +7745,6 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb, ...@@ -7860,10 +7745,6 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
case FIB_EVENT_ENTRY_ADD: case FIB_EVENT_ENTRY_ADD:
case FIB_EVENT_ENTRY_REPLACE: case FIB_EVENT_ENTRY_REPLACE:
case FIB_EVENT_ENTRY_APPEND: case FIB_EVENT_ENTRY_APPEND:
if (router->aborted) {
NL_SET_ERR_MSG_MOD(info->extack, "FIB offload was aborted. Not configuring route");
return notifier_from_errno(-EINVAL);
}
if (info->family == AF_INET) { if (info->family == AF_INET) {
struct fib_entry_notifier_info *fen_info = ptr; struct fib_entry_notifier_info *fen_info = ptr;
......
...@@ -58,7 +58,6 @@ struct mlxsw_sp_router { ...@@ -58,7 +58,6 @@ struct mlxsw_sp_router {
#define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */ #define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */
struct list_head nexthop_neighs_list; struct list_head nexthop_neighs_list;
struct list_head ipip_list; struct list_head ipip_list;
bool aborted;
struct notifier_block nexthop_nb; struct notifier_block nexthop_nb;
struct notifier_block fib_nb; struct notifier_block fib_nb;
struct notifier_block netevent_nb; struct notifier_block netevent_nb;
......
...@@ -109,6 +109,9 @@ router_destroy() ...@@ -109,6 +109,9 @@ router_destroy()
__addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64 __addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64
tc qdisc del dev $rp2 clsact tc qdisc del dev $rp2 clsact
ip link set dev $rp2 down
ip link set dev $rp1 down
} }
setup_prepare() setup_prepare()
......
...@@ -111,6 +111,9 @@ router_destroy() ...@@ -111,6 +111,9 @@ router_destroy()
__addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64 __addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64
tc qdisc del dev $rp2 clsact tc qdisc del dev $rp2 clsact
ip link set dev $rp2 down
ip link set dev $rp1 down
} }
setup_prepare() setup_prepare()
......
...@@ -93,7 +93,9 @@ switch_destroy() ...@@ -93,7 +93,9 @@ switch_destroy()
lldptool -T -i $swp1 -V APP -d $(dscp_map 10) >/dev/null lldptool -T -i $swp1 -V APP -d $(dscp_map 10) >/dev/null
lldpad_app_wait_del lldpad_app_wait_del
ip link set dev $swp2 down
ip link set dev $swp2 nomaster ip link set dev $swp2 nomaster
ip link set dev $swp1 down
ip link set dev $swp1 nomaster ip link set dev $swp1 nomaster
ip link del dev br1 ip link del dev br1
} }
......
...@@ -68,7 +68,7 @@ wait_for_routes() ...@@ -68,7 +68,7 @@ wait_for_routes()
local t0=$1; shift local t0=$1; shift
local route_count=$1; shift local route_count=$1; shift
local t1=$(ip route | grep -o 'offload' | wc -l) local t1=$(ip route | grep 'offload' | grep -v 'offload_failed' | wc -l)
local delta=$((t1 - t0)) local delta=$((t1 - t0))
echo $delta echo $delta
[[ $delta -ge $route_count ]] [[ $delta -ge $route_count ]]
......
...@@ -24,13 +24,15 @@ ALL_TESTS=" ...@@ -24,13 +24,15 @@ ALL_TESTS="
NETDEVSIM_PATH=/sys/bus/netdevsim/ NETDEVSIM_PATH=/sys/bus/netdevsim/
DEV_ADDR=1337 DEV_ADDR=1337
DEV=netdevsim${DEV_ADDR} DEV=netdevsim${DEV_ADDR}
DEVLINK_DEV=netdevsim/${DEV}
DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/ DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
SLEEP_TIME=1 SLEEP_TIME=1
NETDEV="" NETDEV=""
NUM_NETIFS=0 NUM_NETIFS=0
source $lib_dir/lib.sh source $lib_dir/lib.sh
DEVLINK_DEV=
source $lib_dir/devlink_lib.sh source $lib_dir/devlink_lib.sh
DEVLINK_DEV=netdevsim/${DEV}
require_command udevadm require_command udevadm
......
...@@ -33,13 +33,15 @@ ALL_TESTS=" ...@@ -33,13 +33,15 @@ ALL_TESTS="
NETDEVSIM_PATH=/sys/bus/netdevsim/ NETDEVSIM_PATH=/sys/bus/netdevsim/
DEV_ADDR=1337 DEV_ADDR=1337
DEV=netdevsim${DEV_ADDR} DEV=netdevsim${DEV_ADDR}
DEVLINK_DEV=netdevsim/${DEV}
SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/ SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
NUM_NETIFS=0 NUM_NETIFS=0
source $lib_dir/lib.sh source $lib_dir/lib.sh
source $lib_dir/devlink_lib.sh
source $lib_dir/fib_offload_lib.sh source $lib_dir/fib_offload_lib.sh
DEVLINK_DEV=
source $lib_dir/devlink_lib.sh
DEVLINK_DEV=netdevsim/${DEV}
ipv4_identical_routes() ipv4_identical_routes()
{ {
fib_ipv4_identical_routes_test "testns1" fib_ipv4_identical_routes_test "testns1"
......
...@@ -44,12 +44,14 @@ ALL_TESTS=" ...@@ -44,12 +44,14 @@ ALL_TESTS="
NETDEVSIM_PATH=/sys/bus/netdevsim/ NETDEVSIM_PATH=/sys/bus/netdevsim/
DEV_ADDR=1337 DEV_ADDR=1337
DEV=netdevsim${DEV_ADDR} DEV=netdevsim${DEV_ADDR}
DEVLINK_DEV=netdevsim/${DEV}
SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/ SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
DEBUGFS_NET_DIR=/sys/kernel/debug/netdevsim/$DEV/ DEBUGFS_NET_DIR=/sys/kernel/debug/netdevsim/$DEV/
NUM_NETIFS=0 NUM_NETIFS=0
source $lib_dir/lib.sh source $lib_dir/lib.sh
DEVLINK_DEV=
source $lib_dir/devlink_lib.sh source $lib_dir/devlink_lib.sh
DEVLINK_DEV=netdevsim/${DEV}
nexthop_check() nexthop_check()
{ {
......
...@@ -14,13 +14,15 @@ ALL_TESTS=" ...@@ -14,13 +14,15 @@ ALL_TESTS="
NETDEVSIM_PATH=/sys/bus/netdevsim/ NETDEVSIM_PATH=/sys/bus/netdevsim/
DEV_ADDR=1337 DEV_ADDR=1337
DEV=netdevsim${DEV_ADDR} DEV=netdevsim${DEV_ADDR}
DEVLINK_DEV=netdevsim/${DEV}
SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/ SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
PSAMPLE_DIR=/sys/kernel/debug/netdevsim/$DEV/psample/ PSAMPLE_DIR=/sys/kernel/debug/netdevsim/$DEV/psample/
CAPTURE_FILE=$(mktemp) CAPTURE_FILE=$(mktemp)
NUM_NETIFS=0 NUM_NETIFS=0
source $lib_dir/lib.sh source $lib_dir/lib.sh
DEVLINK_DEV=
source $lib_dir/devlink_lib.sh source $lib_dir/devlink_lib.sh
DEVLINK_DEV=netdevsim/${DEV}
# Available at https://github.com/Mellanox/libpsample # Available at https://github.com/Mellanox/libpsample
require_command psample require_command psample
......
...@@ -18,7 +18,7 @@ if [[ ! -v DEVLINK_DEV ]]; then ...@@ -18,7 +18,7 @@ if [[ ! -v DEVLINK_DEV ]]; then
DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \ DEVLINK_VIDDID=$(lspci -s $(echo $DEVLINK_DEV | cut -d"/" -f2) \
-n | cut -d" " -f3) -n | cut -d" " -f3)
else elif [[ ! -z "$DEVLINK_DEV" ]]; then
devlink dev show $DEVLINK_DEV &> /dev/null devlink dev show $DEVLINK_DEV &> /dev/null
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "SKIP: devlink device \"$DEVLINK_DEV\" not found" echo "SKIP: devlink device \"$DEVLINK_DEV\" not found"
......
...@@ -75,7 +75,9 @@ switch_destroy() ...@@ -75,7 +75,9 @@ switch_destroy()
tc qdisc del dev $swp2 clsact tc qdisc del dev $swp2 clsact
tc qdisc del dev $swp1 clsact tc qdisc del dev $swp1 clsact
ip link set dev $swp2 down
ip link set dev $swp2 nomaster ip link set dev $swp2 nomaster
ip link set dev $swp1 down
ip link set dev $swp1 nomaster ip link set dev $swp1 nomaster
ip link del dev br1 ip link del dev br1
} }
......
...@@ -71,7 +71,9 @@ switch_destroy() ...@@ -71,7 +71,9 @@ switch_destroy()
tc qdisc del dev $swp2 clsact tc qdisc del dev $swp2 clsact
tc qdisc del dev $swp1 clsact tc qdisc del dev $swp1 clsact
ip link set dev $swp2 down
ip link set dev $swp2 nomaster ip link set dev $swp2 nomaster
ip link set dev $swp1 down
ip link set dev $swp1 nomaster ip link set dev $swp1 nomaster
ip link del dev br1 ip link del dev br1
} }
......
...@@ -72,7 +72,9 @@ switch_destroy() ...@@ -72,7 +72,9 @@ switch_destroy()
tc qdisc del dev $swp2 clsact tc qdisc del dev $swp2 clsact
tc qdisc del dev $swp1 clsact tc qdisc del dev $swp1 clsact
ip link set dev $swp2 down
ip link set dev $swp2 nomaster ip link set dev $swp2 nomaster
ip link set dev $swp1 down
ip link set dev $swp1 nomaster ip link set dev $swp1 nomaster
ip link del dev br1 ip link del dev br1
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment