Skip to content

Commit a08b4ed

Browse files
ayalevin123Saeed Mahameed
authored andcommitted
net/mlx5: Add support to ext_* fields introduced in Port Type and Speed register
This patch exposes new link modes (including 50Gbps per lane), and ext_* fields which describes the new link modes in Port Type and Speed register (PTYS). Access functions, translation functions (speed <-> HW bits) and link max speed function were modified. Signed-off-by: Aya Levin <ayal@mellanox.com> Reviewed-by: Eran Ben Elisha <eranbe@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
1 parent a0a8998 commit a08b4ed

File tree

5 files changed

+94
-30
lines changed

5 files changed

+94
-30
lines changed

drivers/infiniband/hw/mlx5/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,8 @@ static int mlx5_query_port_roce(struct ib_device *device, u8 port_num,
421421
mdev_port_num);
422422
if (err)
423423
goto out;
424-
eth_prot_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
424+
eth_prot_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, false,
425+
eth_proto_oper);
425426

426427
props->active_width = IB_WIDTH_4X;
427428
props->active_speed = IB_SPEED_QDR;

drivers/net/ethernet/mellanox/mlx5/core/en/port.c

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,31 @@ static const u32 mlx5e_link_speed[MLX5E_LINK_MODES_NUMBER] = {
6363
[MLX5E_50GBASE_KR2] = 50000,
6464
};
6565

66-
int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port,
66+
static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = {
67+
[MLX5E_SGMII_100M] = 100,
68+
[MLX5E_1000BASE_X_SGMII] = 1000,
69+
[MLX5E_5GBASE_R] = 5000,
70+
[MLX5E_10GBASE_XFI_XAUI_1] = 10000,
71+
[MLX5E_40GBASE_XLAUI_4_XLPPI_4] = 40000,
72+
[MLX5E_25GAUI_1_25GBASE_CR_KR] = 25000,
73+
[MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = 50000,
74+
[MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = 50000,
75+
[MLX5E_CAUI_4_100GBASE_CR4_KR4] = 100000,
76+
[MLX5E_200GAUI_4_200GBASE_CR4_KR4] = 200000,
77+
[MLX5E_400GAUI_8] = 400000,
78+
};
79+
80+
static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev,
81+
const u32 **arr, u32 *size)
82+
{
83+
bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
84+
85+
*size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) :
86+
ARRAY_SIZE(mlx5e_link_speed);
87+
*arr = ext ? mlx5e_ext_link_speed : mlx5e_link_speed;
88+
}
89+
90+
int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
6791
struct mlx5e_port_eth_proto *eproto)
6892
{
6993
u32 out[MLX5_ST_SZ_DW(ptys_reg)];
@@ -72,13 +96,17 @@ int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port,
7296
if (!eproto)
7397
return -EINVAL;
7498

99+
if (ext != MLX5_CAP_PCAM_FEATURE(dev, ptys_extended_ethernet))
100+
return -EOPNOTSUPP;
101+
75102
err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, port);
76103
if (err)
77104
return err;
78105

79-
eproto->cap = MLX5_GET(ptys_reg, out, eth_proto_capability);
80-
eproto->admin = MLX5_GET(ptys_reg, out, eth_proto_admin);
81-
eproto->oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
106+
eproto->cap = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
107+
eth_proto_capability);
108+
eproto->admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_admin);
109+
eproto->oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_oper);
82110
return 0;
83111
}
84112

@@ -100,7 +128,7 @@ void mlx5_port_query_eth_autoneg(struct mlx5_core_dev *dev, u8 *an_status,
100128
}
101129

102130
int mlx5_port_set_eth_ptys(struct mlx5_core_dev *dev, bool an_disable,
103-
u32 proto_admin)
131+
u32 proto_admin, bool ext)
104132
{
105133
u32 out[MLX5_ST_SZ_DW(ptys_reg)];
106134
u32 in[MLX5_ST_SZ_DW(ptys_reg)];
@@ -118,70 +146,85 @@ int mlx5_port_set_eth_ptys(struct mlx5_core_dev *dev, bool an_disable,
118146
MLX5_SET(ptys_reg, in, local_port, 1);
119147
MLX5_SET(ptys_reg, in, an_disable_admin, an_disable);
120148
MLX5_SET(ptys_reg, in, proto_mask, MLX5_PTYS_EN);
121-
MLX5_SET(ptys_reg, in, eth_proto_admin, proto_admin);
149+
if (ext)
150+
MLX5_SET(ptys_reg, in, ext_eth_proto_admin, proto_admin);
151+
else
152+
MLX5_SET(ptys_reg, in, eth_proto_admin, proto_admin);
122153

123154
return mlx5_core_access_reg(dev, in, sizeof(in), out,
124155
sizeof(out), MLX5_REG_PTYS, 0, 1);
125156
}
126157

127-
u32 mlx5e_port_ptys2speed(u32 eth_proto_oper)
158+
u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper)
128159
{
129160
unsigned long temp = eth_proto_oper;
161+
const u32 *table;
130162
u32 speed = 0;
163+
u32 max_size;
131164
int i;
132165

133-
i = find_first_bit(&temp, MLX5E_LINK_MODES_NUMBER);
134-
if (i < MLX5E_LINK_MODES_NUMBER)
135-
speed = mlx5e_link_speed[i];
136-
166+
mlx5e_port_get_speed_arr(mdev, &table, &max_size);
167+
i = find_first_bit(&temp, max_size);
168+
if (i < max_size)
169+
speed = table[i];
137170
return speed;
138171
}
139172

140173
int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
141174
{
142175
struct mlx5e_port_eth_proto eproto;
176+
bool ext;
143177
int err;
144178

145-
err = mlx5_port_query_eth_proto(mdev, 1, &eproto);
179+
ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
180+
err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
146181
if (err)
147-
return err;
182+
goto out;
148183

149-
*speed = mlx5e_port_ptys2speed(eproto.oper);
184+
*speed = mlx5e_port_ptys2speed(mdev, eproto.oper);
150185
if (!(*speed))
151186
err = -EINVAL;
152187

188+
out:
153189
return err;
154190
}
155191

156192
int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
157193
{
158194
struct mlx5e_port_eth_proto eproto;
159195
u32 max_speed = 0;
196+
const u32 *table;
197+
u32 max_size;
198+
bool ext;
160199
int err;
161200
int i;
162201

163-
err = mlx5_port_query_eth_proto(mdev, 1, &eproto);
202+
ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
203+
err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto);
164204
if (err)
165205
return err;
166206

167-
for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i)
207+
mlx5e_port_get_speed_arr(mdev, &table, &max_size);
208+
for (i = 0; i < max_size; ++i)
168209
if (eproto.cap & MLX5E_PROT_MASK(i))
169-
max_speed = max(max_speed, mlx5e_link_speed[i]);
210+
max_speed = max(max_speed, table[i]);
170211

171212
*speed = max_speed;
172213
return 0;
173214
}
174215

175-
u32 mlx5e_port_speed2linkmodes(u32 speed)
216+
u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed)
176217
{
177218
u32 link_modes = 0;
219+
const u32 *table;
220+
u32 max_size;
178221
int i;
179222

180-
for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
181-
if (mlx5e_link_speed[i] == speed)
223+
mlx5e_port_get_speed_arr(mdev, &table, &max_size);
224+
for (i = 0; i < max_size; ++i) {
225+
if (table[i] == speed)
182226
link_modes |= MLX5E_PROT_MASK(i);
183227
}
184-
185228
return link_modes;
186229
}
187230

drivers/net/ethernet/mellanox/mlx5/core/en/port.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,16 @@ struct mlx5e_port_eth_proto {
4242
u32 oper;
4343
};
4444

45-
int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port,
45+
int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
4646
struct mlx5e_port_eth_proto *eproto);
4747
void mlx5_port_query_eth_autoneg(struct mlx5_core_dev *dev, u8 *an_status,
4848
u8 *an_disable_cap, u8 *an_disable_admin);
4949
int mlx5_port_set_eth_ptys(struct mlx5_core_dev *dev, bool an_disable,
50-
u32 proto_admin);
51-
u32 mlx5e_port_ptys2speed(u32 eth_proto_oper);
50+
u32 proto_admin, bool ext);
51+
u32 mlx5e_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper);
5252
int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
5353
int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
54-
u32 mlx5e_port_speed2linkmodes(u32 speed);
54+
u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed);
5555

5656
int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out);
5757
int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in);

drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -695,13 +695,14 @@ static void get_speed_duplex(struct net_device *netdev,
695695
u32 eth_proto_oper,
696696
struct ethtool_link_ksettings *link_ksettings)
697697
{
698+
struct mlx5e_priv *priv = netdev_priv(netdev);
698699
u32 speed = SPEED_UNKNOWN;
699700
u8 duplex = DUPLEX_UNKNOWN;
700701

701702
if (!netif_carrier_ok(netdev))
702703
goto out;
703704

704-
speed = mlx5e_port_ptys2speed(eth_proto_oper);
705+
speed = mlx5e_port_ptys2speed(priv->mdev, eth_proto_oper);
705706
if (!speed) {
706707
speed = SPEED_UNKNOWN;
707708
goto out;
@@ -896,9 +897,9 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
896897

897898
link_modes = link_ksettings->base.autoneg == AUTONEG_ENABLE ?
898899
mlx5e_ethtool2ptys_adver_link(link_ksettings->link_modes.advertising) :
899-
mlx5e_port_speed2linkmodes(speed);
900+
mlx5e_port_speed2linkmodes(mdev, speed);
900901

901-
err = mlx5_port_query_eth_proto(mdev, 1, &eproto);
902+
err = mlx5_port_query_eth_proto(mdev, 1, false, &eproto);
902903
if (err) {
903904
netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n",
904905
__func__, err);
@@ -923,7 +924,7 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
923924
if (!an_changes && link_modes == eproto.admin)
924925
goto out;
925926

926-
mlx5_port_set_eth_ptys(mdev, an_disable, link_modes);
927+
mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, false);
927928
mlx5_toggle_port_link(mdev);
928929

929930
out:

include/linux/mlx5/port.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,22 @@ enum mlx5e_link_mode {
9292
MLX5E_LINK_MODES_NUMBER,
9393
};
9494

95+
enum mlx5e_ext_link_mode {
96+
MLX5E_SGMII_100M = 0,
97+
MLX5E_1000BASE_X_SGMII = 1,
98+
MLX5E_5GBASE_R = 3,
99+
MLX5E_10GBASE_XFI_XAUI_1 = 4,
100+
MLX5E_40GBASE_XLAUI_4_XLPPI_4 = 5,
101+
MLX5E_25GAUI_1_25GBASE_CR_KR = 6,
102+
MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2 = 7,
103+
MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR = 8,
104+
MLX5E_CAUI_4_100GBASE_CR4_KR4 = 9,
105+
MLX5E_100GAUI_2_100GBASE_CR2_KR2 = 10,
106+
MLX5E_200GAUI_4_200GBASE_CR4_KR4 = 12,
107+
MLX5E_400GAUI_8 = 15,
108+
MLX5E_EXT_LINK_MODES_NUMBER,
109+
};
110+
95111
enum mlx5e_connector_type {
96112
MLX5E_PORT_UNKNOWN = 0,
97113
MLX5E_PORT_NONE = 1,
@@ -106,6 +122,9 @@ enum mlx5e_connector_type {
106122
};
107123

108124
#define MLX5E_PROT_MASK(link_mode) (1 << link_mode)
125+
#define MLX5_GET_ETH_PROTO(reg, out, ext, field) \
126+
(ext ? MLX5_GET(reg, out, ext_##field) : \
127+
MLX5_GET(reg, out, field))
109128

110129
int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps);
111130
int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,

0 commit comments

Comments
 (0)