aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2008-05-26 02:47:41 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-29 04:38:24 -0400
commitb02fd9e3ac118037549baeb86fbe0718561db17f (patch)
tree858f7c763fe0e88a4a9f261eb7ae284413b310db
parent158d7abdae85e9ac43d99780c372d79c119f7626 (diff)
tg3: Add libphy support.
This patch introduces the libphy support. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: Benjamin Li <benli@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tg3.c395
-rw-r--r--drivers/net/tg3.h2
2 files changed, 352 insertions, 45 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ce04c64a8a6e..028276edd3bc 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -1114,11 +1114,17 @@ static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv)
1114 1114
1115static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv) 1115static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
1116{ 1116{
1117 u8 autoneg;
1117 u8 flowctrl = 0; 1118 u8 flowctrl = 0;
1118 u32 old_rx_mode = tp->rx_mode; 1119 u32 old_rx_mode = tp->rx_mode;
1119 u32 old_tx_mode = tp->tx_mode; 1120 u32 old_tx_mode = tp->tx_mode;
1120 1121
1121 if (tp->link_config.autoneg == AUTONEG_ENABLE && 1122 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
1123 autoneg = tp->mdio_bus.phy_map[PHY_ADDR]->autoneg;
1124 else
1125 autoneg = tp->link_config.autoneg;
1126
1127 if (autoneg == AUTONEG_ENABLE &&
1122 (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) { 1128 (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
1123 if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) 1129 if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
1124 flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv); 1130 flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv);
@@ -1146,6 +1152,152 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
1146 tw32_f(MAC_TX_MODE, tp->tx_mode); 1152 tw32_f(MAC_TX_MODE, tp->tx_mode);
1147} 1153}
1148 1154
1155static void tg3_adjust_link(struct net_device *dev)
1156{
1157 u8 oldflowctrl, linkmesg = 0;
1158 u32 mac_mode, lcl_adv, rmt_adv;
1159 struct tg3 *tp = netdev_priv(dev);
1160 struct phy_device *phydev = tp->mdio_bus.phy_map[PHY_ADDR];
1161
1162 spin_lock(&tp->lock);
1163
1164 mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
1165 MAC_MODE_HALF_DUPLEX);
1166
1167 oldflowctrl = tp->link_config.active_flowctrl;
1168
1169 if (phydev->link) {
1170 lcl_adv = 0;
1171 rmt_adv = 0;
1172
1173 if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10)
1174 mac_mode |= MAC_MODE_PORT_MODE_MII;
1175 else
1176 mac_mode |= MAC_MODE_PORT_MODE_GMII;
1177
1178 if (phydev->duplex == DUPLEX_HALF)
1179 mac_mode |= MAC_MODE_HALF_DUPLEX;
1180 else {
1181 lcl_adv = tg3_advert_flowctrl_1000T(
1182 tp->link_config.flowctrl);
1183
1184 if (phydev->pause)
1185 rmt_adv = LPA_PAUSE_CAP;
1186 if (phydev->asym_pause)
1187 rmt_adv |= LPA_PAUSE_ASYM;
1188 }
1189
1190 tg3_setup_flow_control(tp, lcl_adv, rmt_adv);
1191 } else
1192 mac_mode |= MAC_MODE_PORT_MODE_GMII;
1193
1194 if (mac_mode != tp->mac_mode) {
1195 tp->mac_mode = mac_mode;
1196 tw32_f(MAC_MODE, tp->mac_mode);
1197 udelay(40);
1198 }
1199
1200 if (phydev->speed == SPEED_1000 && phydev->duplex == DUPLEX_HALF)
1201 tw32(MAC_TX_LENGTHS,
1202 ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
1203 (6 << TX_LENGTHS_IPG_SHIFT) |
1204 (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)));
1205 else
1206 tw32(MAC_TX_LENGTHS,
1207 ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
1208 (6 << TX_LENGTHS_IPG_SHIFT) |
1209 (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
1210
1211 if ((phydev->link && tp->link_config.active_speed == SPEED_INVALID) ||
1212 (!phydev->link && tp->link_config.active_speed != SPEED_INVALID) ||
1213 phydev->speed != tp->link_config.active_speed ||
1214 phydev->duplex != tp->link_config.active_duplex ||
1215 oldflowctrl != tp->link_config.active_flowctrl)
1216 linkmesg = 1;
1217
1218 tp->link_config.active_speed = phydev->speed;
1219 tp->link_config.active_duplex = phydev->duplex;
1220
1221 spin_unlock(&tp->lock);
1222
1223 if (linkmesg)
1224 tg3_link_report(tp);
1225}
1226
1227static int tg3_phy_init(struct tg3 *tp)
1228{
1229 struct phy_device *phydev;
1230
1231 if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
1232 return 0;
1233
1234 /* Bring the PHY back to a known state. */
1235 tg3_bmcr_reset(tp);
1236
1237 phydev = tp->mdio_bus.phy_map[PHY_ADDR];
1238
1239 /* Attach the MAC to the PHY. */
1240 phydev = phy_connect(tp->dev, phydev->dev.bus_id,
1241 tg3_adjust_link, 0, phydev->interface);
1242 if (IS_ERR(phydev)) {
1243 printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name);
1244 return PTR_ERR(phydev);
1245 }
1246
1247 tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED;
1248
1249 /* Mask with MAC supported features. */
1250 phydev->supported &= (PHY_GBIT_FEATURES |
1251 SUPPORTED_Pause |
1252 SUPPORTED_Asym_Pause);
1253
1254 phydev->advertising = phydev->supported;
1255
1256 printk(KERN_INFO
1257 "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
1258 tp->dev->name, phydev->drv->name, phydev->dev.bus_id);
1259
1260 return 0;
1261}
1262
1263static void tg3_phy_start(struct tg3 *tp)
1264{
1265 struct phy_device *phydev;
1266
1267 if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
1268 return;
1269
1270 phydev = tp->mdio_bus.phy_map[PHY_ADDR];
1271
1272 if (tp->link_config.phy_is_low_power) {
1273 tp->link_config.phy_is_low_power = 0;
1274 phydev->speed = tp->link_config.orig_speed;
1275 phydev->duplex = tp->link_config.orig_duplex;
1276 phydev->autoneg = tp->link_config.orig_autoneg;
1277 phydev->advertising = tp->link_config.orig_advertising;
1278 }
1279
1280 phy_start(phydev);
1281
1282 phy_start_aneg(phydev);
1283}
1284
1285static void tg3_phy_stop(struct tg3 *tp)
1286{
1287 if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
1288 return;
1289
1290 phy_stop(tp->mdio_bus.phy_map[PHY_ADDR]);
1291}
1292
1293static void tg3_phy_fini(struct tg3 *tp)
1294{
1295 if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
1296 phy_disconnect(tp->mdio_bus.phy_map[PHY_ADDR]);
1297 tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
1298 }
1299}
1300
1149static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val) 1301static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
1150{ 1302{
1151 tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg); 1303 tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
@@ -1798,7 +1950,40 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
1798 misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT); 1950 misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
1799 1951
1800 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 1952 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
1801 tp->link_config.phy_is_low_power = 1; 1953 if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) &&
1954 !tp->link_config.phy_is_low_power) {
1955 struct phy_device *phydev;
1956 u32 advertising;
1957
1958 phydev = tp->mdio_bus.phy_map[PHY_ADDR];
1959
1960 tp->link_config.phy_is_low_power = 1;
1961
1962 tp->link_config.orig_speed = phydev->speed;
1963 tp->link_config.orig_duplex = phydev->duplex;
1964 tp->link_config.orig_autoneg = phydev->autoneg;
1965 tp->link_config.orig_advertising = phydev->advertising;
1966
1967 advertising = ADVERTISED_TP |
1968 ADVERTISED_Pause |
1969 ADVERTISED_Autoneg |
1970 ADVERTISED_10baseT_Half;
1971
1972 if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
1973 (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
1974 if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
1975 advertising |=
1976 ADVERTISED_100baseT_Half |
1977 ADVERTISED_100baseT_Full |
1978 ADVERTISED_10baseT_Full;
1979 else
1980 advertising |= ADVERTISED_10baseT_Full;
1981 }
1982
1983 phydev->advertising = advertising;
1984
1985 phy_start_aneg(phydev);
1986 }
1802 } else { 1987 } else {
1803 if (tp->link_config.phy_is_low_power == 0) { 1988 if (tp->link_config.phy_is_low_power == 0) {
1804 tp->link_config.phy_is_low_power = 1; 1989 tp->link_config.phy_is_low_power = 1;
@@ -4233,6 +4418,7 @@ static void tg3_poll_controller(struct net_device *dev)
4233static void tg3_reset_task(struct work_struct *work) 4418static void tg3_reset_task(struct work_struct *work)
4234{ 4419{
4235 struct tg3 *tp = container_of(work, struct tg3, reset_task); 4420 struct tg3 *tp = container_of(work, struct tg3, reset_task);
4421 int err;
4236 unsigned int restart_timer; 4422 unsigned int restart_timer;
4237 4423
4238 tg3_full_lock(tp, 0); 4424 tg3_full_lock(tp, 0);
@@ -4244,6 +4430,8 @@ static void tg3_reset_task(struct work_struct *work)
4244 4430
4245 tg3_full_unlock(tp); 4431 tg3_full_unlock(tp);
4246 4432
4433 tg3_phy_stop(tp);
4434
4247 tg3_netif_stop(tp); 4435 tg3_netif_stop(tp);
4248 4436
4249 tg3_full_lock(tp, 1); 4437 tg3_full_lock(tp, 1);
@@ -4259,7 +4447,8 @@ static void tg3_reset_task(struct work_struct *work)
4259 } 4447 }
4260 4448
4261 tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); 4449 tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
4262 if (tg3_init_hw(tp, 1)) 4450 err = tg3_init_hw(tp, 1);
4451 if (err)
4263 goto out; 4452 goto out;
4264 4453
4265 tg3_netif_start(tp); 4454 tg3_netif_start(tp);
@@ -4269,6 +4458,9 @@ static void tg3_reset_task(struct work_struct *work)
4269 4458
4270out: 4459out:
4271 tg3_full_unlock(tp); 4460 tg3_full_unlock(tp);
4461
4462 if (!err)
4463 tg3_phy_start(tp);
4272} 4464}
4273 4465
4274static void tg3_dump_short_state(struct tg3 *tp) 4466static void tg3_dump_short_state(struct tg3 *tp)
@@ -4772,6 +4964,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
4772 return 0; 4964 return 0;
4773 } 4965 }
4774 4966
4967 tg3_phy_stop(tp);
4968
4775 tg3_netif_stop(tp); 4969 tg3_netif_stop(tp);
4776 4970
4777 tg3_full_lock(tp, 1); 4971 tg3_full_lock(tp, 1);
@@ -4787,6 +4981,9 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
4787 4981
4788 tg3_full_unlock(tp); 4982 tg3_full_unlock(tp);
4789 4983
4984 if (!err)
4985 tg3_phy_start(tp);
4986
4790 return err; 4987 return err;
4791} 4988}
4792 4989
@@ -7864,6 +8061,8 @@ static int tg3_open(struct net_device *dev)
7864 } 8061 }
7865 } 8062 }
7866 8063
8064 tg3_phy_start(tp);
8065
7867 tg3_full_lock(tp, 0); 8066 tg3_full_lock(tp, 0);
7868 8067
7869 add_timer(&tp->timer); 8068 add_timer(&tp->timer);
@@ -8665,7 +8864,13 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
8665 8864
8666static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 8865static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
8667{ 8866{
8668 struct tg3 *tp = netdev_priv(dev); 8867 struct tg3 *tp = netdev_priv(dev);
8868
8869 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
8870 if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
8871 return -EAGAIN;
8872 return phy_ethtool_gset(tp->mdio_bus.phy_map[PHY_ADDR], cmd);
8873 }
8669 8874
8670 cmd->supported = (SUPPORTED_Autoneg); 8875 cmd->supported = (SUPPORTED_Autoneg);
8671 8876
@@ -8702,6 +8907,12 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
8702{ 8907{
8703 struct tg3 *tp = netdev_priv(dev); 8908 struct tg3 *tp = netdev_priv(dev);
8704 8909
8910 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
8911 if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
8912 return -EAGAIN;
8913 return phy_ethtool_sset(tp->mdio_bus.phy_map[PHY_ADDR], cmd);
8914 }
8915
8705 if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { 8916 if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
8706 /* These are the only valid advertisement bits allowed. */ 8917 /* These are the only valid advertisement bits allowed. */
8707 if (cmd->autoneg == AUTONEG_ENABLE && 8918 if (cmd->autoneg == AUTONEG_ENABLE &&
@@ -8734,7 +8945,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
8734 tp->link_config.advertising = 0; 8945 tp->link_config.advertising = 0;
8735 tp->link_config.speed = cmd->speed; 8946 tp->link_config.speed = cmd->speed;
8736 tp->link_config.duplex = cmd->duplex; 8947 tp->link_config.duplex = cmd->duplex;
8737 } 8948 }
8738 8949
8739 tp->link_config.orig_speed = tp->link_config.speed; 8950 tp->link_config.orig_speed = tp->link_config.speed;
8740 tp->link_config.orig_duplex = tp->link_config.duplex; 8951 tp->link_config.orig_duplex = tp->link_config.duplex;
@@ -8828,7 +9039,6 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
8828static int tg3_nway_reset(struct net_device *dev) 9039static int tg3_nway_reset(struct net_device *dev)
8829{ 9040{
8830 struct tg3 *tp = netdev_priv(dev); 9041 struct tg3 *tp = netdev_priv(dev);
8831 u32 bmcr;
8832 int r; 9042 int r;
8833 9043
8834 if (!netif_running(dev)) 9044 if (!netif_running(dev))
@@ -8837,17 +9047,25 @@ static int tg3_nway_reset(struct net_device *dev)
8837 if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) 9047 if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
8838 return -EINVAL; 9048 return -EINVAL;
8839 9049
8840 spin_lock_bh(&tp->lock); 9050 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
8841 r = -EINVAL; 9051 if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
8842 tg3_readphy(tp, MII_BMCR, &bmcr); 9052 return -EAGAIN;
8843 if (!tg3_readphy(tp, MII_BMCR, &bmcr) && 9053 r = phy_start_aneg(tp->mdio_bus.phy_map[PHY_ADDR]);
8844 ((bmcr & BMCR_ANENABLE) || 9054 } else {
8845 (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) { 9055 u32 bmcr;
8846 tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART | 9056
8847 BMCR_ANENABLE); 9057 spin_lock_bh(&tp->lock);
8848 r = 0; 9058 r = -EINVAL;
9059 tg3_readphy(tp, MII_BMCR, &bmcr);
9060 if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
9061 ((bmcr & BMCR_ANENABLE) ||
9062 (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
9063 tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
9064 BMCR_ANENABLE);
9065 r = 0;
9066 }
9067 spin_unlock_bh(&tp->lock);
8849 } 9068 }
8850 spin_unlock_bh(&tp->lock);
8851 9069
8852 return r; 9070 return r;
8853} 9071}
@@ -8889,6 +9107,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
8889 return -EINVAL; 9107 return -EINVAL;
8890 9108
8891 if (netif_running(dev)) { 9109 if (netif_running(dev)) {
9110 tg3_phy_stop(tp);
8892 tg3_netif_stop(tp); 9111 tg3_netif_stop(tp);
8893 irq_sync = 1; 9112 irq_sync = 1;
8894 } 9113 }
@@ -8912,6 +9131,9 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
8912 9131
8913 tg3_full_unlock(tp); 9132 tg3_full_unlock(tp);
8914 9133
9134 if (irq_sync && !err)
9135 tg3_phy_start(tp);
9136
8915 return err; 9137 return err;
8916} 9138}
8917 9139
@@ -8935,36 +9157,92 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
8935static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) 9157static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
8936{ 9158{
8937 struct tg3 *tp = netdev_priv(dev); 9159 struct tg3 *tp = netdev_priv(dev);
8938 int irq_sync = 0, err = 0; 9160 int err = 0;
8939 9161
8940 if (netif_running(dev)) { 9162 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
8941 tg3_netif_stop(tp); 9163 if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
8942 irq_sync = 1; 9164 return -EAGAIN;
8943 }
8944 9165
8945 tg3_full_lock(tp, irq_sync); 9166 if (epause->autoneg) {
9167 u32 newadv;
9168 struct phy_device *phydev;
8946 9169
8947 if (epause->autoneg) 9170 phydev = tp->mdio_bus.phy_map[PHY_ADDR];
8948 tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
8949 else
8950 tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
8951 if (epause->rx_pause)
8952 tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
8953 else
8954 tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
8955 if (epause->tx_pause)
8956 tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
8957 else
8958 tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
8959 9171
8960 if (netif_running(dev)) { 9172 if (epause->rx_pause) {
8961 tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); 9173 if (epause->tx_pause)
8962 err = tg3_restart_hw(tp, 1); 9174 newadv = ADVERTISED_Pause;
8963 if (!err) 9175 else
8964 tg3_netif_start(tp); 9176 newadv = ADVERTISED_Pause |
8965 } 9177 ADVERTISED_Asym_Pause;
9178 } else if (epause->tx_pause) {
9179 newadv = ADVERTISED_Asym_Pause;
9180 } else
9181 newadv = 0;
9182
9183 if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
9184 u32 oldadv = phydev->advertising &
9185 (ADVERTISED_Pause |
9186 ADVERTISED_Asym_Pause);
9187 if (oldadv != newadv) {
9188 phydev->advertising &=
9189 ~(ADVERTISED_Pause |
9190 ADVERTISED_Asym_Pause);
9191 phydev->advertising |= newadv;
9192 err = phy_start_aneg(phydev);
9193 }
9194 } else {
9195 tp->link_config.advertising &=
9196 ~(ADVERTISED_Pause |
9197 ADVERTISED_Asym_Pause);
9198 tp->link_config.advertising |= newadv;
9199 }
9200 } else {
9201 if (epause->rx_pause)
9202 tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
9203 else
9204 tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
8966 9205
8967 tg3_full_unlock(tp); 9206 if (epause->tx_pause)
9207 tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
9208 else
9209 tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
9210
9211 if (netif_running(dev))
9212 tg3_setup_flow_control(tp, 0, 0);
9213 }
9214 } else {
9215 int irq_sync = 0;
9216
9217 if (netif_running(dev)) {
9218 tg3_netif_stop(tp);
9219 irq_sync = 1;
9220 }
9221
9222 tg3_full_lock(tp, irq_sync);
9223
9224 if (epause->autoneg)
9225 tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
9226 else
9227 tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
9228 if (epause->rx_pause)
9229 tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
9230 else
9231 tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
9232 if (epause->tx_pause)
9233 tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
9234 else
9235 tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
9236
9237 if (netif_running(dev)) {
9238 tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
9239 err = tg3_restart_hw(tp, 1);
9240 if (!err)
9241 tg3_netif_start(tp);
9242 }
9243
9244 tg3_full_unlock(tp);
9245 }
8968 9246
8969 return err; 9247 return err;
8970} 9248}
@@ -9799,9 +10077,10 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
9799 data[1] = 1; 10077 data[1] = 1;
9800 } 10078 }
9801 if (etest->flags & ETH_TEST_FL_OFFLINE) { 10079 if (etest->flags & ETH_TEST_FL_OFFLINE) {
9802 int err, irq_sync = 0; 10080 int err, err2 = 0, irq_sync = 0;
9803 10081
9804 if (netif_running(dev)) { 10082 if (netif_running(dev)) {
10083 tg3_phy_stop(tp);
9805 tg3_netif_stop(tp); 10084 tg3_netif_stop(tp);
9806 irq_sync = 1; 10085 irq_sync = 1;
9807 } 10086 }
@@ -9842,11 +10121,15 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
9842 tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); 10121 tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
9843 if (netif_running(dev)) { 10122 if (netif_running(dev)) {
9844 tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; 10123 tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
9845 if (!tg3_restart_hw(tp, 1)) 10124 err2 = tg3_restart_hw(tp, 1);
10125 if (!err2)
9846 tg3_netif_start(tp); 10126 tg3_netif_start(tp);
9847 } 10127 }
9848 10128
9849 tg3_full_unlock(tp); 10129 tg3_full_unlock(tp);
10130
10131 if (irq_sync && !err2)
10132 tg3_phy_start(tp);
9850 } 10133 }
9851 if (tp->link_config.phy_is_low_power) 10134 if (tp->link_config.phy_is_low_power)
9852 tg3_set_power_state(tp, PCI_D3hot); 10135 tg3_set_power_state(tp, PCI_D3hot);
@@ -9859,6 +10142,12 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
9859 struct tg3 *tp = netdev_priv(dev); 10142 struct tg3 *tp = netdev_priv(dev);
9860 int err; 10143 int err;
9861 10144
10145 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
10146 if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
10147 return -EAGAIN;
10148 return phy_mii_ioctl(tp->mdio_bus.phy_map[PHY_ADDR], data, cmd);
10149 }
10150
9862 switch(cmd) { 10151 switch(cmd) {
9863 case SIOCGMIIPHY: 10152 case SIOCGMIIPHY:
9864 data->phy_id = PHY_ADDR; 10153 data->phy_id = PHY_ADDR;
@@ -11110,6 +11399,9 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
11110 u32 hw_phy_id, hw_phy_id_masked; 11399 u32 hw_phy_id, hw_phy_id_masked;
11111 int err; 11400 int err;
11112 11401
11402 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
11403 return tg3_phy_init(tp);
11404
11113 /* Reading the PHY ID register can conflict with ASF 11405 /* Reading the PHY ID register can conflict with ASF
11114 * firwmare access to the PHY hardware. 11406 * firwmare access to the PHY hardware.
11115 */ 11407 */
@@ -12043,6 +12335,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
12043 printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n", 12335 printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n",
12044 pci_name(tp->pdev), err); 12336 pci_name(tp->pdev), err);
12045 /* ... but do not return immediately ... */ 12337 /* ... but do not return immediately ... */
12338 tg3_mdio_fini(tp);
12046 } 12339 }
12047 12340
12048 tg3_read_partno(tp); 12341 tg3_read_partno(tp);
@@ -13163,8 +13456,10 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
13163 13456
13164 flush_scheduled_work(); 13457 flush_scheduled_work();
13165 13458
13166 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) 13459 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
13460 tg3_phy_fini(tp);
13167 tg3_mdio_fini(tp); 13461 tg3_mdio_fini(tp);
13462 }
13168 13463
13169 unregister_netdev(dev); 13464 unregister_netdev(dev);
13170 if (tp->aperegs) { 13465 if (tp->aperegs) {
@@ -13198,6 +13493,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
13198 return 0; 13493 return 0;
13199 13494
13200 flush_scheduled_work(); 13495 flush_scheduled_work();
13496 tg3_phy_stop(tp);
13201 tg3_netif_stop(tp); 13497 tg3_netif_stop(tp);
13202 13498
13203 del_timer_sync(&tp->timer); 13499 del_timer_sync(&tp->timer);
@@ -13215,10 +13511,13 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
13215 13511
13216 err = tg3_set_power_state(tp, pci_choose_state(pdev, state)); 13512 err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
13217 if (err) { 13513 if (err) {
13514 int err2;
13515
13218 tg3_full_lock(tp, 0); 13516 tg3_full_lock(tp, 0);
13219 13517
13220 tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; 13518 tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
13221 if (tg3_restart_hw(tp, 1)) 13519 err2 = tg3_restart_hw(tp, 1);
13520 if (err2)
13222 goto out; 13521 goto out;
13223 13522
13224 tp->timer.expires = jiffies + tp->timer_offset; 13523 tp->timer.expires = jiffies + tp->timer_offset;
@@ -13229,6 +13528,9 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
13229 13528
13230out: 13529out:
13231 tg3_full_unlock(tp); 13530 tg3_full_unlock(tp);
13531
13532 if (!err2)
13533 tg3_phy_start(tp);
13232 } 13534 }
13233 13535
13234 return err; 13536 return err;
@@ -13266,6 +13568,9 @@ static int tg3_resume(struct pci_dev *pdev)
13266out: 13568out:
13267 tg3_full_unlock(tp); 13569 tg3_full_unlock(tp);
13268 13570
13571 if (!err)
13572 tg3_phy_start(tp);
13573
13269 return err; 13574 return err;
13270} 13575}
13271 13576
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index e0914fdaf274..48f45c17f60d 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2205,6 +2205,7 @@ struct tg3_link_config {
2205 u16 orig_speed; 2205 u16 orig_speed;
2206 u8 orig_duplex; 2206 u8 orig_duplex;
2207 u8 orig_autoneg; 2207 u8 orig_autoneg;
2208 u32 orig_advertising;
2208}; 2209};
2209 2210
2210struct tg3_bufmgr_config { 2211struct tg3_bufmgr_config {
@@ -2483,6 +2484,7 @@ struct tg3 {
2483#define TG3_FLG3_USE_PHYLIB 0x00000010 2484#define TG3_FLG3_USE_PHYLIB 0x00000010
2484#define TG3_FLG3_MDIOBUS_INITED 0x00000020 2485#define TG3_FLG3_MDIOBUS_INITED 0x00000020
2485#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040 2486#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040
2487#define TG3_FLG3_PHY_CONNECTED 0x00000080
2486 2488
2487 struct timer_list timer; 2489 struct timer_list timer;
2488 u16 timer_counter; 2490 u16 timer_counter;