Skip to content

Commit 7809592

Browse files
Michael Chandavem330
authored andcommitted
bnxt_en: Enable MSIX early in bnxt_init_one().
To better support the new RDMA driver, we need to move pci_enable_msix() from bnxt_open() to bnxt_init_one(). This way, MSIX vectors are available to the RDMA driver whether the network device is up or down. Part of the existing bnxt_setup_int_mode() function is now refactored into a new bnxt_init_int_mode(). bnxt_init_int_mode() is called during bnxt_init_one() to enable MSIX. The remaining logic in bnxt_setup_int_mode() to map the IRQs to the completion rings is called during bnxt_open(). v2: Fixed compile warning when CONFIG_BNXT_SRIOV is not set. Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 33c2657 commit 7809592

File tree

2 files changed

+115
-69
lines changed

2 files changed

+115
-69
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 114 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4743,6 +4743,80 @@ static int bnxt_trim_rings(struct bnxt *bp, int *rx, int *tx, int max,
47434743
return 0;
47444744
}
47454745

4746+
static void bnxt_setup_msix(struct bnxt *bp)
4747+
{
4748+
const int len = sizeof(bp->irq_tbl[0].name);
4749+
struct net_device *dev = bp->dev;
4750+
int tcs, i;
4751+
4752+
tcs = netdev_get_num_tc(dev);
4753+
if (tcs > 1) {
4754+
bp->tx_nr_rings_per_tc = bp->tx_nr_rings / tcs;
4755+
if (bp->tx_nr_rings_per_tc == 0) {
4756+
netdev_reset_tc(dev);
4757+
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
4758+
} else {
4759+
int i, off, count;
4760+
4761+
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tcs;
4762+
for (i = 0; i < tcs; i++) {
4763+
count = bp->tx_nr_rings_per_tc;
4764+
off = i * count;
4765+
netdev_set_tc_queue(dev, i, count, off);
4766+
}
4767+
}
4768+
}
4769+
4770+
for (i = 0; i < bp->cp_nr_rings; i++) {
4771+
char *attr;
4772+
4773+
if (bp->flags & BNXT_FLAG_SHARED_RINGS)
4774+
attr = "TxRx";
4775+
else if (i < bp->rx_nr_rings)
4776+
attr = "rx";
4777+
else
4778+
attr = "tx";
4779+
4780+
snprintf(bp->irq_tbl[i].name, len, "%s-%s-%d", dev->name, attr,
4781+
i);
4782+
bp->irq_tbl[i].handler = bnxt_msix;
4783+
}
4784+
}
4785+
4786+
static void bnxt_setup_inta(struct bnxt *bp)
4787+
{
4788+
const int len = sizeof(bp->irq_tbl[0].name);
4789+
4790+
if (netdev_get_num_tc(bp->dev))
4791+
netdev_reset_tc(bp->dev);
4792+
4793+
snprintf(bp->irq_tbl[0].name, len, "%s-%s-%d", bp->dev->name, "TxRx",
4794+
0);
4795+
bp->irq_tbl[0].handler = bnxt_inta;
4796+
}
4797+
4798+
static int bnxt_setup_int_mode(struct bnxt *bp)
4799+
{
4800+
int rc;
4801+
4802+
if (bp->flags & BNXT_FLAG_USING_MSIX)
4803+
bnxt_setup_msix(bp);
4804+
else
4805+
bnxt_setup_inta(bp);
4806+
4807+
rc = bnxt_set_real_num_queues(bp);
4808+
return rc;
4809+
}
4810+
4811+
static unsigned int bnxt_get_max_func_irqs(struct bnxt *bp)
4812+
{
4813+
#if defined(CONFIG_BNXT_SRIOV)
4814+
if (BNXT_VF(bp))
4815+
return bp->vf.max_irqs;
4816+
#endif
4817+
return bp->pf.max_irqs;
4818+
}
4819+
47464820
void bnxt_set_max_func_irqs(struct bnxt *bp, unsigned int max_irqs)
47474821
{
47484822
#if defined(CONFIG_BNXT_SRIOV)
@@ -4753,16 +4827,12 @@ void bnxt_set_max_func_irqs(struct bnxt *bp, unsigned int max_irqs)
47534827
bp->pf.max_irqs = max_irqs;
47544828
}
47554829

4756-
static int bnxt_setup_msix(struct bnxt *bp)
4830+
static int bnxt_init_msix(struct bnxt *bp)
47574831
{
4758-
struct msix_entry *msix_ent;
4759-
struct net_device *dev = bp->dev;
47604832
int i, total_vecs, rc = 0, min = 1;
4761-
const int len = sizeof(bp->irq_tbl[0].name);
4762-
4763-
bp->flags &= ~BNXT_FLAG_USING_MSIX;
4764-
total_vecs = bp->cp_nr_rings;
4833+
struct msix_entry *msix_ent;
47654834

4835+
total_vecs = bnxt_get_max_func_irqs(bp);
47664836
msix_ent = kcalloc(total_vecs, sizeof(struct msix_entry), GFP_KERNEL);
47674837
if (!msix_ent)
47684838
return -ENOMEM;
@@ -4783,52 +4853,21 @@ static int bnxt_setup_msix(struct bnxt *bp)
47834853

47844854
bp->irq_tbl = kcalloc(total_vecs, sizeof(struct bnxt_irq), GFP_KERNEL);
47854855
if (bp->irq_tbl) {
4786-
int tcs;
4856+
for (i = 0; i < total_vecs; i++)
4857+
bp->irq_tbl[i].vector = msix_ent[i].vector;
47874858

4859+
bp->total_irqs = total_vecs;
47884860
/* Trim rings based upon num of vectors allocated */
47894861
rc = bnxt_trim_rings(bp, &bp->rx_nr_rings, &bp->tx_nr_rings,
47904862
total_vecs, min == 1);
47914863
if (rc)
47924864
goto msix_setup_exit;
47934865

47944866
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
4795-
tcs = netdev_get_num_tc(dev);
4796-
if (tcs > 1) {
4797-
bp->tx_nr_rings_per_tc = bp->tx_nr_rings / tcs;
4798-
if (bp->tx_nr_rings_per_tc == 0) {
4799-
netdev_reset_tc(dev);
4800-
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
4801-
} else {
4802-
int i, off, count;
4867+
bp->cp_nr_rings = (min == 1) ?
4868+
max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) :
4869+
bp->tx_nr_rings + bp->rx_nr_rings;
48034870

4804-
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tcs;
4805-
for (i = 0; i < tcs; i++) {
4806-
count = bp->tx_nr_rings_per_tc;
4807-
off = i * count;
4808-
netdev_set_tc_queue(dev, i, count, off);
4809-
}
4810-
}
4811-
}
4812-
bp->cp_nr_rings = total_vecs;
4813-
4814-
for (i = 0; i < bp->cp_nr_rings; i++) {
4815-
char *attr;
4816-
4817-
bp->irq_tbl[i].vector = msix_ent[i].vector;
4818-
if (bp->flags & BNXT_FLAG_SHARED_RINGS)
4819-
attr = "TxRx";
4820-
else if (i < bp->rx_nr_rings)
4821-
attr = "rx";
4822-
else
4823-
attr = "tx";
4824-
4825-
snprintf(bp->irq_tbl[i].name, len,
4826-
"%s-%s-%d", dev->name, attr, i);
4827-
bp->irq_tbl[i].handler = bnxt_msix;
4828-
}
4829-
rc = bnxt_set_real_num_queues(bp);
4830-
if (rc)
4831-
goto msix_setup_exit;
48324871
} else {
48334872
rc = -ENOMEM;
48344873
goto msix_setup_exit;
@@ -4838,52 +4877,54 @@ static int bnxt_setup_msix(struct bnxt *bp)
48384877
return 0;
48394878

48404879
msix_setup_exit:
4841-
netdev_err(bp->dev, "bnxt_setup_msix err: %x\n", rc);
4880+
netdev_err(bp->dev, "bnxt_init_msix err: %x\n", rc);
4881+
kfree(bp->irq_tbl);
4882+
bp->irq_tbl = NULL;
48424883
pci_disable_msix(bp->pdev);
48434884
kfree(msix_ent);
48444885
return rc;
48454886
}
48464887

4847-
static int bnxt_setup_inta(struct bnxt *bp)
4888+
static int bnxt_init_inta(struct bnxt *bp)
48484889
{
4849-
int rc;
4850-
const int len = sizeof(bp->irq_tbl[0].name);
4851-
4852-
if (netdev_get_num_tc(bp->dev))
4853-
netdev_reset_tc(bp->dev);
4854-
48554890
bp->irq_tbl = kcalloc(1, sizeof(struct bnxt_irq), GFP_KERNEL);
4856-
if (!bp->irq_tbl) {
4857-
rc = -ENOMEM;
4858-
return rc;
4859-
}
4891+
if (!bp->irq_tbl)
4892+
return -ENOMEM;
4893+
4894+
bp->total_irqs = 1;
48604895
bp->rx_nr_rings = 1;
48614896
bp->tx_nr_rings = 1;
48624897
bp->cp_nr_rings = 1;
48634898
bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
48644899
bp->flags |= BNXT_FLAG_SHARED_RINGS;
48654900
bp->irq_tbl[0].vector = bp->pdev->irq;
4866-
snprintf(bp->irq_tbl[0].name, len,
4867-
"%s-%s-%d", bp->dev->name, "TxRx", 0);
4868-
bp->irq_tbl[0].handler = bnxt_inta;
4869-
rc = bnxt_set_real_num_queues(bp);
4870-
return rc;
4901+
return 0;
48714902
}
48724903

4873-
static int bnxt_setup_int_mode(struct bnxt *bp)
4904+
static int bnxt_init_int_mode(struct bnxt *bp)
48744905
{
48754906
int rc = 0;
48764907

48774908
if (bp->flags & BNXT_FLAG_MSIX_CAP)
4878-
rc = bnxt_setup_msix(bp);
4909+
rc = bnxt_init_msix(bp);
48794910

48804911
if (!(bp->flags & BNXT_FLAG_USING_MSIX) && BNXT_PF(bp)) {
48814912
/* fallback to INTA */
4882-
rc = bnxt_setup_inta(bp);
4913+
rc = bnxt_init_inta(bp);
48834914
}
48844915
return rc;
48854916
}
48864917

4918+
static void bnxt_clear_int_mode(struct bnxt *bp)
4919+
{
4920+
if (bp->flags & BNXT_FLAG_USING_MSIX)
4921+
pci_disable_msix(bp->pdev);
4922+
4923+
kfree(bp->irq_tbl);
4924+
bp->irq_tbl = NULL;
4925+
bp->flags &= ~BNXT_FLAG_USING_MSIX;
4926+
}
4927+
48874928
static void bnxt_free_irq(struct bnxt *bp)
48884929
{
48894930
struct bnxt_irq *irq;
@@ -4902,10 +4943,6 @@ static void bnxt_free_irq(struct bnxt *bp)
49024943
free_irq(irq->vector, bp->bnapi[i]);
49034944
irq->requested = 0;
49044945
}
4905-
if (bp->flags & BNXT_FLAG_USING_MSIX)
4906-
pci_disable_msix(bp->pdev);
4907-
kfree(bp->irq_tbl);
4908-
bp->irq_tbl = NULL;
49094946
}
49104947

49114948
static int bnxt_request_irq(struct bnxt *bp)
@@ -6695,6 +6732,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
66956732
cancel_work_sync(&bp->sp_task);
66966733
bp->sp_event = 0;
66976734

6735+
bnxt_clear_int_mode(bp);
66986736
bnxt_hwrm_func_drv_unrgtr(bp);
66996737
bnxt_free_hwrm_resources(bp);
67006738
bnxt_dcb_free(bp);
@@ -6990,10 +7028,14 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
69907028
if (rc)
69917029
goto init_err;
69927030

6993-
rc = register_netdev(dev);
7031+
rc = bnxt_init_int_mode(bp);
69947032
if (rc)
69957033
goto init_err;
69967034

7035+
rc = register_netdev(dev);
7036+
if (rc)
7037+
goto init_err_clr_int;
7038+
69977039
netdev_info(dev, "%s found at mem %lx, node addr %pM\n",
69987040
board_info[ent->driver_data].name,
69997041
(long)pci_resource_start(pdev, 0), dev->dev_addr);
@@ -7002,6 +7044,9 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
70027044

70037045
return 0;
70047046

7047+
init_err_clr_int:
7048+
bnxt_clear_int_mode(bp);
7049+
70057050
init_err:
70067051
pci_iounmap(pdev, bp->bar0);
70077052
pci_release_regions(pdev);

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,7 @@ struct bnxt {
10241024
#define BNXT_STATE_FN_RST_DONE 2
10251025

10261026
struct bnxt_irq *irq_tbl;
1027+
int total_irqs;
10271028
u8 mac_addr[ETH_ALEN];
10281029

10291030
#ifdef CONFIG_BNXT_DCB

0 commit comments

Comments
 (0)