aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
diff options
context:
space:
mode:
authorDmitry Kravkov <dmitry@broadcom.com>2012-04-03 14:41:26 -0400
committerDavid S. Miller <davem@davemloft.net>2012-04-04 01:37:58 -0400
commit30a5de7723a8a4211be02e94236e9167a424fd07 (patch)
treedf59305dbb4326c2d5675842bb222c565904081d /drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
parent79a8557a6d18c3861d64ae110ddd7606c65d7504 (diff)
bnx2x: added support for working with one msix irq.
Until now, the bnx2x driver needed at least 2 available msix interrupt vectors in order to use msix. This patch add the possibility of configuring msix when only one interrupt vector is available. Notice this patch contains lines with over 80 characters, as it keeps print strings in a single line. Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c66
1 files changed, 45 insertions, 21 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 02e14a34b378..6013d411c9f3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1211,16 +1211,15 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp, int nvecs)
1211 1211
1212void bnx2x_free_irq(struct bnx2x *bp) 1212void bnx2x_free_irq(struct bnx2x *bp)
1213{ 1213{
1214 if (bp->flags & USING_MSIX_FLAG) 1214 if (bp->flags & USING_MSIX_FLAG &&
1215 !(bp->flags & USING_SINGLE_MSIX_FLAG))
1215 bnx2x_free_msix_irqs(bp, BNX2X_NUM_ETH_QUEUES(bp) + 1216 bnx2x_free_msix_irqs(bp, BNX2X_NUM_ETH_QUEUES(bp) +
1216 CNIC_PRESENT + 1); 1217 CNIC_PRESENT + 1);
1217 else if (bp->flags & USING_MSI_FLAG)
1218 free_irq(bp->pdev->irq, bp->dev);
1219 else 1218 else
1220 free_irq(bp->pdev->irq, bp->dev); 1219 free_irq(bp->dev->irq, bp->dev);
1221} 1220}
1222 1221
1223int bnx2x_enable_msix(struct bnx2x *bp) 1222int __devinit bnx2x_enable_msix(struct bnx2x *bp)
1224{ 1223{
1225 int msix_vec = 0, i, rc, req_cnt; 1224 int msix_vec = 0, i, rc, req_cnt;
1226 1225
@@ -1260,8 +1259,8 @@ int bnx2x_enable_msix(struct bnx2x *bp)
1260 rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], rc); 1259 rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], rc);
1261 1260
1262 if (rc) { 1261 if (rc) {
1263 BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); 1262 BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
1264 return rc; 1263 goto no_msix;
1265 } 1264 }
1266 /* 1265 /*
1267 * decrease number of queues by number of unallocated entries 1266 * decrease number of queues by number of unallocated entries
@@ -1269,18 +1268,34 @@ int bnx2x_enable_msix(struct bnx2x *bp)
1269 bp->num_queues -= diff; 1268 bp->num_queues -= diff;
1270 1269
1271 BNX2X_DEV_INFO("New queue configuration set: %d\n", 1270 BNX2X_DEV_INFO("New queue configuration set: %d\n",
1272 bp->num_queues); 1271 bp->num_queues);
1273 } else if (rc) { 1272 } else if (rc > 0) {
1274 /* fall to INTx if not enough memory */ 1273 /* Get by with single vector */
1275 if (rc == -ENOMEM) 1274 rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], 1);
1276 bp->flags |= DISABLE_MSI_FLAG; 1275 if (rc) {
1276 BNX2X_DEV_INFO("Single MSI-X is not attainable rc %d\n",
1277 rc);
1278 goto no_msix;
1279 }
1280
1281 BNX2X_DEV_INFO("Using single MSI-X vector\n");
1282 bp->flags |= USING_SINGLE_MSIX_FLAG;
1283
1284 } else if (rc < 0) {
1277 BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc); 1285 BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
1278 return rc; 1286 goto no_msix;
1279 } 1287 }
1280 1288
1281 bp->flags |= USING_MSIX_FLAG; 1289 bp->flags |= USING_MSIX_FLAG;
1282 1290
1283 return 0; 1291 return 0;
1292
1293no_msix:
1294 /* fall to INTx if not enough memory */
1295 if (rc == -ENOMEM)
1296 bp->flags |= DISABLE_MSI_FLAG;
1297
1298 return rc;
1284} 1299}
1285 1300
1286static int bnx2x_req_msix_irqs(struct bnx2x *bp) 1301static int bnx2x_req_msix_irqs(struct bnx2x *bp)
@@ -1342,22 +1357,26 @@ int bnx2x_enable_msi(struct bnx2x *bp)
1342static int bnx2x_req_irq(struct bnx2x *bp) 1357static int bnx2x_req_irq(struct bnx2x *bp)
1343{ 1358{
1344 unsigned long flags; 1359 unsigned long flags;
1345 int rc; 1360 unsigned int irq;
1346 1361
1347 if (bp->flags & USING_MSI_FLAG) 1362 if (bp->flags & (USING_MSI_FLAG | USING_MSIX_FLAG))
1348 flags = 0; 1363 flags = 0;
1349 else 1364 else
1350 flags = IRQF_SHARED; 1365 flags = IRQF_SHARED;
1351 1366
1352 rc = request_irq(bp->pdev->irq, bnx2x_interrupt, flags, 1367 if (bp->flags & USING_MSIX_FLAG)
1353 bp->dev->name, bp->dev); 1368 irq = bp->msix_table[0].vector;
1354 return rc; 1369 else
1370 irq = bp->pdev->irq;
1371
1372 return request_irq(irq, bnx2x_interrupt, flags, bp->dev->name, bp->dev);
1355} 1373}
1356 1374
1357static inline int bnx2x_setup_irqs(struct bnx2x *bp) 1375static inline int bnx2x_setup_irqs(struct bnx2x *bp)
1358{ 1376{
1359 int rc = 0; 1377 int rc = 0;
1360 if (bp->flags & USING_MSIX_FLAG) { 1378 if (bp->flags & USING_MSIX_FLAG &&
1379 !(bp->flags & USING_SINGLE_MSIX_FLAG)) {
1361 rc = bnx2x_req_msix_irqs(bp); 1380 rc = bnx2x_req_msix_irqs(bp);
1362 if (rc) 1381 if (rc)
1363 return rc; 1382 return rc;
@@ -1370,8 +1389,13 @@ static inline int bnx2x_setup_irqs(struct bnx2x *bp)
1370 } 1389 }
1371 if (bp->flags & USING_MSI_FLAG) { 1390 if (bp->flags & USING_MSI_FLAG) {
1372 bp->dev->irq = bp->pdev->irq; 1391 bp->dev->irq = bp->pdev->irq;
1373 netdev_info(bp->dev, "using MSI IRQ %d\n", 1392 netdev_info(bp->dev, "using MSI IRQ %d\n",
1374 bp->pdev->irq); 1393 bp->dev->irq);
1394 }
1395 if (bp->flags & USING_MSIX_FLAG) {
1396 bp->dev->irq = bp->msix_table[0].vector;
1397 netdev_info(bp->dev, "using MSIX IRQ %d\n",
1398 bp->dev->irq);
1375 } 1399 }
1376 } 1400 }
1377 1401