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 /drivers | |
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>
Diffstat (limited to 'drivers')
-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"); |