Merge branch 'mlx5-misc-enhancements-2025-03-04'

Tariq Toukan says:

====================
mlx5 misc enhancements 2025-03-04

This series introduces enhancements to the mlx5 core and Eth drivers.

Patches 1-3 by Shahar introduce support for configuring lanes alongside
speed when autonegotiation is disabled. The combination of speed and the
number of lanes corresponds to a specific link mode (in the extended
mask typically used in newer hardware), allowing the user to select a
precise link mode when autonegotiation is off, instead of just choosing
the speed.

Patch 4 by Amir extends the multi-port LAG support.

Patches 5-6 by Leon enhance IPsec matching logic.

v1: https://lore.kernel.org/20250226114752.104838-1-tariqt@nvidia.com
====================

Link: https://patch.msgid.link/20250304160620.417580-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-03-06 17:53:37 -08:00
commit 865eddcf0a
9 changed files with 341 additions and 273 deletions

View File

@ -80,6 +80,7 @@ int mlx5_port_set_eth_ptys(struct mlx5_core_dev *dev, bool an_disable,
int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
{
struct mlx5_port_eth_proto eproto;
const struct mlx5_link_info *info;
bool force_legacy = false;
bool ext;
int err;
@ -94,9 +95,13 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
if (err)
goto out;
}
*speed = mlx5_port_ptys2speed(mdev, eproto.oper, force_legacy);
if (!(*speed))
info = mlx5_port_ptys2info(mdev, eproto.oper, force_legacy);
if (!info) {
*speed = SPEED_UNKNOWN;
err = -EINVAL;
goto out;
}
*speed = info->speed;
out:
return err;

View File

@ -277,12 +277,12 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
case XFRM_DEV_OFFLOAD_IN:
src = attrs->dmac;
dst = attrs->smac;
pkey = &attrs->saddr.a4;
pkey = &attrs->addrs.saddr.a4;
break;
case XFRM_DEV_OFFLOAD_OUT:
src = attrs->smac;
dst = attrs->dmac;
pkey = &attrs->daddr.a4;
pkey = &attrs->addrs.daddr.a4;
break;
default:
return;
@ -303,6 +303,16 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
neigh_release(n);
}
static void mlx5e_ipsec_state_mask(struct mlx5e_ipsec_addr *addrs)
{
/*
* State doesn't have subnet prefixes in outer headers.
* The match is performed for exaxt source/destination addresses.
*/
memset(addrs->smask.m6, 0xFF, sizeof(__be32) * 4);
memset(addrs->dmask.m6, 0xFF, sizeof(__be32) * 4);
}
void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
struct mlx5_accel_esp_xfrm_attrs *attrs)
{
@ -374,9 +384,11 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
attrs->spi = be32_to_cpu(x->id.spi);
/* source , destination ips */
memcpy(&attrs->saddr, x->props.saddr.a6, sizeof(attrs->saddr));
memcpy(&attrs->daddr, x->id.daddr.a6, sizeof(attrs->daddr));
attrs->family = x->props.family;
memcpy(&attrs->addrs.saddr, x->props.saddr.a6,
sizeof(attrs->addrs.saddr));
memcpy(&attrs->addrs.daddr, x->id.daddr.a6, sizeof(attrs->addrs.daddr));
attrs->addrs.family = x->props.family;
mlx5e_ipsec_state_mask(&attrs->addrs);
attrs->type = x->xso.type;
attrs->reqid = x->props.reqid;
attrs->upspec.dport = ntohs(x->sel.dport);
@ -428,7 +440,8 @@ static int mlx5e_xfrm_validate_state(struct mlx5_core_dev *mdev,
}
if (x->encap) {
if (!(mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_ESPINUDP)) {
NL_SET_ERR_MSG_MOD(extack, "Encapsulation is not supported");
NL_SET_ERR_MSG_MOD(extack,
"Encapsulation is not supported");
return -EINVAL;
}
@ -853,13 +866,13 @@ static int mlx5e_ipsec_netevent_event(struct notifier_block *nb,
xa_for_each_marked(&ipsec->sadb, idx, sa_entry, MLX5E_IPSEC_TUNNEL_SA) {
attrs = &sa_entry->attrs;
if (attrs->family == AF_INET) {
if (!neigh_key_eq32(n, &attrs->saddr.a4) &&
!neigh_key_eq32(n, &attrs->daddr.a4))
if (attrs->addrs.family == AF_INET) {
if (!neigh_key_eq32(n, &attrs->addrs.saddr.a4) &&
!neigh_key_eq32(n, &attrs->addrs.daddr.a4))
continue;
} else {
if (!neigh_key_eq128(n, &attrs->saddr.a4) &&
!neigh_key_eq128(n, &attrs->daddr.a4))
if (!neigh_key_eq128(n, &attrs->addrs.saddr.a4) &&
!neigh_key_eq128(n, &attrs->addrs.daddr.a4))
continue;
}
@ -1035,7 +1048,7 @@ static void mlx5e_xfrm_update_stats(struct xfrm_state *x)
* by removing always available headers.
*/
headers = sizeof(struct ethhdr);
if (sa_entry->attrs.family == AF_INET)
if (sa_entry->attrs.addrs.family == AF_INET)
headers += sizeof(struct iphdr);
else
headers += sizeof(struct ipv6hdr);
@ -1044,6 +1057,43 @@ static void mlx5e_xfrm_update_stats(struct xfrm_state *x)
x->curlft.bytes += success_bytes - headers * success_packets;
}
static __be32 word_to_mask(int prefix)
{
if (prefix < 0)
return 0;
if (!prefix || prefix > 31)
return cpu_to_be32(0xFFFFFFFF);
return cpu_to_be32(((1U << prefix) - 1) << (32 - prefix));
}
static void mlx5e_ipsec_policy_mask(struct mlx5e_ipsec_addr *addrs,
struct xfrm_selector *sel)
{
int i;
if (addrs->family == AF_INET) {
addrs->smask.m4 = word_to_mask(sel->prefixlen_s);
addrs->saddr.a4 &= addrs->smask.m4;
addrs->dmask.m4 = word_to_mask(sel->prefixlen_d);
addrs->daddr.a4 &= addrs->dmask.m4;
return;
}
for (i = 0; i < 4; i++) {
if (sel->prefixlen_s != 32 * i)
addrs->smask.m6[i] =
word_to_mask(sel->prefixlen_s - 32 * i);
addrs->saddr.a6[i] &= addrs->smask.m6[i];
if (sel->prefixlen_d != 32 * i)
addrs->dmask.m6[i] =
word_to_mask(sel->prefixlen_d - 32 * i);
addrs->daddr.a6[i] &= addrs->dmask.m6[i];
}
}
static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,
struct xfrm_policy *x,
struct netlink_ext_ack *extack)
@ -1116,9 +1166,10 @@ mlx5e_ipsec_build_accel_pol_attrs(struct mlx5e_ipsec_pol_entry *pol_entry,
sel = &x->selector;
memset(attrs, 0, sizeof(*attrs));
memcpy(&attrs->saddr, sel->saddr.a6, sizeof(attrs->saddr));
memcpy(&attrs->daddr, sel->daddr.a6, sizeof(attrs->daddr));
attrs->family = sel->family;
memcpy(&attrs->addrs.saddr, sel->saddr.a6, sizeof(attrs->addrs.saddr));
memcpy(&attrs->addrs.daddr, sel->daddr.a6, sizeof(attrs->addrs.daddr));
attrs->addrs.family = sel->family;
mlx5e_ipsec_policy_mask(&attrs->addrs, sel);
attrs->dir = x->xdo.dir;
attrs->action = x->action;
attrs->type = XFRM_DEV_OFFLOAD_PACKET;

View File

@ -76,27 +76,36 @@ struct mlx5_replay_esn {
u8 trigger : 1;
};
struct mlx5_accel_esp_xfrm_attrs {
u32 spi;
u32 mode;
struct aes_gcm_keymat aes_gcm;
struct mlx5e_ipsec_addr {
union {
__be32 a4;
__be32 a6[4];
} saddr;
union {
__be32 m4;
__be32 m6[4];
} smask;
union {
__be32 a4;
__be32 a6[4];
} daddr;
union {
__be32 m4;
__be32 m6[4];
} dmask;
u8 family;
};
struct mlx5_accel_esp_xfrm_attrs {
u32 spi;
u32 mode;
struct aes_gcm_keymat aes_gcm;
struct mlx5e_ipsec_addr addrs;
struct upspec upspec;
u8 dir : 2;
u8 type : 2;
u8 drop : 1;
u8 encap : 1;
u8 family;
struct mlx5_replay_esn replay_esn;
u32 authsize;
u32 reqid;
@ -279,18 +288,8 @@ struct mlx5e_ipsec_sa_entry {
};
struct mlx5_accel_pol_xfrm_attrs {
union {
__be32 a4;
__be32 a6[4];
} saddr;
union {
__be32 a4;
__be32 a6[4];
} daddr;
struct mlx5e_ipsec_addr addrs;
struct upspec upspec;
u8 family;
u8 action;
u8 type : 2;
u8 dir : 2;

View File

@ -1484,9 +1484,14 @@ static void tx_ft_put_policy(struct mlx5e_ipsec *ipsec, u32 prio, int type)
mutex_unlock(&tx->ft.mutex);
}
static void setup_fte_addr4(struct mlx5_flow_spec *spec, __be32 *saddr,
__be32 *daddr)
static void setup_fte_addr4(struct mlx5_flow_spec *spec,
struct mlx5e_ipsec_addr *addrs)
{
__be32 *saddr = &addrs->saddr.a4;
__be32 *smask = &addrs->smask.m4;
__be32 *daddr = &addrs->daddr.a4;
__be32 *dmask = &addrs->dmask.m4;
if (!*saddr && !*daddr)
return;
@ -1498,21 +1503,26 @@ static void setup_fte_addr4(struct mlx5_flow_spec *spec, __be32 *saddr,
if (*saddr) {
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4), saddr, 4);
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4);
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4), smask, 4);
}
if (*daddr) {
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4), daddr, 4);
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4), dmask, 4);
}
}
static void setup_fte_addr6(struct mlx5_flow_spec *spec, __be32 *saddr,
__be32 *daddr)
static void setup_fte_addr6(struct mlx5_flow_spec *spec,
struct mlx5e_ipsec_addr *addrs)
{
__be32 *saddr = addrs->saddr.a6;
__be32 *smask = addrs->smask.m6;
__be32 *daddr = addrs->daddr.a6;
__be32 *dmask = addrs->dmask.m6;
if (addr6_all_zero(saddr) && addr6_all_zero(daddr))
return;
@ -1524,15 +1534,15 @@ static void setup_fte_addr6(struct mlx5_flow_spec *spec, __be32 *saddr,
if (!addr6_all_zero(saddr)) {
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6), saddr, 16);
memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6), 0xff, 16);
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6), dmask, 16);
}
if (!addr6_all_zero(daddr)) {
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value,
outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6), daddr, 16);
memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6), 0xff, 16);
memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6), smask, 16);
}
}
@ -1722,7 +1732,7 @@ setup_pkt_tunnel_reformat(struct mlx5_core_dev *mdev,
if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) {
bfflen += sizeof(*esp_hdr) + 8;
switch (attrs->family) {
switch (attrs->addrs.family) {
case AF_INET:
bfflen += sizeof(*iphdr);
break;
@ -1739,7 +1749,7 @@ setup_pkt_tunnel_reformat(struct mlx5_core_dev *mdev,
return -ENOMEM;
eth_hdr = (struct ethhdr *)reformatbf;
switch (attrs->family) {
switch (attrs->addrs.family) {
case AF_INET:
eth_hdr->h_proto = htons(ETH_P_IP);
break;
@ -1762,11 +1772,11 @@ setup_pkt_tunnel_reformat(struct mlx5_core_dev *mdev,
reformat_params->param_0 = attrs->authsize;
hdr = reformatbf + sizeof(*eth_hdr);
switch (attrs->family) {
switch (attrs->addrs.family) {
case AF_INET:
iphdr = (struct iphdr *)hdr;
memcpy(&iphdr->saddr, &attrs->saddr.a4, 4);
memcpy(&iphdr->daddr, &attrs->daddr.a4, 4);
memcpy(&iphdr->saddr, &attrs->addrs.saddr.a4, 4);
memcpy(&iphdr->daddr, &attrs->addrs.daddr.a4, 4);
iphdr->version = 4;
iphdr->ihl = 5;
iphdr->ttl = IPSEC_TUNNEL_DEFAULT_TTL;
@ -1775,8 +1785,8 @@ setup_pkt_tunnel_reformat(struct mlx5_core_dev *mdev,
break;
case AF_INET6:
ipv6hdr = (struct ipv6hdr *)hdr;
memcpy(&ipv6hdr->saddr, &attrs->saddr.a6, 16);
memcpy(&ipv6hdr->daddr, &attrs->daddr.a6, 16);
memcpy(&ipv6hdr->saddr, &attrs->addrs.saddr.a6, 16);
memcpy(&ipv6hdr->daddr, &attrs->addrs.daddr.a6, 16);
ipv6hdr->nexthdr = IPPROTO_ESP;
ipv6hdr->version = 6;
ipv6hdr->hop_limit = IPSEC_TUNNEL_DEFAULT_TTL;
@ -1810,7 +1820,7 @@ static int get_reformat_type(struct mlx5_accel_esp_xfrm_attrs *attrs)
return MLX5_REFORMAT_TYPE_DEL_ESP_TRANSPORT_OVER_UDP;
return MLX5_REFORMAT_TYPE_DEL_ESP_TRANSPORT;
case XFRM_DEV_OFFLOAD_OUT:
if (attrs->family == AF_INET) {
if (attrs->addrs.family == AF_INET) {
if (attrs->encap)
return MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_UDPV4;
return MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_OVER_IPV4;
@ -2003,7 +2013,7 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
struct mlx5_fc *counter;
int err = 0;
rx = rx_ft_get(mdev, ipsec, attrs->family, attrs->type);
rx = rx_ft_get(mdev, ipsec, attrs->addrs.family, attrs->type);
if (IS_ERR(rx))
return PTR_ERR(rx);
@ -2013,10 +2023,10 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
goto err_alloc;
}
if (attrs->family == AF_INET)
setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
if (attrs->addrs.family == AF_INET)
setup_fte_addr4(spec, &attrs->addrs);
else
setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
setup_fte_addr6(spec, &attrs->addrs);
setup_fte_spi(spec, attrs->spi, attrs->encap);
if (!attrs->encap)
@ -2116,7 +2126,7 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
err_mod_header:
kvfree(spec);
err_alloc:
rx_ft_put(ipsec, attrs->family, attrs->type);
rx_ft_put(ipsec, attrs->addrs.family, attrs->type);
return err;
}
@ -2148,10 +2158,10 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
switch (attrs->type) {
case XFRM_DEV_OFFLOAD_CRYPTO:
if (attrs->family == AF_INET)
setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
if (attrs->addrs.family == AF_INET)
setup_fte_addr4(spec, &attrs->addrs);
else
setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
setup_fte_addr6(spec, &attrs->addrs);
setup_fte_spi(spec, attrs->spi, false);
setup_fte_esp(spec);
setup_fte_reg_a(spec);
@ -2235,10 +2245,10 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
}
tx = ipsec_tx(ipsec, attrs->type);
if (attrs->family == AF_INET)
setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
if (attrs->addrs.family == AF_INET)
setup_fte_addr4(spec, &attrs->addrs);
else
setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
setup_fte_addr6(spec, &attrs->addrs);
setup_fte_no_frags(spec);
setup_fte_upper_proto_match(spec, &attrs->upspec);
@ -2308,12 +2318,12 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
struct mlx5e_ipsec_rx *rx;
int err, dstn = 0;
ft = rx_ft_get_policy(mdev, pol_entry->ipsec, attrs->family, attrs->prio,
attrs->type);
ft = rx_ft_get_policy(mdev, pol_entry->ipsec, attrs->addrs.family,
attrs->prio, attrs->type);
if (IS_ERR(ft))
return PTR_ERR(ft);
rx = ipsec_rx(pol_entry->ipsec, attrs->family, attrs->type);
rx = ipsec_rx(pol_entry->ipsec, attrs->addrs.family, attrs->type);
spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
if (!spec) {
@ -2321,10 +2331,10 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
goto err_alloc;
}
if (attrs->family == AF_INET)
setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
if (attrs->addrs.family == AF_INET)
setup_fte_addr4(spec, &attrs->addrs);
else
setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
setup_fte_addr6(spec, &attrs->addrs);
setup_fte_no_frags(spec);
setup_fte_upper_proto_match(spec, &attrs->upspec);
@ -2364,7 +2374,8 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
err_action:
kvfree(spec);
err_alloc:
rx_ft_put_policy(pol_entry->ipsec, attrs->family, attrs->prio, attrs->type);
rx_ft_put_policy(pol_entry->ipsec, attrs->addrs.family, attrs->prio,
attrs->type);
return err;
}
@ -2638,7 +2649,8 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
mlx5_fc_destroy(mdev, ipsec_rule->replay.fc);
}
mlx5_esw_ipsec_rx_id_mapping_remove(sa_entry);
rx_ft_put(sa_entry->ipsec, sa_entry->attrs.family, sa_entry->attrs.type);
rx_ft_put(sa_entry->ipsec, sa_entry->attrs.addrs.family,
sa_entry->attrs.type);
}
int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
@ -2674,7 +2686,8 @@ void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry)
mlx5e_ipsec_unblock_tc_offload(pol_entry->ipsec->mdev);
if (pol_entry->attrs.dir == XFRM_DEV_OFFLOAD_IN) {
rx_ft_put_policy(pol_entry->ipsec, pol_entry->attrs.family,
rx_ft_put_policy(pol_entry->ipsec,
pol_entry->attrs.addrs.family,
pol_entry->attrs.prio, pol_entry->attrs.type);
return;
}
@ -2814,7 +2827,7 @@ bool mlx5e_ipsec_fs_tunnel_enabled(struct mlx5e_ipsec_sa_entry *sa_entry)
struct mlx5e_ipsec_rx *rx;
struct mlx5e_ipsec_tx *tx;
rx = ipsec_rx(sa_entry->ipsec, attrs->family, attrs->type);
rx = ipsec_rx(sa_entry->ipsec, attrs->addrs.family, attrs->type);
tx = ipsec_tx(sa_entry->ipsec, attrs->type);
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
return tx->allow_tunnel_mode;

View File

@ -42,6 +42,9 @@
#include "lib/clock.h"
#include "en/fs_ethtool.h"
#define LANES_UNKNOWN 0
#define MAX_LANES 8
void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
struct ethtool_drvinfo *drvinfo)
{
@ -1076,32 +1079,34 @@ static void ptys2ethtool_supported_advertised_port(struct mlx5_core_dev *mdev,
}
}
static void get_speed_duplex(struct net_device *netdev,
u32 eth_proto_oper, bool force_legacy,
u16 data_rate_oper,
struct ethtool_link_ksettings *link_ksettings)
static void get_link_properties(struct net_device *netdev,
u32 eth_proto_oper, bool force_legacy,
u16 data_rate_oper,
struct ethtool_link_ksettings *link_ksettings)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
u32 speed = SPEED_UNKNOWN;
const struct mlx5_link_info *info;
u8 duplex = DUPLEX_UNKNOWN;
u32 speed = SPEED_UNKNOWN;
u32 lanes = LANES_UNKNOWN;
if (!netif_carrier_ok(netdev))
goto out;
speed = mlx5_port_ptys2speed(priv->mdev, eth_proto_oper, force_legacy);
if (!speed) {
if (data_rate_oper)
speed = 100 * data_rate_oper;
else
speed = SPEED_UNKNOWN;
goto out;
info = mlx5_port_ptys2info(priv->mdev, eth_proto_oper, force_legacy);
if (info) {
speed = info->speed;
lanes = info->lanes;
duplex = DUPLEX_FULL;
} else if (data_rate_oper) {
speed = 100 * data_rate_oper;
lanes = MAX_LANES;
}
duplex = DUPLEX_FULL;
out:
link_ksettings->base.speed = speed;
link_ksettings->base.duplex = duplex;
link_ksettings->base.speed = speed;
link_ksettings->lanes = lanes;
}
static void get_supported(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
@ -1238,8 +1243,8 @@ static int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
get_supported(mdev, eth_proto_cap, link_ksettings);
get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings,
admin_ext);
get_speed_duplex(priv->netdev, eth_proto_oper, !admin_ext,
data_rate_oper, link_ksettings);
get_link_properties(priv->netdev, eth_proto_oper, !admin_ext,
data_rate_oper, link_ksettings);
eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
connector_type = connector_type < MLX5E_CONNECTOR_TYPE_NUMBER ?
@ -1349,6 +1354,7 @@ static int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
{
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5_port_eth_proto eproto;
struct mlx5_link_info info = {};
const unsigned long *adver;
bool an_changes = false;
u8 an_disable_admin;
@ -1359,7 +1365,6 @@ static int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
u32 link_modes;
u8 an_status;
u8 autoneg;
u32 speed;
bool ext;
int err;
@ -1367,7 +1372,8 @@ static int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
adver = link_ksettings->link_modes.advertising;
autoneg = link_ksettings->base.autoneg;
speed = link_ksettings->base.speed;
info.speed = link_ksettings->base.speed;
info.lanes = link_ksettings->lanes;
ext_supported = mlx5_ptys_ext_supported(mdev);
ext_requested = ext_link_mode_requested(adver);
@ -1384,7 +1390,7 @@ static int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
goto out;
}
link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) :
mlx5_port_speed2linkmodes(mdev, speed, !ext);
mlx5_port_info2linkmodes(mdev, &info, !ext);
err = mlx5e_speed_validate(priv->netdev, ext, link_modes, autoneg);
if (err)
@ -2615,6 +2621,7 @@ static void mlx5e_get_ts_stats(struct net_device *netdev,
}
const struct ethtool_ops mlx5e_ethtool_ops = {
.cap_link_lanes_supported = true,
.cap_rss_ctx_supported = true,
.rxfh_per_ctx_key = true,
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |

View File

@ -65,7 +65,6 @@ static int mlx5_mpesw_metadata_set(struct mlx5_lag *ldev)
return err;
}
#define MLX5_LAG_MPESW_OFFLOADS_SUPPORTED_PORTS 4
static int enable_mpesw(struct mlx5_lag *ldev)
{
int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
@ -77,9 +76,6 @@ static int enable_mpesw(struct mlx5_lag *ldev)
return -EINVAL;
dev0 = ldev->pf[idx].dev;
if (ldev->ports > MLX5_LAG_MPESW_OFFLOADS_SUPPORTED_PORTS)
return -EOPNOTSUPP;
if (mlx5_eswitch_mode(dev0) != MLX5_ESWITCH_OFFLOADS ||
!MLX5_CAP_PORT_SELECTION(dev0, port_select_flow_table) ||
!MLX5_CAP_GEN(dev0, create_lag_when_not_master_up) ||

View File

@ -114,6 +114,26 @@ struct mlx5_cmd_alias_obj_create_attr {
u8 access_key[ACCESS_KEY_LEN];
};
struct mlx5_port_eth_proto {
u32 cap;
u32 admin;
u32 oper;
};
struct mlx5_module_eeprom_query_params {
u16 size;
u16 offset;
u16 i2c_address;
u32 page;
u32 bank;
u32 module_number;
};
struct mlx5_link_info {
u32 speed;
u32 lanes;
};
static inline void mlx5_printk(struct mlx5_core_dev *dev, int level, const char *format, ...)
{
struct device *device = dev->device;
@ -280,6 +300,78 @@ int mlx5_set_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 arm, u8 mode);
struct mlx5_dm *mlx5_dm_create(struct mlx5_core_dev *dev);
void mlx5_dm_cleanup(struct mlx5_core_dev *dev);
void mlx5_toggle_port_link(struct mlx5_core_dev *dev);
int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
enum mlx5_port_status status);
int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
enum mlx5_port_status *status);
int mlx5_set_port_beacon(struct mlx5_core_dev *dev, u16 beacon_duration);
int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port);
int mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 rx_pause, u32 tx_pause);
int mlx5_query_port_pause(struct mlx5_core_dev *dev,
u32 *rx_pause, u32 *tx_pause);
int mlx5_set_port_pfc(struct mlx5_core_dev *dev, u8 pfc_en_tx, u8 pfc_en_rx);
int mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx,
u8 *pfc_en_rx);
int mlx5_set_port_stall_watermark(struct mlx5_core_dev *dev,
u16 stall_critical_watermark,
u16 stall_minor_watermark);
int mlx5_query_port_stall_watermark(struct mlx5_core_dev *dev,
u16 *stall_critical_watermark,
u16 *stall_minor_watermark);
int mlx5_max_tc(struct mlx5_core_dev *mdev);
int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc);
int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
u8 prio, u8 *tc);
int mlx5_set_port_tc_group(struct mlx5_core_dev *mdev, u8 *tc_group);
int mlx5_query_port_tc_group(struct mlx5_core_dev *mdev,
u8 tc, u8 *tc_group);
int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw);
int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev,
u8 tc, u8 *bw_pct);
int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
u8 *max_bw_value,
u8 *max_bw_unit);
int mlx5_query_port_ets_rate_limit(struct mlx5_core_dev *mdev,
u8 *max_bw_value,
u8 *max_bw_unit);
int mlx5_set_port_wol(struct mlx5_core_dev *mdev, u8 wol_mode);
int mlx5_query_port_wol(struct mlx5_core_dev *mdev, u8 *wol_mode);
int mlx5_query_ports_check(struct mlx5_core_dev *mdev, u32 *out, int outlen);
int mlx5_set_ports_check(struct mlx5_core_dev *mdev, u32 *in, int inlen);
int mlx5_set_port_fcs(struct mlx5_core_dev *mdev, u8 enable);
void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported,
bool *enabled);
int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
u16 offset, u16 size, u8 *data);
int
mlx5_query_module_eeprom_by_page(struct mlx5_core_dev *dev,
struct mlx5_module_eeprom_query_params *params,
u8 *data);
int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);
int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
int mlx5_set_trust_state(struct mlx5_core_dev *mdev, u8 trust_state);
int mlx5_query_trust_state(struct mlx5_core_dev *mdev, u8 *trust_state);
int mlx5_set_dscp2prio(struct mlx5_core_dev *mdev, u8 dscp, u8 prio);
int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio);
int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
struct mlx5_port_eth_proto *eproto);
bool mlx5_ptys_ext_supported(struct mlx5_core_dev *mdev);
const struct mlx5_link_info *mlx5_port_ptys2info(struct mlx5_core_dev *mdev,
u32 eth_proto_oper,
bool force_legacy);
u32 mlx5_port_info2linkmodes(struct mlx5_core_dev *mdev,
struct mlx5_link_info *info,
bool force_legacy);
int mlx5_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
#define MLX5_PPS_CAP(mdev) (MLX5_CAP_GEN((mdev), pps) && \
MLX5_CAP_GEN((mdev), pps_modify) && \
MLX5_CAP_MCAM_FEATURE((mdev), mtpps_fs) && \

View File

@ -196,7 +196,6 @@ void mlx5_toggle_port_link(struct mlx5_core_dev *dev)
if (ps == MLX5_PORT_UP)
mlx5_set_port_admin_status(dev, MLX5_PORT_UP);
}
EXPORT_SYMBOL_GPL(mlx5_toggle_port_link);
int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
enum mlx5_port_status status)
@ -210,7 +209,6 @@ int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
return mlx5_core_access_reg(dev, in, sizeof(in), out,
sizeof(out), MLX5_REG_PAOS, 0, 1);
}
EXPORT_SYMBOL_GPL(mlx5_set_port_admin_status);
int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
enum mlx5_port_status *status)
@ -227,7 +225,6 @@ int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
*status = MLX5_GET(paos_reg, out, admin_status);
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_admin_status);
static void mlx5_query_port_mtu(struct mlx5_core_dev *dev, u16 *admin_mtu,
u16 *max_mtu, u16 *oper_mtu, u8 port)
@ -257,7 +254,6 @@ int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port)
return mlx5_core_access_reg(dev, in, sizeof(in), out,
sizeof(out), MLX5_REG_PMTU, 0, 1);
}
EXPORT_SYMBOL_GPL(mlx5_set_port_mtu);
void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu,
u8 port)
@ -447,7 +443,6 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
return mlx5_query_mcia(dev, &query, data);
}
EXPORT_SYMBOL_GPL(mlx5_query_module_eeprom);
int mlx5_query_module_eeprom_by_page(struct mlx5_core_dev *dev,
struct mlx5_module_eeprom_query_params *params,
@ -467,7 +462,6 @@ int mlx5_query_module_eeprom_by_page(struct mlx5_core_dev *dev,
return mlx5_query_mcia(dev, params, data);
}
EXPORT_SYMBOL_GPL(mlx5_query_module_eeprom_by_page);
static int mlx5_query_port_pvlc(struct mlx5_core_dev *dev, u32 *pvlc,
int pvlc_size, u8 local_port)
@ -518,7 +512,6 @@ int mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 rx_pause, u32 tx_pause)
return mlx5_core_access_reg(dev, in, sizeof(in), out,
sizeof(out), MLX5_REG_PFCC, 0, 1);
}
EXPORT_SYMBOL_GPL(mlx5_set_port_pause);
int mlx5_query_port_pause(struct mlx5_core_dev *dev,
u32 *rx_pause, u32 *tx_pause)
@ -538,7 +531,6 @@ int mlx5_query_port_pause(struct mlx5_core_dev *dev,
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_pause);
int mlx5_set_port_stall_watermark(struct mlx5_core_dev *dev,
u16 stall_critical_watermark,
@ -597,7 +589,6 @@ int mlx5_set_port_pfc(struct mlx5_core_dev *dev, u8 pfc_en_tx, u8 pfc_en_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)
{
@ -616,7 +607,6 @@ int mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx, u8 *pfc_en_rx)
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_pfc);
int mlx5_max_tc(struct mlx5_core_dev *mdev)
{
@ -667,7 +657,6 @@ int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc)
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_set_port_prio_tc);
int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
u8 prio, u8 *tc)
@ -689,7 +678,6 @@ int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
return err;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_prio_tc);
static int mlx5_set_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *in,
int inlen)
@ -728,7 +716,6 @@ int mlx5_set_port_tc_group(struct mlx5_core_dev *mdev, u8 *tc_group)
return mlx5_set_port_qetcr_reg(mdev, in, sizeof(in));
}
EXPORT_SYMBOL_GPL(mlx5_set_port_tc_group);
int mlx5_query_port_tc_group(struct mlx5_core_dev *mdev,
u8 tc, u8 *tc_group)
@ -749,7 +736,6 @@ int mlx5_query_port_tc_group(struct mlx5_core_dev *mdev,
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_tc_group);
int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw)
{
@ -763,7 +749,6 @@ int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw)
return mlx5_set_port_qetcr_reg(mdev, in, sizeof(in));
}
EXPORT_SYMBOL_GPL(mlx5_set_port_tc_bw_alloc);
int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev,
u8 tc, u8 *bw_pct)
@ -784,7 +769,6 @@ int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev,
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_tc_bw_alloc);
int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
u8 *max_bw_value,
@ -808,7 +792,6 @@ int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
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,
@ -834,7 +817,6 @@ int mlx5_query_port_ets_rate_limit(struct mlx5_core_dev *mdev,
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_ets_rate_limit);
int mlx5_set_port_wol(struct mlx5_core_dev *mdev, u8 wol_mode)
{
@ -845,7 +827,6 @@ int mlx5_set_port_wol(struct mlx5_core_dev *mdev, u8 wol_mode)
MLX5_SET(set_wol_rol_in, in, wol_mode, wol_mode);
return mlx5_cmd_exec_in(mdev, set_wol_rol, in);
}
EXPORT_SYMBOL_GPL(mlx5_set_port_wol);
int mlx5_query_port_wol(struct mlx5_core_dev *mdev, u8 *wol_mode)
{
@ -860,7 +841,6 @@ int mlx5_query_port_wol(struct mlx5_core_dev *mdev, u8 *wol_mode)
return err;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_wol);
int mlx5_query_ports_check(struct mlx5_core_dev *mdev, u32 *out, int outlen)
{
@ -1058,56 +1038,57 @@ int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio)
}
/* 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] = 10000,
[MLX5E_40GBASE_SR4] = 40000,
[MLX5E_40GBASE_LR4] = 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 struct mlx5_link_info mlx5e_link_info[MLX5E_LINK_MODES_NUMBER] = {
[MLX5E_1000BASE_CX_SGMII] = {.speed = 1000, .lanes = 1},
[MLX5E_1000BASE_KX] = {.speed = 1000, .lanes = 1},
[MLX5E_10GBASE_CX4] = {.speed = 10000, .lanes = 4},
[MLX5E_10GBASE_KX4] = {.speed = 10000, .lanes = 4},
[MLX5E_10GBASE_KR] = {.speed = 10000, .lanes = 1},
[MLX5E_20GBASE_KR2] = {.speed = 20000, .lanes = 2},
[MLX5E_40GBASE_CR4] = {.speed = 40000, .lanes = 4},
[MLX5E_40GBASE_KR4] = {.speed = 40000, .lanes = 4},
[MLX5E_56GBASE_R4] = {.speed = 56000, .lanes = 4},
[MLX5E_10GBASE_CR] = {.speed = 10000, .lanes = 1},
[MLX5E_10GBASE_SR] = {.speed = 10000, .lanes = 1},
[MLX5E_10GBASE_ER] = {.speed = 10000, .lanes = 1},
[MLX5E_40GBASE_SR4] = {.speed = 40000, .lanes = 4},
[MLX5E_40GBASE_LR4] = {.speed = 40000, .lanes = 4},
[MLX5E_50GBASE_SR2] = {.speed = 50000, .lanes = 2},
[MLX5E_100GBASE_CR4] = {.speed = 100000, .lanes = 4},
[MLX5E_100GBASE_SR4] = {.speed = 100000, .lanes = 4},
[MLX5E_100GBASE_KR4] = {.speed = 100000, .lanes = 4},
[MLX5E_100GBASE_LR4] = {.speed = 100000, .lanes = 4},
[MLX5E_100BASE_TX] = {.speed = 100, .lanes = 1},
[MLX5E_1000BASE_T] = {.speed = 1000, .lanes = 1},
[MLX5E_10GBASE_T] = {.speed = 10000, .lanes = 1},
[MLX5E_25GBASE_CR] = {.speed = 25000, .lanes = 1},
[MLX5E_25GBASE_KR] = {.speed = 25000, .lanes = 1},
[MLX5E_25GBASE_SR] = {.speed = 25000, .lanes = 1},
[MLX5E_50GBASE_CR2] = {.speed = 50000, .lanes = 2},
[MLX5E_50GBASE_KR2] = {.speed = 50000, .lanes = 2},
};
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_100GAUI_2_100GBASE_CR2_KR2] = 100000,
[MLX5E_200GAUI_4_200GBASE_CR4_KR4] = 200000,
[MLX5E_400GAUI_8_400GBASE_CR8] = 400000,
[MLX5E_100GAUI_1_100GBASE_CR_KR] = 100000,
[MLX5E_200GAUI_2_200GBASE_CR2_KR2] = 200000,
[MLX5E_400GAUI_4_400GBASE_CR4_KR4] = 400000,
[MLX5E_800GAUI_8_800GBASE_CR8_KR8] = 800000,
[MLX5E_200GAUI_1_200GBASE_CR1_KR1] = 200000,
[MLX5E_400GAUI_2_400GBASE_CR2_KR2] = 400000,
[MLX5E_800GAUI_4_800GBASE_CR4_KR4] = 800000,
static const struct mlx5_link_info
mlx5e_ext_link_info[MLX5E_EXT_LINK_MODES_NUMBER] = {
[MLX5E_SGMII_100M] = {.speed = 100, .lanes = 1},
[MLX5E_1000BASE_X_SGMII] = {.speed = 1000, .lanes = 1},
[MLX5E_5GBASE_R] = {.speed = 5000, .lanes = 1},
[MLX5E_10GBASE_XFI_XAUI_1] = {.speed = 10000, .lanes = 1},
[MLX5E_40GBASE_XLAUI_4_XLPPI_4] = {.speed = 40000, .lanes = 4},
[MLX5E_25GAUI_1_25GBASE_CR_KR] = {.speed = 25000, .lanes = 1},
[MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = {.speed = 50000, .lanes = 2},
[MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = {.speed = 50000, .lanes = 1},
[MLX5E_CAUI_4_100GBASE_CR4_KR4] = {.speed = 100000, .lanes = 4},
[MLX5E_100GAUI_2_100GBASE_CR2_KR2] = {.speed = 100000, .lanes = 2},
[MLX5E_200GAUI_4_200GBASE_CR4_KR4] = {.speed = 200000, .lanes = 4},
[MLX5E_400GAUI_8_400GBASE_CR8] = {.speed = 400000, .lanes = 8},
[MLX5E_100GAUI_1_100GBASE_CR_KR] = {.speed = 100000, .lanes = 1},
[MLX5E_200GAUI_2_200GBASE_CR2_KR2] = {.speed = 200000, .lanes = 2},
[MLX5E_400GAUI_4_400GBASE_CR4_KR4] = {.speed = 400000, .lanes = 4},
[MLX5E_800GAUI_8_800GBASE_CR8_KR8] = {.speed = 800000, .lanes = 8},
[MLX5E_200GAUI_1_200GBASE_CR1_KR1] = {.speed = 200000, .lanes = 1},
[MLX5E_400GAUI_2_400GBASE_CR2_KR2] = {.speed = 400000, .lanes = 2},
[MLX5E_800GAUI_4_800GBASE_CR4_KR4] = {.speed = 800000, .lanes = 4},
};
int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
@ -1145,54 +1126,61 @@ bool mlx5_ptys_ext_supported(struct mlx5_core_dev *mdev)
return !!eproto.cap;
}
static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev,
const u32 **arr, u32 *size,
bool force_legacy)
static void mlx5e_port_get_link_mode_info_arr(struct mlx5_core_dev *mdev,
const struct mlx5_link_info **arr,
u32 *size,
bool force_legacy)
{
bool ext = force_legacy ? false : mlx5_ptys_ext_supported(mdev);
*size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) :
ARRAY_SIZE(mlx5e_link_speed);
*arr = ext ? mlx5e_ext_link_speed : mlx5e_link_speed;
*size = ext ? ARRAY_SIZE(mlx5e_ext_link_info) :
ARRAY_SIZE(mlx5e_link_info);
*arr = ext ? mlx5e_ext_link_info : mlx5e_link_info;
}
u32 mlx5_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper,
bool force_legacy)
const struct mlx5_link_info *mlx5_port_ptys2info(struct mlx5_core_dev *mdev,
u32 eth_proto_oper,
bool force_legacy)
{
unsigned long temp = eth_proto_oper;
const u32 *table;
u32 speed = 0;
const struct mlx5_link_info *table;
u32 max_size;
int i;
mlx5e_port_get_speed_arr(mdev, &table, &max_size, force_legacy);
mlx5e_port_get_link_mode_info_arr(mdev, &table, &max_size,
force_legacy);
i = find_first_bit(&temp, max_size);
if (i < max_size)
speed = table[i];
return speed;
return &table[i];
return NULL;
}
u32 mlx5_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed,
bool force_legacy)
u32 mlx5_port_info2linkmodes(struct mlx5_core_dev *mdev,
struct mlx5_link_info *info,
bool force_legacy)
{
const struct mlx5_link_info *table;
u32 link_modes = 0;
const u32 *table;
u32 max_size;
int i;
mlx5e_port_get_speed_arr(mdev, &table, &max_size, force_legacy);
mlx5e_port_get_link_mode_info_arr(mdev, &table, &max_size,
force_legacy);
for (i = 0; i < max_size; ++i) {
if (table[i] == speed)
link_modes |= MLX5E_PROT_MASK(i);
if (table[i].speed == info->speed) {
if (!info->lanes || table[i].lanes == info->lanes)
link_modes |= MLX5E_PROT_MASK(i);
}
}
return link_modes;
}
int mlx5_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
{
const struct mlx5_link_info *table;
struct mlx5_port_eth_proto eproto;
u32 max_speed = 0;
const u32 *table;
u32 max_size;
bool ext;
int err;
@ -1203,10 +1191,10 @@ int mlx5_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed)
if (err)
return err;
mlx5e_port_get_speed_arr(mdev, &table, &max_size, false);
mlx5e_port_get_link_mode_info_arr(mdev, &table, &max_size, false);
for (i = 0; i < max_size; ++i)
if (eproto.cap & MLX5E_PROT_MASK(i))
max_speed = max(max_speed, table[i]);
max_speed = max(max_speed, table[i].speed);
*speed = max_speed;
return 0;

View File

@ -61,15 +61,6 @@ enum mlx5_an_status {
#define MLX5_EEPROM_PAGE_LENGTH 256
#define MLX5_EEPROM_HIGH_PAGE_LENGTH 128
struct mlx5_module_eeprom_query_params {
u16 size;
u16 offset;
u16 i2c_address;
u32 page;
u32 bank;
u32 module_number;
};
enum mlx5e_link_mode {
MLX5E_1000BASE_CX_SGMII = 0,
MLX5E_1000BASE_KX = 1,
@ -145,12 +136,6 @@ enum mlx5_ptys_width {
MLX5_PTYS_WIDTH_12X = 1 << 4,
};
struct mlx5_port_eth_proto {
u32 cap;
u32 admin;
u32 oper;
};
#define MLX5E_PROT_MASK(link_mode) (1U << link_mode)
#define MLX5_GET_ETH_PROTO(reg, out, ext, field) \
(ext ? MLX5_GET(reg, out, ext_##field) : \
@ -163,14 +148,7 @@ int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
int mlx5_query_ib_port_oper(struct mlx5_core_dev *dev, u16 *link_width_oper,
u16 *proto_oper, u8 local_port, u8 plane_index);
void mlx5_toggle_port_link(struct mlx5_core_dev *dev);
int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
enum mlx5_port_status status);
int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
enum mlx5_port_status *status);
int mlx5_set_port_beacon(struct mlx5_core_dev *dev, u16 beacon_duration);
int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port);
void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, u8 port);
void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu,
u8 port);
@ -178,65 +156,4 @@ void mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, u16 *oper_mtu,
int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev,
u8 *vl_hw_cap, u8 local_port);
int mlx5_set_port_pause(struct mlx5_core_dev *dev, u32 rx_pause, u32 tx_pause);
int mlx5_query_port_pause(struct mlx5_core_dev *dev,
u32 *rx_pause, u32 *tx_pause);
int mlx5_set_port_pfc(struct mlx5_core_dev *dev, u8 pfc_en_tx, u8 pfc_en_rx);
int mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx,
u8 *pfc_en_rx);
int mlx5_set_port_stall_watermark(struct mlx5_core_dev *dev,
u16 stall_critical_watermark,
u16 stall_minor_watermark);
int mlx5_query_port_stall_watermark(struct mlx5_core_dev *dev,
u16 *stall_critical_watermark, u16 *stall_minor_watermark);
int mlx5_max_tc(struct mlx5_core_dev *mdev);
int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc);
int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
u8 prio, u8 *tc);
int mlx5_set_port_tc_group(struct mlx5_core_dev *mdev, u8 *tc_group);
int mlx5_query_port_tc_group(struct mlx5_core_dev *mdev,
u8 tc, u8 *tc_group);
int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw);
int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev,
u8 tc, u8 *bw_pct);
int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
u8 *max_bw_value,
u8 *max_bw_unit);
int mlx5_query_port_ets_rate_limit(struct mlx5_core_dev *mdev,
u8 *max_bw_value,
u8 *max_bw_unit);
int mlx5_set_port_wol(struct mlx5_core_dev *mdev, u8 wol_mode);
int mlx5_query_port_wol(struct mlx5_core_dev *mdev, u8 *wol_mode);
int mlx5_query_ports_check(struct mlx5_core_dev *mdev, u32 *out, int outlen);
int mlx5_set_ports_check(struct mlx5_core_dev *mdev, u32 *in, int inlen);
int mlx5_set_port_fcs(struct mlx5_core_dev *mdev, u8 enable);
void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported,
bool *enabled);
int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
u16 offset, u16 size, u8 *data);
int mlx5_query_module_eeprom_by_page(struct mlx5_core_dev *dev,
struct mlx5_module_eeprom_query_params *params, u8 *data);
int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);
int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
int mlx5_set_trust_state(struct mlx5_core_dev *mdev, u8 trust_state);
int mlx5_query_trust_state(struct mlx5_core_dev *mdev, u8 *trust_state);
int mlx5_set_dscp2prio(struct mlx5_core_dev *mdev, u8 dscp, u8 prio);
int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio);
int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
struct mlx5_port_eth_proto *eproto);
bool mlx5_ptys_ext_supported(struct mlx5_core_dev *mdev);
u32 mlx5_port_ptys2speed(struct mlx5_core_dev *mdev, u32 eth_proto_oper,
bool force_legacy);
u32 mlx5_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed,
bool force_legacy);
int mlx5_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
#endif /* __MLX5_PORT_H__ */