diff options
author | Maxim Levitsky <maximlevitsky@gmail.com> | 2007-03-06 05:41:53 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-03-06 06:10:02 -0500 |
commit | cfa51b9dbf5aa385c6d1f8645587fdc4fe8c13fd (patch) | |
tree | 545f0226197bdd3b10f2cee33fd924de8245303b /drivers/net/tulip/dmfe.c | |
parent | 4dc68f3de5e36d72663bb51b94662d2d5db84125 (diff) |
dmfe: Fix link detection
Add link detection
Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
Cc: Valerie Henson <val_henson@linux.intel.com>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/tulip/dmfe.c')
-rw-r--r-- | drivers/net/tulip/dmfe.c | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index afd5e527032b..24a29c99ba94 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c | |||
@@ -248,7 +248,6 @@ struct dmfe_board_info { | |||
248 | u8 media_mode; /* user specify media mode */ | 248 | u8 media_mode; /* user specify media mode */ |
249 | u8 op_mode; /* real work media mode */ | 249 | u8 op_mode; /* real work media mode */ |
250 | u8 phy_addr; | 250 | u8 phy_addr; |
251 | u8 link_failed; /* Ever link failed */ | ||
252 | u8 wait_reset; /* Hardware failed, need to reset */ | 251 | u8 wait_reset; /* Hardware failed, need to reset */ |
253 | u8 dm910x_chk_mode; /* Operating mode check */ | 252 | u8 dm910x_chk_mode; /* Operating mode check */ |
254 | u8 first_in_callback; /* Flag to record state */ | 253 | u8 first_in_callback; /* Flag to record state */ |
@@ -447,6 +446,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, | |||
447 | dev->poll_controller = &poll_dmfe; | 446 | dev->poll_controller = &poll_dmfe; |
448 | #endif | 447 | #endif |
449 | dev->ethtool_ops = &netdev_ethtool_ops; | 448 | dev->ethtool_ops = &netdev_ethtool_ops; |
449 | netif_carrier_off(dev); | ||
450 | spin_lock_init(&db->lock); | 450 | spin_lock_init(&db->lock); |
451 | 451 | ||
452 | pci_read_config_dword(pdev, 0x50, &pci_pmr); | 452 | pci_read_config_dword(pdev, 0x50, &pci_pmr); |
@@ -541,7 +541,6 @@ static int dmfe_open(struct DEVICE *dev) | |||
541 | db->tx_packet_cnt = 0; | 541 | db->tx_packet_cnt = 0; |
542 | db->tx_queue_cnt = 0; | 542 | db->tx_queue_cnt = 0; |
543 | db->rx_avail_cnt = 0; | 543 | db->rx_avail_cnt = 0; |
544 | db->link_failed = 1; | ||
545 | db->wait_reset = 0; | 544 | db->wait_reset = 0; |
546 | 545 | ||
547 | db->first_in_callback = 0; | 546 | db->first_in_callback = 0; |
@@ -1082,6 +1081,7 @@ static void netdev_get_drvinfo(struct net_device *dev, | |||
1082 | 1081 | ||
1083 | static const struct ethtool_ops netdev_ethtool_ops = { | 1082 | static const struct ethtool_ops netdev_ethtool_ops = { |
1084 | .get_drvinfo = netdev_get_drvinfo, | 1083 | .get_drvinfo = netdev_get_drvinfo, |
1084 | .get_link = ethtool_op_get_link, | ||
1085 | }; | 1085 | }; |
1086 | 1086 | ||
1087 | /* | 1087 | /* |
@@ -1097,6 +1097,8 @@ static void dmfe_timer(unsigned long data) | |||
1097 | struct dmfe_board_info *db = netdev_priv(dev); | 1097 | struct dmfe_board_info *db = netdev_priv(dev); |
1098 | unsigned long flags; | 1098 | unsigned long flags; |
1099 | 1099 | ||
1100 | int link_ok, link_ok_phy; | ||
1101 | |||
1100 | DMFE_DBUG(0, "dmfe_timer()", 0); | 1102 | DMFE_DBUG(0, "dmfe_timer()", 0); |
1101 | spin_lock_irqsave(&db->lock, flags); | 1103 | spin_lock_irqsave(&db->lock, flags); |
1102 | 1104 | ||
@@ -1168,15 +1170,35 @@ static void dmfe_timer(unsigned long data) | |||
1168 | (db->chip_revision == 0x02000010)) ) { | 1170 | (db->chip_revision == 0x02000010)) ) { |
1169 | /* DM9102A Chip */ | 1171 | /* DM9102A Chip */ |
1170 | if (tmp_cr12 & 2) | 1172 | if (tmp_cr12 & 2) |
1171 | tmp_cr12 = 0x0; /* Link failed */ | 1173 | link_ok = 0; |
1172 | else | 1174 | else |
1173 | tmp_cr12 = 0x3; /* Link OK */ | 1175 | link_ok = 1; |
1174 | } | 1176 | } |
1177 | else | ||
1178 | /*0x43 is used instead of 0x3 because bit 6 should represent | ||
1179 | link status of external PHY */ | ||
1180 | link_ok = (tmp_cr12 & 0x43) ? 1 : 0; | ||
1181 | |||
1182 | |||
1183 | /* If chip reports that link is failed it could be because external | ||
1184 | PHY link status pin is not conected correctly to chip | ||
1185 | To be sure ask PHY too. | ||
1186 | */ | ||
1187 | |||
1188 | /* need a dummy read because of PHY's register latch*/ | ||
1189 | phy_read (db->ioaddr, db->phy_addr, 1, db->chip_id); | ||
1190 | link_ok_phy = (phy_read (db->ioaddr, | ||
1191 | db->phy_addr, 1, db->chip_id) & 0x4) ? 1 : 0; | ||
1192 | |||
1193 | if (link_ok_phy != link_ok) { | ||
1194 | DMFE_DBUG (0, "PHY and chip report different link status", 0); | ||
1195 | link_ok = link_ok | link_ok_phy; | ||
1196 | } | ||
1175 | 1197 | ||
1176 | if ( !(tmp_cr12 & 0x3) && !db->link_failed ) { | 1198 | if ( !link_ok && netif_carrier_ok(dev)) { |
1177 | /* Link Failed */ | 1199 | /* Link Failed */ |
1178 | DMFE_DBUG(0, "Link Failed", tmp_cr12); | 1200 | DMFE_DBUG(0, "Link Failed", tmp_cr12); |
1179 | db->link_failed = 1; | 1201 | netif_carrier_off(dev); |
1180 | 1202 | ||
1181 | /* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */ | 1203 | /* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */ |
1182 | /* AUTO or force 1M Homerun/Longrun don't need */ | 1204 | /* AUTO or force 1M Homerun/Longrun don't need */ |
@@ -1191,19 +1213,19 @@ static void dmfe_timer(unsigned long data) | |||
1191 | db->cr6_data&=~0x00000200; /* bit9=0, HD mode */ | 1213 | db->cr6_data&=~0x00000200; /* bit9=0, HD mode */ |
1192 | update_cr6(db->cr6_data, db->ioaddr); | 1214 | update_cr6(db->cr6_data, db->ioaddr); |
1193 | } | 1215 | } |
1194 | } else | 1216 | } else if (!netif_carrier_ok(dev)) { |
1195 | if ((tmp_cr12 & 0x3) && db->link_failed) { | 1217 | |
1196 | DMFE_DBUG(0, "Link link OK", tmp_cr12); | 1218 | DMFE_DBUG(0, "Link link OK", tmp_cr12); |
1197 | db->link_failed = 0; | 1219 | |
1198 | 1220 | /* Auto Sense Speed */ | |
1199 | /* Auto Sense Speed */ | 1221 | if ( !(db->media_mode & DMFE_AUTO) || !dmfe_sense_speed(db)) { |
1200 | if ( (db->media_mode & DMFE_AUTO) && | 1222 | netif_carrier_on(dev); |
1201 | dmfe_sense_speed(db) ) | 1223 | SHOW_MEDIA_TYPE(db->op_mode); |
1202 | db->link_failed = 1; | ||
1203 | dmfe_process_mode(db); | ||
1204 | /* SHOW_MEDIA_TYPE(db->op_mode); */ | ||
1205 | } | 1224 | } |
1206 | 1225 | ||
1226 | dmfe_process_mode(db); | ||
1227 | } | ||
1228 | |||
1207 | /* HPNA remote command check */ | 1229 | /* HPNA remote command check */ |
1208 | if (db->HPNA_command & 0xf00) { | 1230 | if (db->HPNA_command & 0xf00) { |
1209 | db->HPNA_timer--; | 1231 | db->HPNA_timer--; |
@@ -1248,7 +1270,7 @@ static void dmfe_dynamic_reset(struct DEVICE *dev) | |||
1248 | db->tx_packet_cnt = 0; | 1270 | db->tx_packet_cnt = 0; |
1249 | db->tx_queue_cnt = 0; | 1271 | db->tx_queue_cnt = 0; |
1250 | db->rx_avail_cnt = 0; | 1272 | db->rx_avail_cnt = 0; |
1251 | db->link_failed = 1; | 1273 | netif_carrier_off(dev); |
1252 | db->wait_reset = 0; | 1274 | db->wait_reset = 0; |
1253 | 1275 | ||
1254 | /* Re-initilize DM910X board */ | 1276 | /* Re-initilize DM910X board */ |