net/mlx5e: Device's mtu field is u16 and not int
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / port.c
index 5635ce7..53cc1e2 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <linux/module.h>
 #include <linux/mlx5/driver.h>
+#include <linux/mlx5/port.h>
 #include <linux/mlx5/cmd.h>
 #include "mlx5_core.h"
 
@@ -246,8 +247,8 @@ int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
 }
 EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status);
 
-static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu,
-                               int *max_mtu, int *oper_mtu, u8 port)
+static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, u16 *admin_mtu,
+                               u16 *max_mtu, u16 *oper_mtu, u8 port)
 {
        u32 in[MLX5_ST_SZ_DW(pmtu_reg)];
        u32 out[MLX5_ST_SZ_DW(pmtu_reg)];
@@ -267,7 +268,7 @@ static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, int *admin_mtu,
                *admin_mtu = MLX5_GET(pmtu_reg, out, admin_mtu);
 }
 
-int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port)
+int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port)
 {
        u32 in[MLX5_ST_SZ_DW(pmtu_reg)];
        u32 out[MLX5_ST_SZ_DW(pmtu_reg)];
@@ -282,14 +283,14 @@ int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu, u8 port)
 }
 EXPORT_SYMBOL_GPL(mlx5_set_port_mtu);
 
-void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu,
+void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu,
                             u8 port)
 {
        mlx5_query_port_mtu(dev, NULL, max_mtu, NULL, port);
 }
 EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu);
 
-void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu,
+void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu,
                              u8 port)
 {
        mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu, port);
@@ -386,3 +387,223 @@ int mlx5_query_port_pause(struct mlx5_core_dev *dev,
        return 0;
 }
 EXPORT_SYMBOL_GPL(mlx5_query_port_pause);
+
+int mlx5_set_port_pfc(struct mlx5_core_dev *dev, u8 pfc_en_tx, u8 pfc_en_rx)
+{
+       u32 in[MLX5_ST_SZ_DW(pfcc_reg)];
+       u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
+
+       memset(in, 0, sizeof(in));
+       MLX5_SET(pfcc_reg, in, local_port, 1);
+       MLX5_SET(pfcc_reg, in, pfctx, pfc_en_tx);
+       MLX5_SET(pfcc_reg, in, pfcrx, pfc_en_rx);
+       MLX5_SET_TO_ONES(pfcc_reg, in, prio_mask_tx);
+       MLX5_SET_TO_ONES(pfcc_reg, in, prio_mask_rx);
+
+       return mlx5_core_access_reg(dev, in, sizeof(in), out,
+                                   sizeof(out), MLX5_REG_PFCC, 0, 1);
+}
+EXPORT_SYMBOL_GPL(mlx5_set_port_pfc);
+
+int mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx, u8 *pfc_en_rx)
+{
+       u32 in[MLX5_ST_SZ_DW(pfcc_reg)];
+       u32 out[MLX5_ST_SZ_DW(pfcc_reg)];
+       int err;
+
+       memset(in, 0, sizeof(in));
+       MLX5_SET(pfcc_reg, in, local_port, 1);
+
+       err = mlx5_core_access_reg(dev, in, sizeof(in), out,
+                                  sizeof(out), MLX5_REG_PFCC, 0, 0);
+       if (err)
+               return err;
+
+       if (pfc_en_tx)
+               *pfc_en_tx = MLX5_GET(pfcc_reg, out, pfctx);
+
+       if (pfc_en_rx)
+               *pfc_en_rx = MLX5_GET(pfcc_reg, out, pfcrx);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_port_pfc);
+
+int mlx5_max_tc(struct mlx5_core_dev *mdev)
+{
+       u8 num_tc = MLX5_CAP_GEN(mdev, max_tc) ? : 8;
+
+       return num_tc - 1;
+}
+
+int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc)
+{
+       u32 in[MLX5_ST_SZ_DW(qtct_reg)];
+       u32 out[MLX5_ST_SZ_DW(qtct_reg)];
+       int err;
+       int i;
+
+       memset(in, 0, sizeof(in));
+       for (i = 0; i < 8; i++) {
+               if (prio_tc[i] > mlx5_max_tc(mdev))
+                       return -EINVAL;
+
+               MLX5_SET(qtct_reg, in, prio, i);
+               MLX5_SET(qtct_reg, in, tclass, prio_tc[i]);
+
+               err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
+                                          sizeof(out), MLX5_REG_QTCT, 0, 1);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mlx5_set_port_prio_tc);
+
+static int mlx5_set_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *in,
+                                  int inlen)
+{
+       u32 out[MLX5_ST_SZ_DW(qtct_reg)];
+
+       if (!MLX5_CAP_GEN(mdev, ets))
+               return -ENOTSUPP;
+
+       return mlx5_core_access_reg(mdev, in, inlen, out, sizeof(out),
+                                   MLX5_REG_QETCR, 0, 1);
+}
+
+static int mlx5_query_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *out,
+                                    int outlen)
+{
+       u32 in[MLX5_ST_SZ_DW(qtct_reg)];
+
+       if (!MLX5_CAP_GEN(mdev, ets))
+               return -ENOTSUPP;
+
+       memset(in, 0, sizeof(in));
+       return mlx5_core_access_reg(mdev, in, sizeof(in), out, outlen,
+                                   MLX5_REG_QETCR, 0, 0);
+}
+
+int mlx5_set_port_tc_group(struct mlx5_core_dev *mdev, u8 *tc_group)
+{
+       u32 in[MLX5_ST_SZ_DW(qetc_reg)];
+       int i;
+
+       memset(in, 0, sizeof(in));
+
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               MLX5_SET(qetc_reg, in, tc_configuration[i].g, 1);
+               MLX5_SET(qetc_reg, in, tc_configuration[i].group, tc_group[i]);
+       }
+
+       return mlx5_set_port_qetcr_reg(mdev, in, sizeof(in));
+}
+EXPORT_SYMBOL_GPL(mlx5_set_port_tc_group);
+
+int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw)
+{
+       u32 in[MLX5_ST_SZ_DW(qetc_reg)];
+       int i;
+
+       memset(in, 0, sizeof(in));
+
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               MLX5_SET(qetc_reg, in, tc_configuration[i].b, 1);
+               MLX5_SET(qetc_reg, in, tc_configuration[i].bw_allocation, tc_bw[i]);
+       }
+
+       return mlx5_set_port_qetcr_reg(mdev, in, sizeof(in));
+}
+EXPORT_SYMBOL_GPL(mlx5_set_port_tc_bw_alloc);
+
+int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
+                                   u8 *max_bw_value,
+                                   u8 *max_bw_units)
+{
+       u32 in[MLX5_ST_SZ_DW(qetc_reg)];
+       void *ets_tcn_conf;
+       int i;
+
+       memset(in, 0, sizeof(in));
+
+       MLX5_SET(qetc_reg, in, port_number, 1);
+
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, in, tc_configuration[i]);
+
+               MLX5_SET(ets_tcn_config_reg, ets_tcn_conf, r, 1);
+               MLX5_SET(ets_tcn_config_reg, ets_tcn_conf, max_bw_units,
+                        max_bw_units[i]);
+               MLX5_SET(ets_tcn_config_reg, ets_tcn_conf, max_bw_value,
+                        max_bw_value[i]);
+       }
+
+       return mlx5_set_port_qetcr_reg(mdev, in, sizeof(in));
+}
+EXPORT_SYMBOL_GPL(mlx5_modify_port_ets_rate_limit);
+
+int mlx5_query_port_ets_rate_limit(struct mlx5_core_dev *mdev,
+                                  u8 *max_bw_value,
+                                  u8 *max_bw_units)
+{
+       u32 out[MLX5_ST_SZ_DW(qetc_reg)];
+       void *ets_tcn_conf;
+       int err;
+       int i;
+
+       err = mlx5_query_port_qetcr_reg(mdev, out, sizeof(out));
+       if (err)
+               return err;
+
+       for (i = 0; i <= mlx5_max_tc(mdev); i++) {
+               ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, out, tc_configuration[i]);
+
+               max_bw_value[i] = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf,
+                                          max_bw_value);
+               max_bw_units[i] = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf,
+                                          max_bw_units);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_port_ets_rate_limit);
+
+int mlx5_set_port_wol(struct mlx5_core_dev *mdev, u8 wol_mode)
+{
+       u32 in[MLX5_ST_SZ_DW(set_wol_rol_in)];
+       u32 out[MLX5_ST_SZ_DW(set_wol_rol_out)];
+
+       memset(in, 0, sizeof(in));
+       memset(out, 0, sizeof(out));
+
+       MLX5_SET(set_wol_rol_in, in, opcode, MLX5_CMD_OP_SET_WOL_ROL);
+       MLX5_SET(set_wol_rol_in, in, wol_mode_valid, 1);
+       MLX5_SET(set_wol_rol_in, in, wol_mode, wol_mode);
+
+       return mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
+                                         out, sizeof(out));
+}
+EXPORT_SYMBOL_GPL(mlx5_set_port_wol);
+
+int mlx5_query_port_wol(struct mlx5_core_dev *mdev, u8 *wol_mode)
+{
+       u32 in[MLX5_ST_SZ_DW(query_wol_rol_in)];
+       u32 out[MLX5_ST_SZ_DW(query_wol_rol_out)];
+       int err;
+
+       memset(in, 0, sizeof(in));
+       memset(out, 0, sizeof(out));
+
+       MLX5_SET(query_wol_rol_in, in, opcode, MLX5_CMD_OP_QUERY_WOL_ROL);
+
+       err = mlx5_cmd_exec_check_status(mdev, in, sizeof(in),
+                                        out, sizeof(out));
+
+       if (!err)
+               *wol_mode = MLX5_GET(query_wol_rol_out, out, wol_mode);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_port_wol);