Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/arm/sociox - add one more missing RXC_EN.



details:   https://anonhg.NetBSD.org/src/rev/49f1ac66fd40
branches:  trunk
changeset: 970344:49f1ac66fd40
user:      nisimura <nisimura%NetBSD.org@localhost>
date:      Sat Mar 21 08:16:19 2020 +0000

description:
- add one more missing RXC_EN.
- handle link speed change.
- fix genmask0() bit mask generation error.

diffstat:

 sys/arch/arm/sociox/if_ave.c |  53 ++++++++++++++++++++++++++++++++++---------
 1 files changed, 41 insertions(+), 12 deletions(-)

diffs (123 lines):

diff -r 442fd194221d -r 49f1ac66fd40 sys/arch/arm/sociox/if_ave.c
--- a/sys/arch/arm/sociox/if_ave.c      Sat Mar 21 07:16:16 2020 +0000
+++ b/sys/arch/arm/sociox/if_ave.c      Sat Mar 21 08:16:19 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ave.c,v 1.6 2020/03/21 07:16:16 nisimura Exp $      */
+/*     $NetBSD: if_ave.c,v 1.7 2020/03/21 08:16:19 nisimura Exp $      */
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ave.c,v 1.6 2020/03/21 07:16:16 nisimura Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ave.c,v 1.7 2020/03/21 08:16:19 nisimura Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -122,7 +122,7 @@
 #define AVEAFMSKB      0x0d00          /* byte mask base */
 #define  MSKBYTE0      0xfffffff3f     /* zeros in 7:6 */
 #define  MSKBYTE1      0x003ffffff     /* ones in 25:0 */
-#define  genmask0(x)   (MSKBYTE0 & (~0U << (32-(x))))
+#define  genmask0(x)   (MSKBYTE0 & (~0U << (x)))
 #define AVEAFMSKV      0x0e00          /* bit mask base */
 #define AVEAFRING      0x0f00          /* entry ring number selector */
 #define AVEAFEN                0x0ffc          /* entry enable bit vector */
@@ -132,6 +132,11 @@
 #define AVE32TDB       0x1000  /* 32bit Tx store base, upto 256 */
 #define AVE32RDB       0x1800  /* 32bit Rx store base, upto 2048 */
 
+#define AVERMIIC       0x8028          /* RMII control */
+#define  RMIIC_RST     (1U<<16)        /* reset */
+#define AVELINKSEL     0x8034          /* link speed selection */
+#define  LINKSEL_SPD100        (1U<<0)         /* RMII speed 100Mbps */
+
 /*
  * descriptor size is 12 bytes when 64bit paddr design, 8 bytes otherwise.
  */
@@ -635,17 +640,19 @@
 {
        struct ave_softc *sc = ifp->if_softc;
        struct mii_data *mii = &sc->sc_mii;
-       uint32_t txcr, rxcr;
+       struct ifmedia * const ifm = &mii->mii_media;
+       uint32_t txcr, rxcr, csr;
 
-       /* Get flow control negotiation result. */
+       /* 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->sc_flowflags)
                sc->sc_flowflags = mii->mii_media_active & IFM_ETH_FMASK;
 
-       /* Adjust PAUSE flow control. */
        txcr = CSR_READ(sc, AVETXC);
        rxcr = CSR_READ(sc, AVERXC);
        CSR_WRITE(sc, AVERXC, rxcr &~ RXC_EN); /* stop Rx first */
+
+       /* adjust 802.3x PAUSE flow control */
        if ((mii->mii_media_active & IFM_FDX)
            && (sc->sc_flowflags & IFM_ETH_TXPAUSE))
                txcr |= TXC_FCE;
@@ -656,9 +663,28 @@
                rxcr |= RXC_FCE;
        else
                rxcr &= ~RXC_FCE;
+
+       /* HW does not handle auto speed adjustment */
+       txcr &= ~(TXC_SPD1000 | TXC_SPD100);
+       if ((sc->sc_phymode & CFG_MII) == 0 /* RGMII model */
+            && IFM_SUBTYPE(ifm->ifm_cur->ifm_media) == IFM_100_TX)
+               txcr |= TXC_SPD1000;
+       else if (IFM_SUBTYPE(ifm->ifm_cur->ifm_media) == IFM_100_TX)
+               txcr |= TXC_SPD100;
+
+       /* adjust LINKSEL when MII/RMII too */
+       if (sc->sc_phymode & CFG_MII) {
+               csr = CSR_READ(sc, AVELINKSEL);
+               if (IFM_SUBTYPE(ifm->ifm_cur->ifm_media) == IFM_100_TX)
+                       csr |= LINKSEL_SPD100;
+               else
+                       csr &= ~LINKSEL_SPD100;
+               CSR_WRITE(sc, AVELINKSEL, csr);
+       }
+
        sc->sc_rxc = rxcr;
        CSR_WRITE(sc, AVETXC, txcr);
-       CSR_WRITE(sc, AVERXC, rxcr);
+       CSR_WRITE(sc, AVERXC, rxcr | RXC_EN);
 
 printf("%ctxfe, %crxfe\n",
        (txcr & TXC_FCE) ? '+' : '-', (rxcr & RXC_FCE) ? '+' : '-');
@@ -776,22 +802,25 @@
 static void
 ave_write_filt(struct ave_softc *sc, int i, const uint8_t *en)
 {
-       uint32_t n, macl, mach;
+       uint32_t macl, mach, n, mskbyte0;
 
-       /* pick v4mcast or v6mcast length */
-       n = (en[0] == 0x01) ? 3 : (en[0] == 0x33) ? 2 : ETHER_ADDR_LEN;
        macl = mach = 0;
        macl |= (en[3]<<24) | (en[2]<<16)| (en[1]<<8) | en[0];
        mach |= (en[5]<<8)  | en[4];
+       /* pick v4mcast or v6mcast length */
+       n = (en[0] == 0x01) ? 3 : (en[0] == 0x33) ? 2 : ETHER_ADDR_LEN;
+       /* entry 0 is reserved for promisc mode */
+       mskbyte0 = (i > 0) ? genmask0(n) : MSKBYTE0;
+
        /* set frame address first */
        CSR_WRITE(sc, AVEAFB + (i * 0x40) + 0, macl);
        CSR_WRITE(sc, AVEAFB + (i * 0x40) + 4, mach);
        /* set byte mask according to mask length, any of 6, 3, or 2 */
-       CSR_WRITE(sc, AVEAFMSKB + (i * 8) + 0, genmask0(n));
+       CSR_WRITE(sc, AVEAFMSKB + (i * 8) + 0, mskbyte0);
        CSR_WRITE(sc, AVEAFMSKB + (i * 8) + 4, MSKBYTE1);
        /* set bit vector mask */
        CSR_WRITE(sc, AVEAFMSKV + (i * 4), 0xffff);
-       /* use Rx ring 0 for any entry */
+       /* use Rx ring 0 anyway */
        CSR_WRITE(sc, AVEAFRING + (i * 4), 0);
        /* filter entry enable bit vector */
        CSR_WRITE(sc, AVEAFEN, CSR_READ(sc, AVEAFEN) | 1U << i);



Home | Main Index | Thread Index | Old Index