diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-02-12 03:36:43 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-16 02:31:15 -0500 |
commit | 1c06328c0345638ea7532b45cadfe713c9e9781e (patch) | |
tree | f0bc6c0986f22802655b347367ff5222074870dc /drivers/net/bnx2x_main.c | |
parent | 8a1c38d17d88c8df3dcbea1c01a390ab2087f8ad (diff) |
bnx2x: Flow control enhancement
Setting better HW thresholds and enabling FW capabilities for better
enforcement. Also set the HW to more efficiently use the internal buffers if
this is a single port design
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 96 |
1 files changed, 87 insertions, 9 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ce55e84c44da..77793bba7a9f 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -2165,6 +2165,19 @@ static void bnx2x_link_attn(struct bnx2x *bp) | |||
2165 | 2165 | ||
2166 | if (bp->link_vars.link_up) { | 2166 | if (bp->link_vars.link_up) { |
2167 | 2167 | ||
2168 | /* dropless flow control */ | ||
2169 | if (CHIP_IS_E1H(bp)) { | ||
2170 | int port = BP_PORT(bp); | ||
2171 | u32 pause_enabled = 0; | ||
2172 | |||
2173 | if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) | ||
2174 | pause_enabled = 1; | ||
2175 | |||
2176 | REG_WR(bp, BAR_USTRORM_INTMEM + | ||
2177 | USTORM_PAUSE_ENABLED_OFFSET(port), | ||
2178 | pause_enabled); | ||
2179 | } | ||
2180 | |||
2168 | if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { | 2181 | if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { |
2169 | struct host_port_stats *pstats; | 2182 | struct host_port_stats *pstats; |
2170 | 2183 | ||
@@ -4909,6 +4922,38 @@ static void bnx2x_init_internal_func(struct bnx2x *bp) | |||
4909 | max_agg_size); | 4922 | max_agg_size); |
4910 | } | 4923 | } |
4911 | 4924 | ||
4925 | /* dropless flow control */ | ||
4926 | if (CHIP_IS_E1H(bp)) { | ||
4927 | struct ustorm_eth_rx_pause_data_e1h rx_pause = {0}; | ||
4928 | |||
4929 | rx_pause.bd_thr_low = 250; | ||
4930 | rx_pause.cqe_thr_low = 250; | ||
4931 | rx_pause.cos = 1; | ||
4932 | rx_pause.sge_thr_low = 0; | ||
4933 | rx_pause.bd_thr_high = 350; | ||
4934 | rx_pause.cqe_thr_high = 350; | ||
4935 | rx_pause.sge_thr_high = 0; | ||
4936 | |||
4937 | for_each_rx_queue(bp, i) { | ||
4938 | struct bnx2x_fastpath *fp = &bp->fp[i]; | ||
4939 | |||
4940 | if (!fp->disable_tpa) { | ||
4941 | rx_pause.sge_thr_low = 150; | ||
4942 | rx_pause.sge_thr_high = 250; | ||
4943 | } | ||
4944 | |||
4945 | |||
4946 | offset = BAR_USTRORM_INTMEM + | ||
4947 | USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, | ||
4948 | fp->cl_id); | ||
4949 | for (j = 0; | ||
4950 | j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4; | ||
4951 | j++) | ||
4952 | REG_WR(bp, offset + j*4, | ||
4953 | ((u32 *)&rx_pause)[j]); | ||
4954 | } | ||
4955 | } | ||
4956 | |||
4912 | memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); | 4957 | memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); |
4913 | 4958 | ||
4914 | /* Init rate shaping and fairness contexts */ | 4959 | /* Init rate shaping and fairness contexts */ |
@@ -5437,14 +5482,6 @@ static int bnx2x_init_common(struct bnx2x *bp) | |||
5437 | } | 5482 | } |
5438 | 5483 | ||
5439 | bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); | 5484 | bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); |
5440 | if (CHIP_REV_IS_SLOW(bp)) { | ||
5441 | /* fix for emulation and FPGA for no pause */ | ||
5442 | REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 513); | ||
5443 | REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 513); | ||
5444 | REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0); | ||
5445 | REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0); | ||
5446 | } | ||
5447 | |||
5448 | bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); | 5485 | bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); |
5449 | REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); | 5486 | REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); |
5450 | /* set NIC mode */ | 5487 | /* set NIC mode */ |
@@ -5626,6 +5663,7 @@ static int bnx2x_init_common(struct bnx2x *bp) | |||
5626 | static int bnx2x_init_port(struct bnx2x *bp) | 5663 | static int bnx2x_init_port(struct bnx2x *bp) |
5627 | { | 5664 | { |
5628 | int port = BP_PORT(bp); | 5665 | int port = BP_PORT(bp); |
5666 | u32 low, high; | ||
5629 | u32 val; | 5667 | u32 val; |
5630 | 5668 | ||
5631 | DP(BNX2X_MSG_MCP, "starting port init port %x\n", port); | 5669 | DP(BNX2X_MSG_MCP, "starting port init port %x\n", port); |
@@ -5672,7 +5710,32 @@ static int bnx2x_init_port(struct bnx2x *bp) | |||
5672 | func ? TIMERS_PORT1_END : TIMERS_PORT0_END); | 5710 | func ? TIMERS_PORT1_END : TIMERS_PORT0_END); |
5673 | #endif | 5711 | #endif |
5674 | /* Port DQ comes here */ | 5712 | /* Port DQ comes here */ |
5675 | /* Port BRB1 comes here */ | 5713 | |
5714 | bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START), | ||
5715 | (port ? BRB1_PORT1_END : BRB1_PORT0_END)); | ||
5716 | if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) { | ||
5717 | /* no pause for emulation and FPGA */ | ||
5718 | low = 0; | ||
5719 | high = 513; | ||
5720 | } else { | ||
5721 | if (IS_E1HMF(bp)) | ||
5722 | low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); | ||
5723 | else if (bp->dev->mtu > 4096) { | ||
5724 | if (bp->flags & ONE_PORT_FLAG) | ||
5725 | low = 160; | ||
5726 | else { | ||
5727 | val = bp->dev->mtu; | ||
5728 | /* (24*1024 + val*4)/256 */ | ||
5729 | low = 96 + (val/64) + ((val % 64) ? 1 : 0); | ||
5730 | } | ||
5731 | } else | ||
5732 | low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); | ||
5733 | high = low + 56; /* 14*1024/256 */ | ||
5734 | } | ||
5735 | REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); | ||
5736 | REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); | ||
5737 | |||
5738 | |||
5676 | /* Port PRS comes here */ | 5739 | /* Port PRS comes here */ |
5677 | /* Port TSDM comes here */ | 5740 | /* Port TSDM comes here */ |
5678 | /* Port CSDM comes here */ | 5741 | /* Port CSDM comes here */ |
@@ -5754,6 +5817,14 @@ static int bnx2x_init_port(struct bnx2x *bp) | |||
5754 | REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, | 5817 | REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, |
5755 | (IS_E1HMF(bp) ? 0x1 : 0x2)); | 5818 | (IS_E1HMF(bp) ? 0x1 : 0x2)); |
5756 | 5819 | ||
5820 | /* support pause requests from USDM, TSDM and BRB */ | ||
5821 | REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0 + port*4, 0x7); | ||
5822 | |||
5823 | { | ||
5824 | REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0); | ||
5825 | REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0); | ||
5826 | REG_WR(bp, NIG_REG_PAUSE_ENABLE_0 + port*4, 1); | ||
5827 | } | ||
5757 | } | 5828 | } |
5758 | 5829 | ||
5759 | /* Port MCP comes here */ | 5830 | /* Port MCP comes here */ |
@@ -7331,6 +7402,13 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) | |||
7331 | bp->link_params.chip_id = bp->common.chip_id; | 7402 | bp->link_params.chip_id = bp->common.chip_id; |
7332 | BNX2X_DEV_INFO("chip ID is 0x%x\n", id); | 7403 | BNX2X_DEV_INFO("chip ID is 0x%x\n", id); |
7333 | 7404 | ||
7405 | val = (REG_RD(bp, 0x2874) & 0x55); | ||
7406 | if ((bp->common.chip_id & 0x1) || | ||
7407 | (CHIP_IS_E1(bp) && val) || (CHIP_IS_E1H(bp) && (val == 0x55))) { | ||
7408 | bp->flags |= ONE_PORT_FLAG; | ||
7409 | BNX2X_DEV_INFO("single port device\n"); | ||
7410 | } | ||
7411 | |||
7334 | val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4); | 7412 | val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4); |
7335 | bp->common.flash_size = (NVRAM_1MB_SIZE << | 7413 | bp->common.flash_size = (NVRAM_1MB_SIZE << |
7336 | (val & MCPR_NVM_CFG4_FLASH_SIZE)); | 7414 | (val & MCPR_NVM_CFG4_FLASH_SIZE)); |