From 1271813421f5c0e4930a03f4bd341f8678c76010 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Mon, 24 Apr 2017 15:10:41 +0200 Subject: leon, greth: EDCL and DD is disabled during reset The EDCL and Duplex-Detection are now disabled during soft-reset of the GRETH core. The speed settings are preserved on boot and greth_stop() also, this is required to keep EDCL operational when DD is set. --- c/src/lib/libbsp/sparc/shared/include/greth.h | 1 + c/src/lib/libbsp/sparc/shared/net/greth.c | 47 +++++++++++++++++++-------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/c/src/lib/libbsp/sparc/shared/include/greth.h b/c/src/lib/libbsp/sparc/shared/include/greth.h index 904f60cdb5..648f51f12b 100644 --- a/c/src/lib/libbsp/sparc/shared/include/greth.h +++ b/c/src/lib/libbsp/sparc/shared/include/greth.h @@ -82,6 +82,7 @@ typedef struct _greth_regs { #define GRETH_CTRL_PRO 0x00000020 /* Promiscuous (receive all) */ #define GRETH_CTRL_RST 0x00000040 /* Reset MAC */ #define GRETH_CTRL_DD 0x00001000 /* Disable EDCL Duplex Detection */ +#define GRETH_CTRL_ED 0x00004000 /* EDCL Disable */ /* Status Register */ #define GRETH_STATUS_RXERR 0x00000001 /* Receive Error */ diff --git a/c/src/lib/libbsp/sparc/shared/net/greth.c b/c/src/lib/libbsp/sparc/shared/net/greth.c index b2ecf90e9e..87162a2b29 100644 --- a/c/src/lib/libbsp/sparc/shared/net/greth.c +++ b/c/src/lib/libbsp/sparc/shared/net/greth.c @@ -154,6 +154,7 @@ struct greth_softc greth_regs *regs; int minor; int phyaddr; /* PHY Address configured by user (or -1 to autodetect) */ + unsigned int edcl_dis; int acceptBroadcast; rtems_id daemonTid; @@ -350,19 +351,18 @@ greth_initialize_hardware (struct greth_softc *sc) int tmp1; int tmp2; struct timespec tstart, tnow; - greth_regs *regs; regs = sc->regs; - + /* Reset the controller. */ sc->rxInterrupts = 0; sc->rxPackets = 0; - regs->ctrl = GRETH_CTRL_RST; /* Reset ON */ + regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD | GRETH_CTRL_ED; /* Reset ON */ for (i = 0; i<100 && (regs->ctrl & GRETH_CTRL_RST); i++) ; - regs->ctrl = GRETH_CTRL_DD; /* Reset OFF. SW do PHY Init */ + regs->ctrl = GRETH_CTRL_DD | GRETH_CTRL_ED; /* Reset OFF. SW do PHY Init */ /* Check if mac is gbit capable*/ sc->gbit_mac = (regs->ctrl >> 27) & 1; @@ -504,10 +504,10 @@ auto_neg_done: } while ((read_mii(sc, phyaddr, 0)) & 0x8000) {} - regs->ctrl = GRETH_CTRL_RST; /* Reset ON */ + regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD | GRETH_CTRL_ED; /* Reset ON */ for (i = 0; i < 100 && (regs->ctrl & GRETH_CTRL_RST); i++) ; - regs->ctrl = GRETH_CTRL_DD; + regs->ctrl = GRETH_CTRL_DD | sc->edcl_dis; /* Reset OFF. SW do PHY Init */ /* Initialize rx/tx descriptor table pointers. Due to alignment we * always allocate maximum table size. @@ -584,7 +584,7 @@ auto_neg_done: sc->tx_int_gen = sc->tx_int_gen_cur = sc->txbufs/2; } sc->next_tx_mbuf = NULL; - + if ( !sc->gbit_mac ) sc->max_fragsize = 1; @@ -1160,9 +1160,13 @@ greth_stop (struct greth_softc *sc) SPIN_LOCK_IRQ(&sc->devlock, flags); ifp->if_flags &= ~IFF_RUNNING; - sc->regs->ctrl = 0; /* RX/TX OFF */ - sc->regs->ctrl = GRETH_CTRL_RST; /* Reset ON */ - sc->regs->ctrl = 0; /* Reset OFF */ + /* RX/TX OFF */ + sc->regs->ctrl = GRETH_CTRL_DD | GRETH_CTRL_ED; + /* Reset ON */ + sc->regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD | GRETH_CTRL_ED; + /* Reset OFF and restore link settings previously detected if any */ + sc->regs->ctrl = GRETH_CTRL_DD | sc->edcl_dis | + (sc->gb << 8) | (sc->sp << 7) | (sc->fd << 4); SPIN_UNLOCK_IRQ(&sc->devlock, flags); sc->next_tx_mbuf = NULL; @@ -1424,6 +1428,7 @@ int greth_device_init(struct greth_softc *sc) struct amba_dev_info *ambadev; struct ambapp_core *pnpinfo; union drvmgr_key_value *value; + unsigned int speed; /* Get device information from AMBA PnP information */ ambadev = (struct amba_dev_info *)sc->dev->businfo; @@ -1434,13 +1439,27 @@ int greth_device_init(struct greth_softc *sc) sc->regs = (greth_regs *)pnpinfo->apb_slv->start; sc->minor = sc->dev->minor_drv; - /* clear control register and reset NIC + /* Remember EDCL enabled/disable state before reset */ + sc->edcl_dis = sc->regs->ctrl & GRETH_CTRL_ED; + + /* Default is to inherit EDCL Disable bit from HW. User can force En/Dis */ + value = drvmgr_dev_key_get(sc->dev, "edclDis", DRVMGR_KT_INT); + if ( value ) { + /* Force EDCL mode. Has an effect later when GRETH+PHY is initialized */ + if (value->i > 0) + sc->edcl_dis = GRETH_CTRL_ED; + else + sc->edcl_dis = 0; + } + + /* clear control register and reset NIC and keep current speed modes. * This should be done as quick as possible during startup, this is to * stop DMA transfers after a reboot. */ - sc->regs->ctrl = 0; - sc->regs->ctrl = GRETH_CTRL_RST; - sc->regs->ctrl = 0; + speed = sc->regs->ctrl & (GRETH_CTRL_GB | GRETH_CTRL_SP | GRETH_CTRL_FULLD); + sc->regs->ctrl = GRETH_CTRL_DD | GRETH_CTRL_ED; + sc->regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD | GRETH_CTRL_ED; + sc->regs->ctrl = GRETH_CTRL_DD | sc->edcl_dis | speed; /* Configure driver by overriding default config with the bus resources * configured by the user -- cgit v1.2.3