mlxsw: spectrum: Refactor port buffer configuration
authorIdo Schimmel <idosch@mellanox.com>
Fri, 24 Mar 2017 07:02:50 +0000 (08:02 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 24 Mar 2017 20:53:29 +0000 (13:53 -0700)
The sizes and thresholds of the priority group (PG) buffers are
configured in cells, which represent a specific amount of bytes.

The cell size can vary in different devices, so it's better to query it
from the firmware than hard coding it.

Refactor the code dealing with this value into different functions, so
that it will be easier to make the conversion in the next patch.

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>
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h

index 7d0bd027cf1ef2d6bcfbe3f24bc16ff22be8c71f..c440b351a0e4206f62a8d6cd846b102134c3b229 100644 (file)
@@ -800,19 +800,40 @@ static int mlxsw_sp_port_set_mac_address(struct net_device *dev, void *p)
        return 0;
 }
 
-static void mlxsw_sp_pg_buf_pack(char *pbmc_pl, int pg_index, int mtu,
-                                bool pause_en, bool pfc_en, u16 delay)
+static u16 mlxsw_sp_pg_buf_threshold_get(int mtu)
 {
-       u16 pg_size = 2 * MLXSW_SP_BYTES_TO_CELLS(mtu);
+       return 2 * MLXSW_SP_BYTES_TO_CELLS(mtu);
+}
 
-       delay = pfc_en ? mlxsw_sp_pfc_delay_get(mtu, delay) :
-                        MLXSW_SP_PAUSE_DELAY;
+#define MLXSW_SP_CELL_FACTOR 2 /* 2 * cell_size / (IPG + cell_size + 1) */
+static u16 mlxsw_sp_pfc_delay_get(int mtu, u16 delay)
+{
+       delay = MLXSW_SP_BYTES_TO_CELLS(DIV_ROUND_UP(delay, BITS_PER_BYTE));
+       return MLXSW_SP_CELL_FACTOR * delay + MLXSW_SP_BYTES_TO_CELLS(mtu);
+}
 
-       if (pause_en || pfc_en)
-               mlxsw_reg_pbmc_lossless_buffer_pack(pbmc_pl, pg_index,
-                                                   pg_size + delay, pg_size);
+/* Maximum delay buffer needed in case of PAUSE frames, in cells.
+ * Assumes 100m cable and maximum MTU.
+ */
+#define MLXSW_SP_PAUSE_DELAY 612
+static u16 mlxsw_sp_pg_buf_delay_get(int mtu, u16 delay, bool pfc, bool pause)
+{
+       if (pfc)
+               return mlxsw_sp_pfc_delay_get(mtu, delay);
+       else if (pause)
+               return MLXSW_SP_PAUSE_DELAY;
        else
-               mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, pg_index, pg_size);
+               return 0;
+}
+
+static void mlxsw_sp_pg_buf_pack(char *pbmc_pl, int index, u16 size, u16 thres,
+                                bool lossy)
+{
+       if (lossy)
+               mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, index, size);
+       else
+               mlxsw_reg_pbmc_lossless_buffer_pack(pbmc_pl, index, size,
+                                                   thres);
 }
 
 int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
@@ -833,6 +854,8 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
                bool configure = false;
                bool pfc = false;
+               bool lossy;
+               u16 thres;
 
                for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) {
                        if (prio_tc[j] == i) {
@@ -844,7 +867,11 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
 
                if (!configure)
                        continue;
-               mlxsw_sp_pg_buf_pack(pbmc_pl, i, mtu, pause_en, pfc, delay);
+
+               lossy = !(pfc || pause_en);
+               thres = mlxsw_sp_pg_buf_threshold_get(mtu);
+               delay = mlxsw_sp_pg_buf_delay_get(mtu, delay, pfc, pause_en);
+               mlxsw_sp_pg_buf_pack(pbmc_pl, i, thres + delay, thres, lossy);
        }
 
        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
index 80a0d7d3e1b5e9d5d84e68a18daca21965e545d3..958acac91ba8cf7278a19f3fb7b3cb7b37b41b5a 100644 (file)
 #define MLXSW_SP_KVD_LINEAR_SIZE 65536 /* entries */
 #define MLXSW_SP_KVD_GRANULARITY 128
 
-/* Maximum delay buffer needed in case of PAUSE frames, in cells.
- * Assumes 100m cable and maximum MTU.
- */
-#define MLXSW_SP_PAUSE_DELAY 612
-
-#define MLXSW_SP_CELL_FACTOR 2 /* 2 * cell_size / (IPG + cell_size + 1) */
-
-static inline u16 mlxsw_sp_pfc_delay_get(int mtu, u16 delay)
-{
-       delay = MLXSW_SP_BYTES_TO_CELLS(DIV_ROUND_UP(delay, BITS_PER_BYTE));
-       return MLXSW_SP_CELL_FACTOR * delay + MLXSW_SP_BYTES_TO_CELLS(mtu);
-}
-
 struct mlxsw_sp_port;
 struct mlxsw_sp_rif;