if_bge driver problem. - Upgrade to RELEASE :)

Oleg Bulyzhin oleg at FreeBSD.org
Tue Jan 31 17:05:47 PST 2006


On Tue, Jan 31, 2006 at 04:23:12PM +0200, husnu demir wrote:
> On Tue, Jan 31, 2006 at 05:16:55PM +0300, Oleg Bulyzhin wrote:
> > On Tue, Jan 31, 2006 at 03:31:11PM +0200, husnu demir wrote:
> > > Anyway, let me learn to use cvs some other day. I do what u said and applied patch. It is working. At least I can ping and when I gave an IP address to the Interface and remove the physical connection, it shows UP/DOWN. If it is made UP but has no IP address, It shows nothing. But I will use it with an IP address so no problem.
> > > 
> > 
> > Excuse me, I didnt understand this one:
> > "If it is made UP but has no IP address, It shows nothing."
> > 
> > Are you talking about running 'ifconfig bge2 up' (without ip bound to bge2)?
> > "It shows nothing" -  does it mean no UP/DOWN messages in console.log or
> > ifconfig bge2 reports status 'no carrier'?
> > 
> 
> Yes, I made ifconfig bge2 up without ip bound. Then remove the physical connection but no messages seen on the console. Even it did not show 'no carrier' messages. Still sees active.
> 

If you are not tired yet - new patch attached (it's against RELENG_6 so you have
to revert previous patch).

P.S. Thanks for your testing. Unfortunatly i've got only copper bges so i cant
test it myself.
P.P.S. if possible, test polling mode too.

-- 
Oleg.

-------------- next part --------------
Index: if_bgereg.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/bge/if_bgereg.h,v
retrieving revision 1.45
diff -u -r1.45 if_bgereg.h
--- if_bgereg.h	18 Jan 2006 14:31:21 -0000	1.45
+++ if_bgereg.h	1 Feb 2006 00:52:12 -0000
@@ -2421,7 +2421,8 @@
 	u_int32_t		bge_tx_buf_ratio;
 	int			bge_if_flags;
 	int			bge_txcnt;
-	int			bge_link;
+	int			bge_link;	/* link state */
+	int			bge_link_evt;	/* pending link event */
 	struct callout		bge_stat_ch;
 	char			*bge_vpd_prodname;
 	char			*bge_vpd_readonly;
Index: if_bge.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/bge/if_bge.c,v
retrieving revision 1.118
diff -u -r1.118 if_bge.c
--- if_bge.c	30 Jan 2006 13:45:55 -0000	1.118
+++ if_bge.c	1 Feb 2006 00:52:20 -0000
@@ -2732,31 +2732,33 @@
 bge_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct bge_softc *sc = ifp->if_softc;
+	uint32_t statusword;
 
 	BGE_LOCK_ASSERT(sc);
 
-	sc->rxcycles = count;
-	bge_rxeof(sc);
-	bge_txeof(sc);
-	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-		bge_start_locked(ifp);
+	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTREAD);
 
-	if (cmd == POLL_AND_CHECK_STATUS) {
-		uint32_t statusword;
+	statusword = atomic_readandclear_32(&sc->bge_ldata.bge_status_block->bge_status);
 
-		bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
-		    sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTREAD);
+	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
 
-	    	statusword = atomic_readandclear_32(&sc->bge_ldata.bge_status_block->bge_status);
+	/* Note link event. It will be processed by POLL_AND_CHECK_STATUS cmd */
+	if (statusword & BGE_STATFLAG_LINKSTATE_CHANGED)
+		sc->bge_link_evt++;
 
+	if (cmd == POLL_AND_CHECK_STATUS)
 		if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
 		    sc->bge_chipid != BGE_CHIPID_BCM5700_B1) ||
-		    statusword & BGE_STATFLAG_LINKSTATE_CHANGED)
+		    sc->bge_link_evt || sc->bge_tbi)
 			bge_link_upd(sc);
 
-		bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
-		    sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
-	}
+	sc->rxcycles = count;
+	bge_rxeof(sc);
+	bge_txeof(sc);
+	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+		bge_start_locked(ifp);
 }
 #endif /* DEVICE_POLLING */
 
@@ -2787,6 +2789,9 @@
 	statusword =
 	    atomic_readandclear_32(&sc->bge_ldata.bge_status_block->bge_status);
 
+	bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+	    sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
+
 #ifdef notdef
 	/* Avoid this for now -- checking this register is expensive. */
 	/* Make sure this is really our interrupt. */
@@ -2798,7 +2803,7 @@
 
 	if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
 	    sc->bge_chipid != BGE_CHIPID_BCM5700_B1) ||
-	    statusword & BGE_STATFLAG_LINKSTATE_CHANGED)
+	    statusword & BGE_STATFLAG_LINKSTATE_CHANGED || sc->bge_link_evt)
 		bge_link_upd(sc);
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
@@ -2826,12 +2831,9 @@
 	struct bge_softc *sc;
 {
 	struct mii_data *mii = NULL;
-	struct ifnet *ifp;
 
 	BGE_LOCK_ASSERT(sc);
 
-	ifp = sc->bge_ifp;
-
 	if (sc->bge_asicrev == BGE_ASICREV_BCM5705 ||
 	    sc->bge_asicrev == BGE_ASICREV_BCM5750)
 		bge_stats_update_regs(sc);
@@ -2841,6 +2843,20 @@
 	if (!sc->bge_tbi) {
 		mii = device_get_softc(sc->bge_miibus);
 		mii_tick(mii);
+	} else {
+		/*
+		 * Since in TBI mode auto-polling can't be used we should poll
+		 * link status manually. Here we register pending link event
+		 * and trigger interrupt.
+		 */
+#ifdef DEVICE_POLLING
+		/* In polling mode we poll link state in bge_poll_locked() */
+		if (!(sc->bge_ifp->if_capenable & IFCAP_POLLING))
+#endif
+		{
+		sc->bge_link_evt++;
+		BGE_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET);
+		}
 	}
 
 	callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
@@ -3722,6 +3738,9 @@
 
 	BGE_LOCK_ASSERT(sc);
 
+	/* Clear 'pending link event' flag */
+	sc->bge_link_evt = 0;
+
 	/*
 	 * Process link state changes.
 	 * Grrr. The link status word in the status block does
@@ -3770,23 +3789,9 @@
 	} 
 
 	if (sc->bge_tbi) {
-		/*
-		 * Sometimes PCS encoding errors are detected in
-		 * TBI mode (on fiber NICs), and for some reason
-		 * the chip will signal them as link changes.
-		 * If we get a link change event, but the 'PCS
-		 * encoding error' bit in the MAC status register
-		 * is set, don't bother doing a link check.
-		 * This avoids spurious "link UP" messages
-		 * that sometimes appear on fiber NICs during
-		 * periods of heavy traffic. (There should be no
-		 * effect on copper NICs.)
-		 */
 		status = CSR_READ_4(sc, BGE_MAC_STS);
-		if (!(status & (BGE_MACSTAT_PORT_DECODE_ERROR|
-		    BGE_MACSTAT_MI_COMPLETE))) {
-			if (!sc->bge_link &&
-			    (status & BGE_MACSTAT_TBI_PCS_SYNCHED)) {
+		if (status & BGE_MACSTAT_TBI_PCS_SYNCHED) {
+			if (!sc->bge_link) {
 				sc->bge_link++;
 				if (sc->bge_asicrev == BGE_ASICREV_BCM5704)
 					BGE_CLRBIT(sc, BGE_MAC_MODE,
@@ -3794,11 +3799,13 @@
 				CSR_WRITE_4(sc, BGE_MAC_STS, 0xFFFFFFFF);
 				if (bootverbose)
 					if_printf(sc->bge_ifp, "link UP\n");
-			} else if (sc->bge_link) {
-				sc->bge_link = 0;
-				if (bootverbose)
-					if_printf(sc->bge_ifp, "link DOWN\n");
+				if_link_state_change(sc->bge_ifp, LINK_STATE_UP);
 			}
+		} else if (sc->bge_link) {
+			sc->bge_link = 0;
+			if (bootverbose)
+				if_printf(sc->bge_ifp, "link DOWN\n");
+			if_link_state_change(sc->bge_ifp, LINK_STATE_DOWN);
 		}
 	} else {
 		/* 


More information about the freebsd-stable mailing list