diff options
author | Michael Chan <mchan@broadcom.com> | 2006-11-19 17:10:45 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:24:26 -0500 |
commit | 59b47d8ad35b9858d63d6fd3db76e698e4a98f36 (patch) | |
tree | fe7d9a55df98a9327b252a57fc050c215c352c80 /drivers/net/bnx2.c | |
parent | 9052a840fffa2f565ed13e6ecd53fbe2532d51b9 (diff) |
[BNX2]: Add 5709 init code.
Add basic support to initialize the 5709 chip.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 167 |
1 files changed, 130 insertions, 37 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 2633579b8c43..baad015b3d6d 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -236,8 +236,23 @@ static void | |||
236 | bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) | 236 | bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) |
237 | { | 237 | { |
238 | offset += cid_addr; | 238 | offset += cid_addr; |
239 | REG_WR(bp, BNX2_CTX_DATA_ADR, offset); | 239 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { |
240 | REG_WR(bp, BNX2_CTX_DATA, val); | 240 | int i; |
241 | |||
242 | REG_WR(bp, BNX2_CTX_CTX_DATA, val); | ||
243 | REG_WR(bp, BNX2_CTX_CTX_CTRL, | ||
244 | offset | BNX2_CTX_CTX_CTRL_WRITE_REQ); | ||
245 | for (i = 0; i < 5; i++) { | ||
246 | u32 val; | ||
247 | val = REG_RD(bp, BNX2_CTX_CTX_CTRL); | ||
248 | if ((val & BNX2_CTX_CTX_CTRL_WRITE_REQ) == 0) | ||
249 | break; | ||
250 | udelay(5); | ||
251 | } | ||
252 | } else { | ||
253 | REG_WR(bp, BNX2_CTX_DATA_ADR, offset); | ||
254 | REG_WR(bp, BNX2_CTX_DATA, val); | ||
255 | } | ||
241 | } | 256 | } |
242 | 257 | ||
243 | static int | 258 | static int |
@@ -403,6 +418,14 @@ bnx2_free_mem(struct bnx2 *bp) | |||
403 | { | 418 | { |
404 | int i; | 419 | int i; |
405 | 420 | ||
421 | for (i = 0; i < bp->ctx_pages; i++) { | ||
422 | if (bp->ctx_blk[i]) { | ||
423 | pci_free_consistent(bp->pdev, BCM_PAGE_SIZE, | ||
424 | bp->ctx_blk[i], | ||
425 | bp->ctx_blk_mapping[i]); | ||
426 | bp->ctx_blk[i] = NULL; | ||
427 | } | ||
428 | } | ||
406 | if (bp->status_blk) { | 429 | if (bp->status_blk) { |
407 | pci_free_consistent(bp->pdev, bp->status_stats_size, | 430 | pci_free_consistent(bp->pdev, bp->status_stats_size, |
408 | bp->status_blk, bp->status_blk_mapping); | 431 | bp->status_blk, bp->status_blk_mapping); |
@@ -481,6 +504,18 @@ bnx2_alloc_mem(struct bnx2 *bp) | |||
481 | 504 | ||
482 | bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size; | 505 | bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size; |
483 | 506 | ||
507 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | ||
508 | bp->ctx_pages = 0x2000 / BCM_PAGE_SIZE; | ||
509 | if (bp->ctx_pages == 0) | ||
510 | bp->ctx_pages = 1; | ||
511 | for (i = 0; i < bp->ctx_pages; i++) { | ||
512 | bp->ctx_blk[i] = pci_alloc_consistent(bp->pdev, | ||
513 | BCM_PAGE_SIZE, | ||
514 | &bp->ctx_blk_mapping[i]); | ||
515 | if (bp->ctx_blk[i] == NULL) | ||
516 | goto alloc_mem_err; | ||
517 | } | ||
518 | } | ||
484 | return 0; | 519 | return 0; |
485 | 520 | ||
486 | alloc_mem_err: | 521 | alloc_mem_err: |
@@ -803,13 +838,13 @@ bnx2_set_mac_link(struct bnx2 *bp) | |||
803 | 838 | ||
804 | val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | | 839 | val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | |
805 | BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | | 840 | BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | |
806 | BNX2_EMAC_MODE_25G); | 841 | BNX2_EMAC_MODE_25G_MODE); |
807 | 842 | ||
808 | if (bp->link_up) { | 843 | if (bp->link_up) { |
809 | switch (bp->line_speed) { | 844 | switch (bp->line_speed) { |
810 | case SPEED_10: | 845 | case SPEED_10: |
811 | if (CHIP_NUM(bp) == CHIP_NUM_5708) { | 846 | if (CHIP_NUM(bp) != CHIP_NUM_5706) { |
812 | val |= BNX2_EMAC_MODE_PORT_MII_10; | 847 | val |= BNX2_EMAC_MODE_PORT_MII_10M; |
813 | break; | 848 | break; |
814 | } | 849 | } |
815 | /* fall through */ | 850 | /* fall through */ |
@@ -817,7 +852,7 @@ bnx2_set_mac_link(struct bnx2 *bp) | |||
817 | val |= BNX2_EMAC_MODE_PORT_MII; | 852 | val |= BNX2_EMAC_MODE_PORT_MII; |
818 | break; | 853 | break; |
819 | case SPEED_2500: | 854 | case SPEED_2500: |
820 | val |= BNX2_EMAC_MODE_25G; | 855 | val |= BNX2_EMAC_MODE_25G_MODE; |
821 | /* fall through */ | 856 | /* fall through */ |
822 | case SPEED_1000: | 857 | case SPEED_1000: |
823 | val |= BNX2_EMAC_MODE_PORT_GMII; | 858 | val |= BNX2_EMAC_MODE_PORT_GMII; |
@@ -1263,9 +1298,8 @@ bnx2_init_5706s_phy(struct bnx2 *bp) | |||
1263 | { | 1298 | { |
1264 | bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; | 1299 | bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; |
1265 | 1300 | ||
1266 | if (CHIP_NUM(bp) == CHIP_NUM_5706) { | 1301 | if (CHIP_NUM(bp) == CHIP_NUM_5706) |
1267 | REG_WR(bp, BNX2_MISC_UNUSED0, 0x300); | 1302 | REG_WR(bp, BNX2_MISC_GP_HW_CTL0, 0x300); |
1268 | } | ||
1269 | 1303 | ||
1270 | if (bp->dev->mtu > 1500) { | 1304 | if (bp->dev->mtu > 1500) { |
1271 | u32 val; | 1305 | u32 val; |
@@ -1408,7 +1442,7 @@ bnx2_set_phy_loopback(struct bnx2 *bp) | |||
1408 | mac_mode = REG_RD(bp, BNX2_EMAC_MODE); | 1442 | mac_mode = REG_RD(bp, BNX2_EMAC_MODE); |
1409 | mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | | 1443 | mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | |
1410 | BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | | 1444 | BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | |
1411 | BNX2_EMAC_MODE_25G); | 1445 | BNX2_EMAC_MODE_25G_MODE); |
1412 | 1446 | ||
1413 | mac_mode |= BNX2_EMAC_MODE_PORT_GMII; | 1447 | mac_mode |= BNX2_EMAC_MODE_PORT_GMII; |
1414 | REG_WR(bp, BNX2_EMAC_MODE, mac_mode); | 1448 | REG_WR(bp, BNX2_EMAC_MODE, mac_mode); |
@@ -1459,6 +1493,40 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent) | |||
1459 | return 0; | 1493 | return 0; |
1460 | } | 1494 | } |
1461 | 1495 | ||
1496 | static int | ||
1497 | bnx2_init_5709_context(struct bnx2 *bp) | ||
1498 | { | ||
1499 | int i, ret = 0; | ||
1500 | u32 val; | ||
1501 | |||
1502 | val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12); | ||
1503 | val |= (BCM_PAGE_BITS - 8) << 16; | ||
1504 | REG_WR(bp, BNX2_CTX_COMMAND, val); | ||
1505 | for (i = 0; i < bp->ctx_pages; i++) { | ||
1506 | int j; | ||
1507 | |||
1508 | REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA0, | ||
1509 | (bp->ctx_blk_mapping[i] & 0xffffffff) | | ||
1510 | BNX2_CTX_HOST_PAGE_TBL_DATA0_VALID); | ||
1511 | REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_DATA1, | ||
1512 | (u64) bp->ctx_blk_mapping[i] >> 32); | ||
1513 | REG_WR(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL, i | | ||
1514 | BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ); | ||
1515 | for (j = 0; j < 10; j++) { | ||
1516 | |||
1517 | val = REG_RD(bp, BNX2_CTX_HOST_PAGE_TBL_CTRL); | ||
1518 | if (!(val & BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ)) | ||
1519 | break; | ||
1520 | udelay(5); | ||
1521 | } | ||
1522 | if (val & BNX2_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) { | ||
1523 | ret = -EBUSY; | ||
1524 | break; | ||
1525 | } | ||
1526 | } | ||
1527 | return ret; | ||
1528 | } | ||
1529 | |||
1462 | static void | 1530 | static void |
1463 | bnx2_init_context(struct bnx2 *bp) | 1531 | bnx2_init_context(struct bnx2 *bp) |
1464 | { | 1532 | { |
@@ -1581,9 +1649,8 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index) | |||
1581 | return -ENOMEM; | 1649 | return -ENOMEM; |
1582 | } | 1650 | } |
1583 | 1651 | ||
1584 | if (unlikely((align = (unsigned long) skb->data & 0x7))) { | 1652 | if (unlikely((align = (unsigned long) skb->data & (BNX2_RX_ALIGN - 1)))) |
1585 | skb_reserve(skb, 8 - align); | 1653 | skb_reserve(skb, BNX2_RX_ALIGN - align); |
1586 | } | ||
1587 | 1654 | ||
1588 | mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, | 1655 | mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, |
1589 | PCI_DMA_FROMDEVICE); | 1656 | PCI_DMA_FROMDEVICE); |
@@ -3282,7 +3349,10 @@ bnx2_init_chip(struct bnx2 *bp) | |||
3282 | 3349 | ||
3283 | /* Initialize context mapping and zero out the quick contexts. The | 3350 | /* Initialize context mapping and zero out the quick contexts. The |
3284 | * context block must have already been enabled. */ | 3351 | * context block must have already been enabled. */ |
3285 | bnx2_init_context(bp); | 3352 | if (CHIP_NUM(bp) == CHIP_NUM_5709) |
3353 | bnx2_init_5709_context(bp); | ||
3354 | else | ||
3355 | bnx2_init_context(bp); | ||
3286 | 3356 | ||
3287 | if ((rc = bnx2_init_cpus(bp)) != 0) | 3357 | if ((rc = bnx2_init_cpus(bp)) != 0) |
3288 | return rc; | 3358 | return rc; |
@@ -3393,12 +3463,40 @@ bnx2_init_chip(struct bnx2 *bp) | |||
3393 | return rc; | 3463 | return rc; |
3394 | } | 3464 | } |
3395 | 3465 | ||
3466 | static void | ||
3467 | bnx2_init_tx_context(struct bnx2 *bp, u32 cid) | ||
3468 | { | ||
3469 | u32 val, offset0, offset1, offset2, offset3; | ||
3470 | |||
3471 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | ||
3472 | offset0 = BNX2_L2CTX_TYPE_XI; | ||
3473 | offset1 = BNX2_L2CTX_CMD_TYPE_XI; | ||
3474 | offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI; | ||
3475 | offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI; | ||
3476 | } else { | ||
3477 | offset0 = BNX2_L2CTX_TYPE; | ||
3478 | offset1 = BNX2_L2CTX_CMD_TYPE; | ||
3479 | offset2 = BNX2_L2CTX_TBDR_BHADDR_HI; | ||
3480 | offset3 = BNX2_L2CTX_TBDR_BHADDR_LO; | ||
3481 | } | ||
3482 | val = BNX2_L2CTX_TYPE_TYPE_L2 | BNX2_L2CTX_TYPE_SIZE_L2; | ||
3483 | CTX_WR(bp, GET_CID_ADDR(cid), offset0, val); | ||
3484 | |||
3485 | val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16); | ||
3486 | CTX_WR(bp, GET_CID_ADDR(cid), offset1, val); | ||
3487 | |||
3488 | val = (u64) bp->tx_desc_mapping >> 32; | ||
3489 | CTX_WR(bp, GET_CID_ADDR(cid), offset2, val); | ||
3490 | |||
3491 | val = (u64) bp->tx_desc_mapping & 0xffffffff; | ||
3492 | CTX_WR(bp, GET_CID_ADDR(cid), offset3, val); | ||
3493 | } | ||
3396 | 3494 | ||
3397 | static void | 3495 | static void |
3398 | bnx2_init_tx_ring(struct bnx2 *bp) | 3496 | bnx2_init_tx_ring(struct bnx2 *bp) |
3399 | { | 3497 | { |
3400 | struct tx_bd *txbd; | 3498 | struct tx_bd *txbd; |
3401 | u32 val; | 3499 | u32 cid; |
3402 | 3500 | ||
3403 | bp->tx_wake_thresh = bp->tx_ring_size / 2; | 3501 | bp->tx_wake_thresh = bp->tx_ring_size / 2; |
3404 | 3502 | ||
@@ -3412,19 +3510,11 @@ bnx2_init_tx_ring(struct bnx2 *bp) | |||
3412 | bp->hw_tx_cons = 0; | 3510 | bp->hw_tx_cons = 0; |
3413 | bp->tx_prod_bseq = 0; | 3511 | bp->tx_prod_bseq = 0; |
3414 | 3512 | ||
3415 | val = BNX2_L2CTX_TYPE_TYPE_L2; | 3513 | cid = TX_CID; |
3416 | val |= BNX2_L2CTX_TYPE_SIZE_L2; | 3514 | bp->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX; |
3417 | CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val); | 3515 | bp->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ; |
3418 | 3516 | ||
3419 | val = BNX2_L2CTX_CMD_TYPE_TYPE_L2; | 3517 | bnx2_init_tx_context(bp, cid); |
3420 | val |= 8 << 16; | ||
3421 | CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val); | ||
3422 | |||
3423 | val = (u64) bp->tx_desc_mapping >> 32; | ||
3424 | CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, val); | ||
3425 | |||
3426 | val = (u64) bp->tx_desc_mapping & 0xffffffff; | ||
3427 | CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val); | ||
3428 | } | 3518 | } |
3429 | 3519 | ||
3430 | static void | 3520 | static void |
@@ -3437,8 +3527,8 @@ bnx2_init_rx_ring(struct bnx2 *bp) | |||
3437 | 3527 | ||
3438 | /* 8 for CRC and VLAN */ | 3528 | /* 8 for CRC and VLAN */ |
3439 | bp->rx_buf_use_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8; | 3529 | bp->rx_buf_use_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8; |
3440 | /* 8 for alignment */ | 3530 | /* hw alignment */ |
3441 | bp->rx_buf_size = bp->rx_buf_use_size + 8; | 3531 | bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN; |
3442 | 3532 | ||
3443 | ring_prod = prod = bp->rx_prod = 0; | 3533 | ring_prod = prod = bp->rx_prod = 0; |
3444 | bp->rx_cons = 0; | 3534 | bp->rx_cons = 0; |
@@ -5542,13 +5632,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5542 | goto err_out_release; | 5632 | goto err_out_release; |
5543 | } | 5633 | } |
5544 | 5634 | ||
5545 | bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); | ||
5546 | if (bp->pcix_cap == 0) { | ||
5547 | dev_err(&pdev->dev, "Cannot find PCIX capability, aborting.\n"); | ||
5548 | rc = -EIO; | ||
5549 | goto err_out_release; | ||
5550 | } | ||
5551 | |||
5552 | if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) { | 5635 | if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) { |
5553 | bp->flags |= USING_DAC_FLAG; | 5636 | bp->flags |= USING_DAC_FLAG; |
5554 | if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) { | 5637 | if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) { |
@@ -5571,7 +5654,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5571 | INIT_WORK(&bp->reset_task, bnx2_reset_task, bp); | 5654 | INIT_WORK(&bp->reset_task, bnx2_reset_task, bp); |
5572 | 5655 | ||
5573 | dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); | 5656 | dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); |
5574 | mem_len = MB_GET_CID_ADDR(17); | 5657 | mem_len = MB_GET_CID_ADDR(TX_TSS_CID + 1); |
5575 | dev->mem_end = dev->mem_start + mem_len; | 5658 | dev->mem_end = dev->mem_start + mem_len; |
5576 | dev->irq = pdev->irq; | 5659 | dev->irq = pdev->irq; |
5577 | 5660 | ||
@@ -5595,6 +5678,16 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5595 | 5678 | ||
5596 | bp->chip_id = REG_RD(bp, BNX2_MISC_ID); | 5679 | bp->chip_id = REG_RD(bp, BNX2_MISC_ID); |
5597 | 5680 | ||
5681 | if (CHIP_NUM(bp) != CHIP_NUM_5709) { | ||
5682 | bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); | ||
5683 | if (bp->pcix_cap == 0) { | ||
5684 | dev_err(&pdev->dev, | ||
5685 | "Cannot find PCIX capability, aborting.\n"); | ||
5686 | rc = -EIO; | ||
5687 | goto err_out_unmap; | ||
5688 | } | ||
5689 | } | ||
5690 | |||
5598 | /* Get bus information. */ | 5691 | /* Get bus information. */ |
5599 | reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); | 5692 | reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); |
5600 | if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { | 5693 | if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { |