X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fdpaa2%2Fdpaa2_ethdev.c;h=dc24bedb27efcdb0050be1c819d9e4516ef176c0;hb=638233dc29e10e837da2a9afef9d41a8941baec2;hp=d0f8a8fe087cc15c0c0f2ae1480570d347e07487;hpb=ba9219fe42e19fa93a51474bbb7a1fd656dce9ac;p=dpdk.git diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c index d0f8a8fe08..dc24bedb27 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -54,6 +54,8 @@ static struct rte_dpaa2_driver rte_dpaa2_pmd; static int dpaa2_dev_uninit(struct rte_eth_dev *eth_dev); +static int dpaa2_dev_link_update(struct rte_eth_dev *dev, + int wait_to_complete); static int dpaa2_dev_set_link_up(struct rte_eth_dev *dev); static int dpaa2_dev_set_link_down(struct rte_eth_dev *dev); static int dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); @@ -324,18 +326,7 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev) } } - /* Check for correct configuration */ - if (eth_conf->rxmode.mq_mode != ETH_MQ_RX_RSS && - data->nb_rx_queues > 1) { - PMD_INIT_LOG(ERR, "Distribution is not enabled, " - "but Rx queues more than 1\n"); - return -1; - } - if (eth_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) { - /* Return in case number of Rx queues is 1 */ - if (data->nb_rx_queues == 1) - return 0; ret = dpaa2_setup_flow_dist(dev, eth_conf->rx_adv_conf.rss_conf.rss_hf); if (ret) { @@ -344,6 +335,10 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev) return ret; } } + + /* update the current status */ + dpaa2_dev_link_update(dev, 0); + return 0; } @@ -419,6 +414,7 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev, /*enabling per rx queue congestion control */ taildrop.threshold = CONG_THRESHOLD_RX_Q; taildrop.units = DPNI_CONGESTION_UNIT_BYTES; + taildrop.oal = CONG_RX_OAL; PMD_INIT_LOG(DEBUG, "Enabling Early Drop on queue = %d", rx_queue_id); ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token, @@ -488,7 +484,7 @@ dpaa2_dev_tx_queue_setup(struct rte_eth_dev *dev, } dpaa2_q->tc_index = tc_id; - if (priv->flags & DPAA2_TX_CGR_SUPPORT) { + if (!(priv->flags & DPAA2_TX_CGR_OFF)) { struct dpni_congestion_notification_cfg cong_notif_cfg; cong_notif_cfg.units = DPNI_CONGESTION_UNIT_FRAMES; @@ -555,9 +551,87 @@ dpaa2_supported_ptypes_get(struct rte_eth_dev *dev) return NULL; } +/** + * Dpaa2 link Interrupt handler + * + * @param param + * The address of parameter (struct rte_eth_dev *) regsitered before. + * + * @return + * void + */ +static void +dpaa2_interrupt_handler(void *param) +{ + struct rte_eth_dev *dev = param; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + int ret; + int irq_index = DPNI_IRQ_INDEX; + unsigned int status = 0, clear = 0; + + PMD_INIT_FUNC_TRACE(); + + if (dpni == NULL) { + RTE_LOG(ERR, PMD, "dpni is NULL"); + return; + } + + ret = dpni_get_irq_status(dpni, CMD_PRI_LOW, priv->token, + irq_index, &status); + if (unlikely(ret)) { + RTE_LOG(ERR, PMD, "Can't get irq status (err %d)", ret); + clear = 0xffffffff; + goto out; + } + + if (status & DPNI_IRQ_EVENT_LINK_CHANGED) { + clear = DPNI_IRQ_EVENT_LINK_CHANGED; + dpaa2_dev_link_update(dev, 0); + /* calling all the apps registered for link status event */ + _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, + NULL, NULL); + } +out: + ret = dpni_clear_irq_status(dpni, CMD_PRI_LOW, priv->token, + irq_index, clear); + if (unlikely(ret)) + RTE_LOG(ERR, PMD, "Can't clear irq status (err %d)", ret); +} + +static int +dpaa2_eth_setup_irqs(struct rte_eth_dev *dev, int enable) +{ + int err = 0; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; + int irq_index = DPNI_IRQ_INDEX; + unsigned int mask = DPNI_IRQ_EVENT_LINK_CHANGED; + + PMD_INIT_FUNC_TRACE(); + + err = dpni_set_irq_mask(dpni, CMD_PRI_LOW, priv->token, + irq_index, mask); + if (err < 0) { + PMD_INIT_LOG(ERR, "Error: dpni_set_irq_mask():%d (%s)", err, + strerror(-err)); + return err; + } + + err = dpni_set_irq_enable(dpni, CMD_PRI_LOW, priv->token, + irq_index, enable); + if (err < 0) + PMD_INIT_LOG(ERR, "Error: dpni_set_irq_enable():%d (%s)", err, + strerror(-err)); + + return err; +} + static int dpaa2_dev_start(struct rte_eth_dev *dev) { + struct rte_device *rdev = dev->device; + struct rte_dpaa2_device *dpaa2_dev; struct rte_eth_dev_data *data = dev->data; struct dpaa2_dev_priv *priv = data->dev_private; struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; @@ -567,6 +641,10 @@ dpaa2_dev_start(struct rte_eth_dev *dev) struct dpni_queue_id qid; struct dpaa2_queue *dpaa2_q; int ret, i; + struct rte_intr_handle *intr_handle; + + dpaa2_dev = container_of(rdev, struct rte_dpaa2_device, device); + intr_handle = &dpaa2_dev->intr_handle; PMD_INIT_FUNC_TRACE(); @@ -577,7 +655,7 @@ dpaa2_dev_start(struct rte_eth_dev *dev) return ret; } - /* Power up the phy. Needed to make the link go Up */ + /* Power up the phy. Needed to make the link go UP */ dpaa2_dev_set_link_up(dev); ret = dpni_get_qdid(dpni, CMD_PRI_LOW, priv->token, @@ -646,6 +724,24 @@ dpaa2_dev_start(struct rte_eth_dev *dev) if (priv->max_vlan_filters) dpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK); + /* if the interrupts were configured on this devices*/ + if (intr_handle && (intr_handle->fd) && + (dev->data->dev_conf.intr_conf.lsc != 0)) { + /* Registering LSC interrupt handler */ + rte_intr_callback_register(intr_handle, + dpaa2_interrupt_handler, + (void *)dev); + + /* enable vfio intr/eventfd mapping + * Interrupt index 0 is required, so we can not use + * rte_intr_enable. + */ + rte_dpaa2_intr_enable(intr_handle, DPNI_IRQ_INDEX); + + /* enable dpni_irqs */ + dpaa2_eth_setup_irqs(dev, 1); + } + return 0; } @@ -660,9 +756,25 @@ dpaa2_dev_stop(struct rte_eth_dev *dev) struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw; int ret; struct rte_eth_link link; + struct rte_intr_handle *intr_handle = dev->intr_handle; PMD_INIT_FUNC_TRACE(); + /* reset interrupt callback */ + if (intr_handle && (intr_handle->fd) && + (dev->data->dev_conf.intr_conf.lsc != 0)) { + /*disable dpni irqs */ + dpaa2_eth_setup_irqs(dev, 0); + + /* disable vfio intr before callback unregister */ + rte_dpaa2_intr_disable(intr_handle, DPNI_IRQ_INDEX); + + /* Unregistering LSC interrupt handler */ + rte_intr_callback_unregister(intr_handle, + dpaa2_interrupt_handler, + (void *)dev); + } + dpaa2_dev_set_link_down(dev); ret = dpni_disable(dpni, CMD_PRI_LOW, priv->token); @@ -941,7 +1053,7 @@ void dpaa2_dev_stats_get(struct rte_eth_dev *dev, /*Get Counters from page_0*/ retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, - page0, &value); + page0, 0, &value); if (retcode) goto err; @@ -950,7 +1062,7 @@ void dpaa2_dev_stats_get(struct rte_eth_dev *dev, /*Get Counters from page_1*/ retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, - page1, &value); + page1, 0, &value); if (retcode) goto err; @@ -959,7 +1071,7 @@ void dpaa2_dev_stats_get(struct rte_eth_dev *dev, /*Get Counters from page_2*/ retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token, - page2, &value); + page2, 0, &value); if (retcode) goto err; @@ -1014,8 +1126,6 @@ dpaa2_dev_link_update(struct rte_eth_dev *dev, struct rte_eth_link link, old; struct dpni_link_state state = {0}; - PMD_INIT_FUNC_TRACE(); - if (dpni == NULL) { RTE_LOG(ERR, PMD, "dpni is NULL\n"); return 0; @@ -1048,7 +1158,7 @@ dpaa2_dev_link_update(struct rte_eth_dev *dev, if (link.link_status) PMD_DRV_LOG(INFO, "Port %d Link is Up\n", dev->data->port_id); else - PMD_DRV_LOG(INFO, "Port %d Link is Down\n", dev->data->port_id); + PMD_DRV_LOG(INFO, "Port %d Link is Down", dev->data->port_id); return 0; } @@ -1063,8 +1173,7 @@ dpaa2_dev_set_link_up(struct rte_eth_dev *dev) struct dpaa2_dev_priv *priv; struct fsl_mc_io *dpni; int en = 0; - - PMD_INIT_FUNC_TRACE(); + struct dpni_link_state state = {0}; priv = dev->data->dev_private; dpni = (struct fsl_mc_io *)priv->hw; @@ -1090,11 +1199,21 @@ dpaa2_dev_set_link_up(struct rte_eth_dev *dev) return -EINVAL; } } + ret = dpni_get_link_state(dpni, CMD_PRI_LOW, priv->token, &state); + if (ret < 0) { + RTE_LOG(ERR, PMD, "error: dpni_get_link_state %d\n", ret); + return -1; + } + /* changing tx burst function to start enqueues */ dev->tx_pkt_burst = dpaa2_dev_tx; - dev->data->dev_link.link_status = 1; + dev->data->dev_link.link_status = state.up; - PMD_DRV_LOG(INFO, "Port %d Link UP successful", dev->data->port_id); + if (state.up) + PMD_DRV_LOG(INFO, "Port %d Link is set as UP", + dev->data->port_id); + else + PMD_DRV_LOG(INFO, "Port %d Link is DOWN", dev->data->port_id); return ret; } @@ -1384,22 +1503,19 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) goto init_err; } - priv->num_tc = attr.num_tcs; + priv->num_rx_tc = attr.num_rx_tcs; - /* Resetting the "num_rx_vqueues" to equal number of queues in first TC + /* Resetting the "num_rx_queues" to equal number of queues in first TC * as only one TC is supported on Rx Side. Once Multiple TCs will be * in use for Rx processing then this will be changed or removed. */ priv->nb_rx_queues = attr.num_queues; - /* TODO:Using hard coded value for number of TX queues due to dependency - * in MC. - */ - priv->nb_tx_queues = 8; + /* Using number of TX queues as number of TX TCs */ + priv->nb_tx_queues = attr.num_tx_tcs; - PMD_INIT_LOG(DEBUG, "num TC - RX %d", priv->num_tc); - PMD_INIT_LOG(DEBUG, "nb_tx_queues %d", priv->nb_tx_queues); - PMD_INIT_LOG(DEBUG, "nb_rx_queues %d", priv->nb_rx_queues); + PMD_DRV_LOG(DEBUG, "RX-TC= %d, nb_rx_queues= %d, nb_tx_queues=%d", + priv->num_tc, priv->nb_rx_queues, priv->nb_tx_queues); priv->hw = dpni_dev; priv->hw_id = hw_id; @@ -1460,6 +1576,7 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev) } eth_dev->dev_ops = &dpaa2_ethdev_ops; + eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC; eth_dev->rx_pkt_burst = dpaa2_dev_prefetch_rx; eth_dev->tx_pkt_burst = dpaa2_dev_tx; @@ -1482,7 +1599,7 @@ dpaa2_dev_uninit(struct rte_eth_dev *eth_dev) PMD_INIT_FUNC_TRACE(); if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return -EPERM; + return 0; if (!dpni) { PMD_INIT_LOG(WARNING, "Already closed or not started"); @@ -1535,11 +1652,10 @@ rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv, struct rte_eth_dev *eth_dev; int diag; - eth_dev = rte_eth_dev_allocate(dpaa2_dev->device.name); - if (eth_dev == NULL) - return -ENOMEM; - if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + eth_dev = rte_eth_dev_allocate(dpaa2_dev->device.name); + if (!eth_dev) + return -ENODEV; eth_dev->data->dev_private = rte_zmalloc( "ethdev private structure", sizeof(struct dpaa2_dev_priv), @@ -1550,7 +1666,12 @@ rte_dpaa2_probe(struct rte_dpaa2_driver *dpaa2_drv, rte_eth_dev_release_port(eth_dev); return -ENOMEM; } + } else { + eth_dev = rte_eth_dev_attach_secondary(dpaa2_dev->device.name); + if (!eth_dev) + return -ENODEV; } + eth_dev->device = &dpaa2_dev->device; eth_dev->device->driver = &dpaa2_drv->driver; @@ -1584,7 +1705,7 @@ rte_dpaa2_remove(struct rte_dpaa2_device *dpaa2_dev) } static struct rte_dpaa2_driver rte_dpaa2_pmd = { - .drv_type = DPAA2_MC_DPNI_DEVID, + .drv_type = DPAA2_ETH, .probe = rte_dpaa2_probe, .remove = rte_dpaa2_remove, };