aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@mellanox.com>2016-07-15 05:15:02 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-15 17:49:51 -0400
commit11719a58bdf7724c463db54ea2abcec54a87b69c (patch)
tree350eb82b62a4ca63c17e907e4130c1c3ec5a61f9
parent28f5275e4aab97680c8243ec26e202e44c99e5bf (diff)
mlxsw: spectrum: Prevent invalid ingress buffer mapping
Packets entering the switch are mapped to a Switch Priority (SP) according to their PCP value (untagged frames are mapped to SP 0). The packets are classified to a priority group (PG) buffer in the port's headroom according to their SP. The switch maintains another mapping (SP to IEEE priority), which is used to generate PFC frames for lossless PGs. This mapping is initialized to IEEE = SP % 8. Therefore, when mapping SP 'x' to PG 'y' we create a situation in which an IEEE priority is mapped to two different PGs: IEEE 'x' ---> SP 'x' ---> PG 'y' IEEE 'x' ---> SP 'x + 8' ---> PG '0' (default) Which is invalid, as a flow can use only one PG buffer. Fix this by mapping both SP 'x' and 'x + 8' to the same PG buffer. Fixes: 8e8dfe9fdf06 ("mlxsw: spectrum: Add IEEE 802.1Qaz ETS support") Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/reg.h17
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c3
3 files changed, 19 insertions, 3 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 1977e7a5c530..57d48da709fb 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -2718,7 +2718,7 @@ static inline void mlxsw_reg_ppcnt_pack(char *payload, u8 local_port,
2718 * Configures the switch priority to buffer table. 2718 * Configures the switch priority to buffer table.
2719 */ 2719 */
2720#define MLXSW_REG_PPTB_ID 0x500B 2720#define MLXSW_REG_PPTB_ID 0x500B
2721#define MLXSW_REG_PPTB_LEN 0x0C 2721#define MLXSW_REG_PPTB_LEN 0x10
2722 2722
2723static const struct mlxsw_reg_info mlxsw_reg_pptb = { 2723static const struct mlxsw_reg_info mlxsw_reg_pptb = {
2724 .id = MLXSW_REG_PPTB_ID, 2724 .id = MLXSW_REG_PPTB_ID,
@@ -2784,6 +2784,13 @@ MLXSW_ITEM32(reg, pptb, pm_msb, 0x08, 24, 8);
2784 */ 2784 */
2785MLXSW_ITEM32(reg, pptb, untagged_buff, 0x08, 0, 4); 2785MLXSW_ITEM32(reg, pptb, untagged_buff, 0x08, 0, 4);
2786 2786
2787/* reg_pptb_prio_to_buff_msb
2788 * Mapping of switch priority <i+8> to one of the allocated receive port
2789 * buffers.
2790 * Access: RW
2791 */
2792MLXSW_ITEM_BIT_ARRAY(reg, pptb, prio_to_buff_msb, 0x0C, 0x04, 4);
2793
2787#define MLXSW_REG_PPTB_ALL_PRIO 0xFF 2794#define MLXSW_REG_PPTB_ALL_PRIO 0xFF
2788 2795
2789static inline void mlxsw_reg_pptb_pack(char *payload, u8 local_port) 2796static inline void mlxsw_reg_pptb_pack(char *payload, u8 local_port)
@@ -2792,6 +2799,14 @@ static inline void mlxsw_reg_pptb_pack(char *payload, u8 local_port)
2792 mlxsw_reg_pptb_mm_set(payload, MLXSW_REG_PPTB_MM_UM); 2799 mlxsw_reg_pptb_mm_set(payload, MLXSW_REG_PPTB_MM_UM);
2793 mlxsw_reg_pptb_local_port_set(payload, local_port); 2800 mlxsw_reg_pptb_local_port_set(payload, local_port);
2794 mlxsw_reg_pptb_pm_set(payload, MLXSW_REG_PPTB_ALL_PRIO); 2801 mlxsw_reg_pptb_pm_set(payload, MLXSW_REG_PPTB_ALL_PRIO);
2802 mlxsw_reg_pptb_pm_msb_set(payload, MLXSW_REG_PPTB_ALL_PRIO);
2803}
2804
2805static inline void mlxsw_reg_pptb_prio_to_buff_pack(char *payload, u8 prio,
2806 u8 buff)
2807{
2808 mlxsw_reg_pptb_prio_to_buff_set(payload, prio, buff);
2809 mlxsw_reg_pptb_prio_to_buff_msb_set(payload, prio, buff);
2795} 2810}
2796 2811
2797/* PBMC - Port Buffer Management Control Register 2812/* PBMC - Port Buffer Management Control Register
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
index a3720a0fad7d..074cdda7b6f3 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
@@ -194,7 +194,7 @@ static int mlxsw_sp_port_pb_prio_init(struct mlxsw_sp_port *mlxsw_sp_port)
194 194
195 mlxsw_reg_pptb_pack(pptb_pl, mlxsw_sp_port->local_port); 195 mlxsw_reg_pptb_pack(pptb_pl, mlxsw_sp_port->local_port);
196 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 196 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
197 mlxsw_reg_pptb_prio_to_buff_set(pptb_pl, i, 0); 197 mlxsw_reg_pptb_prio_to_buff_pack(pptb_pl, i, 0);
198 return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pptb), 198 return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pptb),
199 pptb_pl); 199 pptb_pl);
200} 200}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c
index 4af3f2728e47..01cfb7512827 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c
@@ -103,7 +103,8 @@ static int mlxsw_sp_port_pg_prio_map(struct mlxsw_sp_port *mlxsw_sp_port,
103 103
104 mlxsw_reg_pptb_pack(pptb_pl, mlxsw_sp_port->local_port); 104 mlxsw_reg_pptb_pack(pptb_pl, mlxsw_sp_port->local_port);
105 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 105 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
106 mlxsw_reg_pptb_prio_to_buff_set(pptb_pl, i, prio_tc[i]); 106 mlxsw_reg_pptb_prio_to_buff_pack(pptb_pl, i, prio_tc[i]);
107
107 return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pptb), 108 return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pptb),
108 pptb_pl); 109 pptb_pl);
109} 110}