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