Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Matt Carlson and committed by
David S. Miller
b02fd9e3 158d7abd

+355 -48
+353 -48
drivers/net/tg3.c
··· 1114 1114 1115 1115 static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv) 1116 1116 { 1117 + u8 autoneg; 1117 1118 u8 flowctrl = 0; 1118 1119 u32 old_rx_mode = tp->rx_mode; 1119 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 1128 (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) { 1123 1129 if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) 1124 1130 flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv); ··· 1150 1144 1151 1145 if (old_tx_mode != tp->tx_mode) 1152 1146 tw32_f(MAC_TX_MODE, tp->tx_mode); 1147 + } 1148 + 1149 + static void tg3_adjust_link(struct net_device *dev) 1150 + { 1151 + u8 oldflowctrl, linkmesg = 0; 1152 + u32 mac_mode, lcl_adv, rmt_adv; 1153 + struct tg3 *tp = netdev_priv(dev); 1154 + struct phy_device *phydev = tp->mdio_bus.phy_map[PHY_ADDR]; 1155 + 1156 + spin_lock(&tp->lock); 1157 + 1158 + mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK | 1159 + MAC_MODE_HALF_DUPLEX); 1160 + 1161 + oldflowctrl = tp->link_config.active_flowctrl; 1162 + 1163 + if (phydev->link) { 1164 + lcl_adv = 0; 1165 + rmt_adv = 0; 1166 + 1167 + if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10) 1168 + mac_mode |= MAC_MODE_PORT_MODE_MII; 1169 + else 1170 + mac_mode |= MAC_MODE_PORT_MODE_GMII; 1171 + 1172 + if (phydev->duplex == DUPLEX_HALF) 1173 + mac_mode |= MAC_MODE_HALF_DUPLEX; 1174 + else { 1175 + lcl_adv = tg3_advert_flowctrl_1000T( 1176 + tp->link_config.flowctrl); 1177 + 1178 + if (phydev->pause) 1179 + rmt_adv = LPA_PAUSE_CAP; 1180 + if (phydev->asym_pause) 1181 + rmt_adv |= LPA_PAUSE_ASYM; 1182 + } 1183 + 1184 + tg3_setup_flow_control(tp, lcl_adv, rmt_adv); 1185 + } else 1186 + mac_mode |= MAC_MODE_PORT_MODE_GMII; 1187 + 1188 + if (mac_mode != tp->mac_mode) { 1189 + tp->mac_mode = mac_mode; 1190 + tw32_f(MAC_MODE, tp->mac_mode); 1191 + udelay(40); 1192 + } 1193 + 1194 + if (phydev->speed == SPEED_1000 && phydev->duplex == DUPLEX_HALF) 1195 + tw32(MAC_TX_LENGTHS, 1196 + ((2 << TX_LENGTHS_IPG_CRS_SHIFT) | 1197 + (6 << TX_LENGTHS_IPG_SHIFT) | 1198 + (0xff << TX_LENGTHS_SLOT_TIME_SHIFT))); 1199 + else 1200 + tw32(MAC_TX_LENGTHS, 1201 + ((2 << TX_LENGTHS_IPG_CRS_SHIFT) | 1202 + (6 << TX_LENGTHS_IPG_SHIFT) | 1203 + (32 << TX_LENGTHS_SLOT_TIME_SHIFT))); 1204 + 1205 + if ((phydev->link && tp->link_config.active_speed == SPEED_INVALID) || 1206 + (!phydev->link && tp->link_config.active_speed != SPEED_INVALID) || 1207 + phydev->speed != tp->link_config.active_speed || 1208 + phydev->duplex != tp->link_config.active_duplex || 1209 + oldflowctrl != tp->link_config.active_flowctrl) 1210 + linkmesg = 1; 1211 + 1212 + tp->link_config.active_speed = phydev->speed; 1213 + tp->link_config.active_duplex = phydev->duplex; 1214 + 1215 + spin_unlock(&tp->lock); 1216 + 1217 + if (linkmesg) 1218 + tg3_link_report(tp); 1219 + } 1220 + 1221 + static int tg3_phy_init(struct tg3 *tp) 1222 + { 1223 + struct phy_device *phydev; 1224 + 1225 + if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) 1226 + return 0; 1227 + 1228 + /* Bring the PHY back to a known state. */ 1229 + tg3_bmcr_reset(tp); 1230 + 1231 + phydev = tp->mdio_bus.phy_map[PHY_ADDR]; 1232 + 1233 + /* Attach the MAC to the PHY. */ 1234 + phydev = phy_connect(tp->dev, phydev->dev.bus_id, 1235 + tg3_adjust_link, 0, phydev->interface); 1236 + if (IS_ERR(phydev)) { 1237 + printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name); 1238 + return PTR_ERR(phydev); 1239 + } 1240 + 1241 + tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED; 1242 + 1243 + /* Mask with MAC supported features. */ 1244 + phydev->supported &= (PHY_GBIT_FEATURES | 1245 + SUPPORTED_Pause | 1246 + SUPPORTED_Asym_Pause); 1247 + 1248 + phydev->advertising = phydev->supported; 1249 + 1250 + printk(KERN_INFO 1251 + "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", 1252 + tp->dev->name, phydev->drv->name, phydev->dev.bus_id); 1253 + 1254 + return 0; 1255 + } 1256 + 1257 + static void tg3_phy_start(struct tg3 *tp) 1258 + { 1259 + struct phy_device *phydev; 1260 + 1261 + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) 1262 + return; 1263 + 1264 + phydev = tp->mdio_bus.phy_map[PHY_ADDR]; 1265 + 1266 + if (tp->link_config.phy_is_low_power) { 1267 + tp->link_config.phy_is_low_power = 0; 1268 + phydev->speed = tp->link_config.orig_speed; 1269 + phydev->duplex = tp->link_config.orig_duplex; 1270 + phydev->autoneg = tp->link_config.orig_autoneg; 1271 + phydev->advertising = tp->link_config.orig_advertising; 1272 + } 1273 + 1274 + phy_start(phydev); 1275 + 1276 + phy_start_aneg(phydev); 1277 + } 1278 + 1279 + static void tg3_phy_stop(struct tg3 *tp) 1280 + { 1281 + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) 1282 + return; 1283 + 1284 + phy_stop(tp->mdio_bus.phy_map[PHY_ADDR]); 1285 + } 1286 + 1287 + static void tg3_phy_fini(struct tg3 *tp) 1288 + { 1289 + if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) { 1290 + phy_disconnect(tp->mdio_bus.phy_map[PHY_ADDR]); 1291 + tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED; 1292 + } 1153 1293 } 1154 1294 1155 1295 static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val) ··· 1950 1798 misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT); 1951 1799 1952 1800 if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 1953 - tp->link_config.phy_is_low_power = 1; 1801 + if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) && 1802 + !tp->link_config.phy_is_low_power) { 1803 + struct phy_device *phydev; 1804 + u32 advertising; 1805 + 1806 + phydev = tp->mdio_bus.phy_map[PHY_ADDR]; 1807 + 1808 + tp->link_config.phy_is_low_power = 1; 1809 + 1810 + tp->link_config.orig_speed = phydev->speed; 1811 + tp->link_config.orig_duplex = phydev->duplex; 1812 + tp->link_config.orig_autoneg = phydev->autoneg; 1813 + tp->link_config.orig_advertising = phydev->advertising; 1814 + 1815 + advertising = ADVERTISED_TP | 1816 + ADVERTISED_Pause | 1817 + ADVERTISED_Autoneg | 1818 + ADVERTISED_10baseT_Half; 1819 + 1820 + if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) || 1821 + (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) { 1822 + if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB) 1823 + advertising |= 1824 + ADVERTISED_100baseT_Half | 1825 + ADVERTISED_100baseT_Full | 1826 + ADVERTISED_10baseT_Full; 1827 + else 1828 + advertising |= ADVERTISED_10baseT_Full; 1829 + } 1830 + 1831 + phydev->advertising = advertising; 1832 + 1833 + phy_start_aneg(phydev); 1834 + } 1954 1835 } else { 1955 1836 if (tp->link_config.phy_is_low_power == 0) { 1956 1837 tp->link_config.phy_is_low_power = 1; ··· 4418 4233 static void tg3_reset_task(struct work_struct *work) 4419 4234 { 4420 4235 struct tg3 *tp = container_of(work, struct tg3, reset_task); 4236 + int err; 4421 4237 unsigned int restart_timer; 4422 4238 4423 4239 tg3_full_lock(tp, 0); ··· 4429 4243 } 4430 4244 4431 4245 tg3_full_unlock(tp); 4246 + 4247 + tg3_phy_stop(tp); 4432 4248 4433 4249 tg3_netif_stop(tp); 4434 4250 ··· 4447 4259 } 4448 4260 4449 4261 tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); 4450 - if (tg3_init_hw(tp, 1)) 4262 + err = tg3_init_hw(tp, 1); 4263 + if (err) 4451 4264 goto out; 4452 4265 4453 4266 tg3_netif_start(tp); ··· 4458 4269 4459 4270 out: 4460 4271 tg3_full_unlock(tp); 4272 + 4273 + if (!err) 4274 + tg3_phy_start(tp); 4461 4275 } 4462 4276 4463 4277 static void tg3_dump_short_state(struct tg3 *tp) ··· 4964 4772 return 0; 4965 4773 } 4966 4774 4775 + tg3_phy_stop(tp); 4776 + 4967 4777 tg3_netif_stop(tp); 4968 4778 4969 4779 tg3_full_lock(tp, 1); ··· 4980 4786 tg3_netif_start(tp); 4981 4787 4982 4788 tg3_full_unlock(tp); 4789 + 4790 + if (!err) 4791 + tg3_phy_start(tp); 4983 4792 4984 4793 return err; 4985 4794 } ··· 8061 7864 } 8062 7865 } 8063 7866 7867 + tg3_phy_start(tp); 7868 + 8064 7869 tg3_full_lock(tp, 0); 8065 7870 8066 7871 add_timer(&tp->timer); ··· 8864 8665 8865 8666 static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 8866 8667 { 8867 - struct tg3 *tp = netdev_priv(dev); 8668 + struct tg3 *tp = netdev_priv(dev); 8669 + 8670 + if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 8671 + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) 8672 + return -EAGAIN; 8673 + return phy_ethtool_gset(tp->mdio_bus.phy_map[PHY_ADDR], cmd); 8674 + } 8868 8675 8869 8676 cmd->supported = (SUPPORTED_Autoneg); 8870 8677 ··· 8907 8702 { 8908 8703 struct tg3 *tp = netdev_priv(dev); 8909 8704 8705 + if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 8706 + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) 8707 + return -EAGAIN; 8708 + return phy_ethtool_sset(tp->mdio_bus.phy_map[PHY_ADDR], cmd); 8709 + } 8710 + 8910 8711 if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { 8911 8712 /* These are the only valid advertisement bits allowed. */ 8912 8713 if (cmd->autoneg == AUTONEG_ENABLE && ··· 8945 8734 tp->link_config.advertising = 0; 8946 8735 tp->link_config.speed = cmd->speed; 8947 8736 tp->link_config.duplex = cmd->duplex; 8948 - } 8737 + } 8949 8738 8950 8739 tp->link_config.orig_speed = tp->link_config.speed; 8951 8740 tp->link_config.orig_duplex = tp->link_config.duplex; ··· 9039 8828 static int tg3_nway_reset(struct net_device *dev) 9040 8829 { 9041 8830 struct tg3 *tp = netdev_priv(dev); 9042 - u32 bmcr; 9043 8831 int r; 9044 8832 9045 8833 if (!netif_running(dev)) ··· 9047 8837 if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) 9048 8838 return -EINVAL; 9049 8839 9050 - spin_lock_bh(&tp->lock); 9051 - r = -EINVAL; 9052 - tg3_readphy(tp, MII_BMCR, &bmcr); 9053 - if (!tg3_readphy(tp, MII_BMCR, &bmcr) && 9054 - ((bmcr & BMCR_ANENABLE) || 9055 - (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) { 9056 - tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART | 9057 - BMCR_ANENABLE); 9058 - r = 0; 8840 + if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 8841 + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) 8842 + return -EAGAIN; 8843 + r = phy_start_aneg(tp->mdio_bus.phy_map[PHY_ADDR]); 8844 + } else { 8845 + u32 bmcr; 8846 + 8847 + spin_lock_bh(&tp->lock); 8848 + r = -EINVAL; 8849 + tg3_readphy(tp, MII_BMCR, &bmcr); 8850 + if (!tg3_readphy(tp, MII_BMCR, &bmcr) && 8851 + ((bmcr & BMCR_ANENABLE) || 8852 + (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) { 8853 + tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART | 8854 + BMCR_ANENABLE); 8855 + r = 0; 8856 + } 8857 + spin_unlock_bh(&tp->lock); 9059 8858 } 9060 - spin_unlock_bh(&tp->lock); 9061 8859 9062 8860 return r; 9063 8861 } ··· 9107 8889 return -EINVAL; 9108 8890 9109 8891 if (netif_running(dev)) { 8892 + tg3_phy_stop(tp); 9110 8893 tg3_netif_stop(tp); 9111 8894 irq_sync = 1; 9112 8895 } ··· 9130 8911 } 9131 8912 9132 8913 tg3_full_unlock(tp); 8914 + 8915 + if (irq_sync && !err) 8916 + tg3_phy_start(tp); 9133 8917 9134 8918 return err; 9135 8919 } ··· 9157 8935 static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) 9158 8936 { 9159 8937 struct tg3 *tp = netdev_priv(dev); 9160 - int irq_sync = 0, err = 0; 8938 + int err = 0; 9161 8939 9162 - if (netif_running(dev)) { 9163 - tg3_netif_stop(tp); 9164 - irq_sync = 1; 8940 + if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 8941 + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) 8942 + return -EAGAIN; 8943 + 8944 + if (epause->autoneg) { 8945 + u32 newadv; 8946 + struct phy_device *phydev; 8947 + 8948 + phydev = tp->mdio_bus.phy_map[PHY_ADDR]; 8949 + 8950 + if (epause->rx_pause) { 8951 + if (epause->tx_pause) 8952 + newadv = ADVERTISED_Pause; 8953 + else 8954 + newadv = ADVERTISED_Pause | 8955 + ADVERTISED_Asym_Pause; 8956 + } else if (epause->tx_pause) { 8957 + newadv = ADVERTISED_Asym_Pause; 8958 + } else 8959 + newadv = 0; 8960 + 8961 + if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) { 8962 + u32 oldadv = phydev->advertising & 8963 + (ADVERTISED_Pause | 8964 + ADVERTISED_Asym_Pause); 8965 + if (oldadv != newadv) { 8966 + phydev->advertising &= 8967 + ~(ADVERTISED_Pause | 8968 + ADVERTISED_Asym_Pause); 8969 + phydev->advertising |= newadv; 8970 + err = phy_start_aneg(phydev); 8971 + } 8972 + } else { 8973 + tp->link_config.advertising &= 8974 + ~(ADVERTISED_Pause | 8975 + ADVERTISED_Asym_Pause); 8976 + tp->link_config.advertising |= newadv; 8977 + } 8978 + } else { 8979 + if (epause->rx_pause) 8980 + tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX; 8981 + else 8982 + tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX; 8983 + 8984 + if (epause->tx_pause) 8985 + tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX; 8986 + else 8987 + tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX; 8988 + 8989 + if (netif_running(dev)) 8990 + tg3_setup_flow_control(tp, 0, 0); 8991 + } 8992 + } else { 8993 + int irq_sync = 0; 8994 + 8995 + if (netif_running(dev)) { 8996 + tg3_netif_stop(tp); 8997 + irq_sync = 1; 8998 + } 8999 + 9000 + tg3_full_lock(tp, irq_sync); 9001 + 9002 + if (epause->autoneg) 9003 + tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; 9004 + else 9005 + tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; 9006 + if (epause->rx_pause) 9007 + tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX; 9008 + else 9009 + tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX; 9010 + if (epause->tx_pause) 9011 + tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX; 9012 + else 9013 + tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX; 9014 + 9015 + if (netif_running(dev)) { 9016 + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); 9017 + err = tg3_restart_hw(tp, 1); 9018 + if (!err) 9019 + tg3_netif_start(tp); 9020 + } 9021 + 9022 + tg3_full_unlock(tp); 9165 9023 } 9166 - 9167 - tg3_full_lock(tp, irq_sync); 9168 - 9169 - if (epause->autoneg) 9170 - tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; 9171 - else 9172 - tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG; 9173 - if (epause->rx_pause) 9174 - tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX; 9175 - else 9176 - tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX; 9177 - if (epause->tx_pause) 9178 - tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX; 9179 - else 9180 - tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX; 9181 - 9182 - if (netif_running(dev)) { 9183 - tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); 9184 - err = tg3_restart_hw(tp, 1); 9185 - if (!err) 9186 - tg3_netif_start(tp); 9187 - } 9188 - 9189 - tg3_full_unlock(tp); 9190 9024 9191 9025 return err; 9192 9026 } ··· 10077 9799 data[1] = 1; 10078 9800 } 10079 9801 if (etest->flags & ETH_TEST_FL_OFFLINE) { 10080 - int err, irq_sync = 0; 9802 + int err, err2 = 0, irq_sync = 0; 10081 9803 10082 9804 if (netif_running(dev)) { 9805 + tg3_phy_stop(tp); 10083 9806 tg3_netif_stop(tp); 10084 9807 irq_sync = 1; 10085 9808 } ··· 10121 9842 tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); 10122 9843 if (netif_running(dev)) { 10123 9844 tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; 10124 - if (!tg3_restart_hw(tp, 1)) 9845 + err2 = tg3_restart_hw(tp, 1); 9846 + if (!err2) 10125 9847 tg3_netif_start(tp); 10126 9848 } 10127 9849 10128 9850 tg3_full_unlock(tp); 9851 + 9852 + if (irq_sync && !err2) 9853 + tg3_phy_start(tp); 10129 9854 } 10130 9855 if (tp->link_config.phy_is_low_power) 10131 9856 tg3_set_power_state(tp, PCI_D3hot); ··· 10141 9858 struct mii_ioctl_data *data = if_mii(ifr); 10142 9859 struct tg3 *tp = netdev_priv(dev); 10143 9860 int err; 9861 + 9862 + if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 9863 + if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) 9864 + return -EAGAIN; 9865 + return phy_mii_ioctl(tp->mdio_bus.phy_map[PHY_ADDR], data, cmd); 9866 + } 10144 9867 10145 9868 switch(cmd) { 10146 9869 case SIOCGMIIPHY: ··· 11399 11110 u32 hw_phy_id, hw_phy_id_masked; 11400 11111 int err; 11401 11112 11113 + if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) 11114 + return tg3_phy_init(tp); 11115 + 11402 11116 /* Reading the PHY ID register can conflict with ASF 11403 11117 * firwmare access to the PHY hardware. 11404 11118 */ ··· 12335 12043 printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n", 12336 12044 pci_name(tp->pdev), err); 12337 12045 /* ... but do not return immediately ... */ 12046 + tg3_mdio_fini(tp); 12338 12047 } 12339 12048 12340 12049 tg3_read_partno(tp); ··· 13456 13163 13457 13164 flush_scheduled_work(); 13458 13165 13459 - if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) 13166 + if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { 13167 + tg3_phy_fini(tp); 13460 13168 tg3_mdio_fini(tp); 13169 + } 13461 13170 13462 13171 unregister_netdev(dev); 13463 13172 if (tp->aperegs) { ··· 13493 13198 return 0; 13494 13199 13495 13200 flush_scheduled_work(); 13201 + tg3_phy_stop(tp); 13496 13202 tg3_netif_stop(tp); 13497 13203 13498 13204 del_timer_sync(&tp->timer); ··· 13511 13215 13512 13216 err = tg3_set_power_state(tp, pci_choose_state(pdev, state)); 13513 13217 if (err) { 13218 + int err2; 13219 + 13514 13220 tg3_full_lock(tp, 0); 13515 13221 13516 13222 tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; 13517 - if (tg3_restart_hw(tp, 1)) 13223 + err2 = tg3_restart_hw(tp, 1); 13224 + if (err2) 13518 13225 goto out; 13519 13226 13520 13227 tp->timer.expires = jiffies + tp->timer_offset; ··· 13528 13229 13529 13230 out: 13530 13231 tg3_full_unlock(tp); 13232 + 13233 + if (!err2) 13234 + tg3_phy_start(tp); 13531 13235 } 13532 13236 13533 13237 return err; ··· 13567 13265 13568 13266 out: 13569 13267 tg3_full_unlock(tp); 13268 + 13269 + if (!err) 13270 + tg3_phy_start(tp); 13570 13271 13571 13272 return err; 13572 13273 }
+2
drivers/net/tg3.h
··· 2205 2205 u16 orig_speed; 2206 2206 u8 orig_duplex; 2207 2207 u8 orig_autoneg; 2208 + u32 orig_advertising; 2208 2209 }; 2209 2210 2210 2211 struct tg3_bufmgr_config { ··· 2484 2483 #define TG3_FLG3_USE_PHYLIB 0x00000010 2485 2484 #define TG3_FLG3_MDIOBUS_INITED 0x00000020 2486 2485 #define TG3_FLG3_MDIOBUS_PAUSED 0x00000040 2486 + #define TG3_FLG3_PHY_CONNECTED 0x00000080 2487 2487 2488 2488 struct timer_list timer; 2489 2489 u16 timer_counter;