net/sfc: retrieve link info
Signed-off-by: Artem Andreev <artem.andreev@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> Reviewed-by: Andy Moreton <amoreton@solarflare.com> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
This commit is contained in:
parent
03ed21195d
commit
886f8d8a05
@ -4,6 +4,7 @@
|
||||
; Refer to default.ini for the full list of available PMD features.
|
||||
;
|
||||
[Features]
|
||||
Link status = Y
|
||||
BSD nic_uio = Y
|
||||
Linux UIO = Y
|
||||
Linux VFIO = Y
|
||||
|
@ -44,6 +44,8 @@ SFC EFX PMD has support for:
|
||||
|
||||
- Multiple transmit and receive queues
|
||||
|
||||
- Link state information
|
||||
|
||||
|
||||
Non-supported Features
|
||||
----------------------
|
||||
|
@ -37,6 +37,8 @@ CFLAGS += -I$(SRCDIR)/base/
|
||||
CFLAGS += -I$(SRCDIR)
|
||||
CFLAGS += -O3
|
||||
CFLAGS += $(WERROR_FLAGS)
|
||||
# Strict-aliasing rules are violated by rte_eth_link to uint64_t casts
|
||||
CFLAGS += -Wno-strict-aliasing
|
||||
|
||||
# Enable extra warnings
|
||||
CFLAGS += -Wextra
|
||||
|
@ -218,6 +218,9 @@ int sfc_port_init(struct sfc_adapter *sa);
|
||||
void sfc_port_fini(struct sfc_adapter *sa);
|
||||
int sfc_port_start(struct sfc_adapter *sa);
|
||||
void sfc_port_stop(struct sfc_adapter *sa);
|
||||
void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
|
||||
struct rte_eth_link *link_info);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "sfc_debug.h"
|
||||
#include "sfc_log.h"
|
||||
#include "sfc_kvargs.h"
|
||||
#include "sfc_ev.h"
|
||||
|
||||
|
||||
static void
|
||||
@ -99,6 +100,46 @@ sfc_dev_start(struct rte_eth_dev *dev)
|
||||
return -rc;
|
||||
}
|
||||
|
||||
static int
|
||||
sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
|
||||
{
|
||||
struct sfc_adapter *sa = dev->data->dev_private;
|
||||
struct rte_eth_link *dev_link = &dev->data->dev_link;
|
||||
struct rte_eth_link old_link;
|
||||
struct rte_eth_link current_link;
|
||||
|
||||
sfc_log_init(sa, "entry");
|
||||
|
||||
if (sa->state != SFC_ADAPTER_STARTED)
|
||||
return 0;
|
||||
|
||||
retry:
|
||||
EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
|
||||
*(int64_t *)&old_link = rte_atomic64_read((rte_atomic64_t *)dev_link);
|
||||
|
||||
if (wait_to_complete) {
|
||||
efx_link_mode_t link_mode;
|
||||
|
||||
efx_port_poll(sa->nic, &link_mode);
|
||||
sfc_port_link_mode_to_info(link_mode, ¤t_link);
|
||||
|
||||
if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link,
|
||||
*(uint64_t *)&old_link,
|
||||
*(uint64_t *)¤t_link))
|
||||
goto retry;
|
||||
} else {
|
||||
sfc_ev_mgmt_qpoll(sa);
|
||||
*(int64_t *)¤t_link =
|
||||
rte_atomic64_read((rte_atomic64_t *)dev_link);
|
||||
}
|
||||
|
||||
if (old_link.link_status != current_link.link_status)
|
||||
sfc_info(sa, "Link status is %s",
|
||||
current_link.link_status ? "UP" : "DOWN");
|
||||
|
||||
return old_link.link_status == current_link.link_status ? 0 : -1;
|
||||
}
|
||||
|
||||
static void
|
||||
sfc_dev_stop(struct rte_eth_dev *dev)
|
||||
{
|
||||
@ -146,6 +187,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
|
||||
.dev_start = sfc_dev_start,
|
||||
.dev_stop = sfc_dev_stop,
|
||||
.dev_close = sfc_dev_close,
|
||||
.link_update = sfc_dev_link_update,
|
||||
.dev_infos_get = sfc_dev_infos_get,
|
||||
};
|
||||
|
||||
|
@ -181,13 +181,19 @@ sfc_ev_timer(void *arg, uint32_t index)
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
sfc_ev_link_change(void *arg, __rte_unused efx_link_mode_t link_mode)
|
||||
sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
|
||||
{
|
||||
struct sfc_evq *evq = arg;
|
||||
struct sfc_adapter *sa = evq->sa;
|
||||
struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
|
||||
struct rte_eth_link new_link;
|
||||
|
||||
sfc_err(evq->sa, "EVQ %u unexpected link change",
|
||||
evq->evq_index);
|
||||
return B_TRUE;
|
||||
EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
|
||||
|
||||
sfc_port_link_mode_to_info(link_mode, &new_link);
|
||||
rte_atomic64_set((rte_atomic64_t *)dev_link, *(uint64_t *)&new_link);
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
static const efx_ev_callbacks_t sfc_ev_callbacks = {
|
||||
|
@ -129,3 +129,61 @@ sfc_port_fini(struct sfc_adapter *sa)
|
||||
|
||||
sfc_log_init(sa, "done");
|
||||
}
|
||||
|
||||
void
|
||||
sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
|
||||
struct rte_eth_link *link_info)
|
||||
{
|
||||
SFC_ASSERT(link_mode < EFX_LINK_NMODES);
|
||||
|
||||
memset(link_info, 0, sizeof(*link_info));
|
||||
if ((link_mode == EFX_LINK_DOWN) || (link_mode == EFX_LINK_UNKNOWN))
|
||||
link_info->link_status = ETH_LINK_DOWN;
|
||||
else
|
||||
link_info->link_status = ETH_LINK_UP;
|
||||
|
||||
switch (link_mode) {
|
||||
case EFX_LINK_10HDX:
|
||||
link_info->link_speed = ETH_SPEED_NUM_10M;
|
||||
link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
|
||||
break;
|
||||
case EFX_LINK_10FDX:
|
||||
link_info->link_speed = ETH_SPEED_NUM_10M;
|
||||
link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
|
||||
break;
|
||||
case EFX_LINK_100HDX:
|
||||
link_info->link_speed = ETH_SPEED_NUM_100M;
|
||||
link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
|
||||
break;
|
||||
case EFX_LINK_100FDX:
|
||||
link_info->link_speed = ETH_SPEED_NUM_100M;
|
||||
link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
|
||||
break;
|
||||
case EFX_LINK_1000HDX:
|
||||
link_info->link_speed = ETH_SPEED_NUM_1G;
|
||||
link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
|
||||
break;
|
||||
case EFX_LINK_1000FDX:
|
||||
link_info->link_speed = ETH_SPEED_NUM_1G;
|
||||
link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
|
||||
break;
|
||||
case EFX_LINK_10000FDX:
|
||||
link_info->link_speed = ETH_SPEED_NUM_10G;
|
||||
link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
|
||||
break;
|
||||
case EFX_LINK_40000FDX:
|
||||
link_info->link_speed = ETH_SPEED_NUM_40G;
|
||||
link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
|
||||
break;
|
||||
default:
|
||||
SFC_ASSERT(B_FALSE);
|
||||
/* FALLTHROUGH */
|
||||
case EFX_LINK_UNKNOWN:
|
||||
case EFX_LINK_DOWN:
|
||||
link_info->link_speed = ETH_SPEED_NUM_NONE;
|
||||
link_info->link_duplex = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
link_info->link_autoneg = ETH_LINK_AUTONEG;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user