@@ -646,7 +646,7 @@ static u16 mlxsw_sp_hdroom_buf_delay_get(const struct mlxsw_sp *mlxsw_sp,
int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_hdroom *hdroom,
- u8 *prio_tc, bool pause_en, struct ieee_pfc *my_pfc)
+ bool pause_en, struct ieee_pfc *my_pfc)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
u8 pfc_en = !!my_pfc ? my_pfc->pfc_en : 0;
@@ -671,7 +671,7 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
bool lossy;
for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) {
- if (prio_tc[j] == i) {
+ if (hdroom->prios.prio[j].buf_idx == i) {
pfc = pfc_en & BIT(j);
configure = true;
break;
@@ -708,15 +708,12 @@ int mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_hdroom *hdroom,
bool pause_en)
{
- u8 def_prio_tc[IEEE_8021QAZ_MAX_TCS] = {0};
bool dcb_en = !!mlxsw_sp_port->dcb.ets;
struct ieee_pfc *my_pfc;
- u8 *prio_tc;
- prio_tc = dcb_en ? mlxsw_sp_port->dcb.ets->prio_tc : def_prio_tc;
my_pfc = dcb_en ? mlxsw_sp_port->dcb.pfc : NULL;
- return __mlxsw_sp_port_headroom_set(mlxsw_sp_port, hdroom, prio_tc, pause_en, my_pfc);
+ return __mlxsw_sp_port_headroom_set(mlxsw_sp_port, hdroom, pause_en, my_pfc);
}
static int mlxsw_sp_port_change_mtu(struct net_device *dev, int mtu)
@@ -439,7 +439,19 @@ int mlxsw_sp_port_admin_status_set(struct mlxsw_sp_port *mlxsw_sp_port,
bool is_up);
/* spectrum_buffers.c */
+struct mlxsw_sp_hdroom_prio {
+ /* Number of port buffer associated with this priority. This is the
+ * actually configured value.
+ */
+ u8 buf_idx;
+ /* Value of buf_idx deduced from the DCB ETS configuration. */
+ u8 ets_buf_idx;
+};
+
struct mlxsw_sp_hdroom {
+ struct {
+ struct mlxsw_sp_hdroom_prio prio[IEEE_8021Q_MAX_PRIORITIES];
+ } prios;
int delay_bytes;
int mtu;
};
@@ -484,6 +496,7 @@ int mlxsw_sp_sb_occ_tc_port_bind_get(struct mlxsw_core_port *mlxsw_core_port,
u32 mlxsw_sp_cells_bytes(const struct mlxsw_sp *mlxsw_sp, u32 cells);
u32 mlxsw_sp_bytes_cells(const struct mlxsw_sp *mlxsw_sp, u32 bytes);
u32 mlxsw_sp_sb_max_headroom_cells(const struct mlxsw_sp *mlxsw_sp);
+void mlxsw_sp_hdroom_prios_reset_buf_idx(struct mlxsw_sp_hdroom *hdroom);
extern const struct mlxsw_sp_sb_vals mlxsw_sp1_sb_vals;
extern const struct mlxsw_sp_sb_vals mlxsw_sp2_sb_vals;
@@ -527,7 +540,7 @@ int mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port *mlxsw_sp_port,
u8 switch_prio, u8 tclass);
int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_hdroom *hdroom,
- u8 *prio_tc, bool pause_en, struct ieee_pfc *my_pfc);
+ bool pause_en, struct ieee_pfc *my_pfc);
int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
enum mlxsw_reg_qeec_hr hr, u8 index,
u8 next_index, u32 maxrate, u8 burst_size);
@@ -332,6 +332,14 @@ static int mlxsw_sp_port_pb_prio_init(struct mlxsw_sp_port *mlxsw_sp_port)
pptb_pl);
}
+void mlxsw_sp_hdroom_prios_reset_buf_idx(struct mlxsw_sp_hdroom *hdroom)
+{
+ int prio;
+
+ for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++)
+ hdroom->prios.prio[prio].buf_idx = hdroom->prios.prio[prio].ets_buf_idx;
+}
+
static int mlxsw_sp_port_headroom_init(struct mlxsw_sp_port *mlxsw_sp_port)
{
int err;
@@ -116,13 +116,19 @@ static int mlxsw_sp_port_headroom_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
bool pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
struct ieee_ets *my_ets = mlxsw_sp_port->dcb.ets;
struct net_device *dev = mlxsw_sp_port->dev;
+ struct mlxsw_sp_hdroom hdroom;
+ int prio;
int err;
+ hdroom = *mlxsw_sp_port->hdroom;
+ for (prio = 0; prio < IEEE_8021QAZ_MAX_TCS; prio++)
+ hdroom.prios.prio[prio].ets_buf_idx = ets->prio_tc[prio];
+ mlxsw_sp_hdroom_prios_reset_buf_idx(&hdroom);
+
/* Create the required PGs, but don't destroy existing ones, as
* traffic is still directed to them.
*/
- err = __mlxsw_sp_port_headroom_set(mlxsw_sp_port, mlxsw_sp_port->hdroom,
- ets->prio_tc, pause_en,
+ err = __mlxsw_sp_port_headroom_set(mlxsw_sp_port, &hdroom, pause_en,
mlxsw_sp_port->dcb.pfc);
if (err) {
netdev_err(dev, "Failed to configure port's headroom\n");
@@ -622,8 +628,7 @@ static int mlxsw_sp_dcbnl_ieee_setpfc(struct net_device *dev,
else
hdroom.delay_bytes = 0;
- err = __mlxsw_sp_port_headroom_set(mlxsw_sp_port, &hdroom, mlxsw_sp_port->dcb.ets->prio_tc,
- pause_en, pfc);
+ err = __mlxsw_sp_port_headroom_set(mlxsw_sp_port, &hdroom, pause_en, pfc);
if (err) {
netdev_err(dev, "Failed to configure port's headroom for PFC\n");
return err;
@@ -641,8 +646,7 @@ static int mlxsw_sp_dcbnl_ieee_setpfc(struct net_device *dev,
return 0;
err_port_pfc_set:
- __mlxsw_sp_port_headroom_set(mlxsw_sp_port, &orig_hdroom, mlxsw_sp_port->dcb.ets->prio_tc,
- pause_en, mlxsw_sp_port->dcb.pfc);
+ __mlxsw_sp_port_headroom_set(mlxsw_sp_port, &orig_hdroom, pause_en, mlxsw_sp_port->dcb.pfc);
return err;
}