#include <rte_eal.h>
#include <rte_alarm.h>
#include <rte_ether.h>
-#include <rte_ethdev_driver.h>
+#include <ethdev_driver.h>
#include <rte_malloc.h>
#include <rte_ring.h>
#include <fsl_bman.h>
#include <fsl_fman.h>
#include <process.h>
+#include <fmlib/fm_ext.h>
/* Supported Rx offloads */
static uint64_t dev_rx_offloads_sup =
return -EINVAL;
}
- if (frame_size > RTE_ETHER_MAX_LEN)
+ if (frame_size > DPAA_ETH_MAX_LEN)
dev->data->dev_conf.rxmode.offloads |=
DEV_RX_OFFLOAD_JUMBO_FRAME;
else
uint64_t rx_offloads = eth_conf->rxmode.offloads;
uint64_t tx_offloads = eth_conf->txmode.offloads;
struct rte_device *rdev = dev->device;
+ struct rte_eth_link *link = &dev->data->dev_link;
struct rte_dpaa_device *dpaa_dev;
struct fman_if *fif = dev->process_private;
struct __fman_if *__fif;
struct rte_intr_handle *intr_handle;
+ int speed, duplex;
int ret;
PMD_INIT_FUNC_TRACE();
dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
}
}
+
+ /* Wait for link status to get updated */
+ if (!link->link_status)
+ sleep(1);
+
+ /* Configure link only if link is UP*/
+ if (link->link_status) {
+ if (eth_conf->link_speeds == ETH_LINK_SPEED_AUTONEG) {
+ /* Start autoneg only if link is not in autoneg mode */
+ if (!link->link_autoneg)
+ dpaa_restart_link_autoneg(__fif->node_name);
+ } else if (eth_conf->link_speeds & ETH_LINK_SPEED_FIXED) {
+ switch (eth_conf->link_speeds & ~ETH_LINK_SPEED_FIXED) {
+ case ETH_LINK_SPEED_10M_HD:
+ speed = ETH_SPEED_NUM_10M;
+ duplex = ETH_LINK_HALF_DUPLEX;
+ break;
+ case ETH_LINK_SPEED_10M:
+ speed = ETH_SPEED_NUM_10M;
+ duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ case ETH_LINK_SPEED_100M_HD:
+ speed = ETH_SPEED_NUM_100M;
+ duplex = ETH_LINK_HALF_DUPLEX;
+ break;
+ case ETH_LINK_SPEED_100M:
+ speed = ETH_SPEED_NUM_100M;
+ duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ case ETH_LINK_SPEED_1G:
+ speed = ETH_SPEED_NUM_1G;
+ duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ case ETH_LINK_SPEED_2_5G:
+ speed = ETH_SPEED_NUM_2_5G;
+ duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ case ETH_LINK_SPEED_10G:
+ speed = ETH_SPEED_NUM_10G;
+ duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ default:
+ speed = ETH_SPEED_NUM_NONE;
+ duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ }
+ /* Set link speed */
+ dpaa_update_link_speed(__fif->node_name, speed, duplex);
+ } else {
+ /* Manual autoneg - custom advertisement speed. */
+ printf("Custom Advertisement speeds not supported\n");
+ }
+ }
+
return 0;
}
return 0;
}
-static void dpaa_eth_dev_stop(struct rte_eth_dev *dev)
+static int dpaa_eth_dev_stop(struct rte_eth_dev *dev)
{
struct fman_if *fif = dev->process_private;
PMD_INIT_FUNC_TRACE();
+ dev->data->dev_started = 0;
if (!fif->is_shared_mac)
fman_if_disable_rx(fif);
dev->tx_pkt_burst = dpaa_eth_tx_drop_all;
+
+ return 0;
}
static int dpaa_eth_dev_close(struct rte_eth_dev *dev)
struct rte_device *rdev = dev->device;
struct rte_dpaa_device *dpaa_dev;
struct rte_intr_handle *intr_handle;
+ struct rte_eth_link *link = &dev->data->dev_link;
struct dpaa_if *dpaa_intf = dev->data->dev_private;
int loop;
+ int ret;
PMD_INIT_FUNC_TRACE();
intr_handle = &dpaa_dev->intr_handle;
__fif = container_of(fif, struct __fman_if, __if);
- dpaa_eth_dev_stop(dev);
+ ret = dpaa_eth_dev_stop(dev);
+
+ /* Reset link to autoneg */
+ if (link->link_status && !link->link_autoneg)
+ dpaa_restart_link_autoneg(__fif->node_name);
if (intr_handle && intr_handle->fd &&
dev->data->dev_conf.intr_conf.lsc != 0) {
rte_free(dpaa_intf->tx_queues);
dpaa_intf->tx_queues = NULL;
- dev->dev_ops = NULL;
- dev->rx_pkt_burst = NULL;
- dev->tx_pkt_burst = NULL;
-
- return 0;
+ return ret;
}
static int
dev_info->flow_type_rss_offloads = DPAA_RSS_OFFLOAD_ALL;
if (fif->mac_type == fman_mac_1g) {
- dev_info->speed_capa = ETH_LINK_SPEED_1G;
+ dev_info->speed_capa = ETH_LINK_SPEED_10M_HD
+ | ETH_LINK_SPEED_10M
+ | ETH_LINK_SPEED_100M_HD
+ | ETH_LINK_SPEED_100M
+ | ETH_LINK_SPEED_1G;
} else if (fif->mac_type == fman_mac_2_5g) {
- dev_info->speed_capa = ETH_LINK_SPEED_1G
+ dev_info->speed_capa = ETH_LINK_SPEED_10M_HD
+ | ETH_LINK_SPEED_10M
+ | ETH_LINK_SPEED_100M_HD
+ | ETH_LINK_SPEED_100M
+ | ETH_LINK_SPEED_1G
| ETH_LINK_SPEED_2_5G;
} else if (fif->mac_type == fman_mac_10g) {
- dev_info->speed_capa = ETH_LINK_SPEED_1G
+ dev_info->speed_capa = ETH_LINK_SPEED_10M_HD
+ | ETH_LINK_SPEED_10M
+ | ETH_LINK_SPEED_100M_HD
+ | ETH_LINK_SPEED_100M
+ | ETH_LINK_SPEED_1G
| ETH_LINK_SPEED_2_5G
| ETH_LINK_SPEED_10G;
} else {
struct rte_eth_link *link = &dev->data->dev_link;
struct fman_if *fif = dev->process_private;
struct __fman_if *__fif = container_of(fif, struct __fman_if, __if);
- int ret;
+ int ret, ioctl_version;
PMD_INIT_FUNC_TRACE();
- if (fif->mac_type == fman_mac_1g)
- link->link_speed = ETH_SPEED_NUM_1G;
- else if (fif->mac_type == fman_mac_2_5g)
- link->link_speed = ETH_SPEED_NUM_2_5G;
- else if (fif->mac_type == fman_mac_10g)
- link->link_speed = ETH_SPEED_NUM_10G;
- else
- DPAA_PMD_ERR("invalid link_speed: %s, %d",
- dpaa_intf->name, fif->mac_type);
+ ioctl_version = dpaa_get_ioctl_version_number();
+
if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) {
- ret = dpaa_get_link_status(__fif->node_name);
- if (ret < 0)
+ ret = dpaa_get_link_status(__fif->node_name, link);
+ if (ret)
return ret;
- link->link_status = ret;
} else {
link->link_status = dpaa_intf->valid;
}
- link->link_duplex = ETH_LINK_FULL_DUPLEX;
- link->link_autoneg = ETH_LINK_AUTONEG;
+ if (ioctl_version < 2) {
+ link->link_duplex = ETH_LINK_FULL_DUPLEX;
+ link->link_autoneg = ETH_LINK_AUTONEG;
+
+ if (fif->mac_type == fman_mac_1g)
+ link->link_speed = ETH_SPEED_NUM_1G;
+ else if (fif->mac_type == fman_mac_2_5g)
+ link->link_speed = ETH_SPEED_NUM_2_5G;
+ else if (fif->mac_type == fman_mac_10g)
+ link->link_speed = ETH_SPEED_NUM_10G;
+ else
+ DPAA_PMD_ERR("invalid link_speed: %s, %d",
+ dpaa_intf->name, fif->mac_type);
+ }
DPAA_PMD_INFO("Port %d Link is %s\n", dev->data->port_id,
link->link_status ? "Up" : "Down");
rxq->fqid, ret);
}
}
-
+ /* Enable main queue to receive error packets also by default */
+ fman_if_set_err_fqid(fif, rxq->fqid);
return 0;
}
if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
dpaa_update_link_status(__fif->node_name, ETH_LINK_DOWN);
else
- dpaa_eth_dev_stop(dev);
+ return dpaa_eth_dev_stop(dev);
return 0;
}
dpaa_intf->nb_tx_queues = MAX_DPAA_CORES;
#ifdef RTE_LIBRTE_DPAA_DEBUG_DRIVER
- dpaa_debug_queue_init(&dpaa_intf->debug_queues[
- DPAA_DEBUG_FQ_RX_ERROR], fman_intf->fqid_rx_err);
+ ret = dpaa_debug_queue_init(&dpaa_intf->debug_queues
+ [DPAA_DEBUG_FQ_RX_ERROR], fman_intf->fqid_rx_err);
+ if (ret) {
+ DPAA_PMD_ERR("DPAA RX ERROR queue init failed!");
+ goto free_tx;
+ }
dpaa_intf->debug_queues[DPAA_DEBUG_FQ_RX_ERROR].dpaa_intf = dpaa_intf;
- dpaa_debug_queue_init(&dpaa_intf->debug_queues[
- DPAA_DEBUG_FQ_TX_ERROR], fman_intf->fqid_tx_err);
+ ret = dpaa_debug_queue_init(&dpaa_intf->debug_queues
+ [DPAA_DEBUG_FQ_TX_ERROR], fman_intf->fqid_tx_err);
+ if (ret) {
+ DPAA_PMD_ERR("DPAA TX ERROR queue init failed!");
+ goto free_tx;
+ }
dpaa_intf->debug_queues[DPAA_DEBUG_FQ_TX_ERROR].dpaa_intf = dpaa_intf;
#endif
fman_intf->mac_addr.addr_bytes[5]);
if (!fman_intf->is_shared_mac) {
+ /* Configure error packet handling */
+ fman_if_receive_rx_errors(fman_intf,
+ FM_FD_RX_STATUS_ERR_MASK);
/* Disable RX mode */
- fman_if_discard_rx_errors(fman_intf);
fman_if_disable_rx(fman_intf);
/* Disable promiscuous mode */
fman_if_promiscuous_disable(fman_intf);
qman_ern_register_cb(dpaa_free_mbuf);
- eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
if (dpaa_drv->drv_flags & RTE_DPAA_DRV_INTR_LSC)
eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
+
/* Invoke PMD device initialization function */
diag = dpaa_dev_init(eth_dev);
if (diag == 0) {