summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c439
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.h15
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c59
3 files changed, 328 insertions, 185 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 319653a3e333..f9569493034b 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -179,7 +179,6 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 len, free_size, vlan_tag_flags, cfa_action, flags;
u16 prod, last_frag;
struct pci_dev *pdev = bp->pdev;
- struct bnxt_napi *bnapi;
struct bnxt_tx_ring_info *txr;
struct bnxt_sw_tx_bd *tx_buf;
@@ -189,8 +188,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
- bnapi = bp->bnapi[i];
- txr = &bnapi->tx_ring;
+ txr = &bp->tx_ring[i];
txq = netdev_get_tx_queue(dev, i);
prod = txr->tx_prod;
@@ -423,8 +421,8 @@ tx_dma_error:
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;
+ struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
+ 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;
@@ -602,7 +600,7 @@ static void bnxt_reuse_rx_agg_bufs(struct bnxt_napi *bnapi, u16 cp_cons,
{
struct bnxt *bp = bnapi->bp;
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
- struct bnxt_rx_ring_info *rxr = &bnapi->rx_ring;
+ struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
u16 prod = rxr->rx_agg_prod;
u16 sw_prod = rxr->rx_sw_agg_prod;
u32 i;
@@ -681,7 +679,7 @@ static struct sk_buff *bnxt_rx_pages(struct bnxt *bp, struct bnxt_napi *bnapi,
{
struct pci_dev *pdev = bp->pdev;
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
- struct bnxt_rx_ring_info *rxr = &bnapi->rx_ring;
+ struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
u16 prod = rxr->rx_agg_prod;
u32 i;
@@ -940,7 +938,7 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp,
bool *agg_event)
{
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
- struct bnxt_rx_ring_info *rxr = &bnapi->rx_ring;
+ struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
u8 agg_id = TPA_END_AGG_ID(tpa_end);
u8 *data, agg_bufs;
u16 cp_cons = RING_CMP(*raw_cons);
@@ -1056,7 +1054,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_napi *bnapi, u32 *raw_cons,
bool *agg_event)
{
struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
- struct bnxt_rx_ring_info *rxr = &bnapi->rx_ring;
+ struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
struct net_device *dev = bp->dev;
struct rx_cmp *rxcmp;
struct rx_cmp_ext *rxcmp1;
@@ -1390,7 +1388,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
bnxt_tx_int(bp, bnapi, tx_pkts);
if (rx_event) {
- struct bnxt_rx_ring_info *rxr = &bnapi->rx_ring;
+ struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
@@ -1459,19 +1457,14 @@ static void bnxt_free_tx_skbs(struct bnxt *bp)
int i, max_idx;
struct pci_dev *pdev = bp->pdev;
- if (!bp->bnapi)
+ if (!bp->tx_ring)
return;
max_idx = bp->tx_nr_pages * TX_DESC_CNT;
for (i = 0; i < bp->tx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_tx_ring_info *txr;
+ struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
int j;
- if (!bnapi)
- continue;
-
- txr = &bnapi->tx_ring;
for (j = 0; j < max_idx;) {
struct bnxt_sw_tx_bd *tx_buf = &txr->tx_buf_ring[j];
struct sk_buff *skb = tx_buf->skb;
@@ -1517,21 +1510,15 @@ static void bnxt_free_rx_skbs(struct bnxt *bp)
int i, max_idx, max_agg_idx;
struct pci_dev *pdev = bp->pdev;
- if (!bp->bnapi)
+ if (!bp->rx_ring)
return;
max_idx = bp->rx_nr_pages * RX_DESC_CNT;
max_agg_idx = bp->rx_agg_nr_pages * RX_DESC_CNT;
for (i = 0; i < bp->rx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_rx_ring_info *rxr;
+ struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
int j;
- if (!bnapi)
- continue;
-
- rxr = &bnapi->rx_ring;
-
if (rxr->rx_tpa) {
for (j = 0; j < MAX_TPA; j++) {
struct bnxt_tpa_info *tpa_info =
@@ -1659,19 +1646,13 @@ static void bnxt_free_rx_rings(struct bnxt *bp)
{
int i;
- if (!bp->bnapi)
+ if (!bp->rx_ring)
return;
for (i = 0; i < bp->rx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_rx_ring_info *rxr;
+ struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
struct bnxt_ring_struct *ring;
- if (!bnapi)
- continue;
-
- rxr = &bnapi->rx_ring;
-
kfree(rxr->rx_tpa);
rxr->rx_tpa = NULL;
@@ -1690,6 +1671,9 @@ static int bnxt_alloc_rx_rings(struct bnxt *bp)
{
int i, rc, agg_rings = 0, tpa_rings = 0;
+ if (!bp->rx_ring)
+ return -ENOMEM;
+
if (bp->flags & BNXT_FLAG_AGG_RINGS)
agg_rings = 1;
@@ -1697,14 +1681,9 @@ static int bnxt_alloc_rx_rings(struct bnxt *bp)
tpa_rings = 1;
for (i = 0; i < bp->rx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_rx_ring_info *rxr;
+ struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
struct bnxt_ring_struct *ring;
- if (!bnapi)
- continue;
-
- rxr = &bnapi->rx_ring;
ring = &rxr->rx_ring_struct;
rc = bnxt_alloc_ring(bp, ring);
@@ -1742,19 +1721,13 @@ static void bnxt_free_tx_rings(struct bnxt *bp)
int i;
struct pci_dev *pdev = bp->pdev;
- if (!bp->bnapi)
+ if (!bp->tx_ring)
return;
for (i = 0; i < bp->tx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_tx_ring_info *txr;
+ struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
struct bnxt_ring_struct *ring;
- if (!bnapi)
- continue;
-
- txr = &bnapi->tx_ring;
-
if (txr->tx_push) {
dma_free_coherent(&pdev->dev, bp->tx_push_size,
txr->tx_push, txr->tx_push_mapping);
@@ -1788,14 +1761,9 @@ static int bnxt_alloc_tx_rings(struct bnxt *bp)
}
for (i = 0, j = 0; i < bp->tx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_tx_ring_info *txr;
+ struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
struct bnxt_ring_struct *ring;
- if (!bnapi)
- continue;
-
- txr = &bnapi->tx_ring;
ring = &txr->tx_ring_struct;
rc = bnxt_alloc_ring(bp, ring);
@@ -1898,7 +1866,10 @@ static void bnxt_init_ring_struct(struct bnxt *bp)
ring->dma_arr = cpr->cp_desc_mapping;
ring->vmem_size = 0;
- rxr = &bnapi->rx_ring;
+ rxr = bnapi->rx_ring;
+ if (!rxr)
+ goto skip_rx;
+
ring = &rxr->rx_ring_struct;
ring->nr_pages = bp->rx_nr_pages;
ring->page_size = HW_RXBD_RING_SIZE;
@@ -1915,7 +1886,11 @@ static void bnxt_init_ring_struct(struct bnxt *bp)
ring->vmem_size = SW_RXBD_AGG_RING_SIZE * bp->rx_agg_nr_pages;
ring->vmem = (void **)&rxr->rx_agg_ring;
- txr = &bnapi->tx_ring;
+skip_rx:
+ txr = bnapi->tx_ring;
+ if (!txr)
+ continue;
+
ring = &txr->tx_ring_struct;
ring->nr_pages = bp->tx_nr_pages;
ring->page_size = HW_RXBD_RING_SIZE;
@@ -1951,22 +1926,18 @@ static void bnxt_init_rxbd_pages(struct bnxt_ring_struct *ring, u32 type)
static int bnxt_init_one_rx_ring(struct bnxt *bp, int ring_nr)
{
struct net_device *dev = bp->dev;
- struct bnxt_napi *bnapi = bp->bnapi[ring_nr];
struct bnxt_rx_ring_info *rxr;
struct bnxt_ring_struct *ring;
u32 prod, type;
int i;
- if (!bnapi)
- return -EINVAL;
-
type = (bp->rx_buf_use_size << RX_BD_LEN_SHIFT) |
RX_BD_TYPE_RX_PACKET_BD | RX_BD_FLAGS_EOP;
if (NET_IP_ALIGN == 2)
type |= RX_BD_FLAGS_SOP;
- rxr = &bnapi->rx_ring;
+ rxr = &bp->rx_ring[ring_nr];
ring = &rxr->rx_ring_struct;
bnxt_init_rxbd_pages(ring, type);
@@ -2048,8 +2019,7 @@ static int bnxt_init_tx_rings(struct bnxt *bp)
MAX_SKB_FRAGS + 1);
for (i = 0; i < bp->tx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_tx_ring_info *txr = &bnapi->tx_ring;
+ struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
struct bnxt_ring_struct *ring = &txr->tx_ring_struct;
ring->fw_ring_id = INVALID_HW_RING_ID;
@@ -2436,14 +2406,18 @@ static void bnxt_clear_ring_indices(struct bnxt *bp)
cpr = &bnapi->cp_ring;
cpr->cp_raw_cons = 0;
- txr = &bnapi->tx_ring;
- txr->tx_prod = 0;
- txr->tx_cons = 0;
+ txr = bnapi->tx_ring;
+ if (txr) {
+ txr->tx_prod = 0;
+ txr->tx_cons = 0;
+ }
- rxr = &bnapi->rx_ring;
- rxr->rx_prod = 0;
- rxr->rx_agg_prod = 0;
- rxr->rx_sw_agg_prod = 0;
+ rxr = bnapi->rx_ring;
+ if (rxr) {
+ rxr->rx_prod = 0;
+ rxr->rx_agg_prod = 0;
+ rxr->rx_sw_agg_prod = 0;
+ }
}
}
@@ -2509,6 +2483,10 @@ static void bnxt_free_mem(struct bnxt *bp, bool irq_re_init)
bnxt_free_stats(bp);
bnxt_free_ring_grps(bp);
bnxt_free_vnics(bp);
+ kfree(bp->tx_ring);
+ bp->tx_ring = NULL;
+ kfree(bp->rx_ring);
+ bp->rx_ring = NULL;
kfree(bp->bnapi);
bp->bnapi = NULL;
} else {
@@ -2518,7 +2496,7 @@ static void bnxt_free_mem(struct bnxt *bp, bool irq_re_init)
static int bnxt_alloc_mem(struct bnxt *bp, bool irq_re_init)
{
- int i, rc, size, arr_size;
+ int i, j, rc, size, arr_size;
void *bnapi;
if (irq_re_init) {
@@ -2540,6 +2518,33 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool irq_re_init)
bp->bnapi[i]->bp = bp;
}
+ bp->rx_ring = kcalloc(bp->rx_nr_rings,
+ sizeof(struct bnxt_rx_ring_info),
+ GFP_KERNEL);
+ if (!bp->rx_ring)
+ return -ENOMEM;
+
+ for (i = 0; i < bp->rx_nr_rings; i++) {
+ bp->rx_ring[i].bnapi = bp->bnapi[i];
+ bp->bnapi[i]->rx_ring = &bp->rx_ring[i];
+ }
+
+ bp->tx_ring = kcalloc(bp->tx_nr_rings,
+ sizeof(struct bnxt_tx_ring_info),
+ GFP_KERNEL);
+ if (!bp->tx_ring)
+ return -ENOMEM;
+
+ if (bp->flags & BNXT_FLAG_SHARED_RINGS)
+ j = 0;
+ else
+ j = bp->rx_nr_rings;
+
+ for (i = 0; i < bp->tx_nr_rings; i++, j++) {
+ bp->tx_ring[i].bnapi = bp->bnapi[j];
+ bp->bnapi[j]->tx_ring = &bp->tx_ring[i];
+ }
+
rc = bnxt_alloc_stats(bp);
if (rc)
goto alloc_mem_err;
@@ -3082,7 +3087,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 +3098,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 +3143,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 +3188,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;
@@ -3332,51 +3343,51 @@ static int bnxt_hwrm_ring_alloc(struct bnxt *bp)
}
for (i = 0; i < bp->tx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_tx_ring_info *txr = &bnapi->tx_ring;
+ 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_napi *bnapi = bp->bnapi[i];
- struct bnxt_rx_ring_info *rxr = &bnapi->rx_ring;
+ 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) {
for (i = 0; i < bp->rx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_rx_ring_info *rxr = &bnapi->rx_ring;
+ 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:
@@ -3431,10 +3442,10 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
return;
for (i = 0; i < bp->tx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_tx_ring_info *txr = &bnapi->tx_ring;
+ 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,
@@ -3446,10 +3457,10 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
}
for (i = 0; i < bp->rx_nr_rings; i++) {
- struct bnxt_napi *bnapi = bp->bnapi[i];
- struct bnxt_rx_ring_info *rxr = &bnapi->rx_ring;
+ 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,
@@ -3457,15 +3468,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_napi *bnapi = bp->bnapi[i];
- struct bnxt_rx_ring_info *rxr = &bnapi->rx_ring;
+ 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,
@@ -3473,7 +3485,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;
}
}
@@ -3865,7 +3878,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);
@@ -4030,11 +4043,35 @@ static int bnxt_set_real_num_queues(struct bnxt *bp)
return rc;
}
+static int bnxt_trim_rings(struct bnxt *bp, int *rx, int *tx, int max,
+ bool shared)
+{
+ int _rx = *rx, _tx = *tx;
+
+ if (shared) {
+ *rx = min_t(int, _rx, max);
+ *tx = min_t(int, _tx, max);
+ } else {
+ if (max < 2)
+ return -ENOMEM;
+
+ while (_rx + _tx > max) {
+ if (_rx > _tx && _rx > 1)
+ _rx--;
+ else if (_tx > 1)
+ _tx--;
+ }
+ *rx = _rx;
+ *tx = _tx;
+ }
+ return 0;
+}
+
static int bnxt_setup_msix(struct bnxt *bp)
{
struct msix_entry *msix_ent;
struct net_device *dev = bp->dev;
- int i, total_vecs, rc = 0;
+ int i, total_vecs, rc = 0, min = 1;
const int len = sizeof(bp->irq_tbl[0].name);
bp->flags &= ~BNXT_FLAG_USING_MSIX;
@@ -4049,7 +4086,10 @@ static int bnxt_setup_msix(struct bnxt *bp)
msix_ent[i].vector = 0;
}
- total_vecs = pci_enable_msix_range(bp->pdev, msix_ent, 1, total_vecs);
+ if (!(bp->flags & BNXT_FLAG_SHARED_RINGS))
+ min = 2;
+
+ total_vecs = pci_enable_msix_range(bp->pdev, msix_ent, min, total_vecs);
if (total_vecs < 0) {
rc = -ENODEV;
goto msix_setup_exit;
@@ -4060,8 +4100,11 @@ static int bnxt_setup_msix(struct bnxt *bp)
int tcs;
/* Trim rings based upon num of vectors allocated */
- bp->rx_nr_rings = min_t(int, total_vecs, bp->rx_nr_rings);
- bp->tx_nr_rings = min_t(int, total_vecs, bp->tx_nr_rings);
+ rc = bnxt_trim_rings(bp, &bp->rx_nr_rings, &bp->tx_nr_rings,
+ total_vecs, min == 1);
+ if (rc)
+ goto msix_setup_exit;
+
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
tcs = netdev_get_num_tc(dev);
if (tcs > 1) {
@@ -4080,12 +4123,21 @@ static int bnxt_setup_msix(struct bnxt *bp)
}
}
}
- bp->cp_nr_rings = max_t(int, bp->rx_nr_rings, bp->tx_nr_rings);
+ bp->cp_nr_rings = total_vecs;
for (i = 0; i < bp->cp_nr_rings; i++) {
+ char *attr;
+
bp->irq_tbl[i].vector = msix_ent[i].vector;
+ if (bp->flags & BNXT_FLAG_SHARED_RINGS)
+ attr = "TxRx";
+ else if (i < bp->rx_nr_rings)
+ attr = "rx";
+ else
+ attr = "tx";
+
snprintf(bp->irq_tbl[i].name, len,
- "%s-%s-%d", dev->name, "TxRx", i);
+ "%s-%s-%d", dev->name, attr, i);
bp->irq_tbl[i].handler = bnxt_msix;
}
rc = bnxt_set_real_num_queues(bp);
@@ -4123,6 +4175,7 @@ static int bnxt_setup_inta(struct bnxt *bp)
bp->tx_nr_rings = 1;
bp->cp_nr_rings = 1;
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
+ bp->flags |= BNXT_FLAG_SHARED_RINGS;
bp->irq_tbl[0].vector = bp->pdev->irq;
snprintf(bp->irq_tbl[0].name, len,
"%s-%s-%d", bp->dev->name, "TxRx", 0);
@@ -4171,7 +4224,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;
@@ -4180,14 +4233,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,
@@ -4258,14 +4312,12 @@ static void bnxt_enable_napi(struct bnxt *bp)
static void bnxt_tx_disable(struct bnxt *bp)
{
int i;
- struct bnxt_napi *bnapi;
struct bnxt_tx_ring_info *txr;
struct netdev_queue *txq;
- if (bp->bnapi) {
+ if (bp->tx_ring) {
for (i = 0; i < bp->tx_nr_rings; i++) {
- bnapi = bp->bnapi[i];
- txr = &bnapi->tx_ring;
+ txr = &bp->tx_ring[i];
txq = netdev_get_tx_queue(bp->dev, i);
__netif_tx_lock(txq, smp_processor_id());
txr->dev_state = BNXT_DEV_STATE_CLOSING;
@@ -4280,13 +4332,11 @@ static void bnxt_tx_disable(struct bnxt *bp)
static void bnxt_tx_enable(struct bnxt *bp)
{
int i;
- struct bnxt_napi *bnapi;
struct bnxt_tx_ring_info *txr;
struct netdev_queue *txq;
for (i = 0; i < bp->tx_nr_rings; i++) {
- bnapi = bp->bnapi[i];
- txr = &bnapi->tx_ring;
+ txr = &bp->tx_ring[i];
txq = netdev_get_tx_queue(bp->dev, i);
txr->dev_state = 0;
}
@@ -5015,31 +5065,53 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features)
return rc;
}
+static void bnxt_dump_tx_sw_state(struct bnxt_napi *bnapi)
+{
+ struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
+ int i = bnapi->index;
+
+ if (!txr)
+ return;
+
+ netdev_info(bnapi->bp->dev, "[%d]: tx{fw_ring: %d prod: %x cons: %x}\n",
+ i, txr->tx_ring_struct.fw_ring_id, txr->tx_prod,
+ txr->tx_cons);
+}
+
+static void bnxt_dump_rx_sw_state(struct bnxt_napi *bnapi)
+{
+ struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
+ int i = bnapi->index;
+
+ if (!rxr)
+ return;
+
+ netdev_info(bnapi->bp->dev, "[%d]: rx{fw_ring: %d prod: %x} rx_agg{fw_ring: %d agg_prod: %x sw_agg_prod: %x}\n",
+ i, rxr->rx_ring_struct.fw_ring_id, rxr->rx_prod,
+ rxr->rx_agg_ring_struct.fw_ring_id, rxr->rx_agg_prod,
+ rxr->rx_sw_agg_prod);
+}
+
+static void bnxt_dump_cp_sw_state(struct bnxt_napi *bnapi)
+{
+ struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring;
+ int i = bnapi->index;
+
+ netdev_info(bnapi->bp->dev, "[%d]: cp{fw_ring: %d raw_cons: %x}\n",
+ i, cpr->cp_ring_struct.fw_ring_id, cpr->cp_raw_cons);
+}
+
static void bnxt_dbg_dump_states(struct bnxt *bp)
{
int i;
struct bnxt_napi *bnapi;
- struct bnxt_tx_ring_info *txr;
- struct bnxt_rx_ring_info *rxr;
- struct bnxt_cp_ring_info *cpr;
for (i = 0; i < bp->cp_nr_rings; i++) {
bnapi = bp->bnapi[i];
- txr = &bnapi->tx_ring;
- rxr = &bnapi->rx_ring;
- cpr = &bnapi->cp_ring;
if (netif_msg_drv(bp)) {
- netdev_info(bp->dev, "[%d]: tx{fw_ring: %d prod: %x cons: %x}\n",
- i, txr->tx_ring_struct.fw_ring_id,
- txr->tx_prod, txr->tx_cons);
- netdev_info(bp->dev, "[%d]: rx{fw_ring: %d prod: %x} rx_agg{fw_ring: %d agg_prod: %x sw_agg_prod: %x}\n",
- i, rxr->rx_ring_struct.fw_ring_id,
- rxr->rx_prod,
- rxr->rx_agg_ring_struct.fw_ring_id,
- rxr->rx_agg_prod, rxr->rx_sw_agg_prod);
- netdev_info(bp->dev, "[%d]: cp{fw_ring: %d raw_cons: %x}\n",
- i, cpr->cp_ring_struct.fw_ring_id,
- cpr->cp_raw_cons);
+ bnxt_dump_tx_sw_state(bnapi);
+ bnxt_dump_rx_sw_state(bnapi);
+ bnxt_dump_cp_sw_state(bnapi);
}
}
}
@@ -5310,10 +5382,14 @@ static int bnxt_setup_tc(struct net_device *dev, u8 tc)
return 0;
if (tc) {
- int max_rx_rings, max_tx_rings;
+ int max_rx_rings, max_tx_rings, rc;
+ bool sh = false;
+
+ if (bp->flags & BNXT_FLAG_SHARED_RINGS)
+ sh = true;
- bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings);
- if (bp->tx_nr_rings_per_tc * tc > max_tx_rings)
+ rc = bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, sh);
+ if (rc || bp->tx_nr_rings_per_tc * tc > max_tx_rings)
return -ENOMEM;
}
@@ -5627,31 +5703,62 @@ static int bnxt_get_max_irq(struct pci_dev *pdev)
return (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1;
}
-void bnxt_get_max_rings(struct bnxt *bp, int *max_rx, int *max_tx)
+static void _bnxt_get_max_rings(struct bnxt *bp, int *max_rx, int *max_tx,
+ int *max_cp)
{
- int max_rings = 0, max_ring_grps = 0;
+ int max_ring_grps = 0;
if (BNXT_PF(bp)) {
*max_tx = bp->pf.max_tx_rings;
*max_rx = bp->pf.max_rx_rings;
- max_rings = min_t(int, bp->pf.max_irqs, bp->pf.max_cp_rings);
- max_rings = min_t(int, max_rings, bp->pf.max_stat_ctxs);
+ *max_cp = min_t(int, bp->pf.max_irqs, bp->pf.max_cp_rings);
+ *max_cp = min_t(int, *max_cp, bp->pf.max_stat_ctxs);
max_ring_grps = bp->pf.max_hw_ring_grps;
} else {
#ifdef CONFIG_BNXT_SRIOV
*max_tx = bp->vf.max_tx_rings;
*max_rx = bp->vf.max_rx_rings;
- max_rings = min_t(int, bp->vf.max_irqs, bp->vf.max_cp_rings);
- max_rings = min_t(int, max_rings, bp->vf.max_stat_ctxs);
+ *max_cp = min_t(int, bp->vf.max_irqs, bp->vf.max_cp_rings);
+ *max_cp = min_t(int, *max_cp, bp->vf.max_stat_ctxs);
max_ring_grps = bp->vf.max_hw_ring_grps;
#endif
}
if (bp->flags & BNXT_FLAG_AGG_RINGS)
*max_rx >>= 1;
-
- *max_rx = min_t(int, *max_rx, max_rings);
*max_rx = min_t(int, *max_rx, max_ring_grps);
- *max_tx = min_t(int, *max_tx, max_rings);
+}
+
+int bnxt_get_max_rings(struct bnxt *bp, int *max_rx, int *max_tx, bool shared)
+{
+ int rx, tx, cp;
+
+ _bnxt_get_max_rings(bp, &rx, &tx, &cp);
+ if (!rx || !tx || !cp)
+ return -ENOMEM;
+
+ *max_rx = rx;
+ *max_tx = tx;
+ return bnxt_trim_rings(bp, max_rx, max_tx, cp, shared);
+}
+
+static int bnxt_set_dflt_rings(struct bnxt *bp)
+{
+ int dflt_rings, max_rx_rings, max_tx_rings, rc;
+ bool sh = true;
+
+ if (sh)
+ bp->flags |= BNXT_FLAG_SHARED_RINGS;
+ dflt_rings = netif_get_num_default_rss_queues();
+ rc = bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, sh);
+ if (rc)
+ return rc;
+ bp->rx_nr_rings = min_t(int, dflt_rings, max_rx_rings);
+ bp->tx_nr_rings_per_tc = min_t(int, dflt_rings, max_tx_rings);
+ bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
+ bp->cp_nr_rings = sh ? max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) :
+ bp->tx_nr_rings + bp->rx_nr_rings;
+ bp->num_stat_ctxs = bp->cp_nr_rings;
+ return rc;
}
static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -5659,7 +5766,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
static int version_printed;
struct net_device *dev;
struct bnxt *bp;
- int rc, max_rx_rings, max_tx_rings, max_irqs, dflt_rings;
+ int rc, max_irqs;
if (version_printed++ == 0)
pr_info("%s", version);
@@ -5738,19 +5845,13 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
bnxt_set_tpa_flags(bp);
bnxt_set_ring_params(bp);
- dflt_rings = netif_get_num_default_rss_queues();
if (BNXT_PF(bp))
bp->pf.max_irqs = max_irqs;
#if defined(CONFIG_BNXT_SRIOV)
else
bp->vf.max_irqs = max_irqs;
#endif
- bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings);
- bp->rx_nr_rings = min_t(int, dflt_rings, max_rx_rings);
- bp->tx_nr_rings_per_tc = min_t(int, dflt_rings, max_tx_rings);
- bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
- bp->cp_nr_rings = max_t(int, bp->rx_nr_rings, bp->tx_nr_rings);
- bp->num_stat_ctxs = bp->cp_nr_rings;
+ bnxt_set_dflt_rings(bp);
if (BNXT_PF(bp)) {
dev->hw_features |= NETIF_F_NTUPLE;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 78d639d259d1..8af3ca8efcef 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -528,6 +528,7 @@ struct tx_push_bd {
};
struct bnxt_tx_ring_info {
+ struct bnxt_napi *bnapi;
u16 tx_prod;
u16 tx_cons;
void __iomem *tx_doorbell;
@@ -558,6 +559,7 @@ struct bnxt_tpa_info {
};
struct bnxt_rx_ring_info {
+ struct bnxt_napi *bnapi;
u16 rx_prod;
u16 rx_agg_prod;
u16 rx_sw_agg_prod;
@@ -604,8 +606,8 @@ struct bnxt_napi {
int index;
struct bnxt_cp_ring_info cp_ring;
- struct bnxt_rx_ring_info rx_ring;
- struct bnxt_tx_ring_info tx_ring;
+ struct bnxt_rx_ring_info *rx_ring;
+ struct bnxt_tx_ring_info *tx_ring;
#ifdef CONFIG_NET_RX_BUSY_POLL
atomic_t poll_state;
@@ -875,6 +877,8 @@ struct bnxt {
#define BNXT_FLAG_USING_MSIX 0x40
#define BNXT_FLAG_MSIX_CAP 0x80
#define BNXT_FLAG_RFS 0x100
+ #define BNXT_FLAG_SHARED_RINGS 0x200
+
#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \
BNXT_FLAG_RFS | \
BNXT_FLAG_STRIP_VLAN)
@@ -884,6 +888,9 @@ struct bnxt {
struct bnxt_napi **bnapi;
+ struct bnxt_rx_ring_info *rx_ring;
+ struct bnxt_tx_ring_info *tx_ring;
+
u32 rx_buf_size;
u32 rx_buf_use_size; /* useable size */
u32 rx_ring_size;
@@ -913,6 +920,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;
@@ -1089,5 +1098,5 @@ int bnxt_hwrm_set_pause(struct bnxt *);
int bnxt_hwrm_set_link_setting(struct bnxt *, bool);
int bnxt_open_nic(struct bnxt *, bool, bool);
int bnxt_close_nic(struct bnxt *, bool, bool);
-void bnxt_get_max_rings(struct bnxt *, int *, int *);
+int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
#endif
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index a39511f5be75..4f62c9fa96d5 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -211,7 +211,10 @@ static void bnxt_get_channels(struct net_device *dev,
struct bnxt *bp = netdev_priv(dev);
int max_rx_rings, max_tx_rings, tcs;
- bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings);
+ bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, true);
+ channel->max_combined = max_rx_rings;
+
+ bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, false);
tcs = netdev_get_num_tc(dev);
if (tcs > 1)
max_tx_rings /= tcs;
@@ -219,9 +222,12 @@ static void bnxt_get_channels(struct net_device *dev,
channel->max_rx = max_rx_rings;
channel->max_tx = max_tx_rings;
channel->max_other = 0;
- channel->max_combined = 0;
- channel->rx_count = bp->rx_nr_rings;
- channel->tx_count = bp->tx_nr_rings_per_tc;
+ if (bp->flags & BNXT_FLAG_SHARED_RINGS) {
+ channel->combined_count = bp->rx_nr_rings;
+ } else {
+ channel->rx_count = bp->rx_nr_rings;
+ channel->tx_count = bp->tx_nr_rings_per_tc;
+ }
}
static int bnxt_set_channels(struct net_device *dev,
@@ -230,19 +236,35 @@ static int bnxt_set_channels(struct net_device *dev,
struct bnxt *bp = netdev_priv(dev);
int max_rx_rings, max_tx_rings, tcs;
u32 rc = 0;
+ bool sh = false;
+
+ if (channel->other_count)
+ return -EINVAL;
- if (channel->other_count || channel->combined_count ||
- !channel->rx_count || !channel->tx_count)
+ if (!channel->combined_count &&
+ (!channel->rx_count || !channel->tx_count))
return -EINVAL;
- bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings);
+ if (channel->combined_count &&
+ (channel->rx_count || channel->tx_count))
+ return -EINVAL;
+
+ if (channel->combined_count)
+ sh = true;
+
+ bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, sh);
+
tcs = netdev_get_num_tc(dev);
if (tcs > 1)
max_tx_rings /= tcs;
- if (channel->rx_count > max_rx_rings ||
- channel->tx_count > max_tx_rings)
- return -EINVAL;
+ if (sh && (channel->combined_count > max_rx_rings ||
+ channel->combined_count > max_tx_rings))
+ return -ENOMEM;
+
+ if (!sh && (channel->rx_count > max_rx_rings ||
+ channel->tx_count > max_tx_rings))
+ return -ENOMEM;
if (netif_running(dev)) {
if (BNXT_PF(bp)) {
@@ -258,12 +280,23 @@ static int bnxt_set_channels(struct net_device *dev,
}
}
- bp->rx_nr_rings = channel->rx_count;
- bp->tx_nr_rings_per_tc = channel->tx_count;
+ if (sh) {
+ bp->flags |= BNXT_FLAG_SHARED_RINGS;
+ bp->rx_nr_rings = channel->combined_count;
+ bp->tx_nr_rings_per_tc = channel->combined_count;
+ } else {
+ bp->flags &= ~BNXT_FLAG_SHARED_RINGS;
+ bp->rx_nr_rings = channel->rx_count;
+ bp->tx_nr_rings_per_tc = channel->tx_count;
+ }
+
bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
if (tcs > 1)
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tcs;
- bp->cp_nr_rings = max_t(int, bp->tx_nr_rings, bp->rx_nr_rings);
+
+ bp->cp_nr_rings = sh ? max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) :
+ bp->tx_nr_rings + bp->rx_nr_rings;
+
bp->num_stat_ctxs = bp->cp_nr_rings;
/* After changing number of rx channels, update NTUPLE feature. */