Skip to content

Commit

Permalink
Import Linux code to query/set buffer state in mlx5en(4).
Browse files Browse the repository at this point in the history
Submitted by:	kib@
MFC after:	3 days
Sponsored by:	Mellanox Technologies
  • Loading branch information
hselasky committed Oct 2, 2019
1 parent 6e2bd34 commit 82af45a
Show file tree
Hide file tree
Showing 7 changed files with 656 additions and 0 deletions.
2 changes: 2 additions & 0 deletions sys/conf/files
Original file line number Diff line number Diff line change
Expand Up @@ -4770,6 +4770,8 @@ dev/mlx5/mlx5_en/mlx5_en_rl.c optional mlx5en pci inet inet6 \
compile-with "${OFED_C}"
dev/mlx5/mlx5_en/mlx5_en_txrx.c optional mlx5en pci inet inet6 \
compile-with "${OFED_C}"
dev/mlx5/mlx5_en/mlx5_en_port_buffer.c optional mlx5en pci inet inet6 \
compile-with "${OFED_C}"

# crypto support
opencrypto/cast.c optional crypto | ipsec | ipsec_support
Expand Down
217 changes: 217 additions & 0 deletions sys/dev/mlx5/mlx5_core/mlx5_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,3 +1236,220 @@ mlx5_set_mfrl_reg(struct mlx5_core_dev *mdev, u8 reset_level)
return (mlx5_core_access_reg(mdev, mfrl, sz, mfrl, sz, MLX5_REG_MFRL,
0, 1));
}

/* speed in units of 1Mb */
static const u32 mlx5e_link_speed[/*MLX5E_LINK_MODES_NUMBER*/] = {
[MLX5E_1000BASE_CX_SGMII] = 1000,
[MLX5E_1000BASE_KX] = 1000,
[MLX5E_10GBASE_CX4] = 10000,
[MLX5E_10GBASE_KX4] = 10000,
[MLX5E_10GBASE_KR] = 10000,
[MLX5E_20GBASE_KR2] = 20000,
[MLX5E_40GBASE_CR4] = 40000,
[MLX5E_40GBASE_KR4] = 40000,
[MLX5E_56GBASE_R4] = 56000,
[MLX5E_10GBASE_CR] = 10000,
[MLX5E_10GBASE_SR] = 10000,
[MLX5E_10GBASE_ER_LR] = 10000,
[MLX5E_40GBASE_SR4] = 40000,
[MLX5E_40GBASE_LR4_ER4] = 40000,
[MLX5E_50GBASE_SR2] = 50000,
[MLX5E_100GBASE_CR4] = 100000,
[MLX5E_100GBASE_SR4] = 100000,
[MLX5E_100GBASE_KR4] = 100000,
[MLX5E_100GBASE_LR4] = 100000,
[MLX5E_100BASE_TX] = 100,
[MLX5E_1000BASE_T] = 1000,
[MLX5E_10GBASE_T] = 10000,
[MLX5E_25GBASE_CR] = 25000,
[MLX5E_25GBASE_KR] = 25000,
[MLX5E_25GBASE_SR] = 25000,
[MLX5E_50GBASE_CR2] = 50000,
[MLX5E_50GBASE_KR2] = 50000,
};

static const u32 mlx5e_ext_link_speed[/*MLX5E_EXT_LINK_MODES_NUMBER*/] = {
[MLX5E_SGMII_100M] = 100,
[MLX5E_1000BASE_X_SGMII] = 1000,
[MLX5E_5GBASE_R] = 5000,
[MLX5E_10GBASE_XFI_XAUI_1] = 10000,
[MLX5E_40GBASE_XLAUI_4_XLPPI_4] = 40000,
[MLX5E_25GAUI_1_25GBASE_CR_KR] = 25000,
[MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = 50000,
[MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = 50000,
[MLX5E_CAUI_4_100GBASE_CR4_KR4] = 100000,
[MLX5E_200GAUI_4_200GBASE_CR4_KR4] = 200000,
[MLX5E_400GAUI_8] = 400000,
};

static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev,
const u32 **arr, u32 *size)
{
bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);

*size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) :
ARRAY_SIZE(mlx5e_link_speed);
*arr = ext ? mlx5e_ext_link_speed : mlx5e_link_speed;
}

u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper)
{
unsigned long temp = eth_proto_oper;
const u32 *table;
u32 speed = 0;
u32 max_size;
int i;

mlx5e_port_get_speed_arr(mdev, &table, &max_size);
i = find_first_bit(&temp, max_size);
if (i < max_size)
speed = table[i];
return speed;
}

int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
struct mlx5e_port_eth_proto *eproto)
{
u32 out[MLX5_ST_SZ_DW(ptys_reg)];
int err;

if (!eproto)
return -EINVAL;

err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, port);
if (err)
return err;

eproto->cap = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
eth_proto_capability);
eproto->admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_admin);
eproto->oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_oper);
return 0;
}

int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
{
struct mlx5e_port_eth_proto eproto;
bool ext;
int err;

ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
if (err)
goto out;

*speed = mlx5e_port_ptys2speed(mdev, eproto.oper);
if (!(*speed))
err = -EINVAL;

out:
return err;
}

int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out)
{
int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
void *in;
int err;

in = kzalloc(sz, GFP_KERNEL);
if (!in)
return -ENOMEM;

MLX5_SET(pbmc_reg, in, local_port, 1);
err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PBMC, 0, 0);

kfree(in);
return err;
}

int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in)
{
int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
void *out;
int err;

out = kzalloc(sz, GFP_KERNEL);
if (!out)
return -ENOMEM;

MLX5_SET(pbmc_reg, in, local_port, 1);
err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PBMC, 0, 1);

kfree(out);
return err;
}

/* buffer[i]: buffer that priority i mapped to */
int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
{
int sz = MLX5_ST_SZ_BYTES(pptb_reg);
u32 prio_x_buff;
void *out;
void *in;
int prio;
int err;

in = kzalloc(sz, GFP_KERNEL);
out = kzalloc(sz, GFP_KERNEL);
if (!in || !out) {
err = -ENOMEM;
goto out;
}

MLX5_SET(pptb_reg, in, local_port, 1);
err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 0);
if (err)
goto out;

prio_x_buff = MLX5_GET(pptb_reg, out, prio_x_buff);
for (prio = 0; prio < 8; prio++) {
buffer[prio] = (u8)(prio_x_buff >> (4 * prio)) & 0xF;
mlx5_core_dbg(mdev, "prio %d, buffer %d\n", prio, buffer[prio]);
}
out:
kfree(in);
kfree(out);
return err;
}

int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
{
int sz = MLX5_ST_SZ_BYTES(pptb_reg);
u32 prio_x_buff;
void *out;
void *in;
int prio;
int err;

in = kzalloc(sz, GFP_KERNEL);
out = kzalloc(sz, GFP_KERNEL);
if (!in || !out) {
err = -ENOMEM;
goto out;
}

/* First query the pptb register */
MLX5_SET(pptb_reg, in, local_port, 1);
err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 0);
if (err)
goto out;

memcpy(in, out, sz);
MLX5_SET(pptb_reg, in, local_port, 1);

/* Update the pm and prio_x_buff */
MLX5_SET(pptb_reg, in, pm, 0xFF);

prio_x_buff = 0;
for (prio = 0; prio < 8; prio++)
prio_x_buff |= (buffer[prio] << (4 * prio));
MLX5_SET(pptb_reg, in, prio_x_buff, prio_x_buff);

err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 1);

out:
kfree(in);
kfree(out);
return err;
}
7 changes: 7 additions & 0 deletions sys/dev/mlx5/mlx5_en/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,11 @@ struct mlx5e_clbr_point {
u_int clbr_gen;
};

struct mlx5e_dcbx {
u32 cable_len;
u32 xoff;
};

struct mlx5e_priv {
struct mlx5_core_dev *mdev; /* must be first */

Expand Down Expand Up @@ -1056,6 +1061,8 @@ struct mlx5e_priv {
struct mlx5e_clbr_point clbr_points[2];
u_int clbr_gen;

struct mlx5e_dcbx dcbx;

struct pfil_head *pfil;
struct mlx5e_channel channel[];
};
Expand Down
Loading

0 comments on commit 82af45a

Please sign in to comment.