Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Add 802.3x flow control support. From HITOSHI O...



details:   https://anonhg.NetBSD.org/src/rev/8bfa984cb88e
branches:  trunk
changeset: 565497:8bfa984cb88e
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sat Apr 10 19:23:49 2004 +0000

description:
Add 802.3x flow control support.  From HITOSHI Osada.

diffstat:

 sys/dev/pci/if_bge.c    |  55 ++++++++++++++++++++++++++++++++++++++++++++----
 sys/dev/pci/if_bgereg.h |   3 +-
 2 files changed, 52 insertions(+), 6 deletions(-)

diffs (136 lines):

diff -r 7fb1260fe3f3 -r 8bfa984cb88e sys/dev/pci/if_bge.c
--- a/sys/dev/pci/if_bge.c      Sat Apr 10 19:22:59 2004 +0000
+++ b/sys/dev/pci/if_bge.c      Sat Apr 10 19:23:49 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bge.c,v 1.68 2004/04/06 08:48:55 keihan Exp $       */
+/*     $NetBSD: if_bge.c,v 1.69 2004/04/10 19:23:49 thorpej Exp $      */
 
 /*
  * Copyright (c) 2001 Wind River Systems
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.68 2004/04/06 08:48:55 keihan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.69 2004/04/10 19:23:49 thorpej Exp $");
 
 #include "bpfilter.h"
 #include "vlan.h"
@@ -583,6 +583,15 @@
        struct bge_softc *sc = (struct bge_softc *)dev;
        struct mii_data *mii = &sc->bge_mii;
 
+       /*
+        * Get flow control negotiation result.
+        */
+       if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&
+           (mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags) {
+               sc->bge_flowflags = mii->mii_media_active & IFM_ETH_FMASK;
+               mii->mii_media_active &= ~IFM_ETH_FMASK;
+       }
+
        BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE);
        if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
                BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII);
@@ -595,6 +604,20 @@
        } else {
                BGE_SETBIT(sc, BGE_MAC_MODE, BGE_MACMODE_HALF_DUPLEX);
        }
+
+       /*
+        * 802.3x flow control
+        */
+       if (sc->bge_flowflags & IFM_ETH_RXPAUSE) {
+               BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_FLOWCTL_ENABLE);
+       } else {
+               BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_FLOWCTL_ENABLE);
+       }
+       if (sc->bge_flowflags & IFM_ETH_TXPAUSE) {
+               BGE_SETBIT(sc, BGE_TX_MODE, BGE_TXMODE_FLOWCTL_ENABLE);
+       } else {
+               BGE_CLRBIT(sc, BGE_TX_MODE, BGE_TXMODE_FLOWCTL_ENABLE);
+       }
 }
 
 /*
@@ -2421,7 +2444,8 @@
                ifmedia_init(&sc->bge_mii.mii_media, 0, bge_ifmedia_upd,
                             bge_ifmedia_sts);
                mii_attach(&sc->bge_dev, &sc->bge_mii, 0xffffffff,
-                          MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG);
+                          MII_PHY_ANY, MII_OFFSET_ANY,
+                          MIIF_FORCEANEG|MIIF_DOPAUSE);
                
                if (LIST_FIRST(&sc->bge_mii.mii_phys) == NULL) {
                        printf("%s: no PHY found!\n", sc->bge_dev.dv_xname);
@@ -3481,6 +3505,7 @@
                default:
                        return(EINVAL);
                }
+               /* XXX 802.3x flow control for 1000BASE-SX */
                return(0);
        }
 
@@ -3516,8 +3541,9 @@
        }
 
        mii_pollstat(mii);
-       ifmr->ifm_active = mii->mii_media_active;
        ifmr->ifm_status = mii->mii_media_status;
+       ifmr->ifm_active = (mii->mii_media_active & ~IFM_ETH_FMASK) |
+           sc->bge_flowflags;
 }
 
 int
@@ -3565,6 +3591,26 @@
                error = 0;
                break;
        case SIOCSIFMEDIA:
+               /* XXX Flow control is not supported for 1000BASE-SX */
+               if (sc->bge_tbi) {
+                       ifr->ifr_media &= ~IFM_ETH_FMASK;
+                       sc->bge_flowflags = 0;
+               }
+
+               /* Flow control requires full-duplex mode. */
+               if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO ||
+                   (ifr->ifr_media & IFM_FDX) == 0) {
+                       ifr->ifr_media &= ~IFM_ETH_FMASK;
+               }
+               if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) {
+                       if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) {
+                               /* We an do both TXPAUSE and RXPAUSE. */
+                               ifr->ifr_media |=
+                                   IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE;
+                       }
+                       sc->bge_flowflags = ifr->ifr_media & IFM_ETH_FMASK;
+               }
+               /* FALLTHROUGH */
        case SIOCGIFMEDIA:
                if (sc->bge_tbi) {
                        error = ifmedia_ioctl(ifp, ifr, &sc->bge_ifmedia,
@@ -3574,7 +3620,6 @@
                        error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
                            command);
                }
-               error = 0;
                break;
        default:
                error = ether_ioctl(ifp, command, data);
diff -r 7fb1260fe3f3 -r 8bfa984cb88e sys/dev/pci/if_bgereg.h
--- a/sys/dev/pci/if_bgereg.h   Sat Apr 10 19:22:59 2004 +0000
+++ b/sys/dev/pci/if_bgereg.h   Sat Apr 10 19:23:49 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_bgereg.h,v 1.18 2004/03/20 01:58:51 jonathan Exp $  */
+/*     $NetBSD: if_bgereg.h,v 1.19 2004/04/10 19:23:50 thorpej Exp $   */
 /*
  * Copyright (c) 2001 Wind River Systems
  * Copyright (c) 1997, 1998, 1999, 2001
@@ -2335,6 +2335,7 @@
        u_int32_t               bge_tx_buf_ratio;
        int                     bge_if_flags;
        int                     bge_flags;
+       int                     bge_flowflags;
        int                     bge_txcnt;
        int                     bge_link;
        struct callout          bge_timeout;



Home | Main Index | Thread Index | Old Index