|
@@ -1766,10 +1766,10 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
|
|
|
{
|
|
|
struct sky2_hw *hw = sky2->hw;
|
|
|
unsigned port = sky2->port;
|
|
|
- u16 lpa;
|
|
|
+ u16 advert, lpa;
|
|
|
|
|
|
+ advert = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
|
|
|
lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
|
|
|
-
|
|
|
if (lpa & PHY_M_AN_RF) {
|
|
|
printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name);
|
|
|
return -1;
|
|
@@ -1784,20 +1784,40 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
|
|
|
sky2->speed = sky2_phy_speed(hw, aux);
|
|
|
sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
|
|
|
|
|
|
- /* Pause bits are offset (9..8) */
|
|
|
- if (hw->chip_id == CHIP_ID_YUKON_XL
|
|
|
- || hw->chip_id == CHIP_ID_YUKON_EC_U
|
|
|
- || hw->chip_id == CHIP_ID_YUKON_EX)
|
|
|
- aux >>= 6;
|
|
|
-
|
|
|
- sky2->flow_status = sky2_flow(aux & PHY_M_PS_RX_P_EN,
|
|
|
- aux & PHY_M_PS_TX_P_EN);
|
|
|
+ /* Since the pause result bits seem to in different positions on
|
|
|
+ * different chips. look at registers.
|
|
|
+ */
|
|
|
+ if (!sky2_is_copper(hw)) {
|
|
|
+ /* Shift for bits in fiber PHY */
|
|
|
+ advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM);
|
|
|
+ lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM);
|
|
|
+
|
|
|
+ if (advert & ADVERTISE_1000XPAUSE)
|
|
|
+ advert |= ADVERTISE_PAUSE_CAP;
|
|
|
+ if (advert & ADVERTISE_1000XPSE_ASYM)
|
|
|
+ advert |= ADVERTISE_PAUSE_ASYM;
|
|
|
+ if (lpa & LPA_1000XPAUSE)
|
|
|
+ lpa |= LPA_PAUSE_CAP;
|
|
|
+ if (lpa & LPA_1000XPAUSE_ASYM)
|
|
|
+ lpa |= LPA_PAUSE_ASYM;
|
|
|
+ }
|
|
|
+
|
|
|
+ sky2->flow_status = FC_NONE;
|
|
|
+ if (advert & ADVERTISE_PAUSE_CAP) {
|
|
|
+ if (lpa & LPA_PAUSE_CAP)
|
|
|
+ sky2->flow_status = FC_BOTH;
|
|
|
+ else if (advert & ADVERTISE_PAUSE_ASYM)
|
|
|
+ sky2->flow_status = FC_RX;
|
|
|
+ } else if (advert & ADVERTISE_PAUSE_ASYM) {
|
|
|
+ if ((lpa & LPA_PAUSE_CAP) && (lpa & LPA_PAUSE_ASYM))
|
|
|
+ sky2->flow_status = FC_TX;
|
|
|
+ }
|
|
|
|
|
|
if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000
|
|
|
&& !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
|
|
|
sky2->flow_status = FC_NONE;
|
|
|
|
|
|
- if (aux & PHY_M_PS_RX_P_EN)
|
|
|
+ if (sky2->flow_status & FC_TX)
|
|
|
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
|
|
|
else
|
|
|
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
|