Пример #1
0
static int bnxt_handle_tx_cp(struct bnxt_tx_queue *txq)
{
	struct bnxt_cp_ring_info *cpr = txq->cp_ring;
	uint32_t raw_cons = cpr->cp_raw_cons;
	uint32_t cons;
	int nb_tx_pkts = 0;
	struct tx_cmpl *txcmp;

	if ((txq->tx_ring->tx_ring_struct->ring_size -
			(bnxt_tx_avail(txq->tx_ring))) >
			txq->tx_free_thresh) {
		while (1) {
			cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
			txcmp = (struct tx_cmpl *)&cpr->cp_desc_ring[cons];

			if (!CMP_VALID(txcmp, raw_cons, cpr->cp_ring_struct))
				break;

			if (CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2)
				nb_tx_pkts++;
			else
				RTE_LOG_DP(DEBUG, PMD,
						"Unhandled CMP type %02x\n",
						CMP_TYPE(txcmp));
			raw_cons = NEXT_RAW_CMP(raw_cons);
		}
		if (nb_tx_pkts)
			bnxt_tx_cmp(txq, nb_tx_pkts);
		cpr->cp_raw_cons = raw_cons;
		B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
	}
	return nb_tx_pkts;
}
Пример #2
0
uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
			       uint16_t nb_pkts)
{
	struct bnxt_rx_queue *rxq = rx_queue;
	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
	uint32_t raw_cons = cpr->cp_raw_cons;
	uint32_t cons;
	int nb_rx_pkts = 0;
	bool rx_event = false;
	struct rx_pkt_cmpl *rxcmp;

	/* Handle RX burst request */
	while (1) {
		int rc;

		cons = RING_CMP(cpr->cp_ring_struct, raw_cons);
		rte_prefetch0(&cpr->cp_desc_ring[cons]);
		rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];

		if (!CMP_VALID(rxcmp, raw_cons, cpr->cp_ring_struct))
			break;

		/* TODO: Avoid magic numbers... */
		if ((CMP_TYPE(rxcmp) & 0x30) == 0x10) {
			rc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons);
			if (likely(!rc))
				nb_rx_pkts++;
			else if (rc == -EBUSY)	/* partial completion */
				break;
			rx_event = true;
		}
		raw_cons = NEXT_RAW_CMP(raw_cons);
		if (nb_rx_pkts == nb_pkts)
			break;
	}
	if (raw_cons == cpr->cp_raw_cons) {
		/*
		 * For PMD, there is no need to keep on pushing to REARM
		 * the doorbell if there are no new completions
		 */
		return nb_rx_pkts;
	}
	cpr->cp_raw_cons = raw_cons;

	B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
	if (rx_event)
		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
	return nb_rx_pkts;
}
Пример #3
0
/* ring_grp usage:
 * [0] = default completion ring
 * [1 -> +rx_cp_nr_rings] = rx_cp, rx rings
 * [1+rx_cp_nr_rings + 1 -> +tx_cp_nr_rings] = tx_cp, tx rings
 */
int bnxt_alloc_hwrm_rings(struct bnxt *bp)
{
	struct rte_pci_device *pci_dev = bp->pdev;
	unsigned int i;
	int rc = 0;

	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
		struct bnxt_rx_queue *rxq = bp->rx_queues[i];
		struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
		struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
		struct bnxt_ring *ring = rxr->rx_ring_struct;
		unsigned int idx = i + 1;
		unsigned int map_idx = idx + bp->rx_cp_nr_rings;

		bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;

		/* Rx cmpl */
		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
					idx, HWRM_NA_SIGNATURE,
					HWRM_NA_SIGNATURE);
		if (rc)
			goto err_out;
		cpr->cp_doorbell = (char *)pci_dev->mem_resource[2].addr +
		    idx * 0x80;
		bp->grp_info[i].cp_fw_ring_id = cp_ring->fw_ring_id;
		B_CP_DIS_DB(cpr, cpr->cp_raw_cons);

		/* Rx ring */
		rc = bnxt_hwrm_ring_alloc(bp, ring,
					HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
					idx, cpr->hw_stats_ctx_id,
					cp_ring->fw_ring_id);
		if (rc)
			goto err_out;
		rxr->rx_prod = 0;
		rxr->rx_doorbell = (char *)pci_dev->mem_resource[2].addr +
		    idx * 0x80;
		bp->grp_info[i].rx_fw_ring_id = ring->fw_ring_id;
		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);

		ring = rxr->ag_ring_struct;
		/* Agg ring */
		if (ring == NULL) {
			RTE_LOG(ERR, PMD, "Alloc AGG Ring is NULL!\n");
			goto err_out;
		}

		rc = bnxt_hwrm_ring_alloc(bp, ring,
				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
				map_idx, HWRM_NA_SIGNATURE,
				cp_ring->fw_ring_id);
		if (rc)
			goto err_out;
		RTE_LOG(DEBUG, PMD, "Alloc AGG Done!\n");
		rxr->ag_prod = 0;
		rxr->ag_doorbell =
		    (char *)pci_dev->mem_resource[2].addr +
		    map_idx * 0x80;
		bp->grp_info[i].ag_fw_ring_id = ring->fw_ring_id;
		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);

		rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN +
					ETHER_CRC_LEN + (2 * VLAN_TAG_SIZE);
		if (bnxt_init_one_rx_ring(rxq)) {
			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!\n");
			bnxt_rx_queue_release_op(rxq);
			return -ENOMEM;
		}
		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
		rxq->index = idx;
	}

	for (i = 0; i < bp->tx_cp_nr_rings; i++) {
		struct bnxt_tx_queue *txq = bp->tx_queues[i];
		struct bnxt_cp_ring_info *cpr = txq->cp_ring;
		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
		struct bnxt_tx_ring_info *txr = txq->tx_ring;
		struct bnxt_ring *ring = txr->tx_ring_struct;
		unsigned int idx = i + 1 + bp->rx_cp_nr_rings;

		/* Account for AGG Rings. AGG ring cnt = Rx Cmpl ring cnt */
		idx += bp->rx_cp_nr_rings;

		/* Tx cmpl */
		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
					idx, HWRM_NA_SIGNATURE,
					HWRM_NA_SIGNATURE);
		if (rc)
			goto err_out;

		cpr->cp_doorbell = (char *)pci_dev->mem_resource[2].addr +
		    idx * 0x80;
		B_CP_DIS_DB(cpr, cpr->cp_raw_cons);

		/* Tx ring */
		rc = bnxt_hwrm_ring_alloc(bp, ring,
					HWRM_RING_ALLOC_INPUT_RING_TYPE_TX,
					idx, cpr->hw_stats_ctx_id,
					cp_ring->fw_ring_id);
		if (rc)
			goto err_out;

		txr->tx_doorbell = (char *)pci_dev->mem_resource[2].addr +
		    idx * 0x80;
		txq->index = idx;
	}

err_out:
	return rc;
}
Пример #4
0
/* ring_grp usage:
 * [0] = default completion ring
 * [1 -> +rx_cp_nr_rings] = rx_cp, rx rings
 * [1+rx_cp_nr_rings + 1 -> +tx_cp_nr_rings] = tx_cp, tx rings
 */
int bnxt_alloc_hwrm_rings(struct bnxt *bp)
{
	unsigned int i;
	int rc = 0;

	/* Default completion ring */
	{
		struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;

		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
					  HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
					  0, HWRM_NA_SIGNATURE);
		if (rc)
			goto err_out;
		cpr->cp_doorbell =
		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr;
		B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
		bp->grp_info[0].cp_fw_ring_id = cp_ring->fw_ring_id;
	}

	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
		struct bnxt_rx_queue *rxq = bp->rx_queues[i];
		struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
		struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
		struct bnxt_ring *ring = rxr->rx_ring_struct;
		unsigned int idx = i + 1;

		/* Rx cmpl */
		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
					idx, HWRM_NA_SIGNATURE);
		if (rc)
			goto err_out;
		cpr->cp_doorbell =
		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
		    idx * 0x80;
		bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
		B_CP_DIS_DB(cpr, cpr->cp_raw_cons);

		/* Rx ring */
		rc = bnxt_hwrm_ring_alloc(bp, ring,
					HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
					idx, cpr->hw_stats_ctx_id);
		if (rc)
			goto err_out;
		rxr->rx_prod = 0;
		rxr->rx_doorbell =
		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
		    idx * 0x80;
		bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id;
		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
		if (bnxt_init_one_rx_ring(rxq)) {
			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!");
			bnxt_rx_queue_release_op(rxq);
			return -ENOMEM;
		}
		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
	}

	for (i = 0; i < bp->tx_cp_nr_rings; i++) {
		struct bnxt_tx_queue *txq = bp->tx_queues[i];
		struct bnxt_cp_ring_info *cpr = txq->cp_ring;
		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
		struct bnxt_tx_ring_info *txr = txq->tx_ring;
		struct bnxt_ring *ring = txr->tx_ring_struct;
		unsigned int idx = 1 + bp->rx_cp_nr_rings + i;

		/* Tx cmpl */
		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
					idx, HWRM_NA_SIGNATURE);
		if (rc)
			goto err_out;

		cpr->cp_doorbell =
		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
		    idx * 0x80;
		bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
		B_CP_DIS_DB(cpr, cpr->cp_raw_cons);

		/* Tx ring */
		rc = bnxt_hwrm_ring_alloc(bp, ring,
					HWRM_RING_ALLOC_INPUT_RING_TYPE_TX,
					idx, cpr->hw_stats_ctx_id);
		if (rc)
			goto err_out;

		txr->tx_doorbell =
		    (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
		    idx * 0x80;
	}

err_out:
	return rc;
}