diff options
author | Dmitry Kravkov <dmitry@broadcom.com> | 2012-04-03 14:41:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-04-04 01:37:58 -0400 |
commit | 30a5de7723a8a4211be02e94236e9167a424fd07 (patch) | |
tree | df59305dbb4326c2d5675842bb222c565904081d /drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |
parent | 79a8557a6d18c3861d64ae110ddd7606c65d7504 (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.c | 66 |
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 | ||
1212 | void bnx2x_free_irq(struct bnx2x *bp) | 1212 | void 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 | ||
1223 | int bnx2x_enable_msix(struct bnx2x *bp) | 1222 | int __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 | |||
1293 | no_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 | ||
1286 | static int bnx2x_req_msix_irqs(struct bnx2x *bp) | 1301 | static int bnx2x_req_msix_irqs(struct bnx2x *bp) |
@@ -1342,22 +1357,26 @@ int bnx2x_enable_msi(struct bnx2x *bp) | |||
1342 | static int bnx2x_req_irq(struct bnx2x *bp) | 1357 | static 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 | ||
1357 | static inline int bnx2x_setup_irqs(struct bnx2x *bp) | 1375 | static 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 | ||