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