aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2008-01-30 00:37:17 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:27:16 -0500
commit83e3fc89bb2b7bb27b3a6da5a541c43ce7706f42 (patch)
tree1216f5b1f02e30362d5cd153d29ac4e1182b0f1f /drivers/net/bnx2.c
parent62a8313cddbea04f2a28d1d76acf317c2a56cfae (diff)
[BNX2]: Fine-tune flow control on 5709.
Make use of the programmable high/low water marks in 5709 for 802.3 flow control. 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.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 8af63b4ec67d..bd31a4b9c3ad 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -992,6 +992,42 @@ bnx2_copper_linkup(struct bnx2 *bp)
992 return 0; 992 return 0;
993} 993}
994 994
995static void
996bnx2_init_rx_context0(struct bnx2 *bp)
997{
998 u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID);
999
1000 val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
1001 val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
1002 val |= 0x02 << 8;
1003
1004 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
1005 u32 lo_water, hi_water;
1006
1007 if (bp->flow_ctrl & FLOW_CTRL_TX)
1008 lo_water = BNX2_L2CTX_LO_WATER_MARK_DEFAULT;
1009 else
1010 lo_water = BNX2_L2CTX_LO_WATER_MARK_DIS;
1011 if (lo_water >= bp->rx_ring_size)
1012 lo_water = 0;
1013
1014 hi_water = bp->rx_ring_size / 4;
1015
1016 if (hi_water <= lo_water)
1017 lo_water = 0;
1018
1019 hi_water /= BNX2_L2CTX_HI_WATER_MARK_SCALE;
1020 lo_water /= BNX2_L2CTX_LO_WATER_MARK_SCALE;
1021
1022 if (hi_water > 0xf)
1023 hi_water = 0xf;
1024 else if (hi_water == 0)
1025 lo_water = 0;
1026 val |= lo_water | (hi_water << BNX2_L2CTX_HI_WATER_MARK_SHIFT);
1027 }
1028 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
1029}
1030
995static int 1031static int
996bnx2_set_mac_link(struct bnx2 *bp) 1032bnx2_set_mac_link(struct bnx2 *bp)
997{ 1033{
@@ -1056,6 +1092,9 @@ bnx2_set_mac_link(struct bnx2 *bp)
1056 /* Acknowledge the interrupt. */ 1092 /* Acknowledge the interrupt. */
1057 REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); 1093 REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
1058 1094
1095 if (CHIP_NUM(bp) == CHIP_NUM_5709)
1096 bnx2_init_rx_context0(bp);
1097
1059 return 0; 1098 return 0;
1060} 1099}
1061 1100
@@ -4616,6 +4655,13 @@ bnx2_init_rx_ring(struct bnx2 *bp)
4616 bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping, 4655 bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping,
4617 bp->rx_buf_use_size, bp->rx_max_ring); 4656 bp->rx_buf_use_size, bp->rx_max_ring);
4618 4657
4658 bnx2_init_rx_context0(bp);
4659
4660 if (CHIP_NUM(bp) == CHIP_NUM_5709) {
4661 val = REG_RD(bp, BNX2_MQ_MAP_L2_5);
4662 REG_WR(bp, BNX2_MQ_MAP_L2_5, val | BNX2_MQ_MAP_L2_5_ARM);
4663 }
4664
4619 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0); 4665 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
4620 if (bp->rx_pg_ring_size) { 4666 if (bp->rx_pg_ring_size) {
4621 bnx2_init_rxbd_rings(bp->rx_pg_desc_ring, 4667 bnx2_init_rxbd_rings(bp->rx_pg_desc_ring,
@@ -4636,11 +4682,6 @@ bnx2_init_rx_ring(struct bnx2 *bp)
4636 REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT); 4682 REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
4637 } 4683 }
4638 4684
4639 val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
4640 val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
4641 val |= 0x02 << 8;
4642 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
4643
4644 val = (u64) bp->rx_desc_mapping[0] >> 32; 4685 val = (u64) bp->rx_desc_mapping[0] >> 32;
4645 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val); 4686 bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val);
4646 4687