diff options
| author | Ayaz Abdulla <aabdulla@nvidia.com> | 2008-04-23 14:37:30 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-25 02:08:57 -0400 |
| commit | 9f3f7910c67adfb520bbae3d8b16985439a97198 (patch) | |
| tree | e9f18409bc92f9342b9602bd8e259f044a3d8f72 | |
| parent | cca87c18ce3357e52facf6519f4ab0fbedd1279f (diff) | |
forcedeth: realtek phy crossover detection
This patch fixes an issue seen with the realtek 8201 phy. This phy has a
problem with crossover detection and it needs to be disabled. The
problem only arises on certain switches. Therefore, a module parameter
has been added to allow enabling crossover detection if needed. The
default will be set to disabled.
Signed-off-by: Ayaz Abdulla <aabdulla@nvidia.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
| -rw-r--r-- | drivers/net/forcedeth.c | 220 |
1 files changed, 178 insertions, 42 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 73d85b31fbdc..35f66d4a4595 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
| @@ -483,16 +483,22 @@ union ring_type { | |||
| 483 | #define DESC_VER_3 3 | 483 | #define DESC_VER_3 3 |
| 484 | 484 | ||
| 485 | /* PHY defines */ | 485 | /* PHY defines */ |
| 486 | #define PHY_OUI_MARVELL 0x5043 | 486 | #define PHY_OUI_MARVELL 0x5043 |
| 487 | #define PHY_OUI_CICADA 0x03f1 | 487 | #define PHY_OUI_CICADA 0x03f1 |
| 488 | #define PHY_OUI_VITESSE 0x01c1 | 488 | #define PHY_OUI_VITESSE 0x01c1 |
| 489 | #define PHY_OUI_REALTEK 0x0732 | 489 | #define PHY_OUI_REALTEK 0x0732 |
| 490 | #define PHY_OUI_REALTEK2 0x0020 | ||
| 490 | #define PHYID1_OUI_MASK 0x03ff | 491 | #define PHYID1_OUI_MASK 0x03ff |
| 491 | #define PHYID1_OUI_SHFT 6 | 492 | #define PHYID1_OUI_SHFT 6 |
| 492 | #define PHYID2_OUI_MASK 0xfc00 | 493 | #define PHYID2_OUI_MASK 0xfc00 |
| 493 | #define PHYID2_OUI_SHFT 10 | 494 | #define PHYID2_OUI_SHFT 10 |
| 494 | #define PHYID2_MODEL_MASK 0x03f0 | 495 | #define PHYID2_MODEL_MASK 0x03f0 |
| 495 | #define PHY_MODEL_MARVELL_E3016 0x220 | 496 | #define PHY_MODEL_REALTEK_8211 0x0110 |
| 497 | #define PHY_REV_MASK 0x0001 | ||
| 498 | #define PHY_REV_REALTEK_8211B 0x0000 | ||
| 499 | #define PHY_REV_REALTEK_8211C 0x0001 | ||
| 500 | #define PHY_MODEL_REALTEK_8201 0x0200 | ||
| 501 | #define PHY_MODEL_MARVELL_E3016 0x0220 | ||
| 496 | #define PHY_MARVELL_E3016_INITMASK 0x0300 | 502 | #define PHY_MARVELL_E3016_INITMASK 0x0300 |
| 497 | #define PHY_CICADA_INIT1 0x0f000 | 503 | #define PHY_CICADA_INIT1 0x0f000 |
| 498 | #define PHY_CICADA_INIT2 0x0e00 | 504 | #define PHY_CICADA_INIT2 0x0e00 |
| @@ -519,10 +525,18 @@ union ring_type { | |||
| 519 | #define PHY_REALTEK_INIT_REG1 0x1f | 525 | #define PHY_REALTEK_INIT_REG1 0x1f |
| 520 | #define PHY_REALTEK_INIT_REG2 0x19 | 526 | #define PHY_REALTEK_INIT_REG2 0x19 |
| 521 | #define PHY_REALTEK_INIT_REG3 0x13 | 527 | #define PHY_REALTEK_INIT_REG3 0x13 |
| 528 | #define PHY_REALTEK_INIT_REG4 0x14 | ||
| 529 | #define PHY_REALTEK_INIT_REG5 0x18 | ||
| 530 | #define PHY_REALTEK_INIT_REG6 0x11 | ||
| 522 | #define PHY_REALTEK_INIT1 0x0000 | 531 | #define PHY_REALTEK_INIT1 0x0000 |
| 523 | #define PHY_REALTEK_INIT2 0x8e00 | 532 | #define PHY_REALTEK_INIT2 0x8e00 |
| 524 | #define PHY_REALTEK_INIT3 0x0001 | 533 | #define PHY_REALTEK_INIT3 0x0001 |
| 525 | #define PHY_REALTEK_INIT4 0xad17 | 534 | #define PHY_REALTEK_INIT4 0xad17 |
| 535 | #define PHY_REALTEK_INIT5 0xfb54 | ||
| 536 | #define PHY_REALTEK_INIT6 0xf5c7 | ||
| 537 | #define PHY_REALTEK_INIT7 0x1000 | ||
| 538 | #define PHY_REALTEK_INIT8 0x0003 | ||
| 539 | #define PHY_REALTEK_INIT_MSK1 0x0003 | ||
| 526 | 540 | ||
| 527 | #define PHY_GIGABIT 0x0100 | 541 | #define PHY_GIGABIT 0x0100 |
| 528 | 542 | ||
| @@ -701,6 +715,7 @@ struct fe_priv { | |||
| 701 | int wolenabled; | 715 | int wolenabled; |
| 702 | unsigned int phy_oui; | 716 | unsigned int phy_oui; |
| 703 | unsigned int phy_model; | 717 | unsigned int phy_model; |
| 718 | unsigned int phy_rev; | ||
| 704 | u16 gigabit; | 719 | u16 gigabit; |
| 705 | int intr_test; | 720 | int intr_test; |
| 706 | int recover_error; | 721 | int recover_error; |
| @@ -714,6 +729,7 @@ struct fe_priv { | |||
| 714 | u32 txrxctl_bits; | 729 | u32 txrxctl_bits; |
| 715 | u32 vlanctl_bits; | 730 | u32 vlanctl_bits; |
| 716 | u32 driver_data; | 731 | u32 driver_data; |
| 732 | u32 device_id; | ||
| 717 | u32 register_size; | 733 | u32 register_size; |
| 718 | int rx_csum; | 734 | int rx_csum; |
| 719 | u32 mac_in_use; | 735 | u32 mac_in_use; |
| @@ -824,6 +840,16 @@ enum { | |||
| 824 | }; | 840 | }; |
| 825 | static int dma_64bit = NV_DMA_64BIT_ENABLED; | 841 | static int dma_64bit = NV_DMA_64BIT_ENABLED; |
| 826 | 842 | ||
| 843 | /* | ||
| 844 | * Crossover Detection | ||
| 845 | * Realtek 8201 phy + some OEM boards do not work properly. | ||
| 846 | */ | ||
| 847 | enum { | ||
| 848 | NV_CROSSOVER_DETECTION_DISABLED, | ||
| 849 | NV_CROSSOVER_DETECTION_ENABLED | ||
| 850 | }; | ||
| 851 | static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED; | ||
| 852 | |||
| 827 | static inline struct fe_priv *get_nvpriv(struct net_device *dev) | 853 | static inline struct fe_priv *get_nvpriv(struct net_device *dev) |
| 828 | { | 854 | { |
| 829 | return netdev_priv(dev); | 855 | return netdev_priv(dev); |
| @@ -1088,25 +1114,53 @@ static int phy_init(struct net_device *dev) | |||
| 1088 | } | 1114 | } |
| 1089 | } | 1115 | } |
| 1090 | if (np->phy_oui == PHY_OUI_REALTEK) { | 1116 | if (np->phy_oui == PHY_OUI_REALTEK) { |
| 1091 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | 1117 | if (np->phy_model == PHY_MODEL_REALTEK_8211 && |
| 1092 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1118 | np->phy_rev == PHY_REV_REALTEK_8211B) { |
| 1093 | return PHY_ERROR; | 1119 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { |
| 1094 | } | 1120 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 1095 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { | 1121 | return PHY_ERROR; |
| 1096 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1122 | } |
| 1097 | return PHY_ERROR; | 1123 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { |
| 1098 | } | 1124 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 1099 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { | 1125 | return PHY_ERROR; |
| 1100 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1126 | } |
| 1101 | return PHY_ERROR; | 1127 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { |
| 1102 | } | 1128 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 1103 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { | 1129 | return PHY_ERROR; |
| 1104 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1130 | } |
| 1105 | return PHY_ERROR; | 1131 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { |
| 1132 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1133 | return PHY_ERROR; | ||
| 1134 | } | ||
| 1135 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { | ||
| 1136 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1137 | return PHY_ERROR; | ||
| 1138 | } | ||
| 1139 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { | ||
| 1140 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1141 | return PHY_ERROR; | ||
| 1142 | } | ||
| 1143 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | ||
| 1144 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1145 | return PHY_ERROR; | ||
| 1146 | } | ||
| 1106 | } | 1147 | } |
| 1107 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | 1148 | if (np->phy_model == PHY_MODEL_REALTEK_8201) { |
| 1108 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1149 | if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 || |
| 1109 | return PHY_ERROR; | 1150 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 || |
| 1151 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 || | ||
| 1152 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 || | ||
| 1153 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 || | ||
| 1154 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 || | ||
| 1155 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 || | ||
| 1156 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) { | ||
| 1157 | phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); | ||
| 1158 | phy_reserved |= PHY_REALTEK_INIT7; | ||
| 1159 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { | ||
| 1160 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1161 | return PHY_ERROR; | ||
| 1162 | } | ||
| 1163 | } | ||
| 1110 | } | 1164 | } |
| 1111 | } | 1165 | } |
| 1112 | 1166 | ||
| @@ -1246,26 +1300,71 @@ static int phy_init(struct net_device *dev) | |||
| 1246 | } | 1300 | } |
| 1247 | } | 1301 | } |
| 1248 | if (np->phy_oui == PHY_OUI_REALTEK) { | 1302 | if (np->phy_oui == PHY_OUI_REALTEK) { |
| 1249 | /* reset could have cleared these out, set them back */ | 1303 | if (np->phy_model == PHY_MODEL_REALTEK_8211 && |
| 1250 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | 1304 | np->phy_rev == PHY_REV_REALTEK_8211B) { |
| 1251 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1305 | /* reset could have cleared these out, set them back */ |
| 1252 | return PHY_ERROR; | 1306 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { |
| 1253 | } | 1307 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 1254 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { | 1308 | return PHY_ERROR; |
| 1255 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1309 | } |
| 1256 | return PHY_ERROR; | 1310 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) { |
| 1257 | } | 1311 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 1258 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { | 1312 | return PHY_ERROR; |
| 1259 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1313 | } |
| 1260 | return PHY_ERROR; | 1314 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { |
| 1261 | } | 1315 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
| 1262 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { | 1316 | return PHY_ERROR; |
| 1263 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1317 | } |
| 1264 | return PHY_ERROR; | 1318 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) { |
| 1319 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1320 | return PHY_ERROR; | ||
| 1321 | } | ||
| 1322 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) { | ||
| 1323 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1324 | return PHY_ERROR; | ||
| 1325 | } | ||
| 1326 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) { | ||
| 1327 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1328 | return PHY_ERROR; | ||
| 1329 | } | ||
| 1330 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | ||
| 1331 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1332 | return PHY_ERROR; | ||
| 1333 | } | ||
| 1265 | } | 1334 | } |
| 1266 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | 1335 | if (np->phy_model == PHY_MODEL_REALTEK_8201) { |
| 1267 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 1336 | if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 || |
| 1268 | return PHY_ERROR; | 1337 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 || |
| 1338 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 || | ||
| 1339 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 || | ||
| 1340 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 || | ||
| 1341 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 || | ||
| 1342 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 || | ||
| 1343 | np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) { | ||
| 1344 | phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ); | ||
| 1345 | phy_reserved |= PHY_REALTEK_INIT7; | ||
| 1346 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) { | ||
| 1347 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1348 | return PHY_ERROR; | ||
| 1349 | } | ||
| 1350 | } | ||
| 1351 | if (phy_cross == NV_CROSSOVER_DETECTION_DISABLED) { | ||
| 1352 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) { | ||
| 1353 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1354 | return PHY_ERROR; | ||
| 1355 | } | ||
| 1356 | phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ); | ||
| 1357 | phy_reserved &= ~PHY_REALTEK_INIT_MSK1; | ||
| 1358 | phy_reserved |= PHY_REALTEK_INIT3; | ||
| 1359 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved)) { | ||
| 1360 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1361 | return PHY_ERROR; | ||
| 1362 | } | ||
| 1363 | if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) { | ||
| 1364 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | ||
| 1365 | return PHY_ERROR; | ||
| 1366 | } | ||
| 1367 | } | ||
| 1269 | } | 1368 | } |
| 1270 | } | 1369 | } |
| 1271 | 1370 | ||
| @@ -5254,6 +5353,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
| 5254 | 5353 | ||
| 5255 | /* copy of driver data */ | 5354 | /* copy of driver data */ |
| 5256 | np->driver_data = id->driver_data; | 5355 | np->driver_data = id->driver_data; |
| 5356 | /* copy of device id */ | ||
| 5357 | np->device_id = id->device; | ||
| 5257 | 5358 | ||
| 5258 | /* handle different descriptor versions */ | 5359 | /* handle different descriptor versions */ |
| 5259 | if (id->driver_data & DEV_HAS_HIGH_DMA) { | 5360 | if (id->driver_data & DEV_HAS_HIGH_DMA) { |
| @@ -5543,6 +5644,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
| 5543 | pci_name(pci_dev), id1, id2, phyaddr); | 5644 | pci_name(pci_dev), id1, id2, phyaddr); |
| 5544 | np->phyaddr = phyaddr; | 5645 | np->phyaddr = phyaddr; |
| 5545 | np->phy_oui = id1 | id2; | 5646 | np->phy_oui = id1 | id2; |
| 5647 | |||
| 5648 | /* Realtek hardcoded phy id1 to all zero's on certain phys */ | ||
| 5649 | if (np->phy_oui == PHY_OUI_REALTEK2) | ||
| 5650 | np->phy_oui = PHY_OUI_REALTEK; | ||
| 5651 | /* Setup phy revision for Realtek */ | ||
| 5652 | if (np->phy_oui == PHY_OUI_REALTEK && np->phy_model == PHY_MODEL_REALTEK_8211) | ||
| 5653 | np->phy_rev = mii_rw(dev, phyaddr, MII_RESV1, MII_READ) & PHY_REV_MASK; | ||
| 5654 | |||
| 5546 | break; | 5655 | break; |
| 5547 | } | 5656 | } |
| 5548 | if (i == 33) { | 5657 | if (i == 33) { |
| @@ -5621,6 +5730,28 @@ out: | |||
| 5621 | return err; | 5730 | return err; |
| 5622 | } | 5731 | } |
| 5623 | 5732 | ||
| 5733 | static void nv_restore_phy(struct net_device *dev) | ||
| 5734 | { | ||
| 5735 | struct fe_priv *np = netdev_priv(dev); | ||
| 5736 | u16 phy_reserved, mii_control; | ||
| 5737 | |||
| 5738 | if (np->phy_oui == PHY_OUI_REALTEK && | ||
| 5739 | np->phy_model == PHY_MODEL_REALTEK_8201 && | ||
| 5740 | phy_cross == NV_CROSSOVER_DETECTION_DISABLED) { | ||
| 5741 | mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3); | ||
| 5742 | phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ); | ||
| 5743 | phy_reserved &= ~PHY_REALTEK_INIT_MSK1; | ||
| 5744 | phy_reserved |= PHY_REALTEK_INIT8; | ||
| 5745 | mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved); | ||
| 5746 | mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1); | ||
| 5747 | |||
| 5748 | /* restart auto negotiation */ | ||
| 5749 | mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); | ||
| 5750 | mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); | ||
| 5751 | mii_rw(dev, np->phyaddr, MII_BMCR, mii_control); | ||
| 5752 | } | ||
| 5753 | } | ||
| 5754 | |||
| 5624 | static void __devexit nv_remove(struct pci_dev *pci_dev) | 5755 | static void __devexit nv_remove(struct pci_dev *pci_dev) |
| 5625 | { | 5756 | { |
| 5626 | struct net_device *dev = pci_get_drvdata(pci_dev); | 5757 | struct net_device *dev = pci_get_drvdata(pci_dev); |
| @@ -5637,6 +5768,9 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) | |||
| 5637 | writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV, | 5768 | writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV, |
| 5638 | base + NvRegTransmitPoll); | 5769 | base + NvRegTransmitPoll); |
| 5639 | 5770 | ||
| 5771 | /* restore any phy related changes */ | ||
| 5772 | nv_restore_phy(dev); | ||
| 5773 | |||
| 5640 | /* free all structures */ | 5774 | /* free all structures */ |
| 5641 | free_rings(dev); | 5775 | free_rings(dev); |
| 5642 | iounmap(get_hwbase(dev)); | 5776 | iounmap(get_hwbase(dev)); |
| @@ -5888,6 +6022,8 @@ module_param(msix, int, 0); | |||
| 5888 | MODULE_PARM_DESC(msix, "MSIX interrupts are enabled by setting to 1 and disabled by setting to 0."); | 6022 | MODULE_PARM_DESC(msix, "MSIX interrupts are enabled by setting to 1 and disabled by setting to 0."); |
| 5889 | module_param(dma_64bit, int, 0); | 6023 | module_param(dma_64bit, int, 0); |
| 5890 | MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0."); | 6024 | MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0."); |
| 6025 | module_param(phy_cross, int, 0); | ||
| 6026 | MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0."); | ||
| 5891 | 6027 | ||
| 5892 | MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>"); | 6028 | MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>"); |
| 5893 | MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); | 6029 | MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); |
