Commit 5eabc27d authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-Firmware-version-update'

Ido Schimmel says:

====================
mlxsw: Firmware version update

This patchset updates mlxsw to use a new firmware version and adds
support for split into two ports on Spectrum-2 based systems.

Patch #1 updates the firmware version to 13.2000.1122

Patch #2 queries new resources from the firmware.

Patch #3 makes use of these resources in order to support split into two
ports on Spectrum-2 based systems. The need for these resources is
explained by Shalom:

When splitting a port, different local ports need to be mapped on different
systems. For example:

SN3700 (local_ports_in_2x=2):
  * Without split:
      front panel 1   --> local port 1
      front panel 2   --> local port 5
  * Split to 2:
      front panel 1s0 --> local port 1
      front panel 1s1 --> local port 3
      front panel 2   --> local port 5

SN3800 (local_ports_in_2x=1):
  * Without split:
      front panel 1 --> local port 1
      front panel 2 --> local port 3
  * Split to 2:
      front panel 1s0 --> local port 1
      front panel 1s1 --> local port 2
      front panel 2   --> local port 3

The local_ports_in_{1x, 2x} resources provide the offsets from the base
local ports according to which the new local ports can be calculated.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c0b14a08 fd321c6c
...@@ -24,6 +24,8 @@ enum mlxsw_res_id { ...@@ -24,6 +24,8 @@ enum mlxsw_res_id {
MLXSW_RES_ID_MAX_SYSTEM_PORT, MLXSW_RES_ID_MAX_SYSTEM_PORT,
MLXSW_RES_ID_MAX_LAG, MLXSW_RES_ID_MAX_LAG,
MLXSW_RES_ID_MAX_LAG_MEMBERS, MLXSW_RES_ID_MAX_LAG_MEMBERS,
MLXSW_RES_ID_LOCAL_PORTS_IN_1X,
MLXSW_RES_ID_LOCAL_PORTS_IN_2X,
MLXSW_RES_ID_MAX_BUFFER_SIZE, MLXSW_RES_ID_MAX_BUFFER_SIZE,
MLXSW_RES_ID_CELL_SIZE, MLXSW_RES_ID_CELL_SIZE,
MLXSW_RES_ID_MAX_HEADROOM_SIZE, MLXSW_RES_ID_MAX_HEADROOM_SIZE,
...@@ -78,6 +80,8 @@ static u16 mlxsw_res_ids[] = { ...@@ -78,6 +80,8 @@ static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_MAX_SYSTEM_PORT] = 0x2502, [MLXSW_RES_ID_MAX_SYSTEM_PORT] = 0x2502,
[MLXSW_RES_ID_MAX_LAG] = 0x2520, [MLXSW_RES_ID_MAX_LAG] = 0x2520,
[MLXSW_RES_ID_MAX_LAG_MEMBERS] = 0x2521, [MLXSW_RES_ID_MAX_LAG_MEMBERS] = 0x2521,
[MLXSW_RES_ID_LOCAL_PORTS_IN_1X] = 0x2610,
[MLXSW_RES_ID_LOCAL_PORTS_IN_2X] = 0x2611,
[MLXSW_RES_ID_MAX_BUFFER_SIZE] = 0x2802, /* Bytes */ [MLXSW_RES_ID_MAX_BUFFER_SIZE] = 0x2802, /* Bytes */
[MLXSW_RES_ID_CELL_SIZE] = 0x2803, /* Bytes */ [MLXSW_RES_ID_CELL_SIZE] = 0x2803, /* Bytes */
[MLXSW_RES_ID_MAX_HEADROOM_SIZE] = 0x2811, /* Bytes */ [MLXSW_RES_ID_MAX_HEADROOM_SIZE] = 0x2811, /* Bytes */
......
...@@ -46,8 +46,8 @@ ...@@ -46,8 +46,8 @@
#define MLXSW_SP_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100) #define MLXSW_SP_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)
#define MLXSW_SP1_FWREV_MAJOR 13 #define MLXSW_SP1_FWREV_MAJOR 13
#define MLXSW_SP1_FWREV_MINOR 1910 #define MLXSW_SP1_FWREV_MINOR 2000
#define MLXSW_SP1_FWREV_SUBMINOR 622 #define MLXSW_SP1_FWREV_SUBMINOR 1122
#define MLXSW_SP1_FWREV_CAN_RESET_MINOR 1702 #define MLXSW_SP1_FWREV_CAN_RESET_MINOR 1702
static const struct mlxsw_fw_rev mlxsw_sp1_fw_rev = { static const struct mlxsw_fw_rev mlxsw_sp1_fw_rev = {
...@@ -3699,14 +3699,14 @@ static u8 mlxsw_sp_cluster_base_port_get(u8 local_port) ...@@ -3699,14 +3699,14 @@ static u8 mlxsw_sp_cluster_base_port_get(u8 local_port)
} }
static int mlxsw_sp_port_split_create(struct mlxsw_sp *mlxsw_sp, u8 base_port, static int mlxsw_sp_port_split_create(struct mlxsw_sp *mlxsw_sp, u8 base_port,
u8 module, unsigned int count) u8 module, unsigned int count, u8 offset)
{ {
u8 width = MLXSW_PORT_MODULE_MAX_WIDTH / count; u8 width = MLXSW_PORT_MODULE_MAX_WIDTH / count;
int err, i; int err, i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
err = mlxsw_sp_port_create(mlxsw_sp, base_port + i, true, err = mlxsw_sp_port_create(mlxsw_sp, base_port + i * offset,
module, width, i * width); true, module, width, i * width);
if (err) if (err)
goto err_port_create; goto err_port_create;
} }
...@@ -3715,8 +3715,8 @@ static int mlxsw_sp_port_split_create(struct mlxsw_sp *mlxsw_sp, u8 base_port, ...@@ -3715,8 +3715,8 @@ static int mlxsw_sp_port_split_create(struct mlxsw_sp *mlxsw_sp, u8 base_port,
err_port_create: err_port_create:
for (i--; i >= 0; i--) for (i--; i >= 0; i--)
if (mlxsw_sp_port_created(mlxsw_sp, base_port + i)) if (mlxsw_sp_port_created(mlxsw_sp, base_port + i * offset))
mlxsw_sp_port_remove(mlxsw_sp, base_port + i); mlxsw_sp_port_remove(mlxsw_sp, base_port + i * offset);
return err; return err;
} }
...@@ -3747,11 +3747,19 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3747,11 +3747,19 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
u8 local_ports_in_1x, local_ports_in_2x, offset;
struct mlxsw_sp_port *mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port;
u8 module, cur_width, base_port; u8 module, cur_width, base_port;
int i; int i;
int err; int err;
if (!MLXSW_CORE_RES_VALID(mlxsw_core, LOCAL_PORTS_IN_1X) ||
!MLXSW_CORE_RES_VALID(mlxsw_core, LOCAL_PORTS_IN_2X))
return -EIO;
local_ports_in_1x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_1X);
local_ports_in_2x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_2X);
mlxsw_sp_port = mlxsw_sp->ports[local_port]; mlxsw_sp_port = mlxsw_sp->ports[local_port];
if (!mlxsw_sp_port) { if (!mlxsw_sp_port) {
dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
...@@ -3777,13 +3785,15 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3777,13 +3785,15 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
/* Make sure we have enough slave (even) ports for the split. */ /* Make sure we have enough slave (even) ports for the split. */
if (count == 2) { if (count == 2) {
offset = local_ports_in_2x;
base_port = local_port; base_port = local_port;
if (mlxsw_sp->ports[base_port + 1]) { if (mlxsw_sp->ports[base_port + local_ports_in_2x]) {
netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n"); netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration"); NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration");
return -EINVAL; return -EINVAL;
} }
} else { } else {
offset = local_ports_in_1x;
base_port = mlxsw_sp_cluster_base_port_get(local_port); base_port = mlxsw_sp_cluster_base_port_get(local_port);
if (mlxsw_sp->ports[base_port + 1] || if (mlxsw_sp->ports[base_port + 1] ||
mlxsw_sp->ports[base_port + 3]) { mlxsw_sp->ports[base_port + 3]) {
...@@ -3794,10 +3804,11 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3794,10 +3804,11 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
} }
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
if (mlxsw_sp_port_created(mlxsw_sp, base_port + i)) if (mlxsw_sp_port_created(mlxsw_sp, base_port + i * offset))
mlxsw_sp_port_remove(mlxsw_sp, base_port + i); mlxsw_sp_port_remove(mlxsw_sp, base_port + i * offset);
err = mlxsw_sp_port_split_create(mlxsw_sp, base_port, module, count); err = mlxsw_sp_port_split_create(mlxsw_sp, base_port, module, count,
offset);
if (err) { if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to create split ports\n"); dev_err(mlxsw_sp->bus_info->dev, "Failed to create split ports\n");
goto err_port_split_create; goto err_port_split_create;
...@@ -3814,11 +3825,19 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3814,11 +3825,19 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
u8 local_ports_in_1x, local_ports_in_2x, offset;
struct mlxsw_sp_port *mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port;
u8 cur_width, base_port; u8 cur_width, base_port;
unsigned int count; unsigned int count;
int i; int i;
if (!MLXSW_CORE_RES_VALID(mlxsw_core, LOCAL_PORTS_IN_1X) ||
!MLXSW_CORE_RES_VALID(mlxsw_core, LOCAL_PORTS_IN_2X))
return -EIO;
local_ports_in_1x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_1X);
local_ports_in_2x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_2X);
mlxsw_sp_port = mlxsw_sp->ports[local_port]; mlxsw_sp_port = mlxsw_sp->ports[local_port];
if (!mlxsw_sp_port) { if (!mlxsw_sp_port) {
dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
...@@ -3836,6 +3855,11 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3836,6 +3855,11 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port,
cur_width = mlxsw_sp_port->mapping.width; cur_width = mlxsw_sp_port->mapping.width;
count = cur_width == 1 ? 4 : 2; count = cur_width == 1 ? 4 : 2;
if (count == 2)
offset = local_ports_in_2x;
else
offset = local_ports_in_1x;
base_port = mlxsw_sp_cluster_base_port_get(local_port); base_port = mlxsw_sp_cluster_base_port_get(local_port);
/* Determine which ports to remove. */ /* Determine which ports to remove. */
...@@ -3843,8 +3867,8 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3843,8 +3867,8 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port,
base_port = base_port + 2; base_port = base_port + 2;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
if (mlxsw_sp_port_created(mlxsw_sp, base_port + i)) if (mlxsw_sp_port_created(mlxsw_sp, base_port + i * offset))
mlxsw_sp_port_remove(mlxsw_sp, base_port + i); mlxsw_sp_port_remove(mlxsw_sp, base_port + i * offset);
mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count); mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count);
......
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