From: Maxim Levitsky <[EMAIL PROTECTED]> Subject: [PATCH] [NET] [003] dmfe : fix link detection
Cleanup link detection Fix link not detected when using external PHY Signed-off-by: Maxim Levitsky <[EMAIL PROTECTED]> --- CR12's bits 0 and 1 show link status/speed only for internal PHY. In case external one is used, only bit 6 shows link status via special line , and can be left unnconected Thus we need to check bit 6 and also query PHY for link status Note: internal phy is standard phy , so will indicate link status too. --- linux-2.6.20-mod/drivers/net/tulip/dmfe.c 2007-02-07 18:40:33.000000000 +0200 +++ linux-2.6.20-test/drivers/net/tulip/dmfe.c 2007-02-07 18:44:01.000000000 +0200 @@ -147,7 +147,7 @@ printk(KERN_ERR DRV_NAME ": %s %lx\n", (msg), (long) (value)) #define SHOW_MEDIA_TYPE(mode) \ - printk(KERN_ERR DRV_NAME ": \ + printk(KERN_INFO DRV_NAME ": \ Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", \ mode & 4 ? "full":"half"); @@ -242,7 +242,6 @@ struct dmfe_board_info { u8 media_mode; /* user specify media mode */ u8 op_mode; /* real work media mode */ u8 phy_addr; - u8 link_failed; /* Ever link failed */ u8 wait_reset; /* Hardware failed, need to reset */ u8 dm910x_chk_mode; /* Operating mode check */ u8 first_in_callback; /* Flag to record state */ @@ -536,7 +535,6 @@ static int dmfe_open(struct DEVICE *dev) db->tx_packet_cnt = 0; db->tx_queue_cnt = 0; db->rx_avail_cnt = 0; - db->link_failed = 1; db->wait_reset = 0; db->first_in_callback = 0; @@ -1091,6 +1089,8 @@ static void dmfe_timer(unsigned long dat struct dmfe_board_info *db = netdev_priv(dev); unsigned long flags; + int link_ok, link_ok_phy; + DMFE_DBUG(0, "dmfe_timer()", 0); spin_lock_irqsave(&db->lock, flags); @@ -1155,22 +1155,45 @@ static void dmfe_timer(unsigned long dat else tmp_cr12 = inb(db->ioaddr + DCR12); /* DM9102/DM9102A */ + if ( ((db->chip_id == PCI_DM9102_ID) && (db->chip_revision == 0x02000030)) || ((db->chip_id == PCI_DM9132_ID) && (db->chip_revision == 0x02000010)) ) { /* DM9102A Chip */ if (tmp_cr12 & 2) - tmp_cr12 = 0x0; /* Link failed */ + link_ok = 0; else - tmp_cr12 = 0x3; /* Link OK */ + link_ok = 1; + } + else + /*0x43 is used instead of 0x3 because bit 6 should be + connected to external PHY and specify its link status.*/ + link_ok = (tmp_cr12 & 0x43) ? 1 : 0; + + + /* If chip reports that link is failed it could be because external + PHY is not conected correctly to chip (through pin 89). + To be sure ask PHY too. + */ + + /* need a dummy read because of PHY's register latch*/ + phy_read (db->ioaddr, db->phy_addr, 1, db->chip_id); + link_ok_phy = (phy_read (db->ioaddr, + db->phy_addr, 1, db->chip_id) & 0x4) ? 1 : 0; + + + + if (link_ok_phy != link_ok) { + DMFE_DBUG (0, "PHY and chip report different link status", 0); + link_ok = link_ok | link_ok_phy; } - if ( !(tmp_cr12 & 0x3) && !db->link_failed ) { + if ( !link_ok && netif_carrier_ok(dev) ) { /* Link Failed */ DMFE_DBUG(0, "Link Failed", tmp_cr12); - db->link_failed = 1; - netif_carrier_off(db->dev); + + netif_carrier_off(dev); /* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */ /* AUTO or force 1M Homerun/Longrun don't need */ @@ -1184,19 +1207,17 @@ static void dmfe_timer(unsigned long dat db->cr6_data&=~0x00000200; /* bit9=0, HD mode */ update_cr6(db->cr6_data, db->ioaddr); } - } else - if ((tmp_cr12 & 0x3) && db->link_failed) { - DMFE_DBUG(0, "Link link OK", tmp_cr12); - db->link_failed = 0; + + } else if (!netif_carrier_ok(dev)) { + + DMFE_DBUG(0, "Link OK", tmp_cr12); /* Auto Sense Speed */ - if ( (db->media_mode & DMFE_AUTO) && - dmfe_sense_speed(db) ) - db->link_failed = 1; - else - netif_carrier_on(db->dev); + if (! (db->media_mode & DMFE_AUTO) || !dmfe_sense_speed(db)) { + netif_carrier_on(dev); + SHOW_MEDIA_TYPE(db->op_mode); + } dmfe_process_mode(db); - /* SHOW_MEDIA_TYPE(db->op_mode); */ } /* HPNA remote command check */ @@ -1243,7 +1264,7 @@ static void dmfe_dynamic_reset(struct DE db->tx_packet_cnt = 0; db->tx_queue_cnt = 0; db->rx_avail_cnt = 0; - db->link_failed = 1; + netif_carrier_off(dev); db->wait_reset = 0; /* Re-initilize DM910X board */ ____________________________________________________________________________________ Food fight? Enjoy some healthy debate in the Yahoo! Answers Food & Drink Q&A. http://answers.yahoo.com/dir/?link=list&sid=396545367 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html