Skip to content

Commit 7458120

Browse files
jpirkodavem330
authored andcommitted
mlxsw: spectrum: Implement LAG tx enabled lower state change
Enabling/disabling TX on a LAG port means enabling/disabling distribution in our HW. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 8a1ab5d commit 7458120

File tree

1 file changed

+79
-2
lines changed

1 file changed

+79
-2
lines changed

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

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,8 +2108,47 @@ static int mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
21082108
return 0;
21092109
}
21102110

2111-
static int mlxsw_sp_netdevice_port_event(struct net_device *dev,
2112-
unsigned long event, void *ptr)
2111+
static int mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
2112+
u16 lag_id)
2113+
{
2114+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2115+
char sldr_pl[MLXSW_REG_SLDR_LEN];
2116+
2117+
mlxsw_reg_sldr_lag_add_port_pack(sldr_pl, lag_id,
2118+
mlxsw_sp_port->local_port);
2119+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
2120+
}
2121+
2122+
static int mlxsw_sp_lag_dist_port_remove(struct mlxsw_sp_port *mlxsw_sp_port,
2123+
u16 lag_id)
2124+
{
2125+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2126+
char sldr_pl[MLXSW_REG_SLDR_LEN];
2127+
2128+
mlxsw_reg_sldr_lag_remove_port_pack(sldr_pl, lag_id,
2129+
mlxsw_sp_port->local_port);
2130+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
2131+
}
2132+
2133+
static int mlxsw_sp_port_lag_tx_en_set(struct mlxsw_sp_port *mlxsw_sp_port,
2134+
bool lag_tx_enabled)
2135+
{
2136+
if (lag_tx_enabled)
2137+
return mlxsw_sp_lag_dist_port_add(mlxsw_sp_port,
2138+
mlxsw_sp_port->lag_id);
2139+
else
2140+
return mlxsw_sp_lag_dist_port_remove(mlxsw_sp_port,
2141+
mlxsw_sp_port->lag_id);
2142+
}
2143+
2144+
static int mlxsw_sp_port_lag_changed(struct mlxsw_sp_port *mlxsw_sp_port,
2145+
struct netdev_lag_lower_state_info *info)
2146+
{
2147+
return mlxsw_sp_port_lag_tx_en_set(mlxsw_sp_port, info->tx_enabled);
2148+
}
2149+
2150+
static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
2151+
unsigned long event, void *ptr)
21132152
{
21142153
struct netdev_notifier_changeupper_info *info;
21152154
struct mlxsw_sp_port *mlxsw_sp_port;
@@ -2176,6 +2215,44 @@ static int mlxsw_sp_netdevice_port_event(struct net_device *dev,
21762215
return NOTIFY_DONE;
21772216
}
21782217

2218+
static int mlxsw_sp_netdevice_port_lower_event(struct net_device *dev,
2219+
unsigned long event, void *ptr)
2220+
{
2221+
struct netdev_notifier_changelowerstate_info *info;
2222+
struct mlxsw_sp_port *mlxsw_sp_port;
2223+
int err;
2224+
2225+
mlxsw_sp_port = netdev_priv(dev);
2226+
info = ptr;
2227+
2228+
switch (event) {
2229+
case NETDEV_CHANGELOWERSTATE:
2230+
if (netif_is_lag_port(dev) && mlxsw_sp_port->lagged) {
2231+
err = mlxsw_sp_port_lag_changed(mlxsw_sp_port,
2232+
info->lower_state_info);
2233+
if (err)
2234+
netdev_err(dev, "Failed to reflect link aggregation lower state change\n");
2235+
}
2236+
break;
2237+
}
2238+
2239+
return NOTIFY_DONE;
2240+
}
2241+
2242+
static int mlxsw_sp_netdevice_port_event(struct net_device *dev,
2243+
unsigned long event, void *ptr)
2244+
{
2245+
switch (event) {
2246+
case NETDEV_PRECHANGEUPPER:
2247+
case NETDEV_CHANGEUPPER:
2248+
return mlxsw_sp_netdevice_port_upper_event(dev, event, ptr);
2249+
case NETDEV_CHANGELOWERSTATE:
2250+
return mlxsw_sp_netdevice_port_lower_event(dev, event, ptr);
2251+
}
2252+
2253+
return NOTIFY_DONE;
2254+
}
2255+
21792256
static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
21802257
unsigned long event, void *ptr)
21812258
{

0 commit comments

Comments
 (0)