Skip to content

Commit

Permalink
[TG3]: Correct sw autoneg flow control advertisements
Browse files Browse the repository at this point in the history
This patch modifies the software autoneg code to use the administrator
specified flow control parameters.  Since the autonegotiation code uses
alternative flow control enumerations, the 1000-BaseX utility functions
are used and code was added to convert the definitions to and from the
alternate enumerations.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Matt Carlson authored and David S. Miller committed Jan 28, 2008
1 parent 82cd3d1 commit 5be73b4
Showing 1 changed file with 25 additions and 13 deletions.
38 changes: 25 additions & 13 deletions drivers/net/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1695,7 +1695,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv
u32 old_tx_mode = tp->tx_mode;

if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) {
if (tp->tg3_flags2 & (TG3_FLG2_MII_SERDES|TG3_FLG2_HW_AUTONEG))
if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
new_tg3_flags = tg3_resolve_flowctrl_1000X(local_adv,
remote_adv);
else
Expand Down Expand Up @@ -2317,6 +2317,7 @@ struct tg3_fiber_aneginfo {
static int tg3_fiber_aneg_smachine(struct tg3 *tp,
struct tg3_fiber_aneginfo *ap)
{
u16 flowctrl;
unsigned long delta;
u32 rx_cfg_reg;
int ret;
Expand Down Expand Up @@ -2416,7 +2417,12 @@ static int tg3_fiber_aneg_smachine(struct tg3 *tp,

case ANEG_STATE_ABILITY_DETECT_INIT:
ap->flags &= ~(MR_TOGGLE_TX);
ap->txconfig = (ANEG_CFG_FD | ANEG_CFG_PS1);
ap->txconfig = ANEG_CFG_FD;
flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
if (flowctrl & ADVERTISE_1000XPAUSE)
ap->txconfig |= ANEG_CFG_PS1;
if (flowctrl & ADVERTISE_1000XPSE_ASYM)
ap->txconfig |= ANEG_CFG_PS2;
tw32(MAC_TX_AUTO_NEG, ap->txconfig);
tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
tw32_f(MAC_MODE, tp->mac_mode);
Expand Down Expand Up @@ -2562,7 +2568,7 @@ static int tg3_fiber_aneg_smachine(struct tg3 *tp,
return ret;
}

static int fiber_autoneg(struct tg3 *tp, u32 *flags)
static int fiber_autoneg(struct tg3 *tp, u32 *txflags, u32 *rxflags)
{
int res = 0;
struct tg3_fiber_aneginfo aninfo;
Expand Down Expand Up @@ -2596,7 +2602,8 @@ static int fiber_autoneg(struct tg3 *tp, u32 *flags)
tw32_f(MAC_MODE, tp->mac_mode);
udelay(40);

*flags = aninfo.flags;
*txflags = aninfo.txconfig;
*rxflags = aninfo.flags;

if (status == ANEG_DONE &&
(aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK |
Expand Down Expand Up @@ -2806,18 +2813,21 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status)
goto out;

if (tp->link_config.autoneg == AUTONEG_ENABLE) {
u32 flags;
u32 txflags, rxflags;
int i;

if (fiber_autoneg(tp, &flags)) {
u32 local_adv, remote_adv;
if (fiber_autoneg(tp, &txflags, &rxflags)) {
u32 local_adv = 0, remote_adv = 0;

local_adv = ADVERTISE_PAUSE_CAP;
remote_adv = 0;
if (flags & MR_LP_ADV_SYM_PAUSE)
remote_adv |= LPA_PAUSE_CAP;
if (flags & MR_LP_ADV_ASYM_PAUSE)
remote_adv |= LPA_PAUSE_ASYM;
if (txflags & ANEG_CFG_PS1)
local_adv |= ADVERTISE_1000XPAUSE;
if (txflags & ANEG_CFG_PS2)
local_adv |= ADVERTISE_1000XPSE_ASYM;

if (rxflags & MR_LP_ADV_SYM_PAUSE)
remote_adv |= LPA_1000XPAUSE;
if (rxflags & MR_LP_ADV_ASYM_PAUSE)
remote_adv |= LPA_1000XPAUSE_ASYM;

tg3_setup_flow_control(tp, local_adv, remote_adv);

Expand All @@ -2841,6 +2851,8 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status)
!(mac_status & MAC_STATUS_RCVD_CFG))
current_link_up = 1;
} else {
tg3_setup_flow_control(tp, 0, 0);

/* Forcing 1000FD link up. */
current_link_up = 1;

Expand Down

0 comments on commit 5be73b4

Please sign in to comment.