aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-11-19 17:10:45 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 00:24:26 -0500
commit59b47d8ad35b9858d63d6fd3db76e698e4a98f36 (patch)
treefe7d9a55df98a9327b252a57fc050c215c352c80 /drivers
parent9052a840fffa2f565ed13e6ecd53fbe2532d51b9 (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')
-rw-r--r--drivers/net/bnx2.c167
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
236bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) 236bnx2_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
243static int 258static 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
486alloc_mem_err: 521alloc_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
1496static int
1497bnx2_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
1462static void 1530static void
1463bnx2_init_context(struct bnx2 *bp) 1531bnx2_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
3466static void
3467bnx2_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
3397static void 3495static void
3398bnx2_init_tx_ring(struct bnx2 *bp) 3496bnx2_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
3430static void 3520static 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) {