Module Name:    src
Committed By:   nisimura
Date:           Wed Jun 14 00:07:22 UTC 2023

Modified Files:
        src/sys/arch/arm/sociox: if_scx.c

Log Message:
force PHY loopback while uengine reloading process as tianocore/EDK2 UEFI
mentions.  A piece of comment updates.


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/sys/arch/arm/sociox/if_scx.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/sociox/if_scx.c
diff -u src/sys/arch/arm/sociox/if_scx.c:1.41 src/sys/arch/arm/sociox/if_scx.c:1.42
--- src/sys/arch/arm/sociox/if_scx.c:1.41	Tue Jun 13 00:15:52 2023
+++ src/sys/arch/arm/sociox/if_scx.c	Wed Jun 14 00:07:22 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_scx.c,v 1.41 2023/06/13 00:15:52 nisimura Exp $	*/
+/*	$NetBSD: if_scx.c,v 1.42 2023/06/14 00:07:22 nisimura Exp $	*/
 
 /*-
  * Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -49,7 +49,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.41 2023/06/13 00:15:52 nisimura Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.42 2023/06/14 00:07:22 nisimura Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -156,14 +156,12 @@ struct rdes {
 #define  RXI_RC_ERR	(1U<<16)	/* recv error */
 #define  RXI_PKTCNT	(1U<<15)	/* recv counter has new value */
 #define  RXI_TMREXP	(1U<<14)	/* coalesce guard timer expired */
-/* 13 sets of special purpose desc interrupt handling register exist */
 #define TDBA_LO		0x408		/* tdes array base addr 31:0 */
 #define TDBA_HI		0x434		/* tdes array base addr 63:32 */
 #define RDBA_LO		0x448		/* rdes array base addr 31:0 */
 #define RDBA_HI		0x474		/* rdes array base addr 63:32 */
-/* 13 pairs of special purpose desc array base address register exist */
-#define TXCONF		0x430
-#define RXCONF		0x470
+#define TXCONF		0x430		/* tdes config */
+#define RXCONF		0x470		/* rdes config */
 #define  DESCNF_UP	(1U<<31)	/* 'up-and-running' */
 #define  DESCNF_CHRST	(1U<<30)	/* channel reset */
 #define  DESCNF_TMR	(1U<<4)		/* coalesce timer mode select */
@@ -197,8 +195,8 @@ struct rdes {
 #define MACCMD		0x11c4		/* gmac register operation */
 #define  CMD_IOWR	(1U<<28)	/* write op */
 #define  CMD_BUSY	(1U<<31)	/* busy bit */
-#define MACSTAT		0x1024		/* gmac status; ??? */
-#define MACINTE		0x1028		/* interrupt enable; ??? */
+#define MACSTAT		0x1024		/* mac interrupt status (unused) */
+#define MACINTE		0x1028		/* mac interrupt enable (unused) */
 
 #define FLOWTHR		0x11cc		/* flow control threshold */
 /* 31:16 pause threshold, 15:0 resume threshold */
@@ -212,8 +210,6 @@ struct rdes {
 #define MODE_TRANS	0x500		/* mode change completion status */
 #define  N2T_DONE	(1U<<20)	/* normal->taiki change completed */
 #define  T2N_DONE	(1U<<19)	/* taiki->normal change completed */
-#define MACADRH		0x10c		/* ??? */
-#define MACADRL		0x110		/* ??? */
 #define MCVER		0x22c		/* micro controller version */
 #define HWVER		0x230		/* hardware version */
 
@@ -247,7 +243,7 @@ struct rdes {
 #define  AFR_HPF	(1U<<10)	/* hash+perfect filter, or hash only */
 #define  AFR_SAF	(1U<<9)		/* source address filter */
 #define  AFR_SAIF	(1U<<8)		/* SA inverse filtering */
-#define  AFR_PCF	(2U<<6)		/* ??? */
+#define  AFR_PCF	(2U<<6)		/* 7:6 accept pause frame 0~3 */
 #define  AFR_DBF	(1U<<5)		/* reject broadcast frame */
 #define  AFR_PM		(1U<<4)		/* accept all multicast frame */
 #define  AFR_DAIF	(1U<<3)		/* DA inverse filtering */
@@ -585,6 +581,8 @@ static void dump_hwfeature(struct scx_so
 static void resetuengine(struct scx_softc *);
 static void loaducode(struct scx_softc *);
 static void injectucode(struct scx_softc *, int, bus_addr_t, bus_size_t);
+static void forcephyloopback(struct scx_softc *);
+static void resetphytonormal(struct scx_softc *);
 
 static int get_mdioclk(uint32_t);
 
@@ -997,7 +995,7 @@ aprint_normal_dev(sc->sc_dev, "descripto
 
 	/* 802.1Q VLAN-sized frames, and 9000 jumbo frame are supported */
 	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
-	sc->sc_ethercom.ec_capabilities |= ETHERCAP_JUMBO_MTU;
+	/* sc->sc_ethercom.ec_capabilities |= ETHERCAP_JUMBO_MTU; not yet */
 
 	sc->sc_flowflags = 0; /* track PAUSE flow caps */
 
@@ -1025,12 +1023,24 @@ aprint_normal_dev(sc->sc_dev, "descripto
 	CSR_WRITE(sc, RXCONF, DESCNF_LE);	/* little endian */
 	CSR_WRITE(sc, DMACTL_TMR, sc->sc_freq / 1000000 - 1);
 
+	forcephyloopback(sc);/* make PHY loopback mode for uengine init */
+
+	CSR_WRITE(sc, xINTSR, IRQ_UCODE); /* pre-cautional W1C */
+	CSR_WRITE(sc, CORESTAT, 0);	  /* start uengine to reprogram */
+	error = WAIT_FOR_SET(sc, xINTSR, IRQ_UCODE);
+	if (error) {
+		aprint_error_dev(sc->sc_dev, "uengine start failed\n");
+	}
+	CSR_WRITE(sc, xINTSR, IRQ_UCODE); /* W1C load complete report */
+
+	resetphytonormal(sc); /* take back PHY to normal mode */
+
 	CSR_WRITE(sc, DMACTL_M2H, M2H_MODE_TRANS);
-	CSR_WRITE(sc, PKTCTRL, MODENRM);	/* change to use normal mode */
-	WAIT_FOR_SET(sc, MODE_TRANS, T2N_DONE);
-	/* do {
-		csr = CSR_READ(sc, MODE_TRANS);
-	} while ((csr & T2N_DONE) == 0); */
+	CSR_WRITE(sc, PKTCTRL, MODENRM); /* change to use normal mode */
+	error = WAIT_FOR_SET(sc, MODE_TRANS, T2N_DONE);
+	if (error) {
+		aprint_error_dev(sc->sc_dev, "uengine mode change failed\n");
+	}
 
 	CSR_WRITE(sc, TXISR, ~0);	/* clear pending emtpry/error irq */
 	CSR_WRITE(sc, xINTAE_CLR, ~0);	/* disable tx / rx interrupts */
@@ -1847,9 +1857,6 @@ loaducode(struct scx_softc *sc)
 {
 	uint32_t up, lo, sz;
 	uint64_t addr;
-	int err;
-
-	CSR_WRITE(sc, xINTSR, IRQ_UCODE);
 
 	up = EE_READ(sc, 0x08); /* H->M ucode addr high */
 	lo = EE_READ(sc, 0x0c); /* H->M ucode addr low */
@@ -1878,13 +1885,6 @@ aprint_normal_dev(sc->sc_dev, "0x%x M2H 
 #if UCODE_DEBUG == 1
 aprint_normal_dev(sc->sc_dev, "0x%x PKT ucode %u\n", lo, sz);
 #endif
-
-	CSR_WRITE(sc, CORESTAT, 0);
-	err = WAIT_FOR_SET(sc, xINTSR, IRQ_UCODE);
-	if (err) {
-		aprint_error_dev(sc->sc_dev, "uengine start failed\n");
-	}
-	CSR_WRITE(sc, xINTSR, IRQ_UCODE);
 }
 
 static void
@@ -1907,6 +1907,57 @@ injectucode(struct scx_softc *sc, int po
 	bus_space_unmap(sc->sc_st, bsh, size);
 }
 
+static void
+forcephyloopback(struct scx_softc *sc)
+{
+	struct device *d = sc->sc_dev;
+	uint16_t val;
+	int loop, err;
+
+	err = mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
+	if (err) {
+		aprint_error_dev(d, "forcephyloopback() failed\n");
+		return;
+	}
+	if (val & BMCR_PDOWN)
+		val &=  ~BMCR_PDOWN;
+	val |= BMCR_ISO;
+	(void)mii_writereg(d, sc->sc_phy_id, MII_BMCR, val);
+	loop = 100;
+	do {
+		(void)mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
+	} while (loop-- > 0 && (val & (BMCR_PDOWN | BMCR_ISO)) != 0);
+	(void)mii_writereg(d, sc->sc_phy_id, MII_BMCR, val | BMCR_LOOP);
+	loop = 100;
+	do {
+		(void)mii_readreg(d, sc->sc_phy_id, MII_BMSR, &val);
+	} while (loop-- > 0 && (val & BMSR_LINK) != 0);
+}
+
+static void
+resetphytonormal(struct scx_softc *sc)
+{
+	struct device *d = sc->sc_dev;
+	uint16_t val;
+	int loop, err;
+
+	err = mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
+	if (err) {
+		aprint_error_dev(d, "resetphytonormal() failed\n");
+	}
+	val &= ~BMCR_LOOP;
+	(void)mii_writereg(d, sc->sc_phy_id, MII_BMCR, val);
+	loop = 100;
+	do {
+		(void)mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
+	} while (loop-- > 0 && (val & BMCR_LOOP) != 0);
+	(void)mii_writereg(d, sc->sc_phy_id, MII_BMCR, val | BMCR_RESET);
+	loop = 100;
+	do {
+		(void)mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
+	} while (loop-- > 0 && (val & BMCR_RESET) != 0);
+}
+
 /* GAR 5:2 MDIO frequency selection */
 static int
 get_mdioclk(uint32_t freq)

Reply via email to