bnx2x: dropless flow control not always functional

Since commit 3deb816 "bnx2x: Add a periodic task for link PHY events"
link state changes can be detected not only via the attention flow but also
from the periodic task.
If the link state will change in such a manner (i.e., via the periodic task),
dropless flow-control will not be configured.

This patch remedies the issue, adding the missing configuration to all required
flows.

Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Dmitry Kravkov 2013-08-19 09:11:56 +03:00 committed by David S. Miller
parent f46078cfcd
commit 9156b30b33

View File

@ -2261,6 +2261,23 @@ static void bnx2x_set_requested_fc(struct bnx2x *bp)
bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
}
static void bnx2x_init_dropless_fc(struct bnx2x *bp)
{
u32 pause_enabled = 0;
if (!CHIP_IS_E1(bp) && bp->dropless_fc && bp->link_vars.link_up) {
if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
pause_enabled = 1;
REG_WR(bp, BAR_USTRORM_INTMEM +
USTORM_ETH_PAUSE_ENABLED_OFFSET(BP_PORT(bp)),
pause_enabled);
}
DP(NETIF_MSG_IFUP | NETIF_MSG_LINK, "dropless_fc is %s\n",
pause_enabled ? "enabled" : "disabled");
}
int bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
{
int rc, cfx_idx = bnx2x_get_link_cfg_idx(bp);
@ -2294,6 +2311,8 @@ int bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
bnx2x_release_phy_lock(bp);
bnx2x_init_dropless_fc(bp);
bnx2x_calc_fc_adv(bp);
if (bp->link_vars.link_up) {
@ -2315,6 +2334,8 @@ void bnx2x_link_set(struct bnx2x *bp)
bnx2x_phy_init(&bp->link_params, &bp->link_vars);
bnx2x_release_phy_lock(bp);
bnx2x_init_dropless_fc(bp);
bnx2x_calc_fc_adv(bp);
} else
BNX2X_ERR("Bootcode is missing - can not set link\n");
@ -2556,21 +2577,10 @@ static void bnx2x_link_attn(struct bnx2x *bp)
bnx2x_link_update(&bp->link_params, &bp->link_vars);
bnx2x_init_dropless_fc(bp);
if (bp->link_vars.link_up) {
/* dropless flow control */
if (!CHIP_IS_E1(bp) && bp->dropless_fc) {
int port = BP_PORT(bp);
u32 pause_enabled = 0;
if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
pause_enabled = 1;
REG_WR(bp, BAR_USTRORM_INTMEM +
USTORM_ETH_PAUSE_ENABLED_OFFSET(port),
pause_enabled);
}
if (bp->link_vars.mac_type != MAC_TYPE_EMAC) {
struct host_port_stats *pstats;