#include <dpaa_ethdev.h>
#include <dpaa_rxtx.h>
+#include <rte_pmd_dpaa.h>
#include <fsl_usd.h>
#include <fsl_qman.h>
/* Keep track of whether QMAN and BMAN have been globally initialized */
static int is_global_init;
+/* Per FQ Taildrop in frame count */
+static unsigned int td_threshold = CGR_RX_PERFQ_THRESH;
+
struct rte_dpaa_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
uint32_t offset;
offsetof(struct dpaa_if_stats, tund)},
};
+static struct rte_dpaa_driver rte_dpaa_pmd;
+
static int
dpaa_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
{
static
int dpaa_eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
- uint16_t nb_desc __rte_unused,
+ uint16_t nb_desc,
unsigned int socket_id __rte_unused,
const struct rte_eth_rxconf *rx_conf __rte_unused,
struct rte_mempool *mp)
{
struct dpaa_if *dpaa_intf = dev->data->dev_private;
+ struct qman_fq *rxq = &dpaa_intf->rx_queues[queue_idx];
PMD_INIT_FUNC_TRACE();
dpaa_intf->name, fd_offset,
fman_if_get_fdoff(dpaa_intf->fif));
}
- dev->data->rx_queues[queue_idx] = &dpaa_intf->rx_queues[queue_idx];
+
+ dev->data->rx_queues[queue_idx] = rxq;
+
+ /* configure the CGR size as per the desc size */
+ if (dpaa_intf->cgr_rx) {
+ struct qm_mcc_initcgr cgr_opts = {0};
+ int ret;
+
+ /* Enable tail drop with cgr on this queue */
+ qm_cgr_cs_thres_set64(&cgr_opts.cgr.cs_thres, nb_desc, 0);
+ ret = qman_modify_cgr(dpaa_intf->cgr_rx, 0, &cgr_opts);
+ if (ret) {
+ DPAA_PMD_WARN(
+ "rx taildrop modify fail on fqid %d (ret=%d)",
+ rxq->fqid, ret);
+ }
+ }
return 0;
}
PMD_INIT_FUNC_TRACE();
}
+static uint32_t
+dpaa_dev_rx_queue_count(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct dpaa_if *dpaa_intf = dev->data->dev_private;
+ struct qman_fq *rxq = &dpaa_intf->rx_queues[rx_queue_id];
+ u32 frm_cnt = 0;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (qman_query_fq_frm_cnt(rxq, &frm_cnt) == 0) {
+ RTE_LOG(DEBUG, PMD, "RX frame count for q(%d) is %u\n",
+ rx_queue_id, frm_cnt);
+ }
+ return frm_cnt;
+}
+
static int dpaa_link_down(struct rte_eth_dev *dev)
{
PMD_INIT_FUNC_TRACE();
.tx_queue_setup = dpaa_eth_tx_queue_setup,
.rx_queue_release = dpaa_eth_rx_queue_release,
.tx_queue_release = dpaa_eth_tx_queue_release,
+ .rx_queue_count = dpaa_dev_rx_queue_count,
.flow_ctrl_get = dpaa_flow_ctrl_get,
.flow_ctrl_set = dpaa_flow_ctrl_set,
.fw_version_get = dpaa_fw_version_get,
};
+static bool
+is_device_supported(struct rte_eth_dev *dev, struct rte_dpaa_driver *drv)
+{
+ if (strcmp(dev->device->driver->name,
+ drv->driver.name))
+ return false;
+
+ return true;
+}
+
+static bool
+is_dpaa_supported(struct rte_eth_dev *dev)
+{
+ return is_device_supported(dev, &rte_dpaa_pmd);
+}
+
+int
+rte_pmd_dpaa_set_tx_loopback(uint8_t port, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct dpaa_if *dpaa_intf;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+
+ if (!is_dpaa_supported(dev))
+ return -ENOTSUP;
+
+ dpaa_intf = dev->data->dev_private;
+
+ if (on)
+ fman_if_loopback_enable(dpaa_intf->fif);
+ else
+ fman_if_loopback_disable(dpaa_intf->fif);
+
+ return 0;
+}
+
static int dpaa_fc_set_default(struct dpaa_if *dpaa_intf)
{
struct rte_eth_fc_conf *fc_conf;
}
/* Initialise an Rx FQ */
-static int dpaa_rx_queue_init(struct qman_fq *fq,
+static int dpaa_rx_queue_init(struct qman_fq *fq, struct qman_cgr *cgr_rx,
uint32_t fqid)
{
struct qm_mcc_initfq opts = {0};
int ret;
+ u32 flags = 0;
+ struct qm_mcc_initcgr cgr_opts = {
+ .we_mask = QM_CGR_WE_CS_THRES |
+ QM_CGR_WE_CSTD_EN |
+ QM_CGR_WE_MODE,
+ .cgr = {
+ .cstd_en = QM_CGR_EN,
+ .mode = QMAN_CGR_MODE_FRAME
+ }
+ };
PMD_INIT_FUNC_TRACE();
opts.fqd.context_a.stashing.data_cl = DPAA_IF_RX_DATA_STASH;
opts.fqd.context_a.stashing.context_cl = DPAA_IF_RX_CONTEXT_STASH;
- /*Enable tail drop */
- opts.we_mask = opts.we_mask | QM_INITFQ_WE_TDTHRESH;
- opts.fqd.fq_ctrl = opts.fqd.fq_ctrl | QM_FQCTRL_TDE;
- qm_fqd_taildrop_set(&opts.fqd.td, CONG_THRESHOLD_RX_Q, 1);
-
- ret = qman_init_fq(fq, 0, &opts);
+ if (cgr_rx) {
+ /* Enable tail drop with cgr on this queue */
+ qm_cgr_cs_thres_set64(&cgr_opts.cgr.cs_thres, td_threshold, 0);
+ cgr_rx->cb = NULL;
+ ret = qman_create_cgr(cgr_rx, QMAN_CGR_FLAG_USE_INIT,
+ &cgr_opts);
+ if (ret) {
+ DPAA_PMD_WARN(
+ "rx taildrop init fail on rx fqid %d (ret=%d)",
+ fqid, ret);
+ goto without_cgr;
+ }
+ opts.we_mask |= QM_INITFQ_WE_CGID;
+ opts.fqd.cgid = cgr_rx->cgrid;
+ opts.fqd.fq_ctrl |= QM_FQCTRL_CGE;
+ }
+without_cgr:
+ ret = qman_init_fq(fq, flags, &opts);
if (ret)
DPAA_PMD_ERR("init rx fqid %d failed with ret: %d", fqid, ret);
return ret;
struct fm_eth_port_cfg *cfg;
struct fman_if *fman_intf;
struct fman_if_bpool *bp, *tmp_bp;
+ uint32_t cgrid[DPAA_MAX_NUM_PCD_QUEUES];
PMD_INIT_FUNC_TRACE();
dpaa_intf->rx_queues = rte_zmalloc(NULL,
sizeof(struct qman_fq) * num_rx_fqs, MAX_CACHELINE);
+
+ /* If congestion control is enabled globally*/
+ if (td_threshold) {
+ dpaa_intf->cgr_rx = rte_zmalloc(NULL,
+ sizeof(struct qman_cgr) * num_rx_fqs, MAX_CACHELINE);
+
+ ret = qman_alloc_cgrid_range(&cgrid[0], num_rx_fqs, 1, 0);
+ if (ret != num_rx_fqs) {
+ DPAA_PMD_WARN("insufficient CGRIDs available");
+ return -EINVAL;
+ }
+ } else {
+ dpaa_intf->cgr_rx = NULL;
+ }
+
for (loop = 0; loop < num_rx_fqs; loop++) {
fqid = DPAA_PCD_FQID_START + dpaa_intf->ifid *
DPAA_PCD_FQID_MULTIPLIER + loop;
- ret = dpaa_rx_queue_init(&dpaa_intf->rx_queues[loop], fqid);
+
+ if (dpaa_intf->cgr_rx)
+ dpaa_intf->cgr_rx[loop].cgrid = cgrid[loop];
+
+ ret = dpaa_rx_queue_init(&dpaa_intf->rx_queues[loop],
+ dpaa_intf->cgr_rx ? &dpaa_intf->cgr_rx[loop] : NULL,
+ fqid);
if (ret)
return ret;
dpaa_intf->rx_queues[loop].dpaa_intf = dpaa_intf;
DPAA_PMD_ERR("Failed to allocate %d bytes needed to "
"store MAC addresses",
ETHER_ADDR_LEN * DPAA_MAX_MAC_FILTER);
+ rte_free(dpaa_intf->cgr_rx);
rte_free(dpaa_intf->rx_queues);
rte_free(dpaa_intf->tx_queues);
dpaa_intf->rx_queues = NULL;
dpaa_dev_uninit(struct rte_eth_dev *dev)
{
struct dpaa_if *dpaa_intf = dev->data->dev_private;
+ int loop;
PMD_INIT_FUNC_TRACE();
if (dpaa_intf->fc_conf)
rte_free(dpaa_intf->fc_conf);
+ /* Release RX congestion Groups */
+ if (dpaa_intf->cgr_rx) {
+ for (loop = 0; loop < dpaa_intf->nb_rx_queues; loop++)
+ qman_delete_cgr(&dpaa_intf->cgr_rx[loop]);
+
+ qman_release_cgrid_range(dpaa_intf->cgr_rx[loop].cgrid,
+ dpaa_intf->nb_rx_queues);
+ }
+
+ rte_free(dpaa_intf->cgr_rx);
+ dpaa_intf->cgr_rx = NULL;
+
rte_free(dpaa_intf->rx_queues);
dpaa_intf->rx_queues = NULL;