cxgb3: commnonize LASI phy code
[linux-3.10.git] / drivers / net / cxgb3 / t3_hw.c
index bfce761..58a3097 100644 (file)
@@ -442,6 +442,33 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
        return mdio_write(phy, 0, MII_BMCR, ctl);
 }
 
+int t3_phy_lasi_intr_enable(struct cphy *phy)
+{
+       return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1);
+}
+
+int t3_phy_lasi_intr_disable(struct cphy *phy)
+{
+       return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0);
+}
+
+int t3_phy_lasi_intr_clear(struct cphy *phy)
+{
+       u32 val;
+
+       return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val);
+}
+
+int t3_phy_lasi_intr_handler(struct cphy *phy)
+{
+       unsigned int status;
+       int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status);
+
+       if (err)
+               return err;
+       return (status & 1) ?  cphy_cause_link_change : 0;
+}
+
 static const struct adapter_info t3_adap_info[] = {
        {2, 0,
         F_GPIO2_OEN | F_GPIO4_OEN |
@@ -1132,6 +1159,15 @@ void t3_link_changed(struct adapter *adapter, int port_id)
 
        phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
 
+       if (lc->requested_fc & PAUSE_AUTONEG)
+               fc &= lc->requested_fc;
+       else
+               fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
+
+       if (link_ok == lc->link_ok && speed == lc->speed &&
+           duplex == lc->duplex && fc == lc->fc)
+               return;                            /* nothing changed */
+
        if (link_ok != lc->link_ok && adapter->params.rev > 0 &&
            uses_xaui(adapter)) {
                if (link_ok)
@@ -1142,10 +1178,6 @@ void t3_link_changed(struct adapter *adapter, int port_id)
        lc->link_ok = link_ok;
        lc->speed = speed < 0 ? SPEED_INVALID : speed;
        lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
-       if (lc->requested_fc & PAUSE_AUTONEG)
-               fc &= lc->requested_fc;
-       else
-               fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
 
        if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
                /* Set MAC speed, duplex, and flow control to match PHY. */
@@ -1191,7 +1223,6 @@ int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
                                                   fc);
                        /* Also disables autoneg */
                        phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
-                       phy->ops->reset(phy, 0);
                } else
                        phy->ops->autoneg_enable(phy);
        } else {