aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tulip
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2007-03-06 05:41:53 -0500
committerJeff Garzik <jeff@garzik.org>2007-03-06 06:10:02 -0500
commitcfa51b9dbf5aa385c6d1f8645587fdc4fe8c13fd (patch)
tree545f0226197bdd3b10f2cee33fd924de8245303b /drivers/net/tulip
parent4dc68f3de5e36d72663bb51b94662d2d5db84125 (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')
-rw-r--r--drivers/net/tulip/dmfe.c58
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
1083static const struct ethtool_ops netdev_ethtool_ops = { 1082static 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 */