89df2225c9
Add device start and stop operation callbacks for CN9K and CN10K. Device stop is common for both platforms while device start as some platform dependent portion where the platform specific offload flags are recomputed and the right Rx/Tx burst function is chosen. Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
114 lines
2.6 KiB
C
114 lines
2.6 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright(C) 2021 Marvell.
|
|
*/
|
|
|
|
#include "cnxk_ethdev.h"
|
|
|
|
void
|
|
cnxk_nix_toggle_flag_link_cfg(struct cnxk_eth_dev *dev, bool set)
|
|
{
|
|
if (set)
|
|
dev->flags |= CNXK_LINK_CFG_IN_PROGRESS_F;
|
|
else
|
|
dev->flags &= ~CNXK_LINK_CFG_IN_PROGRESS_F;
|
|
|
|
rte_wmb();
|
|
}
|
|
|
|
static inline int
|
|
nix_wait_for_link_cfg(struct cnxk_eth_dev *dev)
|
|
{
|
|
uint16_t wait = 1000;
|
|
|
|
do {
|
|
rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
|
|
if (!(dev->flags & CNXK_LINK_CFG_IN_PROGRESS_F))
|
|
break;
|
|
wait--;
|
|
rte_delay_ms(1);
|
|
} while (wait);
|
|
|
|
return wait ? 0 : -1;
|
|
}
|
|
|
|
static void
|
|
nix_link_status_print(struct rte_eth_dev *eth_dev, struct rte_eth_link *link)
|
|
{
|
|
if (link && link->link_status)
|
|
plt_info("Port %d: Link Up - speed %u Mbps - %s",
|
|
(int)(eth_dev->data->port_id),
|
|
(uint32_t)link->link_speed,
|
|
link->link_duplex == ETH_LINK_FULL_DUPLEX
|
|
? "full-duplex"
|
|
: "half-duplex");
|
|
else
|
|
plt_info("Port %d: Link Down", (int)(eth_dev->data->port_id));
|
|
}
|
|
|
|
void
|
|
cnxk_eth_dev_link_status_cb(struct roc_nix *nix, struct roc_nix_link_info *link)
|
|
{
|
|
struct cnxk_eth_dev *dev = (struct cnxk_eth_dev *)nix;
|
|
struct rte_eth_link eth_link;
|
|
struct rte_eth_dev *eth_dev;
|
|
|
|
if (!link || !nix)
|
|
return;
|
|
|
|
eth_dev = dev->eth_dev;
|
|
if (!eth_dev || !eth_dev->data->dev_conf.intr_conf.lsc)
|
|
return;
|
|
|
|
if (nix_wait_for_link_cfg(dev)) {
|
|
plt_err("Timeout waiting for link_cfg to complete");
|
|
return;
|
|
}
|
|
|
|
eth_link.link_status = link->status;
|
|
eth_link.link_speed = link->speed;
|
|
eth_link.link_autoneg = ETH_LINK_AUTONEG;
|
|
eth_link.link_duplex = link->full_duplex;
|
|
|
|
/* Print link info */
|
|
nix_link_status_print(eth_dev, ð_link);
|
|
|
|
/* Update link info */
|
|
rte_eth_linkstatus_set(eth_dev, ð_link);
|
|
|
|
/* Set the flag and execute application callbacks */
|
|
rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL);
|
|
}
|
|
|
|
int
|
|
cnxk_nix_link_update(struct rte_eth_dev *eth_dev, int wait_to_complete)
|
|
{
|
|
struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
|
|
struct roc_nix_link_info info;
|
|
struct rte_eth_link link;
|
|
int rc;
|
|
|
|
RTE_SET_USED(wait_to_complete);
|
|
memset(&link, 0, sizeof(struct rte_eth_link));
|
|
|
|
if (roc_nix_is_sdp(&dev->nix))
|
|
return 0;
|
|
|
|
if (roc_nix_is_lbk(&dev->nix)) {
|
|
link.link_status = ETH_LINK_UP;
|
|
link.link_speed = ETH_SPEED_NUM_100G;
|
|
link.link_autoneg = ETH_LINK_FIXED;
|
|
link.link_duplex = ETH_LINK_FULL_DUPLEX;
|
|
} else {
|
|
rc = roc_nix_mac_link_info_get(&dev->nix, &info);
|
|
if (rc)
|
|
return rc;
|
|
link.link_status = info.status;
|
|
link.link_speed = info.speed;
|
|
link.link_autoneg = ETH_LINK_AUTONEG;
|
|
if (info.full_duplex)
|
|
link.link_duplex = info.full_duplex;
|
|
}
|
|
|
|
return rte_eth_linkstatus_set(eth_dev, &link);
|
|
}
|