Commit 265bee72 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-next'

Jiri Pirko says:

====================
mlxsw: small driver update, including switchdev doc update

Ido Schimmel (3):
  mlxsw: spectrum: Reduce number of supported 802.1D bridges
  switchdev: Use switch ID in suggested udev rule
  mlxsw: spectrum: Add support for physical port names
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 15f41e2b 2bf9a586
...@@ -89,6 +89,18 @@ Typically, the management port is not participating in offloaded data plane and ...@@ -89,6 +89,18 @@ Typically, the management port is not participating in offloaded data plane and
is loaded with a different driver, such as a NIC driver, on the management port is loaded with a different driver, such as a NIC driver, on the management port
device. device.
Switch ID
^^^^^^^^^
The switchdev driver must implement the switchdev op switchdev_port_attr_get
for SWITCHDEV_ATTR_ID_PORT_PARENT_ID for each port netdev, returning the same
physical ID for each port of a switch. The ID must be unique between switches
on the same system. The ID does not need to be unique between switches on
different systems.
The switch ID is used to locate ports on a switch and to know if aggregated
ports belong to the same switch.
Port Netdev Naming Port Netdev Naming
^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
...@@ -104,25 +116,13 @@ external configuration. For example, if a physical 40G port is split logically ...@@ -104,25 +116,13 @@ external configuration. For example, if a physical 40G port is split logically
into 4 10G ports, resulting in 4 port netdevs, the device can give a unique into 4 10G ports, resulting in 4 port netdevs, the device can give a unique
name for each port using port PHYS name. The udev rule would be: name for each port using port PHYS name. The udev rule would be:
SUBSYSTEM=="net", ACTION=="add", DRIVER="<driver>", ATTR{phys_port_name}!="", \ SUBSYSTEM=="net", ACTION=="add", ATTR{phys_switch_id}=="<phys_switch_id>", \
NAME="$attr{phys_port_name}" ATTR{phys_port_name}!="", NAME="swX$attr{phys_port_name}"
Suggested naming convention is "swXpYsZ", where X is the switch name or ID, Y Suggested naming convention is "swXpYsZ", where X is the switch name or ID, Y
is the port name or ID, and Z is the sub-port name or ID. For example, sw1p1s0 is the port name or ID, and Z is the sub-port name or ID. For example, sw1p1s0
would be sub-port 0 on port 1 on switch 1. would be sub-port 0 on port 1 on switch 1.
Switch ID
^^^^^^^^^
The switchdev driver must implement the switchdev op switchdev_port_attr_get
for SWITCHDEV_ATTR_ID_PORT_PARENT_ID for each port netdev, returning the same
physical ID for each port of a switch. The ID must be unique between switches
on the same system. The ID does not need to be unique between switches on
different systems.
The switch ID is used to locate ports on a switch and to know if aggregated
ports belong to the same switch.
Port Features Port Features
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
......
...@@ -305,9 +305,9 @@ mlxsw_sp_port_system_port_mapping_set(struct mlxsw_sp_port *mlxsw_sp_port) ...@@ -305,9 +305,9 @@ mlxsw_sp_port_system_port_mapping_set(struct mlxsw_sp_port *mlxsw_sp_port)
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sspr), sspr_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sspr), sspr_pl);
} }
static int mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp, static int __mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
u8 local_port, u8 *p_module, u8 local_port, u8 *p_module,
u8 *p_width) u8 *p_width, u8 *p_lane)
{ {
char pmlp_pl[MLXSW_REG_PMLP_LEN]; char pmlp_pl[MLXSW_REG_PMLP_LEN];
int err; int err;
...@@ -318,9 +318,20 @@ static int mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp, ...@@ -318,9 +318,20 @@ static int mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
return err; return err;
*p_module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0); *p_module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
*p_width = mlxsw_reg_pmlp_width_get(pmlp_pl); *p_width = mlxsw_reg_pmlp_width_get(pmlp_pl);
*p_lane = mlxsw_reg_pmlp_tx_lane_get(pmlp_pl, 0);
return 0; return 0;
} }
static int mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
u8 local_port, u8 *p_module,
u8 *p_width)
{
u8 lane;
return __mlxsw_sp_port_module_info_get(mlxsw_sp, local_port, p_module,
p_width, &lane);
}
static int mlxsw_sp_port_module_map(struct mlxsw_sp *mlxsw_sp, u8 local_port, static int mlxsw_sp_port_module_map(struct mlxsw_sp *mlxsw_sp, u8 local_port,
u8 module, u8 width, u8 lane) u8 module, u8 width, u8 lane)
{ {
...@@ -861,6 +872,33 @@ int mlxsw_sp_port_kill_vid(struct net_device *dev, ...@@ -861,6 +872,33 @@ int mlxsw_sp_port_kill_vid(struct net_device *dev,
return 0; return 0;
} }
static int mlxsw_sp_port_get_phys_port_name(struct net_device *dev, char *name,
size_t len)
{
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
u8 module, width, lane;
int err;
err = __mlxsw_sp_port_module_info_get(mlxsw_sp_port->mlxsw_sp,
mlxsw_sp_port->local_port,
&module, &width, &lane);
if (err) {
netdev_err(dev, "Failed to retrieve module information\n");
return err;
}
if (!mlxsw_sp_port->split)
err = snprintf(name, len, "p%d", module + 1);
else
err = snprintf(name, len, "p%ds%d", module + 1,
lane / width);
if (err >= len)
return -EINVAL;
return 0;
}
static const struct net_device_ops mlxsw_sp_port_netdev_ops = { static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
.ndo_open = mlxsw_sp_port_open, .ndo_open = mlxsw_sp_port_open,
.ndo_stop = mlxsw_sp_port_stop, .ndo_stop = mlxsw_sp_port_stop,
...@@ -877,6 +915,7 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = { ...@@ -877,6 +915,7 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
.ndo_bridge_setlink = switchdev_port_bridge_setlink, .ndo_bridge_setlink = switchdev_port_bridge_setlink,
.ndo_bridge_getlink = switchdev_port_bridge_getlink, .ndo_bridge_getlink = switchdev_port_bridge_getlink,
.ndo_bridge_dellink = switchdev_port_bridge_dellink, .ndo_bridge_dellink = switchdev_port_bridge_dellink,
.ndo_get_phys_port_name = mlxsw_sp_port_get_phys_port_name,
}; };
static void mlxsw_sp_port_get_drvinfo(struct net_device *dev, static void mlxsw_sp_port_get_drvinfo(struct net_device *dev,
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
#define MLXSW_SP_VFID_BASE VLAN_N_VID #define MLXSW_SP_VFID_BASE VLAN_N_VID
#define MLXSW_SP_VFID_PORT_MAX 512 /* Non-bridged VLAN interfaces */ #define MLXSW_SP_VFID_PORT_MAX 512 /* Non-bridged VLAN interfaces */
#define MLXSW_SP_VFID_BR_MAX 8192 /* Bridged VLAN interfaces */ #define MLXSW_SP_VFID_BR_MAX 6144 /* Bridged VLAN interfaces */
#define MLXSW_SP_VFID_MAX (MLXSW_SP_VFID_PORT_MAX + MLXSW_SP_VFID_BR_MAX) #define MLXSW_SP_VFID_MAX (MLXSW_SP_VFID_PORT_MAX + MLXSW_SP_VFID_BR_MAX)
#define MLXSW_SP_LAG_MAX 64 #define MLXSW_SP_LAG_MAX 64
......
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