Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b81a90d3 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller
Browse files

bnxt_en: Re-structure ring indexing and mapping.



In order to support dedicated or shared completion rings, the ring
indexing and mapping are re-structured as below:

1. bp->grp_info[] array index is 1:1 with bp->bnapi[] array index and
completion ring index.

2. rx rings 0 to n will be mapped to completion rings 0 to n.

3. If tx and rx rings share completion rings, then tx rings 0 to m will
be mapped to completion rings 0 to m.

4. If tx and rx rings use dedicated completion rings, then tx rings 0 to
m will be mapped to completion rings n + 1 to n + m.

5. Each tx or rx ring will use the corresponding completion ring index
for doorbell mapping and MSIX mapping.

Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3b2b7d9d
Loading
Loading
Loading
Loading
+53 −38
Original line number Diff line number Diff line
@@ -422,7 +422,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts)
{
	struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
	int index = bnapi->index;
	int index = txr - &bp->tx_ring[0];
	struct netdev_queue *txq = netdev_get_tx_queue(bp->dev, index);
	u16 cons = txr->tx_cons;
	struct pci_dev *pdev = bp->pdev;
@@ -3082,7 +3082,7 @@ static int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, u16 vnic_id)

static int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id)
{
	int grp_idx = 0;
	unsigned int ring = 0, grp_idx;
	struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
	struct hwrm_vnic_cfg_input req = {0};

@@ -3093,10 +3093,11 @@ static int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id)
	req.rss_rule = cpu_to_le16(vnic->fw_rss_cos_lb_ctx);
	req.cos_rule = cpu_to_le16(0xffff);
	if (vnic->flags & BNXT_VNIC_RSS_FLAG)
		grp_idx = 0;
		ring = 0;
	else if (vnic->flags & BNXT_VNIC_RFS_FLAG)
		grp_idx = vnic_id - 1;
		ring = vnic_id - 1;

	grp_idx = bp->rx_ring[ring].bnapi->index;
	req.vnic_id = cpu_to_le16(vnic->fw_vnic_id);
	req.dflt_ring_grp = cpu_to_le16(bp->grp_info[grp_idx].fw_grp_id);

@@ -3137,22 +3138,25 @@ static void bnxt_hwrm_vnic_free(struct bnxt *bp)
		bnxt_hwrm_vnic_free_one(bp, i);
}

static int bnxt_hwrm_vnic_alloc(struct bnxt *bp, u16 vnic_id, u16 start_grp_id,
				u16 end_grp_id)
static int bnxt_hwrm_vnic_alloc(struct bnxt *bp, u16 vnic_id,
				unsigned int start_rx_ring_idx,
				unsigned int nr_rings)
{
	u32 rc = 0, i, j;
	int rc = 0;
	unsigned int i, j, grp_idx, end_idx = start_rx_ring_idx + nr_rings;
	struct hwrm_vnic_alloc_input req = {0};
	struct hwrm_vnic_alloc_output *resp = bp->hwrm_cmd_resp_addr;

	/* map ring groups to this vnic */
	for (i = start_grp_id, j = 0; i < end_grp_id; i++, j++) {
		if (bp->grp_info[i].fw_grp_id == INVALID_HW_RING_ID) {
	for (i = start_rx_ring_idx, j = 0; i < end_idx; i++, j++) {
		grp_idx = bp->rx_ring[i].bnapi->index;
		if (bp->grp_info[grp_idx].fw_grp_id == INVALID_HW_RING_ID) {
			netdev_err(bp->dev, "Not enough ring groups avail:%x req:%x\n",
				   j, (end_grp_id - start_grp_id));
				   j, nr_rings);
			break;
		}
		bp->vnic_info[vnic_id].fw_grp_ids[j] =
					bp->grp_info[i].fw_grp_id;
					bp->grp_info[grp_idx].fw_grp_id;
	}

	bp->vnic_info[vnic_id].fw_rss_cos_lb_ctx = INVALID_HW_RING_ID;
@@ -3179,20 +3183,22 @@ static int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp)
		struct hwrm_ring_grp_alloc_input req = {0};
		struct hwrm_ring_grp_alloc_output *resp =
					bp->hwrm_cmd_resp_addr;
		unsigned int grp_idx = bp->rx_ring[i].bnapi->index;

		bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_RING_GRP_ALLOC, -1, -1);

		req.cr = cpu_to_le16(bp->grp_info[i].cp_fw_ring_id);
		req.rr = cpu_to_le16(bp->grp_info[i].rx_fw_ring_id);
		req.ar = cpu_to_le16(bp->grp_info[i].agg_fw_ring_id);
		req.sc = cpu_to_le16(bp->grp_info[i].fw_stats_ctx);
		req.cr = cpu_to_le16(bp->grp_info[grp_idx].cp_fw_ring_id);
		req.rr = cpu_to_le16(bp->grp_info[grp_idx].rx_fw_ring_id);
		req.ar = cpu_to_le16(bp->grp_info[grp_idx].agg_fw_ring_id);
		req.sc = cpu_to_le16(bp->grp_info[grp_idx].fw_stats_ctx);

		rc = _hwrm_send_message(bp, &req, sizeof(req),
					HWRM_CMD_TIMEOUT);
		if (rc)
			break;

		bp->grp_info[i].fw_grp_id = le32_to_cpu(resp->ring_group_id);
		bp->grp_info[grp_idx].fw_grp_id =
			le32_to_cpu(resp->ring_group_id);
	}
	mutex_unlock(&bp->hwrm_cmd_lock);
	return rc;
@@ -3334,26 +3340,28 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
	for (i = 0; i < bp->tx_nr_rings; i++) {
		struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
		struct bnxt_ring_struct *ring = &txr->tx_ring_struct;
		u16 fw_stats_ctx = bp->grp_info[i].fw_stats_ctx;
		u32 map_idx = txr->bnapi->index;
		u16 fw_stats_ctx = bp->grp_info[map_idx].fw_stats_ctx;

		rc = hwrm_ring_alloc_send_msg(bp, ring, HWRM_RING_ALLOC_TX, i,
					      fw_stats_ctx);
		rc = hwrm_ring_alloc_send_msg(bp, ring, HWRM_RING_ALLOC_TX,
					      map_idx, fw_stats_ctx);
		if (rc)
			goto err_out;
		txr->tx_doorbell = bp->bar1 + i * 0x80;
		txr->tx_doorbell = bp->bar1 + map_idx * 0x80;
	}

	for (i = 0; i < bp->rx_nr_rings; i++) {
		struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
		struct bnxt_ring_struct *ring = &rxr->rx_ring_struct;
		u32 map_idx = rxr->bnapi->index;

		rc = hwrm_ring_alloc_send_msg(bp, ring, HWRM_RING_ALLOC_RX, i,
					      INVALID_STATS_CTX_ID);
		rc = hwrm_ring_alloc_send_msg(bp, ring, HWRM_RING_ALLOC_RX,
					      map_idx, INVALID_STATS_CTX_ID);
		if (rc)
			goto err_out;
		rxr->rx_doorbell = bp->bar1 + i * 0x80;
		rxr->rx_doorbell = bp->bar1 + map_idx * 0x80;
		writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
		bp->grp_info[i].rx_fw_ring_id = ring->fw_ring_id;
		bp->grp_info[map_idx].rx_fw_ring_id = ring->fw_ring_id;
	}

	if (bp->flags & BNXT_FLAG_AGG_RINGS) {
@@ -3361,19 +3369,20 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
			struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
			struct bnxt_ring_struct *ring =
						&rxr->rx_agg_ring_struct;
			u32 grp_idx = rxr->bnapi->index;
			u32 map_idx = grp_idx + bp->rx_nr_rings;

			rc = hwrm_ring_alloc_send_msg(bp, ring,
						      HWRM_RING_ALLOC_AGG,
						      bp->rx_nr_rings + i,
						      map_idx,
						      INVALID_STATS_CTX_ID);
			if (rc)
				goto err_out;

			rxr->rx_agg_doorbell =
				bp->bar1 + (bp->rx_nr_rings + i) * 0x80;
			rxr->rx_agg_doorbell = bp->bar1 + map_idx * 0x80;
			writel(DB_KEY_RX | rxr->rx_agg_prod,
			       rxr->rx_agg_doorbell);
			bp->grp_info[i].agg_fw_ring_id = ring->fw_ring_id;
			bp->grp_info[grp_idx].agg_fw_ring_id = ring->fw_ring_id;
		}
	}
err_out:
@@ -3430,7 +3439,8 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
	for (i = 0; i < bp->tx_nr_rings; i++) {
		struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
		struct bnxt_ring_struct *ring = &txr->tx_ring_struct;
		u32 cmpl_ring_id = bp->grp_info[i].cp_fw_ring_id;
		u32 grp_idx = txr->bnapi->index;
		u32 cmpl_ring_id = bp->grp_info[grp_idx].cp_fw_ring_id;

		if (ring->fw_ring_id != INVALID_HW_RING_ID) {
			hwrm_ring_free_send_msg(bp, ring,
@@ -3444,7 +3454,8 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
	for (i = 0; i < bp->rx_nr_rings; i++) {
		struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
		struct bnxt_ring_struct *ring = &rxr->rx_ring_struct;
		u32 cmpl_ring_id = bp->grp_info[i].cp_fw_ring_id;
		u32 grp_idx = rxr->bnapi->index;
		u32 cmpl_ring_id = bp->grp_info[grp_idx].cp_fw_ring_id;

		if (ring->fw_ring_id != INVALID_HW_RING_ID) {
			hwrm_ring_free_send_msg(bp, ring,
@@ -3452,14 +3463,16 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
						close_path ? cmpl_ring_id :
						INVALID_HW_RING_ID);
			ring->fw_ring_id = INVALID_HW_RING_ID;
			bp->grp_info[i].rx_fw_ring_id = INVALID_HW_RING_ID;
			bp->grp_info[grp_idx].rx_fw_ring_id =
				INVALID_HW_RING_ID;
		}
	}

	for (i = 0; i < bp->rx_nr_rings; i++) {
		struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
		struct bnxt_ring_struct *ring = &rxr->rx_agg_ring_struct;
		u32 cmpl_ring_id = bp->grp_info[i].cp_fw_ring_id;
		u32 grp_idx = rxr->bnapi->index;
		u32 cmpl_ring_id = bp->grp_info[grp_idx].cp_fw_ring_id;

		if (ring->fw_ring_id != INVALID_HW_RING_ID) {
			hwrm_ring_free_send_msg(bp, ring,
@@ -3467,7 +3480,8 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
						close_path ? cmpl_ring_id :
						INVALID_HW_RING_ID);
			ring->fw_ring_id = INVALID_HW_RING_ID;
			bp->grp_info[i].agg_fw_ring_id = INVALID_HW_RING_ID;
			bp->grp_info[grp_idx].agg_fw_ring_id =
				INVALID_HW_RING_ID;
		}
	}

@@ -3859,7 +3873,7 @@ static int bnxt_alloc_rfs_vnics(struct bnxt *bp)
			break;

		bp->vnic_info[vnic_id].flags |= BNXT_VNIC_RFS_FLAG;
		rc = bnxt_hwrm_vnic_alloc(bp, vnic_id, ring_id, ring_id + 1);
		rc = bnxt_hwrm_vnic_alloc(bp, vnic_id, ring_id, 1);
		if (rc) {
			netdev_err(bp->dev, "hwrm vnic %d alloc failure rc: %x\n",
				   vnic_id, rc);
@@ -4165,7 +4179,7 @@ static void bnxt_free_irq(struct bnxt *bp)

static int bnxt_request_irq(struct bnxt *bp)
{
	int i, rc = 0;
	int i, j, rc = 0;
	unsigned long flags = 0;
#ifdef CONFIG_RFS_ACCEL
	struct cpu_rmap *rmap = bp->dev->rx_cpu_rmap;
@@ -4174,14 +4188,15 @@ static int bnxt_request_irq(struct bnxt *bp)
	if (!(bp->flags & BNXT_FLAG_USING_MSIX))
		flags = IRQF_SHARED;

	for (i = 0; i < bp->cp_nr_rings; i++) {
	for (i = 0, j = 0; i < bp->cp_nr_rings; i++) {
		struct bnxt_irq *irq = &bp->irq_tbl[i];
#ifdef CONFIG_RFS_ACCEL
		if (rmap && (i < bp->rx_nr_rings)) {
		if (rmap && bp->bnapi[i]->rx_ring) {
			rc = irq_cpu_rmap_add(rmap, irq->vector);
			if (rc)
				netdev_warn(bp->dev, "failed adding irq rmap for ring %d\n",
					    i);
					    j);
			j++;
		}
#endif
		rc = request_irq(irq->vector, irq->handler, flags, irq->name,
+2 −0
Original line number Diff line number Diff line
@@ -918,6 +918,8 @@ struct bnxt {
	int			cp_nr_rings;

	int			num_stat_ctxs;

	/* grp_info indexed by completion ring index */
	struct bnxt_ring_grp_info	*grp_info;
	struct bnxt_vnic_info	*vnic_info;
	int			nr_vnics;