diff options
Diffstat (limited to 'drivers/net/cxgb3/t3_hw.c')
-rw-r--r-- | drivers/net/cxgb3/t3_hw.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index bfce761156a1..58a3097579f9 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -442,6 +442,33 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) | |||
442 | return mdio_write(phy, 0, MII_BMCR, ctl); | 442 | return mdio_write(phy, 0, MII_BMCR, ctl); |
443 | } | 443 | } |
444 | 444 | ||
445 | int t3_phy_lasi_intr_enable(struct cphy *phy) | ||
446 | { | ||
447 | return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1); | ||
448 | } | ||
449 | |||
450 | int t3_phy_lasi_intr_disable(struct cphy *phy) | ||
451 | { | ||
452 | return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0); | ||
453 | } | ||
454 | |||
455 | int t3_phy_lasi_intr_clear(struct cphy *phy) | ||
456 | { | ||
457 | u32 val; | ||
458 | |||
459 | return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val); | ||
460 | } | ||
461 | |||
462 | int t3_phy_lasi_intr_handler(struct cphy *phy) | ||
463 | { | ||
464 | unsigned int status; | ||
465 | int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status); | ||
466 | |||
467 | if (err) | ||
468 | return err; | ||
469 | return (status & 1) ? cphy_cause_link_change : 0; | ||
470 | } | ||
471 | |||
445 | static const struct adapter_info t3_adap_info[] = { | 472 | static const struct adapter_info t3_adap_info[] = { |
446 | {2, 0, | 473 | {2, 0, |
447 | F_GPIO2_OEN | F_GPIO4_OEN | | 474 | F_GPIO2_OEN | F_GPIO4_OEN | |
@@ -1132,6 +1159,15 @@ void t3_link_changed(struct adapter *adapter, int port_id) | |||
1132 | 1159 | ||
1133 | phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); | 1160 | phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); |
1134 | 1161 | ||
1162 | if (lc->requested_fc & PAUSE_AUTONEG) | ||
1163 | fc &= lc->requested_fc; | ||
1164 | else | ||
1165 | fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); | ||
1166 | |||
1167 | if (link_ok == lc->link_ok && speed == lc->speed && | ||
1168 | duplex == lc->duplex && fc == lc->fc) | ||
1169 | return; /* nothing changed */ | ||
1170 | |||
1135 | if (link_ok != lc->link_ok && adapter->params.rev > 0 && | 1171 | if (link_ok != lc->link_ok && adapter->params.rev > 0 && |
1136 | uses_xaui(adapter)) { | 1172 | uses_xaui(adapter)) { |
1137 | if (link_ok) | 1173 | if (link_ok) |
@@ -1142,10 +1178,6 @@ void t3_link_changed(struct adapter *adapter, int port_id) | |||
1142 | lc->link_ok = link_ok; | 1178 | lc->link_ok = link_ok; |
1143 | lc->speed = speed < 0 ? SPEED_INVALID : speed; | 1179 | lc->speed = speed < 0 ? SPEED_INVALID : speed; |
1144 | lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; | 1180 | lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; |
1145 | if (lc->requested_fc & PAUSE_AUTONEG) | ||
1146 | fc &= lc->requested_fc; | ||
1147 | else | ||
1148 | fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); | ||
1149 | 1181 | ||
1150 | if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { | 1182 | if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { |
1151 | /* Set MAC speed, duplex, and flow control to match PHY. */ | 1183 | /* 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) | |||
1191 | fc); | 1223 | fc); |
1192 | /* Also disables autoneg */ | 1224 | /* Also disables autoneg */ |
1193 | phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); | 1225 | phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); |
1194 | phy->ops->reset(phy, 0); | ||
1195 | } else | 1226 | } else |
1196 | phy->ops->autoneg_enable(phy); | 1227 | phy->ops->autoneg_enable(phy); |
1197 | } else { | 1228 | } else { |