From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56163) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UyXXh-0005xv-8r for Qemu-devel@nongnu.org; Sun, 14 Jul 2013 21:25:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UyXXY-00045t-EJ for Qemu-devel@nongnu.org; Sun, 14 Jul 2013 21:25:33 -0400 Received: from [222.73.24.84] (port=5153 helo=song.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UyXXV-0003rI-PC for Qemu-devel@nongnu.org; Sun, 14 Jul 2013 21:25:24 -0400 Date: Mon, 15 Jul 2013 09:25:11 +0800 From: "Yao Xingtao" References: <1373476202-11277-1-git-send-email-chouteau@adacore.com>, <1373476202-11277-3-git-send-email-chouteau@adacore.com>, <201307110955092430409@cn.fujitsu.com> Message-ID: <201307150925097674522@cn.fujitsu.com> Mime-Version: 1.0 Content-Type: text/plain; charset="gb2312" Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] Fw: [PATCH 2/2] Add Enhanced Three-Speed EthernetController (eTSEC) List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel Cc: Fabien Chouteau >------------------------------------------------------------- >=B7=A2=BC=FE=C8=CB=A3=BAFabien Chouteau >=B7=A2=CB=CD=C8=D5=C6=DA=A3=BA2013-07-11 01:11:11 >=CA=D5=BC=FE=C8=CB=A3=BAqemu-devel >=B3=AD=CB=CD=A3=BAqemu-ppc; agraf >=D6=F7=CC=E2=A3=BA[Qemu-devel] [PATCH 2/2] Add Enhanced Three-Speed Ethern= etController (eTSEC) > >This implementation doesn't include ring priority, TCP/IP Off-Load, QoS. > >Signed-off-by: Fabien Chouteau >--- > default-configs/ppc-softmmu.mak | 1 + > hw/net/Makefile.objs | 1 + > hw/net/etsec.c | 472 +++++++++++++++++++++++++++ > hw/net/etsec.h | 169 ++++++++++ > hw/net/etsec=5Fmiim.c | 146 +++++++++ > hw/net/etsec=5Fregisters.c | 295 +++++++++++++++++ > hw/net/etsec=5Fregisters.h | 302 ++++++++++++++++++ > hw/net/etsec=5Frings.c | 673 ++++++++++++++++++++++++++++++++= +++++++ > 8 files changed, 2059 insertions(+) > create mode 100644 hw/net/etsec.c > create mode 100644 hw/net/etsec.h > create mode 100644 hw/net/etsec=5Fmiim.c > create mode 100644 hw/net/etsec=5Fregisters.c > create mode 100644 hw/net/etsec=5Fregisters.h > create mode 100644 hw/net/etsec=5Frings.c > >diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu= .mak >index 73e4cc5..c7541cf 100644 >--- a/default-configs/ppc-softmmu.mak >+++ b/default-configs/ppc-softmmu.mak >@@ -46,3 +46,4 @@ CONFIG=5FE500=3Dy > CONFIG=5FOPENPIC=5FKVM=3D$(and $(CONFIG=5FE500),$(CONFIG=5FKVM)) > # For PReP > CONFIG=5FMC146818RTC=3Dy >+CONFIG=5FETSEC=3Dy >diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs >index 951cca3..ca03c3f 100644 >--- a/hw/net/Makefile.objs >+++ b/hw/net/Makefile.objs >@@ -28,6 +28,7 @@ obj-$(CONFIG=5FCOLDFIRE) +=3D mcf=5Ffec.o > obj-$(CONFIG=5FMILKYMIST) +=3D milkymist-minimac2.o > obj-$(CONFIG=5FPSERIES) +=3D spapr=5Fllan.o > obj-$(CONFIG=5FXILINX=5FETHLITE) +=3D xilinx=5Fethlite.o >+obj-$(CONFIG=5FETSEC) +=3D etsec.o etsec=5Fregisters.o etsec=5Frings.o et= sec=5Fmiim.o >=20 > obj-$(CONFIG=5FVIRTIO) +=3D virtio-net.o > obj-y +=3D vhost=5Fnet.o >diff --git a/hw/net/etsec.c b/hw/net/etsec.c >new file mode 100644 >index 0000000..4516b01 >--- /dev/null >+++ b/hw/net/etsec.c >@@ -0,0 +1,472 @@ >+/* >+ * QEMU Freescale eTSEC Emulator >+ * >+ * Copyright (c) 2011-2013 AdaCore >+ * >+ * Permission is hereby granted, free of charge, to any person obtaining = a copy >+ * of this software and associated documentation files (the "Software"), = to deal >+ * in the Software without restriction, including without limitation the = rights >+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or s= ell >+ * copies of the Software, and to permit persons to whom the Software is >+ * furnished to do so, subject to the following conditions: >+ * >+ * The above copyright notice and this permission notice shall be include= d in >+ * all copies or substantial portions of the Software. >+ * >+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRES= S OR >+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILIT= Y, >+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR O= THER >+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISIN= G FROM, >+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS= IN >+ * THE SOFTWARE. >+ */ >+ >+#include "sysemu/sysemu.h" >+#include "hw/sysbus.h" >+#include "trace.h" >+#include "hw/ptimer.h" >+#include "hw/net/etsec.h" >+#include "hw/net/etsec=5Fregisters.h" >+ >+/* #define HEX=5FDUMP */ >+/* #define DEBUG=5FREGISTER */ >+ >+static uint64=5Ft etsec=5Fread(void *opaque, hwaddr addr, unsigned size) >+{ >+ eTSEC *etsec =3D opaque; >+ uint32=5Ft reg=5Findex =3D addr / 4; >+ eTSEC=5FRegister *reg =3D NULL; >+ uint32=5Ft ret =3D 0x0; >+ >+ assert(reg=5Findex < REG=5FNUMBER); >+ >+ reg =3D &etsec->regs[reg=5Findex]; >+ >+ >+ switch (reg->access) { >+ case ACC=5FWO: >+ ret =3D 0x00000000; >+ break; >+ >+ case ACC=5FRW: >+ case ACC=5Fw1c: >+ case ACC=5FRO: >+ default: >+ ret =3D reg->value; >+ break; >+ } >+ >+#ifdef DEBUG=5FREGISTER >+ printf("Read 0x%08x @ 0x" TARGET=5FFMT=5Fplx >+ " : %s (%s)\n", >+ ret, addr, reg->name, reg->desc); >+#endif >+ >+ return ret; >+} >+ >+static void write=5Ftstat(eTSEC *etsec, >+ eTSEC=5FRegister *reg, >+ uint32=5Ft reg=5Findex, >+ uint32=5Ft value) >+{ >+ int i =3D 0; >+ >+ for (i =3D 0; i < 8; i++) { >+ /* Check THLTi flag in TSTAT */ >+ if (value & (1 << (31 - i))) { >+ walk=5Ftx=5Fring(etsec, i); >+ } >+ } >+ >+ /* Write 1 to clear */ >+ reg->value &=3D ~value; >+} >+ >+static void write=5Frstat(eTSEC *etsec, >+ eTSEC=5FRegister *reg, >+ uint32=5Ft reg=5Findex, >+ uint32=5Ft value) >+{ >+ int i =3D 0; >+ >+ for (i =3D 0; i < 8; i++) { >+ /* Check QHLTi flag in RSTAT */ >+ if (value & (1 << (23 - i)) && !(reg->value & (1 << (23 - i)))) { >+ walk=5Frx=5Fring(etsec, i); >+ } >+ } >+ >+ /* Write 1 to clear */ >+ reg->value &=3D ~value; >+} >+ >+static void write=5Ftbasex(eTSEC *etsec, >+ eTSEC=5FRegister *reg, >+ uint32=5Ft reg=5Findex, >+ uint32=5Ft value) >+{ >+ reg->value =3D value & ~0x7; >+ >+ /* Copy this value in the ring's TxBD pointer */ >+ etsec->regs[TBPTR0 + (reg=5Findex - TBASE0)].value =3D value & ~0x7; >+} >+ >+static void write=5Frbasex(eTSEC *etsec, >+ eTSEC=5FRegister *reg, >+ uint32=5Ft reg=5Findex, >+ uint32=5Ft value) >+{ >+ reg->value =3D value & ~0x7; >+ >+ /* Copy this value in the ring's RxBD pointer */ >+ etsec->regs[RBPTR0 + (reg=5Findex - RBASE0)].value =3D value & ~0x7; >+} >+ >+static void write=5Fievent(eTSEC *etsec, >+ eTSEC=5FRegister *reg, >+ uint32=5Ft reg=5Findex, >+ uint32=5Ft value) >+{ >+ if (value & IEVENT=5FTXF) { >+ qemu=5Firq=5Flower(etsec->tx=5Firq); >+ } >+ if (value & IEVENT=5FRXF) { >+ qemu=5Firq=5Flower(etsec->rx=5Firq); >+ } >+ >+ /* Write 1 to clear */ >+ reg->value &=3D ~value; >+} >+ >+static void write=5Fdmactrl(eTSEC *etsec, >+ eTSEC=5FRegister *reg, >+ uint32=5Ft reg=5Findex, >+ uint32=5Ft value) >+{ >+ reg->value =3D value; >+ >+ if (value & DMACTRL=5FGRS) { >+ >+ if (etsec->rx=5Fbuffer=5Flen !=3D 0) { >+ /* Graceful receive stop delayed until end of frame */ >+ } else { >+ /* Graceful receive stop now */ >+ etsec->regs[IEVENT].value |=3D IEVENT=5FGRSC; >+ if (etsec->regs[IMASK].value & IMASK=5FGRSCEN) { >+ qemu=5Firq=5Fraise(etsec->err=5Firq); >+ } >+ } >+ } >+ >+ if (value & DMACTRL=5FGTS) { >+ >+ if (etsec->tx=5Fbuffer=5Flen !=3D 0) { >+ /* Graceful transmit stop delayed until end of frame */ >+ } else { >+ /* Graceful transmit stop now */ >+ etsec->regs[IEVENT].value |=3D IEVENT=5FGTSC; >+ if (etsec->regs[IMASK].value & IMASK=5FGTSCEN) { >+ qemu=5Firq=5Fraise(etsec->err=5Firq); >+ } >+ } >+ } >+ >+ if (!(value & DMACTRL=5FWOP)) { >+ /* Start polling */ >+ ptimer=5Fstop(etsec->ptimer); >+ ptimer=5Fset=5Fcount(etsec->ptimer, 1); >+ ptimer=5Frun(etsec->ptimer, 1); >+ } >+} >+ >+static void etsec=5Fwrite(void *opaque, >+ hwaddr addr, >+ uint64=5Ft value, >+ unsigned size) >+{ >+ eTSEC *etsec =3D opaque; >+ uint32=5Ft reg=5Findex =3D addr / 4; >+ eTSEC=5FRegister *reg =3D NULL; >+ uint32=5Ft before =3D 0x0; >+ >+ assert(reg=5Findex < REG=5FNUMBER); >+ >+ reg =3D &etsec->regs[reg=5Findex]; >+ before =3D reg->value; >+ >+ switch (reg=5Findex) { >+ case IEVENT: >+ write=5Fievent(etsec, reg, reg=5Findex, value); >+ break; >+ >+ case DMACTRL: >+ write=5Fdmactrl(etsec, reg, reg=5Findex, value); >+ break; >+ >+ case TSTAT: >+ write=5Ftstat(etsec, reg, reg=5Findex, value); >+ break; >+ >+ case RSTAT: >+ write=5Frstat(etsec, reg, reg=5Findex, value); >+ break; >+ >+ case TBASE0 ... TBASE7: >+ write=5Ftbasex(etsec, reg, reg=5Findex, value); >+ break; >+ >+ case RBASE0 ... RBASE7: >+ write=5Frbasex(etsec, reg, reg=5Findex, value); >+ break; >+ >+ case MIIMCFG ... MIIMIND: >+ write=5Fmiim(etsec, reg, reg=5Findex, value); >+ break; >+ >+ default: >+ /* Default handling */ >+ switch (reg->access) { >+ >+ case ACC=5FRW: >+ case ACC=5FWO: >+ reg->value =3D value; >+ break; >+ >+ case ACC=5Fw1c: >+ reg->value &=3D ~value; >+ break; >+ >+ case ACC=5FRO: >+ default: >+ /* Read Only or Unknown register */ >+ break; >+ } >+ } >+ >+#ifdef DEBUG=5FREGISTER >+ printf("Write 0x%08x @ 0x" TARGET=5FFMT=5Fplx" val:0x%08x->0x%08x : %= s (%s)\n", >+ (unsigned int)value, addr, before, reg->value, reg->name, reg-= >desc); >+#else >+ (void)before; /* Unreferenced */ >+#endif >+ >+} >+ >+static const MemoryRegionOps etsec=5Fops =3D { >+ .read =3D etsec=5Fread, >+ .write =3D etsec=5Fwrite, >+ .endianness =3D DEVICE=5FNATIVE=5FENDIAN, >+ .impl =3D { >+ .min=5Faccess=5Fsize =3D 4, >+ .max=5Faccess=5Fsize =3D 4, >+ }, >+}; >+ >+static void etsec=5Ftimer=5Fhit(void *opaque) >+{ >+ eTSEC *etsec =3D opaque; >+ >+ ptimer=5Fstop(etsec->ptimer); >+ >+ if (!(etsec->regs[DMACTRL].value & DMACTRL=5FWOP)) { >+ >+ if (!(etsec->regs[DMACTRL].value & DMACTRL=5FGTS)) { >+ walk=5Ftx=5Fring(etsec, 0); >+ } >+ ptimer=5Fset=5Fcount(etsec->ptimer, 1); >+ ptimer=5Frun(etsec->ptimer, 1); >+ } >+} >+ >+static void etsec=5Freset(DeviceState *d) >+{ >+ eTSEC *etsec =3D container=5Fof(d, eTSEC, busdev.qdev); >+ int i =3D 0; >+ int reg=5Findex =3D 0; >+ >+ /* Default value for all registers */ >+ for (i =3D 0; i < REG=5FNUMBER; i++) { >+ etsec->regs[i].name =3D "Reserved"; >+ etsec->regs[i].desc =3D ""; >+ etsec->regs[i].access =3D ACC=5FUNKNOWN; >+ etsec->regs[i].value =3D 0x00000000; >+ } >+ >+ /* Set-up known registers */ >+ for (i =3D 0; eTSEC=5Fregisters=5Fdef[i].name !=3D NULL; i++) { >+ >+ reg=5Findex =3D eTSEC=5Fregisters=5Fdef[i].offset / 4; >+ >+ etsec->regs[reg=5Findex].name =3D eTSEC=5Fregisters=5Fdef[i].na= me; >+ etsec->regs[reg=5Findex].desc =3D eTSEC=5Fregisters=5Fdef[i].de= sc; >+ etsec->regs[reg=5Findex].access =3D eTSEC=5Fregisters=5Fdef[i].ac= cess; >+ etsec->regs[reg=5Findex].value =3D eTSEC=5Fregisters=5Fdef[i].re= set; >+ } >+ >+ etsec->tx=5Fbuffer =3D NULL; >+ etsec->tx=5Fbuffer=5Flen =3D 0; >+ etsec->rx=5Fbuffer =3D NULL; >+ etsec->rx=5Fbuffer=5Flen =3D 0; >+ >+ etsec->phy=5Fstatus =3D >+ MII=5FSR=5FEXTENDED=5FCAPS | MII=5FSR=5FLINK=5FSTATUS | MII= =5FSR=5FAUTONEG=5FCAPS | >+ MII=5FSR=5FAUTONEG=5FCOMPLETE | MII=5FSR=5FPREAMBLE=5FSUPPRESS | >+ MII=5FSR=5FEXTENDED=5FSTATUS | MII=5FSR=5F100T2=5FHD=5FCAPS | MI= I=5FSR=5F100T2=5FFD=5FCAPS | >+ MII=5FSR=5F10T=5FHD=5FCAPS | MII=5FSR=5F10T=5FFD=5FCAPS | = MII=5FSR=5F100X=5FHD=5FCAPS | >+ MII=5FSR=5F100X=5FFD=5FCAPS | MII=5FSR=5F100T4=5FCAPS; >+} >+ >+static void etsec=5Fcleanup(NetClientState *nc) >+{ >+ /* printf("eTSEC cleanup\n"); */ >+} >+ >+static int etsec=5Fcan=5Freceive(NetClientState *nc) >+{ >+ /* Yes we always can\ */ >+ return 1; >+} >+ >+#ifdef HEX=5FDUMP >+static void hex=5Fdump(FILE *f, const uint8=5Ft *buf, int size) >+{ >+ int len, i, j, c; >+ >+ for (i =3D 0; i < size; i +=3D 16) { >+ len =3D size - i; >+ if (len > 16) { >+ len =3D 16; >+ } >+ fprintf(f, "%08x ", i); >+ for (j =3D 0; j < 16; j++) { >+ if (j < len) { >+ fprintf(f, " %02x", buf[i + j]); >+ } else { >+ fprintf(f, " "); >+ } >+ } >+ fprintf(f, " "); >+ for (j =3D 0; j < len; j++) { >+ c =3D buf[i + j]; >+ if (c < ' ' || c > '~') { >+ c =3D '.'; >+ } >+ fprintf(f, "%c", c); >+ } >+ fprintf(f, "\n"); >+ } >+} >+#endif >+ >+static ssize=5Ft etsec=5Freceive(NetClientState *nc, >+ const uint8=5Ft *buf, >+ size=5Ft size) >+{ >+ eTSEC *etsec =3D qemu=5Fget=5Fnic=5Fopaque(nc); >+ >+#if defined(HEX=5FDUMP) >+ fprintf(stderr, "%s receive size:%d\n", etsec->nic->nc.name, size); >+ hex=5Fdump(stderr, buf, size); >+#endif >+ rx=5Fring=5Fwrite(etsec, buf, size); >+ return size; >+} >+ >+ >+static void etsec=5Fset=5Flink=5Fstatus(NetClientState *nc) >+{ >+ eTSEC *etsec =3D qemu=5Fget=5Fnic=5Fopaque(nc); >+ >+ miim=5Flink=5Fstatus(etsec, nc); >+} >+ >+static NetClientInfo net=5Fetsec=5Finfo =3D { >+ .type =3D NET=5FCLIENT=5FOPTIONS=5FKIND=5FNIC, >+ .size =3D sizeof(NICState), >+ .can=5Freceive =3D etsec=5Fcan=5Freceive, >+ .receive =3D etsec=5Freceive, >+ .cleanup =3D etsec=5Fcleanup, >+ .link=5Fstatus=5Fchanged =3D etsec=5Fset=5Flink=5Fstatus, >+}; >+ >+static int etsec=5Finit(SysBusDevice *dev) >+{ >+ eTSEC *etsec =3D FROM=5FSYSBUS(typeof(*etsec), dev); >+ >+ memory=5Fregion=5Finit=5Fio(&etsec->io=5Farea, OBJECT(etsec), &etsec= =5Fops, etsec, >+ "eTSEC", 0x1000); >+ >+ sysbus=5Finit=5Fmmio(dev, &etsec->io=5Farea); >+ >+ sysbus=5Finit=5Firq(dev, &etsec->tx=5Firq); >+ sysbus=5Finit=5Firq(dev, &etsec->rx=5Firq); >+ sysbus=5Finit=5Firq(dev, &etsec->err=5Firq); >+ >+ etsec->nic =3D qemu=5Fnew=5Fnic(&net=5Fetsec=5Finfo, &etsec->conf, >+ "eTSEC", etsec->busdev.qdev.id, etsec); >+ qemu=5Fformat=5Fnic=5Finfo=5Fstr(qemu=5Fget=5Fqueue(etsec->nic), etse= c->conf.macaddr.a); >+ >+ >+ etsec->bh =3D qemu=5Fbh=5Fnew(etsec=5Ftimer=5Fhit, etsec); >+ etsec->ptimer =3D ptimer=5Finit(etsec->bh); >+ ptimer=5Fset=5Ffreq(etsec->ptimer, 100); >+ >+ return 0; >+} >+ >+static Property etsec=5Fproperties[] =3D { >+ DEFINE=5FNIC=5FPROPERTIES(eTSEC, conf), >+ DEFINE=5FPROP=5FEND=5FOF=5FLIST(), >+}; >+ >+static void etsec=5Fclass=5Finit(ObjectClass *klass, void *data) >+{ >+ DeviceClass *dc =3D DEVICE=5FCLASS(klass); >+ SysBusDeviceClass *k =3D SYS=5FBUS=5FDEVICE=5FCLASS(klass); >+ >+ k->init =3D etsec=5Finit; >+ dc->reset =3D etsec=5Freset; >+ dc->props =3D etsec=5Fproperties; >+} >+ >+static TypeInfo etsec=5Finfo =3D { >+ .name =3D "eTSEC", >+ .parent =3D TYPE=5FSYS=5FBUS=5FDEVICE, >+ .instance=5Fsize =3D sizeof(eTSEC), >+ .class=5Finit =3D etsec=5Fclass=5Finit, >+}; >+ >+static void etsec=5Fregister=5Ftypes(void) >+{ >+ type=5Fregister=5Fstatic(&etsec=5Finfo); >+} >+ >+type=5Finit(etsec=5Fregister=5Ftypes) >+ >+DeviceState *etsec=5Fcreate(hwaddr base, >+ MemoryRegion * mr, >+ NICInfo * nd, >+ qemu=5Firq tx=5Firq, >+ qemu=5Firq rx=5Firq, >+ qemu=5Firq err=5Firq) >+{ >+ DeviceState *dev; >+ >+ dev =3D qdev=5Fcreate(NULL, "eTSEC"); >+ qdev=5Fset=5Fnic=5Fproperties(dev, nd); >+ >+ if (qdev=5Finit(dev)) { >+ return NULL; >+ } >+ >+ sysbus=5Fconnect=5Firq(SYS=5FBUS=5FDEVICE(dev), 0, tx=5Firq); >+ sysbus=5Fconnect=5Firq(SYS=5FBUS=5FDEVICE(dev), 1, rx=5Firq); >+ sysbus=5Fconnect=5Firq(SYS=5FBUS=5FDEVICE(dev), 2, err=5Firq); >+ >+ memory=5Fregion=5Fadd=5Fsubregion(mr, base, >+ SYS=5FBUS=5FDEVICE(dev)->mmio[0].memory); >+ >+ return dev; >+} >diff --git a/hw/net/etsec.h b/hw/net/etsec.h >new file mode 100644 >index 0000000..4fa9edc >--- /dev/null >+++ b/hw/net/etsec.h >@@ -0,0 +1,169 @@ >+/* >+ * QEMU Freescale eTSEC Emulator >+ * >+ * Copyright (c) 2011-2013 AdaCore >+ * >+ * Permission is hereby granted, free of charge, to any person obtaining = a copy >+ * of this software and associated documentation files (the "Software"), = to deal >+ * in the Software without restriction, including without limitation the = rights >+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or s= ell >+ * copies of the Software, and to permit persons to whom the Software is >+ * furnished to do so, subject to the following conditions: >+ * >+ * The above copyright notice and this permission notice shall be include= d in >+ * all copies or substantial portions of the Software. >+ * >+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRES= S OR >+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILIT= Y, >+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR O= THER >+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISIN= G FROM, >+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS= IN >+ * THE SOFTWARE. >+ */ >+#ifndef =5FETSEC=5FH=5F >+#define =5FETSEC=5FH=5F >+ >+#include "hw/qdev.h" >+#include "hw/sysbus.h" >+#include "net/net.h" >+#include "hw/ptimer.h" >+ >+/* Buffer Descriptors */ >+ >+typedef struct eTSEC=5Frxtx=5Fbd { >+ uint16=5Ft flags; >+ uint16=5Ft length; >+ uint32=5Ft bufptr; >+} eTSEC=5Frxtx=5Fbd; >+ >+#define BD=5FWRAP (1 << 13) >+#define BD=5FINTERRUPT (1 << 12) >+#define BD=5FLAST (1 << 11) >+ >+#define BD=5FTX=5FREADY (1 << 15) >+#define BD=5FTX=5FPADCRC (1 << 14) >+#define BD=5FTX=5FTC (1 << 10) >+#define BD=5FTX=5FPREDEF (1 << 9) >+#define BD=5FTX=5FHFELC (1 << 7) >+#define BD=5FTX=5FCFRL (1 << 6) >+#define BD=5FTX=5FRC=5FMASK 0xF >+#define BD=5FTX=5FRC=5FOFFSET 0x2 >+#define BD=5FTX=5FTOEUN (1 << 1) >+#define BD=5FTX=5FTR (1 << 0) >+ >+#define BD=5FRX=5FEMPTY (1 << 15) >+#define BD=5FRX=5FRO1 (1 << 14) >+#define BD=5FRX=5FFIRST (1 << 10) >+#define BD=5FRX=5FMISS (1 << 8) >+#define BD=5FRX=5FBROADCAST (1 << 7) >+#define BD=5FRX=5FMULTICAST (1 << 6) >+#define BD=5FRX=5FLG (1 << 5) >+#define BD=5FRX=5FNO (1 << 4) >+#define BD=5FRX=5FSH (1 << 3) >+#define BD=5FRX=5FCR (1 << 2) >+#define BD=5FRX=5FOV (1 << 1) >+#define BD=5FRX=5FTR (1 << 0) >+ >+/* Tx FCB flags */ >+#define FCB=5FTX=5FVLN (1 << 7) >+#define FCB=5FTX=5FIP (1 << 6) >+#define FCB=5FTX=5FIP6 (1 << 5) >+#define FCB=5FTX=5FTUP (1 << 4) >+#define FCB=5FTX=5FUDP (1 << 3) >+#define FCB=5FTX=5FCIP (1 << 2) >+#define FCB=5FTX=5FCTU (1 << 1) >+#define FCB=5FTX=5FNPH (1 << 0) >+ >+/* PHY Status Register */ >+#define MII=5FSR=5FEXTENDED=5FCAPS 0x0001 /* Extended register cap= abilities */ >+#define MII=5FSR=5FJABBER=5FDETECT 0x0002 /* Jabber Detected */ >+#define MII=5FSR=5FLINK=5FSTATUS 0x0004 /* Link Status 1 =3D lin= k */ >+#define MII=5FSR=5FAUTONEG=5FCAPS 0x0008 /* Auto Neg Capable */ >+#define MII=5FSR=5FREMOTE=5FFAULT 0x0010 /* Remote Fault Detect */ >+#define MII=5FSR=5FAUTONEG=5FCOMPLETE 0x0020 /* Auto Neg Complete */ >+#define MII=5FSR=5FPREAMBLE=5FSUPPRESS 0x0040 /* Preamble may be suppr= essed */ >+#define MII=5FSR=5FEXTENDED=5FSTATUS 0x0100 /* Ext. status info in R= eg 0x0F */ >+#define MII=5FSR=5F100T2=5FHD=5FCAPS 0x0200 /* 100T2 Half Duplex C= apable */ >+#define MII=5FSR=5F100T2=5FFD=5FCAPS 0x0400 /* 100T2 Full Duplex C= apable */ >+#define MII=5FSR=5F10T=5FHD=5FCAPS 0x0800 /* 10T Half Duplex C= apable */ >+#define MII=5FSR=5F10T=5FFD=5FCAPS 0x1000 /* 10T Full Duplex C= apable */ >+#define MII=5FSR=5F100X=5FHD=5FCAPS 0x2000 /* 100X Half Duplex C= apable */ >+#define MII=5FSR=5F100X=5FFD=5FCAPS 0x4000 /* 100X Full Duplex C= apable */ >+#define MII=5FSR=5F100T4=5FCAPS 0x8000 /* 100T4 Capable */ >+ >+/* eTSEC */ >+ >+#define REG=5FNUMBER 1024 >+ >+typedef struct eTSEC=5FRegister { >+ const char *name; >+ const char *desc; >+ uint32=5Ft access; >+ uint32=5Ft value; >+} eTSEC=5FRegister; >+ >+typedef struct eTSEC { >+ SysBusDevice busdev; >+ >+ MemoryRegion io=5Farea; >+ >+ eTSEC=5FRegister regs[REG=5FNUMBER]; >+ >+ NICState *nic; >+ NICConf conf; >+ >+ /* Tx */ >+ >+ uint8=5Ft *tx=5Fbuffer; >+ uint32=5Ft tx=5Fbuffer=5Flen; >+ eTSEC=5Frxtx=5Fbd first=5Fbd; >+ >+ /* Rx */ >+ >+ uint8=5Ft *rx=5Fbuffer; >+ uint32=5Ft rx=5Fbuffer=5Flen; >+ uint32=5Ft rx=5Fremaining=5Fdata; >+ uint8=5Ft rx=5Ffirst=5Fin=5Fframe; >+ uint8=5Ft rx=5Ffcb=5Fsize; >+ eTSEC=5Frxtx=5Fbd rx=5Ffirst=5Fbd; >+ uint8=5Ft rx=5Ffcb[10]; >+ uint32=5Ft rx=5Fpadding; >+ >+ /* IRQs */ >+ qemu=5Firq tx=5Firq; >+ qemu=5Firq rx=5Firq; >+ qemu=5Firq err=5Firq; >+ >+ >+ uint16=5Ft phy=5Fstatus; >+ uint16=5Ft phy=5Fcontrol; >+ >+ /* Polling */ >+ QEMUBH *bh; >+ struct ptimer=5Fstate *ptimer; >+ >+} eTSEC; >+ >+#define eTSEC=5FTRANSMIT 1 >+#define eTSEC=5FRECEIVE 2 >+ >+DeviceState *etsec=5Fcreate(hwaddr base, >+ MemoryRegion *mr, >+ NICInfo *nd, >+ qemu=5Firq tx=5Firq, >+ qemu=5Firq rx=5Firq, >+ qemu=5Firq err=5Firq); >+ >+void walk=5Ftx=5Fring(eTSEC *etsec, int ring=5Fnbr); >+void walk=5Frx=5Fring(eTSEC *etsec, int ring=5Fnbr); >+void rx=5Fring=5Fwrite(eTSEC *etsec, const uint8=5Ft *buf, size=5Ft size); >+ >+void write=5Fmiim(eTSEC *etsec, >+ eTSEC=5FRegister *reg, >+ uint32=5Ft reg=5Findex, >+ uint32=5Ft value); >+ >+void miim=5Flink=5Fstatus(eTSEC *etsec, NetClientState *nc); >+ >+#endif /* ! =5FETSEC=5FH=5F */ >diff --git a/hw/net/etsec=5Fmiim.c b/hw/net/etsec=5Fmiim.c >new file mode 100644 >index 0000000..2bd9f0d >--- /dev/null >+++ b/hw/net/etsec=5Fmiim.c >@@ -0,0 +1,146 @@ >+/* >+ * QEMU Freescale eTSEC Emulator >+ * >+ * Copyright (c) 2011-2013 AdaCore >+ * >+ * Permission is hereby granted, free of charge, to any person obtaining = a copy >+ * of this software and associated documentation files (the "Software"), = to deal >+ * in the Software without restriction, including without limitation the = rights >+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or s= ell >+ * copies of the Software, and to permit persons to whom the Software is >+ * furnished to do so, subject to the following conditions: >+ * >+ * The above copyright notice and this permission notice shall be include= d in >+ * all copies or substantial portions of the Software. >+ * >+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRES= S OR >+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILIT= Y, >+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR O= THER >+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISIN= G FROM, >+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS= IN >+ * THE SOFTWARE. >+ */ >+ >+#include "etsec.h" >+#include "etsec=5Fregisters.h" >+ >+/* #define DEBUG=5FMIIM */ >+ >+#define MIIM=5FCONTROL 0 >+#define MIIM=5FSTATUS 1 >+#define MIIM=5FPHY=5FID=5F1 2 >+#define MIIM=5FPHY=5FID=5F2 3 >+#define MIIM=5FT2=5FSTATUS 10 >+#define MIIM=5FEXT=5FSTATUS 15 >+ >+static void miim=5Fread=5Fcycle(eTSEC *etsec) >+{ >+ uint8=5Ft phy; >+ uint8=5Ft addr; >+ uint16=5Ft value; >+ >+ phy =3D (etsec->regs[MIIMADD].value >> 8) & 0x1F; >+ (void)phy; /* Unreferenced */ >+ addr =3D etsec->regs[MIIMADD].value & 0x1F; >+ >+ switch (addr) { >+ case MIIM=5FCONTROL: >+ value =3D etsec->phy=5Fcontrol; >+ break; >+ case MIIM=5FSTATUS: >+ value =3D etsec->phy=5Fstatus; >+ break; >+ case MIIM=5FT2=5FSTATUS: >+ value =3D 0x1800; /* Local and remote receivers OK */ >+ break; >+ default: >+ value =3D 0x0; >+ break; >+ }; >+ >+#ifdef DEBUG=5FMIIM >+ printf("%s phy:%d addr:0x%x value:0x%x\n", =5F=5Ffunc=5F=5F, phy, add= r, value); >+#endif >+ >+ etsec->regs[MIIMSTAT].value =3D value; >+} >+ >+static void miim=5Fwrite=5Fcycle(eTSEC *etsec) >+{ >+ uint8=5Ft phy; >+ uint8=5Ft addr; >+ uint16=5Ft value; >+ >+ phy =3D (etsec->regs[MIIMADD].value >> 8) & 0x1F; >+ (void)phy; /* Unreferenced */ >+ addr =3D etsec->regs[MIIMADD].value & 0x1F; >+ value =3D etsec->regs[MIIMCON].value & 0xffff; >+ >+#ifdef DEBUG=5FMIIM >+ printf("%s phy:%d addr:0x%x value:0x%x\n", =5F=5Ffunc=5F=5F, phy, add= r, value); >+#endif >+ >+ switch (addr) { >+ case MIIM=5FCONTROL: >+ etsec->phy=5Fcontrol =3D value & ~(0x8100); >+ break; >+ default: >+ break; >+ }; >+} >+ >+void write=5Fmiim(eTSEC *etsec, >+ eTSEC=5FRegister *reg, >+ uint32=5Ft reg=5Findex, >+ uint32=5Ft value) >+{ >+ >+ switch (reg=5Findex) { >+ >+ case MIIMCOM: >+ /* Read and scan cycle */ >+ >+ if ((!(reg->value & MIIMCOM=5FREAD)) && (value & MIIMCOM=5FREAD))= { >+ /* Read */ >+ miim=5Fread=5Fcycle(etsec); >+ } >+ reg->value =3D value; >+ break; >+ >+ case MIIMCON: >+ reg->value =3D value & 0xffff; >+ miim=5Fwrite=5Fcycle(etsec); >+ break; >+ >+ default: >+ /* Default handling */ >+ switch (reg->access) { >+ >+ case ACC=5FRW: >+ case ACC=5FWO: >+ reg->value =3D value; >+ break; >+ >+ case ACC=5Fw1c: >+ reg->value &=3D ~value; >+ break; >+ >+ case ACC=5FRO: >+ default: >+ /* Read Only or Unknown register */ >+ break; >+ } >+ } >+ >+} >+ >+void miim=5Flink=5Fstatus(eTSEC *etsec, NetClientState *nc) >+{ >+ /* Set link status */ >+ if (nc->link=5Fdown) { >+ etsec->phy=5Fstatus &=3D ~MII=5FSR=5FLINK=5FSTATUS; >+ } else { >+ etsec->phy=5Fstatus |=3D MII=5FSR=5FLINK=5FSTATUS; >+ } >+} >diff --git a/hw/net/etsec=5Fregisters.c b/hw/net/etsec=5Fregisters.c >new file mode 100644 >index 0000000..719a886 >--- /dev/null >+++ b/hw/net/etsec=5Fregisters.c >@@ -0,0 +1,295 @@ >+/* >+ * QEMU Freescale eTSEC Emulator >+ * >+ * Copyright (c) 2011-2013 AdaCore >+ * >+ * Permission is hereby granted, free of charge, to any person obtaining = a copy >+ * of this software and associated documentation files (the "Software"), = to deal >+ * in the Software without restriction, including without limitation the = rights >+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or s= ell >+ * copies of the Software, and to permit persons to whom the Software is >+ * furnished to do so, subject to the following conditions: >+ * >+ * The above copyright notice and this permission notice shall be include= d in >+ * all copies or substantial portions of the Software. >+ * >+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRES= S OR >+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILIT= Y, >+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR O= THER >+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISIN= G FROM, >+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS= IN >+ * THE SOFTWARE. >+ */ >+#include "etsec=5Fregisters.h" >+ >+const eTSEC=5FRegister=5FDefinition eTSEC=5Fregisters=5Fdef[] =3D { >+{0x000, "TSEC=5FID", "Controller ID register", ACC=5FRO, 0x01240000}, >+{0x004, "TSEC=5FID2", "Controller ID register 2", ACC=5FRO, 0x003000F0}, >+{0x010, "IEVENT", "Interrupt event register", ACC=5Fw1c, 0x00000000}, >+{0x014, "IMASK", "Interrupt mask register", ACC=5FRW, 0x00000000}, >+{0x018, "EDIS", "Error disabled register", ACC=5FRW, 0x00000000}, >+{0x020, "ECNTRL", "Ethernet control register", ACC=5FRW, 0x00000040}, >+{0x028, "PTV", "Pause time value register", ACC=5FRW, 0x00000000}, >+{0x02C, "DMACTRL", "DMA control register", ACC=5FRW, 0x00000000}, >+{0x030, "TBIPA", "TBI PHY address register", ACC=5FRW, 0x00000000}, >+ >+/* eTSEC FIFO Control and Status Registers */ >+ >+{0x058, "FIFO=5FRX=5FALARM", "FIFO receive alarm start threshold= register", ACC=5FRW, 0x00000040}, >+{0x05C, "FIFO=5FRX=5FALARM=5FSHUTOFF", "FIFO receive alarm shut-off thre= shold register", ACC=5FRW, 0x00000080}, >+{0x08C, "FIFO=5FTX=5FTHR", "FIFO transmit threshold register",= ACC=5FRW, 0x00000080}, >+{0x098, "FIFO=5FTX=5FSTARVE", "FIFO transmit starve register", = ACC=5FRW, 0x00000040}, >+{0x09C, "FIFO=5FTX=5FSTARVE=5FSHUTOFF", "FIFO transmit starve shut-off re= gister", ACC=5FRW, 0x00000080}, >+ >+/* eTSEC Transmit Control and Status Registers */ >+ >+{0x100, "TCTRL", "Transmit control register", ACC= =5FRW, 0x00000000}, >+{0x104, "TSTAT", "Transmit status register", ACC= =5Fw1c, 0x00000000}, >+{0x108, "DFVLAN", "Default VLAN control word", ACC= =5FRW, 0x81000000}, >+{0x110, "TXIC", "Transmit interrupt coalescing register", ACC= =5FRW, 0x00000000}, >+{0x114, "TQUEUE", "Transmit queue control register", ACC= =5FRW, 0x00008000}, >+{0x140, "TR03WT", "TxBD Rings 0-3 round-robin weightings", ACC= =5FRW, 0x00000000}, >+{0x144, "TR47WT", "TxBD Rings 4-7 round-robin weightings", ACC= =5FRW, 0x00000000}, >+{0x180, "TBDBPH", "Tx data buffer pointer high bits", ACC= =5FRW, 0x00000000}, >+{0x184, "TBPTR0", "TxBD pointer for ring 0", ACC= =5FRW, 0x00000000}, >+{0x18C, "TBPTR1", "TxBD pointer for ring 1", ACC= =5FRW, 0x00000000}, >+{0x194, "TBPTR2", "TxBD pointer for ring 2", ACC= =5FRW, 0x00000000}, >+{0x19C, "TBPTR3", "TxBD pointer for ring 3", ACC= =5FRW, 0x00000000}, >+{0x1A4, "TBPTR4", "TxBD pointer for ring 4", ACC= =5FRW, 0x00000000}, >+{0x1AC, "TBPTR5", "TxBD pointer for ring 5", ACC= =5FRW, 0x00000000}, >+{0x1B4, "TBPTR6", "TxBD pointer for ring 6", ACC= =5FRW, 0x00000000}, >+{0x1BC, "TBPTR7", "TxBD pointer for ring 7", ACC= =5FRW, 0x00000000}, >+{0x200, "TBASEH", "TxBD base address high bits", ACC= =5FRW, 0x00000000}, >+{0x204, "TBASE0", "TxBD base address of ring 0", ACC= =5FRW, 0x00000000}, >+{0x20C, "TBASE1", "TxBD base address of ring 1", ACC= =5FRW, 0x00000000}, >+{0x214, "TBASE2", "TxBD base address of ring 2", ACC= =5FRW, 0x00000000}, >+{0x21C, "TBASE3", "TxBD base address of ring 3", ACC= =5FRW, 0x00000000}, >+{0x224, "TBASE4", "TxBD base address of ring 4", ACC= =5FRW, 0x00000000}, >+{0x22C, "TBASE5", "TxBD base address of ring 5", ACC= =5FRW, 0x00000000}, >+{0x234, "TBASE6", "TxBD base address of ring 6", ACC= =5FRW, 0x00000000}, >+{0x23C, "TBASE7", "TxBD base address of ring 7", ACC= =5FRW, 0x00000000}, >+{0x280, "TMR=5FTXTS1=5FID", "Tx time stamp identification tag (set 1)", A= CC=5FRO, 0x00000000}, >+{0x284, "TMR=5FTXTS2=5FID", "Tx time stamp identification tag (set 2)", A= CC=5FRO, 0x00000000}, >+{0x2C0, "TMR=5FTXTS1=5FH", "Tx time stamp high (set 1)", A= CC=5FRO, 0x00000000}, >+{0x2C4, "TMR=5FTXTS1=5FL", "Tx time stamp high (set 1)", A= CC=5FRO, 0x00000000}, >+{0x2C8, "TMR=5FTXTS2=5FH", "Tx time stamp high (set 2)", A= CC=5FRO, 0x00000000}, >+{0x2CC, "TMR=5FTXTS2=5FL", "Tx time stamp high (set 2)", A= CC=5FRO, 0x00000000}, >+ >+/* eTSEC Receive Control and Status Registers */ >+ >+{0x300, "RCTRL", "Receive control register", ACC= =5FRW, 0x00000000}, >+{0x304, "RSTAT", "Receive status register", ACC= =5Fw1c, 0x00000000}, >+{0x310, "RXIC", "Receive interrupt coalescing register", ACC= =5FRW, 0x00000000}, >+{0x314, "RQUEUE", "Receive queue control register.", ACC= =5FRW, 0x00800080}, >+{0x330, "RBIFX", "Receive bit field extract control register", ACC= =5FRW, 0x00000000}, >+{0x334, "RQFAR", "Receive queue filing table address register", ACC= =5FRW, 0x00000000}, >+{0x338, "RQFCR", "Receive queue filing table control register", ACC= =5FRW, 0x00000000}, >+{0x33C, "RQFPR", "Receive queue filing table property register", ACC= =5FRW, 0x00000000}, >+{0x340, "MRBLR", "Maximum receive buffer length register", ACC= =5FRW, 0x00000000}, >+{0x380, "RBDBPH", "Rx data buffer pointer high bits", ACC= =5FRW, 0x00000000}, >+{0x384, "RBPTR0", "RxBD pointer for ring 0", ACC= =5FRW, 0x00000000}, >+{0x38C, "RBPTR1", "RxBD pointer for ring 1", ACC= =5FRW, 0x00000000}, >+{0x394, "RBPTR2", "RxBD pointer for ring 2", ACC= =5FRW, 0x00000000}, >+{0x39C, "RBPTR3", "RxBD pointer for ring 3", ACC= =5FRW, 0x00000000}, >+{0x3A4, "RBPTR4", "RxBD pointer for ring 4", ACC= =5FRW, 0x00000000}, >+{0x3AC, "RBPTR5", "RxBD pointer for ring 5", ACC= =5FRW, 0x00000000}, >+{0x3B4, "RBPTR6", "RxBD pointer for ring 6", ACC= =5FRW, 0x00000000}, >+{0x3BC, "RBPTR7", "RxBD pointer for ring 7", ACC= =5FRW, 0x00000000}, >+{0x400, "RBASEH", "RxBD base address high bits", ACC= =5FRW, 0x00000000}, >+{0x404, "RBASE0", "RxBD base address of ring 0", ACC= =5FRW, 0x00000000}, >+{0x40C, "RBASE1", "RxBD base address of ring 1", ACC= =5FRW, 0x00000000}, >+{0x414, "RBASE2", "RxBD base address of ring 2", ACC= =5FRW, 0x00000000}, >+{0x41C, "RBASE3", "RxBD base address of ring 3", ACC= =5FRW, 0x00000000}, >+{0x424, "RBASE4", "RxBD base address of ring 4", ACC= =5FRW, 0x00000000}, >+{0x42C, "RBASE5", "RxBD base address of ring 5", ACC= =5FRW, 0x00000000}, >+{0x434, "RBASE6", "RxBD base address of ring 6", ACC= =5FRW, 0x00000000}, >+{0x43C, "RBASE7", "RxBD base address of ring 7", ACC= =5FRW, 0x00000000}, >+{0x4C0, "TMR=5FRXTS=5FH", "Rx timer time stamp register high", = ACC=5FRW, 0x00000000}, >+{0x4C4, "TMR=5FRXTS=5FL", "Rx timer time stamp register low", = ACC=5FRW, 0x00000000}, >+ >+/* eTSEC MAC Registers */ >+ >+{0x500, "MACCFG1", "MAC configuration register 1", ACC=5FRW,= 0x00000000}, >+{0x504, "MACCFG2", "MAC configuration register 2", ACC=5FRW,= 0x00007000}, >+{0x508, "IPGIFG", "Inter-packet/inter-frame gap register", ACC=5FRW,= 0x40605060}, >+{0x50C, "HAFDUP", "Half-duplex control", ACC=5FRW,= 0x00A1F037}, >+{0x510, "MAXFRM", "Maximum frame length", ACC=5FRW,= 0x00000600}, >+{0x520, "MIIMCFG", "MII management configuration", ACC=5FRW,= 0x00000007}, >+{0x524, "MIIMCOM", "MII management command", ACC=5FRW,= 0x00000000}, >+{0x528, "MIIMADD", "MII management address", ACC=5FRW,= 0x00000000}, >+{0x52C, "MIIMCON", "MII management control", ACC=5FWO,= 0x00000000}, >+{0x530, "MIIMSTAT", "MII management status", ACC=5FRO,= 0x00000000}, >+{0x534, "MIIMIND", "MII management indicator", ACC=5FRO,= 0x00000000}, >+{0x53C, "IFSTAT", "Interface status", ACC=5FRO,= 0x00000000}, >+{0x540, "MACSTNADDR1", "MAC station address register 1", ACC=5FRW,= 0x00000000}, >+{0x544, "MACSTNADDR2", "MAC station address register 2", ACC=5FRW,= 0x00000000}, >+{0x548, "MAC01ADDR1", "MAC exact match address 1, part 1", ACC=5FRW,= 0x00000000}, >+{0x54C, "MAC01ADDR2", "MAC exact match address 1, part 2", ACC=5FRW,= 0x00000000}, >+{0x550, "MAC02ADDR1", "MAC exact match address 2, part 1", ACC=5FRW,= 0x00000000}, >+{0x554, "MAC02ADDR2", "MAC exact match address 2, part 2", ACC=5FRW,= 0x00000000}, >+{0x558, "MAC03ADDR1", "MAC exact match address 3, part 1", ACC=5FRW,= 0x00000000}, >+{0x55C, "MAC03ADDR2", "MAC exact match address 3, part 2", ACC=5FRW,= 0x00000000}, >+{0x560, "MAC04ADDR1", "MAC exact match address 4, part 1", ACC=5FRW,= 0x00000000}, >+{0x564, "MAC04ADDR2", "MAC exact match address 4, part 2", ACC=5FRW,= 0x00000000}, >+{0x568, "MAC05ADDR1", "MAC exact match address 5, part 1", ACC=5FRW,= 0x00000000}, >+{0x56C, "MAC05ADDR2", "MAC exact match address 5, part 2", ACC=5FRW,= 0x00000000}, >+{0x570, "MAC06ADDR1", "MAC exact match address 6, part 1", ACC=5FRW,= 0x00000000}, >+{0x574, "MAC06ADDR2", "MAC exact match address 6, part 2", ACC=5FRW,= 0x00000000}, >+{0x578, "MAC07ADDR1", "MAC exact match address 7, part 1", ACC=5FRW,= 0x00000000}, >+{0x57C, "MAC07ADDR2", "MAC exact match address 7, part 2", ACC=5FRW,= 0x00000000}, >+{0x580, "MAC08ADDR1", "MAC exact match address 8, part 1", ACC=5FRW,= 0x00000000}, >+{0x584, "MAC08ADDR2", "MAC exact match address 8, part 2", ACC=5FRW,= 0x00000000}, >+{0x588, "MAC09ADDR1", "MAC exact match address 9, part 1", ACC=5FRW,= 0x00000000}, >+{0x58C, "MAC09ADDR2", "MAC exact match address 9, part 2", ACC=5FRW,= 0x00000000}, >+{0x590, "MAC10ADDR1", "MAC exact match address 10, part 1", ACC=5FRW,= 0x00000000}, >+{0x594, "MAC10ADDR2", "MAC exact match address 10, part 2", ACC=5FRW,= 0x00000000}, >+{0x598, "MAC11ADDR1", "MAC exact match address 11, part 1", ACC=5FRW,= 0x00000000}, >+{0x59C, "MAC11ADDR2", "MAC exact match address 11, part 2", ACC=5FRW,= 0x00000000}, >+{0x5A0, "MAC12ADDR1", "MAC exact match address 12, part 1", ACC=5FRW,= 0x00000000}, >+{0x5A4, "MAC12ADDR2", "MAC exact match address 12, part 2", ACC=5FRW,= 0x00000000}, >+{0x5A8, "MAC13ADDR1", "MAC exact match address 13, part 1", ACC=5FRW,= 0x00000000}, >+{0x5AC, "MAC13ADDR2", "MAC exact match address 13, part 2", ACC=5FRW,= 0x00000000}, >+{0x5B0, "MAC14ADDR1", "MAC exact match address 14, part 1", ACC=5FRW,= 0x00000000}, >+{0x5B4, "MAC14ADDR2", "MAC exact match address 14, part 2", ACC=5FRW,= 0x00000000}, >+{0x5B8, "MAC15ADDR1", "MAC exact match address 15, part 1", ACC=5FRW,= 0x00000000}, >+{0x5BC, "MAC15ADDR2", "MAC exact match address 15, part 2", ACC=5FRW,= 0x00000000}, >+ >+/* eTSEC, "Transmit", "and", Receive, Counters */ >+ >+{0x680, "TR64", "Transmit and receive 64-byte frame counter ", = ACC=5FRW, 0x00000000}, >+{0x684, "TR127", "Transmit and receive 65- to 127-byte frame counter", = ACC=5FRW, 0x00000000}, >+{0x688, "TR255", "Transmit and receive 128- to 255-byte frame counter", = ACC=5FRW, 0x00000000}, >+{0x68C, "TR511", "Transmit and receive 256- to 511-byte frame counter", = ACC=5FRW, 0x00000000}, >+{0x690, "TR1K", "Transmit and receive 512- to 1023-byte frame counter", = ACC=5FRW, 0x00000000}, >+{0x694, "TRMAX", "Transmit and receive 1024- to 1518-byte frame counter",= ACC=5FRW, 0x00000000}, >+{0x698, "TRMGV", "Transmit and receive 1519- to 1522-byte good VLAN frame= count", ACC=5FRW, 0x00000000}, >+ >+/* eTSEC Receive Counters */ >+ >+{0x69C, "RBYT", "Receive byte counter", ACC=5FRW, 0x0000= 0000}, >+{0x6A0, "RPKT", "Receive packet counter", ACC=5FRW, 0x0000= 0000}, >+{0x6A4, "RFCS", "Receive FCS error counter", ACC=5FRW, 0x0000= 0000}, >+{0x6A8, "RMCA", "Receive multicast packet counter", ACC=5FRW, 0x0000= 0000}, >+{0x6AC, "RBCA", "Receive broadcast packet counter", ACC=5FRW, 0x0000= 0000}, >+{0x6B0, "RXCF", "Receive control frame packet counter ", ACC=5FRW, 0x0000= 0000}, >+{0x6B4, "RXPF", "Receive PAUSE frame packet counter", ACC=5FRW, 0x0000= 0000}, >+{0x6B8, "RXUO", "Receive unknown OP code counter ", ACC=5FRW, 0x0000= 0000}, >+{0x6BC, "RALN", "Receive alignment error counter ", ACC=5FRW, 0x0000= 0000}, >+{0x6C0, "RFLR", "Receive frame length error counter ", ACC=5FRW, 0x0000= 0000}, >+{0x6C4, "RCDE", "Receive code error counter ", ACC=5FRW, 0x0000= 0000}, >+{0x6C8, "RCSE", "Receive carrier sense error counter", ACC=5FRW, 0x0000= 0000}, >+{0x6CC, "RUND", "Receive undersize packet counter", ACC=5FRW, 0x0000= 0000}, >+{0x6D0, "ROVR", "Receive oversize packet counter ", ACC=5FRW, 0x0000= 0000}, >+{0x6D4, "RFRG", "Receive fragments counter", ACC=5FRW, 0x0000= 0000}, >+{0x6D8, "RJBR", "Receive jabber counter ", ACC=5FRW, 0x0000= 0000}, >+{0x6DC, "RDRP", "Receive drop counter", ACC=5FRW, 0x0000= 0000}, >+ >+/* eTSEC Transmit Counters */ >+ >+{0x6E0, "TBYT", "Transmit byte counter", ACC=5FRW, = 0x00000000}, >+{0x6E4, "TPKT", "Transmit packet counter", ACC=5FRW, = 0x00000000}, >+{0x6E8, "TMCA", "Transmit multicast packet counter ", ACC=5FRW, = 0x00000000}, >+{0x6EC, "TBCA", "Transmit broadcast packet counter ", ACC=5FRW, = 0x00000000}, >+{0x6F0, "TXPF", "Transmit PAUSE control frame counter ", ACC=5FRW, = 0x00000000}, >+{0x6F4, "TDFR", "Transmit deferral packet counter ", ACC=5FRW, = 0x00000000}, >+{0x6F8, "TEDF", "Transmit excessive deferral packet counter ", ACC=5FRW, = 0x00000000}, >+{0x6FC, "TSCL", "Transmit single collision packet counter", ACC=5FRW, = 0x00000000}, >+{0x700, "TMCL", "Transmit multiple collision packet counter", ACC=5FRW, = 0x00000000}, >+{0x704, "TLCL", "Transmit late collision packet counter", ACC=5FRW, = 0x00000000}, >+{0x708, "TXCL", "Transmit excessive collision packet counter", ACC=5FRW, = 0x00000000}, >+{0x70C, "TNCL", "Transmit total collision counter ", ACC=5FRW, = 0x00000000}, >+{0x714, "TDRP", "Transmit drop frame counter", ACC=5FRW, = 0x00000000}, >+{0x718, "TJBR", "Transmit jabber frame counter ", ACC=5FRW, = 0x00000000}, >+{0x71C, "TFCS", "Transmit FCS error counter", ACC=5FRW, = 0x00000000}, >+{0x720, "TXCF", "Transmit control frame counter ", ACC=5FRW, = 0x00000000}, >+{0x724, "TOVR", "Transmit oversize frame counter", ACC=5FRW, = 0x00000000}, >+{0x728, "TUND", "Transmit undersize frame counter ", ACC=5FRW, = 0x00000000}, >+{0x72C, "TFRG", "Transmit fragments frame counter ", ACC=5FRW, = 0x00000000}, >+ >+/* eTSEC Counter Control and TOE Statistics Registers */ >+ >+{0x730, "CAR1", "Carry register one register", ACC=5Fw1c, 0x000= 00000}, >+{0x734, "CAR2", "Carry register two register ", ACC=5Fw1c, 0x000= 00000}, >+{0x738, "CAM1", "Carry register one mask register ", ACC=5FRW, 0xFE0= 3FFFF}, >+{0x73C, "CAM2", "Carry register two mask register ", ACC=5FRW, 0x000= FFFFD}, >+{0x740, "RREJ", "Receive filer rejected packet counter", ACC=5FRW, 0x000= 00000}, >+ >+/* Hash Function Registers */ >+ >+{0x800, "IGADDR0", "Individual/group address register 0", ACC=5FRW, 0x000= 00000}, >+{0x804, "IGADDR1", "Individual/group address register 1", ACC=5FRW, 0x000= 00000}, >+{0x808, "IGADDR2", "Individual/group address register 2", ACC=5FRW, 0x000= 00000}, >+{0x80C, "IGADDR3", "Individual/group address register 3", ACC=5FRW, 0x000= 00000}, >+{0x810, "IGADDR4", "Individual/group address register 4", ACC=5FRW, 0x000= 00000}, >+{0x814, "IGADDR5", "Individual/group address register 5", ACC=5FRW, 0x000= 00000}, >+{0x818, "IGADDR6", "Individual/group address register 6", ACC=5FRW, 0x000= 00000}, >+{0x81C, "IGADDR7", "Individual/group address register 7", ACC=5FRW, 0x000= 00000}, >+{0x880, "GADDR0", "Group address register 0", ACC=5FRW, 0x000= 00000}, >+{0x884, "GADDR1", "Group address register 1", ACC=5FRW, 0x000= 00000}, >+{0x888, "GADDR2", "Group address register 2", ACC=5FRW, 0x000= 00000}, >+{0x88C, "GADDR3", "Group address register 3", ACC=5FRW, 0x000= 00000}, >+{0x890, "GADDR4", "Group address register 4", ACC=5FRW, 0x000= 00000}, >+{0x894, "GADDR5", "Group address register 5", ACC=5FRW, 0x000= 00000}, >+{0x898, "GADDR6", "Group address register 6", ACC=5FRW, 0x000= 00000}, >+{0x89C, "GADDR7", "Group address register 7", ACC=5FRW, 0x000= 00000}, >+ >+/* eTSEC DMA Attribute Registers */ >+ >+{0xBF8, "ATTR", "Attribute register", = ACC=5FRW, 0x00000000}, >+{0xBFC, "ATTRELI", "Attribute extract length and extract index register",= ACC=5FRW, 0x00000000}, >+ >+ >+/* eTSEC Lossless Flow Control Registers */ >+ >+{0xC00, "RQPRM0", "Receive Queue Parameters register 0 ", ACC=5FRW, 0x00= 000000}, >+{0xC04, "RQPRM1", "Receive Queue Parameters register 1 ", ACC=5FRW, 0x00= 000000}, >+{0xC08, "RQPRM2", "Receive Queue Parameters register 2 ", ACC=5FRW, 0x00= 000000}, >+{0xC0C, "RQPRM3", "Receive Queue Parameters register 3 ", ACC=5FRW, 0x00= 000000}, >+{0xC10, "RQPRM4", "Receive Queue Parameters register 4 ", ACC=5FRW, 0x00= 000000}, >+{0xC14, "RQPRM5", "Receive Queue Parameters register 5 ", ACC=5FRW, 0x00= 000000}, >+{0xC18, "RQPRM6", "Receive Queue Parameters register 6 ", ACC=5FRW, 0x00= 000000}, >+{0xC1C, "RQPRM7", "Receive Queue Parameters register 7 ", ACC=5FRW, 0x00= 000000}, >+{0xC44, "RFBPTR0", "Last Free RxBD pointer for ring 0", ACC=5FRW, 0x00= 000000}, >+{0xC4C, "RFBPTR1", "Last Free RxBD pointer for ring 1", ACC=5FRW, 0x00= 000000}, >+{0xC54, "RFBPTR2", "Last Free RxBD pointer for ring 2", ACC=5FRW, 0x00= 000000}, >+{0xC5C, "RFBPTR3", "Last Free RxBD pointer for ring 3", ACC=5FRW, 0x00= 000000}, >+{0xC64, "RFBPTR4", "Last Free RxBD pointer for ring 4", ACC=5FRW, 0x00= 000000}, >+{0xC6C, "RFBPTR5", "Last Free RxBD pointer for ring 5", ACC=5FRW, 0x00= 000000}, >+{0xC74, "RFBPTR6", "Last Free RxBD pointer for ring 6", ACC=5FRW, 0x00= 000000}, >+{0xC7C, "RFBPTR7", "Last Free RxBD pointer for ring 7", ACC=5FRW, 0x00= 000000}, >+ >+/* eTSEC Future Expansion Space */ >+ >+/* Reserved*/ >+ >+/* eTSEC IEEE 1588 Registers */ >+ >+{0xE00, "TMR=5FCTRL", "Timer control register", = ACC=5FRW, 0x00010001}, >+{0xE04, "TMR=5FTEVENT", "time stamp event register", = ACC=5Fw1c, 0x00000000}, >+{0xE08, "TMR=5FTEMASK", "Timer event mask register", = ACC=5FRW, 0x00000000}, >+{0xE0C, "TMR=5FPEVENT", "time stamp event register", = ACC=5FRW, 0x00000000}, >+{0xE10, "TMR=5FPEMASK", "Timer event mask register", = ACC=5FRW, 0x00000000}, >+{0xE14, "TMR=5FSTAT", "time stamp status register", = ACC=5FRW, 0x00000000}, >+{0xE18, "TMR=5FCNT=5FH", "timer counter high register", = ACC=5FRW, 0x00000000}, >+{0xE1C, "TMR=5FCNT=5FL", "timer counter low register", = ACC=5FRW, 0x00000000}, >+{0xE20, "TMR=5FADD", "Timer drift compensation addend register", = ACC=5FRW, 0x00000000}, >+{0xE24, "TMR=5FACC", "Timer accumulator register", = ACC=5FRW, 0x00000000}, >+{0xE28, "TMR=5FPRSC", "Timer prescale", = ACC=5FRW, 0x00000002}, >+{0xE30, "TMROFF=5FH", "Timer offset high", = ACC=5FRW, 0x00000000}, >+{0xE34, "TMROFF=5FL", "Timer offset low", = ACC=5FRW, 0x00000000}, >+{0xE40, "TMR=5FALARM1=5FH", "Timer alarm 1 high register", = ACC=5FRW, 0xFFFFFFFF}, >+{0xE44, "TMR=5FALARM1=5FL", "Timer alarm 1 high register", = ACC=5FRW, 0xFFFFFFFF}, >+{0xE48, "TMR=5FALARM2=5FH", "Timer alarm 2 high register", = ACC=5FRW, 0xFFFFFFFF}, >+{0xE4C, "TMR=5FALARM2=5FL", "Timer alarm 2 high register", = ACC=5FRW, 0xFFFFFFFF}, >+{0xE80, "TMR=5FFIPER1", "Timer fixed period interval", = ACC=5FRW, 0xFFFFFFFF}, >+{0xE84, "TMR=5FFIPER2", "Timer fixed period interval", = ACC=5FRW, 0xFFFFFFFF}, >+{0xE88, "TMR=5FFIPER3", "Timer fixed period interval", = ACC=5FRW, 0xFFFFFFFF}, >+{0xEA0, "TMR=5FETTS1=5FH", "Time stamp of general purpose external trigg= er ", ACC=5FRW, 0x00000000}, >+{0xEA4, "TMR=5FETTS1=5FL", "Time stamp of general purpose external trigg= er", ACC=5FRW, 0x00000000}, >+{0xEA8, "TMR=5FETTS2=5FH", "Time stamp of general purpose external trigg= er ", ACC=5FRW, 0x00000000}, >+{0xEAC, "TMR=5FETTS2=5FL", "Time stamp of general purpose external trigg= er", ACC=5FRW, 0x00000000}, >+ >+/* End Of Table */ >+{0x0, 0x0, 0x0, 0x0, 0x0} >+}; >diff --git a/hw/net/etsec=5Fregisters.h b/hw/net/etsec=5Fregisters.h >new file mode 100644 >index 0000000..7faeaa9 >--- /dev/null >+++ b/hw/net/etsec=5Fregisters.h >@@ -0,0 +1,302 @@ >+/* >+ * QEMU Freescale eTSEC Emulator >+ * >+ * Copyright (c) 2011-2013 AdaCore >+ * >+ * Permission is hereby granted, free of charge, to any person obtaining = a copy >+ * of this software and associated documentation files (the "Software"), = to deal >+ * in the Software without restriction, including without limitation the = rights >+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or s= ell >+ * copies of the Software, and to permit persons to whom the Software is >+ * furnished to do so, subject to the following conditions: >+ * >+ * The above copyright notice and this permission notice shall be include= d in >+ * all copies or substantial portions of the Software. >+ * >+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRES= S OR >+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILIT= Y, >+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR O= THER >+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISIN= G FROM, >+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS= IN >+ * THE SOFTWARE. >+ */ >+#ifndef =5FETSEC=5FREGISTERS=5FH=5F >+#define =5FETSEC=5FREGISTERS=5FH=5F >+ >+#include >+ >+typedef struct eTSEC=5FRegister=5FDefinition { >+ uint32=5Ft offset; >+ const char *name; >+ const char *desc; >+ uint32=5Ft access; >+ uint32=5Ft reset; >+} eTSEC=5FRegister=5FDefinition; >+ >+#define ACC=5FRW 1 /* Read/Write */ >+#define ACC=5FRO 2 /* Read Only */ >+#define ACC=5FWO 3 /* Write Only */ >+#define ACC=5Fw1c 4 /* Write 1 to clear */ >+#define ACC=5FUNKNOWN 4 /* Unknown register*/ >+ >+extern const eTSEC=5FRegister=5FDefinition eTSEC=5Fregisters=5Fdef[]; >+ >+#define DMACTRL=5FLE (1 << 15) >+#define DMACTRL=5FGRS (1 << 4) >+#define DMACTRL=5FGTS (1 << 3) >+#define DMACTRL=5FWOP (1 << 0) >+ >+#define IEVENT=5FRXF (1 << 7) >+#define IEVENT=5FGRSC (1 << 8) >+#define IEVENT=5FRXB (1 << 15) >+#define IEVENT=5FTXF (1 << 20) >+#define IEVENT=5FTXB (1 << 21) >+#define IEVENT=5FTXC (1 << 23) >+#define IEVENT=5FGTSC (1 << 25) >+#define IEVENT=5FBSY (1 << 29) >+#define IEVENT=5FRXC (1 << 30) >+ >+#define IMASK=5FRXFEN (1 << 7) >+#define IMASK=5FGRSCEN (1 << 8) >+#define IMASK=5FRXBEN (1 << 15) >+#define IMASK=5FTXFEN (1 << 20) >+#define IMASK=5FTXBEN (1 << 21) >+#define IMASK=5FGTSCEN (1 << 25) >+ >+#define MACCFG1=5FTX=5FEN (1 << 0) >+#define MACCFG1=5FRX=5FEN (1 << 2) >+ >+#define MACCFG2=5FCRC=5FEN (1 << 1) >+#define MACCFG2=5FPADCRC (1 << 2) >+ >+#define MIIMCOM=5FREAD (1 << 0) >+#define MIIMCOM=5FSCAN (1 << 1) >+ >+#define RCTRL=5FPRSDEP=5FMASK (0x3) >+#define RCTRL=5FPRSDEP=5FOFFSET (6) >+#define RCTRL=5FRSF (1 << 2) >+ >+/* Index of each register */ >+ >+#define TSEC=5FID (0x000 / 4) >+#define TSEC=5FID2 (0x004 / 4) >+#define IEVENT (0x010 / 4) >+#define IMASK (0x014 / 4) >+#define EDIS (0x018 / 4) >+#define ECNTRL (0x020 / 4) >+#define PTV (0x028 / 4) >+#define DMACTRL (0x02C / 4) >+#define TBIPA (0x030 / 4) >+#define TCTRL (0x100 / 4) >+#define TSTAT (0x104 / 4) >+#define DFVLAN (0x108 / 4) >+#define TXIC (0x110 / 4) >+#define TQUEUE (0x114 / 4) >+#define TR03WT (0x140 / 4) >+#define TR47WT (0x144 / 4) >+#define TBDBPH (0x180 / 4) >+#define TBPTR0 (0x184 / 4) >+#define TBPTR1 (0x18C / 4) >+#define TBPTR2 (0x194 / 4) >+#define TBPTR3 (0x19C / 4) >+#define TBPTR4 (0x1A4 / 4) >+#define TBPTR5 (0x1AC / 4) >+#define TBPTR6 (0x1B4 / 4) >+#define TBPTR7 (0x1BC / 4) >+#define TBASEH (0x200 / 4) >+#define TBASE0 (0x204 / 4) >+#define TBASE1 (0x20C / 4) >+#define TBASE2 (0x214 / 4) >+#define TBASE3 (0x21C / 4) >+#define TBASE4 (0x224 / 4) >+#define TBASE5 (0x22C / 4) >+#define TBASE6 (0x234 / 4) >+#define TBASE7 (0x23C / 4) >+#define TMR=5FTXTS1=5FID (0x280 / 4) >+#define TMR=5FTXTS2=5FID (0x284 / 4) >+#define TMR=5FTXTS1=5FH (0x2C0 / 4) >+#define TMR=5FTXTS1=5FL (0x2C4 / 4) >+#define TMR=5FTXTS2=5FH (0x2C8 / 4) >+#define TMR=5FTXTS2=5FL (0x2CC / 4) >+#define RCTRL (0x300 / 4) >+#define RSTAT (0x304 / 4) >+#define RXIC (0x310 / 4) >+#define RQUEUE (0x314 / 4) >+#define RBIFX (0x330 / 4) >+#define RQFAR (0x334 / 4) >+#define RQFCR (0x338 / 4) >+#define RQFPR (0x33C / 4) >+#define MRBLR (0x340 / 4) >+#define RBDBPH (0x380 / 4) >+#define RBPTR0 (0x384 / 4) >+#define RBPTR1 (0x38C / 4) >+#define RBPTR2 (0x394 / 4) >+#define RBPTR3 (0x39C / 4) >+#define RBPTR4 (0x3A4 / 4) >+#define RBPTR5 (0x3AC / 4) >+#define RBPTR6 (0x3B4 / 4) >+#define RBPTR7 (0x3BC / 4) >+#define RBASEH (0x400 / 4) >+#define RBASE0 (0x404 / 4) >+#define RBASE1 (0x40C / 4) >+#define RBASE2 (0x414 / 4) >+#define RBASE3 (0x41C / 4) >+#define RBASE4 (0x424 / 4) >+#define RBASE5 (0x42C / 4) >+#define RBASE6 (0x434 / 4) >+#define RBASE7 (0x43C / 4) >+#define TMR=5FRXTS=5FH (0x4C0 / 4) >+#define TMR=5FRXTS=5FL (0x4C4 / 4) >+#define MACCFG1 (0x500 / 4) >+#define MACCFG2 (0x504 / 4) >+#define IPGIFG (0x508 / 4) >+#define HAFDUP (0x50C / 4) >+#define MAXFRM (0x510 / 4) >+#define MIIMCFG (0x520 / 4) >+#define MIIMCOM (0x524 / 4) >+#define MIIMADD (0x528 / 4) >+#define MIIMCON (0x52C / 4) >+#define MIIMSTAT (0x530 / 4) >+#define MIIMIND (0x534 / 4) >+#define IFSTAT (0x53C / 4) >+#define MACSTNADDR1 (0x540 / 4) >+#define MACSTNADDR2 (0x544 / 4) >+#define MAC01ADDR1 (0x548 / 4) >+#define MAC01ADDR2 (0x54C / 4) >+#define MAC02ADDR1 (0x550 / 4) >+#define MAC02ADDR2 (0x554 / 4) >+#define MAC03ADDR1 (0x558 / 4) >+#define MAC03ADDR2 (0x55C / 4) >+#define MAC04ADDR1 (0x560 / 4) >+#define MAC04ADDR2 (0x564 / 4) >+#define MAC05ADDR1 (0x568 / 4) >+#define MAC05ADDR2 (0x56C / 4) >+#define MAC06ADDR1 (0x570 / 4) >+#define MAC06ADDR2 (0x574 / 4) >+#define MAC07ADDR1 (0x578 / 4) >+#define MAC07ADDR2 (0x57C / 4) >+#define MAC08ADDR1 (0x580 / 4) >+#define MAC08ADDR2 (0x584 / 4) >+#define MAC09ADDR1 (0x588 / 4) >+#define MAC09ADDR2 (0x58C / 4) >+#define MAC10ADDR1 (0x590 / 4) >+#define MAC10ADDR2 (0x594 / 4) >+#define MAC11ADDR1 (0x598 / 4) >+#define MAC11ADDR2 (0x59C / 4) >+#define MAC12ADDR1 (0x5A0 / 4) >+#define MAC12ADDR2 (0x5A4 / 4) >+#define MAC13ADDR1 (0x5A8 / 4) >+#define MAC13ADDR2 (0x5AC / 4) >+#define MAC14ADDR1 (0x5B0 / 4) >+#define MAC14ADDR2 (0x5B4 / 4) >+#define MAC15ADDR1 (0x5B8 / 4) >+#define MAC15ADDR2 (0x5BC / 4) >+#define TR64 (0x680 / 4) >+#define TR127 (0x684 / 4) >+#define TR255 (0x688 / 4) >+#define TR511 (0x68C / 4) >+#define TR1K (0x690 / 4) >+#define TRMAX (0x694 / 4) >+#define TRMGV (0x698 / 4) >+#define RBYT (0x69C / 4) >+#define RPKT (0x6A0 / 4) >+#define RFCS (0x6A4 / 4) >+#define RMCA (0x6A8 / 4) >+#define RBCA (0x6AC / 4) >+#define RXCF (0x6B0 / 4) >+#define RXPF (0x6B4 / 4) >+#define RXUO (0x6B8 / 4) >+#define RALN (0x6BC / 4) >+#define RFLR (0x6C0 / 4) >+#define RCDE (0x6C4 / 4) >+#define RCSE (0x6C8 / 4) >+#define RUND (0x6CC / 4) >+#define ROVR (0x6D0 / 4) >+#define RFRG (0x6D4 / 4) >+#define RJBR (0x6D8 / 4) >+#define RDRP (0x6DC / 4) >+#define TBYT (0x6E0 / 4) >+#define TPKT (0x6E4 / 4) >+#define TMCA (0x6E8 / 4) >+#define TBCA (0x6EC / 4) >+#define TXPF (0x6F0 / 4) >+#define TDFR (0x6F4 / 4) >+#define TEDF (0x6F8 / 4) >+#define TSCL (0x6FC / 4) >+#define TMCL (0x700 / 4) >+#define TLCL (0x704 / 4) >+#define TXCL (0x708 / 4) >+#define TNCL (0x70C / 4) >+#define TDRP (0x714 / 4) >+#define TJBR (0x718 / 4) >+#define TFCS (0x71C / 4) >+#define TXCF (0x720 / 4) >+#define TOVR (0x724 / 4) >+#define TUND (0x728 / 4) >+#define TFRG (0x72C / 4) >+#define CAR1 (0x730 / 4) >+#define CAR2 (0x734 / 4) >+#define CAM1 (0x738 / 4) >+#define CAM2 (0x73C / 4) >+#define RREJ (0x740 / 4) >+#define IGADDR0 (0x800 / 4) >+#define IGADDR1 (0x804 / 4) >+#define IGADDR2 (0x808 / 4) >+#define IGADDR3 (0x80C / 4) >+#define IGADDR4 (0x810 / 4) >+#define IGADDR5 (0x814 / 4) >+#define IGADDR6 (0x818 / 4) >+#define IGADDR7 (0x81C / 4) >+#define GADDR0 (0x880 / 4) >+#define GADDR1 (0x884 / 4) >+#define GADDR2 (0x888 / 4) >+#define GADDR3 (0x88C / 4) >+#define GADDR4 (0x890 / 4) >+#define GADDR5 (0x894 / 4) >+#define GADDR6 (0x898 / 4) >+#define GADDR7 (0x89C / 4) >+#define ATTR (0xBF8 / 4) >+#define ATTRELI (0xBFC / 4) >+#define RQPRM0 (0xC00 / 4) >+#define RQPRM1 (0xC04 / 4) >+#define RQPRM2 (0xC08 / 4) >+#define RQPRM3 (0xC0C / 4) >+#define RQPRM4 (0xC10 / 4) >+#define RQPRM5 (0xC14 / 4) >+#define RQPRM6 (0xC18 / 4) >+#define RQPRM7 (0xC1C / 4) >+#define RFBPTR0 (0xC44 / 4) >+#define RFBPTR1 (0xC4C / 4) >+#define RFBPTR2 (0xC54 / 4) >+#define RFBPTR3 (0xC5C / 4) >+#define RFBPTR4 (0xC64 / 4) >+#define RFBPTR5 (0xC6C / 4) >+#define RFBPTR6 (0xC74 / 4) >+#define RFBPTR7 (0xC7C / 4) >+#define TMR=5FCTRL (0xE00 / 4) >+#define TMR=5FTEVENT (0xE04 / 4) >+#define TMR=5FTEMASK (0xE08 / 4) >+#define TMR=5FPEVENT (0xE0C / 4) >+#define TMR=5FPEMASK (0xE10 / 4) >+#define TMR=5FSTAT (0xE14 / 4) >+#define TMR=5FCNT=5FH (0xE18 / 4) >+#define TMR=5FCNT=5FL (0xE1C / 4) >+#define TMR=5FADD (0xE20 / 4) >+#define TMR=5FACC (0xE24 / 4) >+#define TMR=5FPRSC (0xE28 / 4) >+#define TMROFF=5FH (0xE30 / 4) >+#define TMROFF=5FL (0xE34 / 4) >+#define TMR=5FALARM1=5FH (0xE40 / 4) >+#define TMR=5FALARM1=5FL (0xE44 / 4) >+#define TMR=5FALARM2=5FH (0xE48 / 4) >+#define TMR=5FALARM2=5FL (0xE4C / 4) >+#define TMR=5FFIPER1 (0xE80 / 4) >+#define TMR=5FFIPER2 (0xE84 / 4) >+#define TMR=5FFIPER3 (0xE88 / 4) >+#define TMR=5FETTS1=5FH (0xEA0 / 4) >+#define TMR=5FETTS1=5FL (0xEA4 / 4) >+#define TMR=5FETTS2=5FH (0xEA8 / 4) >+#define TMR=5FETTS2=5FL (0xEAC / 4) >+ >+#endif /* ! =5FETSEC=5FREGISTERS=5FH=5F */ >diff --git a/hw/net/etsec=5Frings.c b/hw/net/etsec=5Frings.c >new file mode 100644 >index 0000000..15c0616 >--- /dev/null >+++ b/hw/net/etsec=5Frings.c >@@ -0,0 +1,673 @@ >+/* >+ * QEMU Freescale eTSEC Emulator >+ * >+ * Copyright (c) 2011-2013 AdaCore >+ * >+ * Permission is hereby granted, free of charge, to any person obtaining = a copy >+ * of this software and associated documentation files (the "Software"), = to deal >+ * in the Software without restriction, including without limitation the = rights >+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or s= ell >+ * copies of the Software, and to permit persons to whom the Software is >+ * furnished to do so, subject to the following conditions: >+ * >+ * The above copyright notice and this permission notice shall be include= d in >+ * all copies or substantial portions of the Software. >+ * >+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRES= S OR >+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILIT= Y, >+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR O= THER >+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISIN= G FROM, >+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS= IN >+ * THE SOFTWARE. >+ */ >+#include "qemu/bswap.h" >+#include "net/checksum.h" >+ >+#include "etsec.h" >+#include "etsec=5Fregisters.h" >+ >+/* #define ETSEC=5FRING=5FDEBUG */ >+/* #define HEX=5FDUMP */ >+/* #define DEBUG=5FBD */ >+ >+#ifdef ETSEC=5FRING=5FDEBUG >+#define RING=5FDEBUG(fmt, ...) printf("%s:%s " fmt, =5F=5Ffunc=5F=5F ,\ >+ etsec->nic->nc.name, ## =5F=5FVA=5FAR= GS=5F=5F) >+#else >+#define RING=5FDEBUG(...) >+#endif /* ETSEC=5FRING=5FDEBUG */ >+ >+#define RING=5FDEBUG=5FA(fmt, ...) printf("%s:%s " fmt, =5F=5Ffunc=5F=5F = ,\ >+ etsec->nic->nc.name, ## =5F=5FVA=5F= ARGS=5F=5F) >+ >+#ifdef DEBUG=5FBD >+ >+static void print=5Ftx=5Fbd=5Fflags(uint16=5Ft flags) >+{ >+ printf(" Ready: %d\n", !!(flags & BD=5FTX=5FREADY)); >+ printf(" PAD/CRC: %d\n", !!(flags & BD=5FTX=5FPADCRC)); >+ printf(" Wrap: %d\n", !!(flags & BD=5FWRAP)); >+ printf(" Interrupt: %d\n", !!(flags & BD=5FINTERRUPT)); >+ printf(" Last in frame: %d\n", !!(flags & BD=5FLAST)); >+ printf(" Tx CRC: %d\n", !!(flags & BD=5FTX=5FTC)); >+ printf(" User-defined preamble / defer: %d\n", >+ !!(flags & BD=5FTX=5FPREDEF)); >+ printf(" Huge frame enable / Late collision: %d\n", >+ !!(flags & BD=5FTX=5FHFELC)); >+ printf(" Control frame / Retransmission Limit: %d\n", >+ !!(flags & BD=5FTX=5FCFRL)); >+ printf(" Retry count: %d\n", >+ (flags >> BD=5FTX=5FRC=5FOFFSET) & BD=5FTX=5FRC=5FMASK); >+ printf(" Underrun / TCP/IP off-load enable: %d\n", >+ !!(flags & BD=5FTX=5FTOEUN)); >+ printf(" Truncation: %d\n", !!(flags & BD=5FTX=5FTR)); >+} >+ >+static void print=5Frx=5Fbd=5Fflags(uint16=5Ft flags) >+{ >+ printf(" Empty: %d\n", !!(flags & BD=5FRX=5FEMPTY)); >+ printf(" Receive software ownership: %d\n", !!(flags & BD=5FRX= =5FRO1)); >+ printf(" Wrap: %d\n", !!(flags & BD=5FWRAP)); >+ printf(" Interrupt: %d\n", !!(flags & BD=5FINTERRUPT)); >+ printf(" Last in frame: %d\n", !!(flags & BD=5FLAST)); >+ printf(" First in frame: %d\n", !!(flags & BD=5FRX=5FFIRST)); >+ printf(" Miss: %d\n", !!(flags & BD=5FRX=5FMISS)); >+ printf(" Broadcast: %d\n", !!(flags & BD=5FRX=5FBROADCAST)); >+ printf(" Multicast: %d\n", !!(flags & BD=5FRX=5FMULTICAST)); >+ printf(" Rx frame length violation: %d\n", !!(flags & BD=5FRX=5F= LG)); >+ printf(" Rx non-octet aligned frame: %d\n", !!(flags & BD=5FRX= =5FNO)); >+ printf(" Short frame: %d\n", !!(flags & BD=5FRX=5FSH)); >+ printf(" Rx CRC Error: %d\n", !!(flags & BD=5FRX=5FCR)); >+ printf(" Overrun: %d\n", !!(flags & BD=5FRX=5FOV)); >+ printf(" Truncation: %d\n", !!(flags & BD=5FRX=5FTR)); >+} >+ >+ >+static void print=5Fbd(eTSEC=5Frxtx=5Fbd bd, int mode, uint32=5Ft index) >+{ >+ printf("eTSEC %s Data Buffer Descriptor (%u)\n", >+ mode =3D=3D eTSEC=5FTRANSMIT ? "Transmit" : "Receive", >+ index); >+ printf(" Flags : 0x%04x\n", bd.flags); >+ if (mode =3D=3D eTSEC=5FTRANSMIT) { >+ print=5Ftx=5Fbd=5Fflags(bd.flags); >+ } else { >+ print=5Frx=5Fbd=5Fflags(bd.flags); >+ } >+ printf(" Length : 0x%04x\n", bd.length); >+ printf(" Pointer : 0x%08x\n", bd.bufptr); >+} >+ >+#endif /* DEBUG=5FBD */ >+ >+#ifdef HEX=5FDUMP >+ >+static void hex=5Fdump(FILE *f, const uint8=5Ft *buf, int size) >+{ >+ int len, i, j, c; >+ >+ for (i =3D 0; i < size; i +=3D 16) { >+ len =3D size - i; >+ if (len > 16) { >+ len =3D 16; >+ } >+ fprintf(f, "%08x ", i); >+ for (j =3D 0; j < 16; j++) { >+ if (j < len) { >+ fprintf(f, " %02x", buf[i + j]); >+ } else { >+ fprintf(f, " "); >+ } >+ } >+ fprintf(f, " "); >+ for (j =3D 0; j < len; j++) { >+ c =3D buf[i + j]; >+ if (c < ' ' || c > '~') { >+ c =3D '.'; >+ } >+ fprintf(f, "%c", c); >+ } >+ fprintf(f, "\n"); >+ } >+} >+ >+#endif >+ >+static void read=5Fbuffer=5Fdescriptor(eTSEC *etsec, >+ hwaddr addr, >+ eTSEC=5Frxtx=5Fbd *bd) >+{ >+ assert(bd !=3D NULL); >+ >+ RING=5FDEBUG("READ Buffer Descriptor @ 0x" TARGET=5FFMT=5Fplx"\n", ad= dr); >+ cpu=5Fphysical=5Fmemory=5Fread(addr, >+ bd, >+ sizeof(eTSEC=5Frxtx=5Fbd)); >+ >+ if (etsec->regs[DMACTRL].value & DMACTRL=5FLE) { >+ bd->flags =3D le16=5Fto=5Fcpupu(&bd->flags); >+ bd->length =3D le16=5Fto=5Fcpupu(&bd->length); >+ bd->bufptr =3D le32=5Fto=5Fcpupu(&bd->bufptr); >+ } else { >+ bd->flags =3D be16=5Fto=5Fcpupu(&bd->flags); >+ bd->length =3D be16=5Fto=5Fcpupu(&bd->length); >+ bd->bufptr =3D be32=5Fto=5Fcpupu(&bd->bufptr); >+ } >+} >+ >+static void write=5Fbuffer=5Fdescriptor(eTSEC *etsec, >+ hwaddr addr, >+ eTSEC=5Frxtx=5Fbd *bd) >+{ >+ assert(bd !=3D NULL); >+ >+ if (etsec->regs[DMACTRL].value & DMACTRL=5FLE) { >+ cpu=5Fto=5Fle16wu(&bd->flags, bd->flags); >+ cpu=5Fto=5Fle16wu(&bd->length, bd->length); >+ cpu=5Fto=5Fle32wu(&bd->bufptr, bd->bufptr); >+ } else { >+ cpu=5Fto=5Fbe16wu(&bd->flags, bd->flags); >+ cpu=5Fto=5Fbe16wu(&bd->length, bd->length); >+ cpu=5Fto=5Fbe32wu(&bd->bufptr, bd->bufptr); >+ } >+ >+ RING=5FDEBUG("Write Buffer Descriptor @ 0x" TARGET=5FFMT=5Fplx"\n", a= ddr); >+ cpu=5Fphysical=5Fmemory=5Fwrite(addr, >+ bd, >+ sizeof(eTSEC=5Frxtx=5Fbd)); >+} >+ >+static void ievent=5Fset(eTSEC *etsec, >+ uint32=5Ft flags) >+{ >+ etsec->regs[IEVENT].value |=3D flags; >+ >+ if ((flags & IEVENT=5FTXB && etsec->regs[IMASK].value & IMASK=5FTXBEN) >+ || (flags & IEVENT=5FTXF && etsec->regs[IMASK].value & IMASK=5FTX= FEN)) { >+ qemu=5Firq=5Fraise(etsec->tx=5Firq); >+ RING=5FDEBUG("%s Raise Tx IRQ\n", =5F=5Ffunc=5F=5F); >+ } >+ >+ if ((flags & IEVENT=5FRXB && etsec->regs[IMASK].value & IMASK=5FRXBEN) >+ || (flags & IEVENT=5FRXF && etsec->regs[IMASK].value & IMASK=5FRX= FEN)) { >+ qemu=5Firq=5Fpulse(etsec->rx=5Firq); >+ RING=5FDEBUG("%s Raise Rx IRQ\n", =5F=5Ffunc=5F=5F); >+ } >+} >+ >+static void tx=5Fpadding=5Fand=5Fcrc(eTSEC *etsec, uint32=5Ft min=5Fframe= =5Flen) >+{ >+ int add =3D min=5Fframe=5Flen - etsec->tx=5Fbuffer=5Flen; >+ >+ /* Padding */ >+ if (add > 0) { >+ RING=5FDEBUG("pad:%u\n", add); >+ etsec->tx=5Fbuffer =3D g=5Frealloc(etsec->tx=5Fbuffer, >+ etsec->tx=5Fbuffer=5Flen + add); >+ >+ memset(etsec->tx=5Fbuffer + etsec->tx=5Fbuffer=5Flen, 0x0, add); >+ etsec->tx=5Fbuffer=5Flen +=3D add; >+ } >+ >+ /* Never add CRC in QEMU */ >+} >+ >+static void process=5Ftx=5Ffcb(eTSEC *etsec) >+{ >+ uint8=5Ft flags =3D (uint8=5Ft)(*etsec->tx=5Fbuffer); >+ /* L3 header offset from start of frame */ >+ uint8=5Ft l3=5Fheader=5Foffset =3D (uint8=5Ft)*(etsec->tx=5Fbuffer + = 3); >+ /* L4 header offset from start of L3 header */ >+ uint8=5Ft l4=5Fheader=5Foffset =3D (uint8=5Ft)*(etsec->tx=5Fbuffer + = 2); >+ /* L3 header */ >+ uint8=5Ft *l3=5Fheader =3D etsec->tx=5Fbuffer + 8 + l3=5Fheader=5Foff= set; >+ /* L4 header */ >+ uint8=5Ft *l4=5Fheader =3D l3=5Fheader + l4=5Fheader=5Foffset; >+ >+ /* if packet is IP4 and IP checksum is requested */ >+ if (flags & FCB=5FTX=5FIP && flags & FCB=5FTX=5FCIP) { >+ /* do IP4 checksum (TODO This funtion does TCP/UDP checksum but n= ot sure >+ * if it also does IP4 checksum. */ >+ net=5Fchecksum=5Fcalculate(etsec->tx=5Fbuffer + 8, >+ etsec->tx=5Fbuffer=5Flen - 8); >+ } >+ /* TODO Check the correct usage of the PHCS field of the FCB in case = the NPH >+ * flag is on */ >+ >+ /* if packet is IP4 and TCP or UDP */ >+ if (flags & FCB=5FTX=5FIP && flags & FCB=5FTX=5FTUP) { >+ /* if UDP */ >+ if (flags & FCB=5FTX=5FUDP) { >+ /* if checksum is requested */ >+ if (flags & FCB=5FTX=5FCTU) { >+ /* do UDP checksum */ >+ >+ net=5Fchecksum=5Fcalculate(etsec->tx=5Fbuffer + 8, >+ etsec->tx=5Fbuffer=5Flen - 8); >+ } else { >+ /* set checksum field to 0 */ >+ l4=5Fheader[6] =3D 0; >+ l4=5Fheader[7] =3D 0; >+ } >+ } else if (flags & FCB=5FTX=5FCTU) { /* if TCP and checksum is re= quested */ >+ /* do TCP checksum */ >+ net=5Fchecksum=5Fcalculate(etsec->tx=5Fbuffer + 8, >+ etsec->tx=5Fbuffer=5Flen - 8); >+ } >+ } >+} >+ >+static void process=5Ftx=5Fbd(eTSEC *etsec, >+ eTSEC=5Frxtx=5Fbd *bd) >+{ >+ uint8=5Ft *tmp=5Fbuff =3D NULL; >+ >+ if (bd->length =3D=3D 0) { >+ /* ERROR */ >+ return; >+ } >+ >+ if (etsec->tx=5Fbuffer=5Flen =3D=3D 0) { >+ /* It's the first BD */ >+ etsec->first=5Fbd =3D *bd; >+ } >+ >+ /* TODO: if TxBD[TOE/UN] skip the Tx Frame Control Block*/ >+ >+ /* Load this Data Buffer */ >+ etsec->tx=5Fbuffer =3D g=5Frealloc(etsec->tx=5Fbuffer, >+ etsec->tx=5Fbuffer=5Flen + bd->length= ); >+ tmp=5Fbuff =3D etsec->tx=5Fbuffer + etsec->tx=5Fbuffer=5Flen; >+ cpu=5Fphysical=5Fmemory=5Fread(bd->bufptr, tmp=5Fbuff, bd->length); >+ >+ /* Update buffer length */ >+ etsec->tx=5Fbuffer=5Flen +=3D bd->length; >+ >+ >+ if (etsec->tx=5Fbuffer=5Flen !=3D 0 && (bd->flags & BD=5FLAST)) { >+ if (etsec->regs[MACCFG1].value & MACCFG1=5FTX=5FEN) { >+ /* MAC Transmit enabled */ >+ >+ /* Process offload Tx FCB */ >+ if (etsec->first=5Fbd.flags & BD=5FTX=5FTOEUN) { >+ process=5Ftx=5Ffcb(etsec); >+ } >+ >+ if (etsec->first=5Fbd.flags & BD=5FTX=5FPADCRC >+ || etsec->regs[MACCFG2].value & MACCFG2=5FPADCRC) { >+ >+ /* Padding and CRC (Padding implies CRC) */ >+ tx=5Fpadding=5Fand=5Fcrc(etsec, 64); >+ >+ } else if (etsec->first=5Fbd.flags & BD=5FTX=5FTC >+ || etsec->regs[MACCFG2].value & MACCFG2=5FCRC=5FEN= ) { >+ >+ /* Only CRC */ >+ /* Never add CRC in QEMU */ >+ } >+ >+#if defined(HEX=5FDUMP) >+ fprintf(stderr, "eTSEC Send packet size:%d\n", >+ etsec->tx=5Fbuffer=5Flen); >+ hex=5Fdump(stderr, etsec->tx=5Fbuffer, etsec->tx=5Fbuffer=5Fl= en); >+#endif /* ETSEC=5FRING=5FDEBUG */ >+ >+ if (etsec->first=5Fbd.flags & BD=5FTX=5FTOEUN) { >+ qemu=5Fsend=5Fpacket(qemu=5Fget=5Fqueue(etsec->nic), >+ etsec->tx=5Fbuffer + 8, >+ etsec->tx=5Fbuffer=5Flen - 8); >+ } else { >+ qemu=5Fsend=5Fpacket(qemu=5Fget=5Fqueue(etsec->nic), >+ etsec->tx=5Fbuffer, >+ etsec->tx=5Fbuffer=5Flen); >+ } >+ >+ } >+ >+ etsec->tx=5Fbuffer=5Flen =3D 0; >+ >+ if (bd->flags & BD=5FINTERRUPT) { >+ ievent=5Fset(etsec, IEVENT=5FTXF); >+ } >+ } else { >+ if (bd->flags & BD=5FINTERRUPT) { >+ ievent=5Fset(etsec, IEVENT=5FTXB); >+ } >+ } >+ >+ /* Update DB flags */ >+ >+ /* Clear Ready */ >+ bd->flags &=3D ~BD=5FTX=5FREADY; >+ >+ /* Clear Defer */ >+ bd->flags &=3D ~BD=5FTX=5FPREDEF; >+ >+ /* Clear Late Collision */ >+ bd->flags &=3D ~BD=5FTX=5FHFELC; >+ >+ /* Clear Retransmission Limit */ >+ bd->flags &=3D ~BD=5FTX=5FCFRL; >+ >+ /* Clear Retry Count */ >+ bd->flags &=3D ~(BD=5FTX=5FRC=5FMASK << BD=5FTX=5FRC=5FOFFSET); >+ >+ /* Clear Underrun */ >+ bd->flags &=3D ~BD=5FTX=5FTOEUN; >+ >+ /* Clear Truncation */ >+ bd->flags &=3D ~BD=5FTX=5FTR; >+} >+ >+void walk=5Ftx=5Fring(eTSEC *etsec, int ring=5Fnbr) >+{ >+ hwaddr ring=5Fbase =3D 0; >+ hwaddr bd=5Faddr =3D 0; >+ eTSEC=5Frxtx=5Fbd bd; >+ uint16=5Ft bd=5Fflags; >+ >+ if (!(etsec->regs[MACCFG1].value & MACCFG1=5FTX=5FEN)) { >+ RING=5FDEBUG("%s: MAC Transmit not enabled\n", =5F=5Ffunc=5F=5F); >+ return; >+ } >+ >+ /* ring=5Fbase =3D (etsec->regs[TBASEH].value & 0xF) << 32; */ >+ ring=5Fbase +=3D etsec->regs[TBASE0 + ring=5Fnbr].value & ~0x7; >+ bd=5Faddr =3D etsec->regs[TBPTR0 + ring=5Fnbr].value & ~0x7; >+ >+ do { >+ read=5Fbuffer=5Fdescriptor(etsec, bd=5Faddr, &bd); >+ >+#ifdef DEBUG=5FBD >+ print=5Fbd(bd, >+ eTSEC=5FTRANSMIT, >+ (bd=5Faddr - ring=5Fbase) / sizeof(eTSEC=5Frxtx=5Fbd)); >+ >+#endif /* DEBUG=5FBD */ >+ >+ /* Save flags before BD update */ >+ bd=5Fflags =3D bd.flags; >+ >+ if (bd=5Fflags & BD=5FTX=5FREADY) { >+ process=5Ftx=5Fbd(etsec, &bd); >+ >+ /* Write back BD after update */ >+ write=5Fbuffer=5Fdescriptor(etsec, bd=5Faddr, &bd); >+ } >+ >+ /* Wrap or next BD */ >+ if (bd=5Fflags & BD=5FWRAP) { >+ bd=5Faddr =3D ring=5Fbase; >+ } else { >+ bd=5Faddr +=3D sizeof(eTSEC=5Frxtx=5Fbd); >+ } >+ >+ } while (bd=5Faddr !=3D ring=5Fbase); >+ >+ bd=5Faddr =3D ring=5Fbase; >+ >+ /* Save the Buffer Descriptor Pointers to current bd */ >+ etsec->regs[TBPTR0 + ring=5Fnbr].value =3D bd=5Faddr; >+ >+ /* Set transmit halt THLTx */ >+ etsec->regs[TSTAT].value |=3D 1 << (31 - ring=5Fnbr); >+} >+ >+static void fill=5Frx=5Fbd(eTSEC *etsec, >+ eTSEC=5Frxtx=5Fbd *bd, >+ const uint8=5Ft **buf, >+ size=5Ft *size) >+{ >+ uint16=5Ft to=5Fwrite =3D MIN(etsec->rx=5Ffcb=5Fsize + *size - etsec-= >rx=5Fpadding, >+ etsec->regs[MRBLR].value); >+ uint32=5Ft bufptr =3D bd->bufptr; >+ uint8=5Ft padd[etsec->rx=5Fpadding]; >+ uint8=5Ft rem; >+ >+ RING=5FDEBUG("eTSEC fill Rx buffer @ 0x%08x" >+ " size:%u(padding + crc:%u) + fcb:%u\n", >+ bufptr, *size, etsec->rx=5Fpadding, etsec->rx=5Ffcb=5Fsize= ); >+ >+ bd->length =3D 0; >+ if (etsec->rx=5Ffcb=5Fsize !=3D 0) { >+ cpu=5Fphysical=5Fmemory=5Fwrite(bufptr, etsec->rx=5Ffcb, etsec->r= x=5Ffcb=5Fsize); >+ >+ bufptr +=3D etsec->rx=5Ffcb=5Fsize; >+ bd->length +=3D etsec->rx=5Ffcb=5Fsize; >+ to=5Fwrite -=3D etsec->rx=5Ffcb=5Fsize; >+ etsec->rx=5Ffcb=5Fsize =3D 0; >+ >+ } >+ >+ if (to=5Fwrite > 0) { >+ cpu=5Fphysical=5Fmemory=5Fwrite(bufptr, *buf, to=5Fwrite); >+ >+ *buf +=3D to=5Fwrite; >+ bufptr +=3D to=5Fwrite; >+ *size -=3D to=5Fwrite; >+ >+ bd->flags &=3D ~BD=5FRX=5FEMPTY; >+ bd->length +=3D to=5Fwrite; >+ } >+ >+ if (*size =3D=3D etsec->rx=5Fpadding) { >+ /* The remaining bytes are for padding which is not actually allo= cated >+ in the buffer */ >+ >+ rem =3D MIN(etsec->regs[MRBLR].value - bd->length, etsec->rx=5Fpa= dding); >+ >+ if (rem > 0) { >+ memset(padd, 0x0, sizeof(padd)); >+ etsec->rx=5Fpadding -=3D rem; >+ *size -=3D rem; >+ bd->length +=3D rem; >+ cpu=5Fphysical=5Fmemory=5Fwrite(bufptr, padd, rem); >+ } >+ } >+} >+ >+static void rx=5Finit=5Fframe(eTSEC *etsec, const uint8=5Ft *buf, size=5F= t size) >+{ >+ uint32=5Ft fcb=5Fsize =3D 0; >+ uint8=5Ft prsdep =3D (etsec->regs[RCTRL].value >> RCTRL=5FPRSDEP= =5FOFFSET) >+ & RCTRL=5FPRSDEP=5FMASK; >+ >+ if (prsdep !=3D 0) { >+ /* Prepend FCB */ >+ fcb=5Fsize =3D 8 + 2; /* FCB size + align */ >+ /* I can't find this 2 bytes alignement in fsl documentation but = VxWorks >+ expects them */ >+ >+ etsec->rx=5Ffcb=5Fsize =3D fcb=5Fsize; >+ >+ /* TODO: fill=5FFCB(etsec); */ >+ memset(etsec->rx=5Ffcb, 0x0, sizeof(etsec->rx=5Ffcb)); >+ >+ } else { >+ etsec->rx=5Ffcb=5Fsize =3D 0; >+ } >+ >+ if (etsec->rx=5Fbuffer !=3D NULL) { >+ g=5Ffree(etsec->rx=5Fbuffer); >+ } >+ >+ /* Do not copy the frame for now */ >+ etsec->rx=5Fbuffer =3D (uint8=5Ft *)buf; >+ etsec->rx=5Fbuffer=5Flen =3D size; >+ etsec->rx=5Fpadding =3D 4; >+ >+ if (size < 60) { >+ etsec->rx=5Fpadding +=3D 60 - size; >+ } >+ >+ etsec->rx=5Ffirst=5Fin=5Fframe =3D 1; >+ etsec->rx=5Fremaining=5Fdata =3D etsec->rx=5Fbuffer=5Flen; >+ RING=5FDEBUG("%s: rx=5Fbuffer=5Flen:%u rx=5Fpadding+crc:%u\n", =5F=5F= func=5F=5F, >+ etsec->rx=5Fbuffer=5Flen, etsec->rx=5Fpadding); >+} >+ >+void rx=5Fring=5Fwrite(eTSEC *etsec, const uint8=5Ft *buf, size=5Ft size) >+{ >+ int ring=5Fnbr =3D 0; /* Always use ring0 (no filer) */ >+ >+ if (etsec->rx=5Fbuffer=5Flen !=3D 0) { >+ RING=5FDEBUG("%s: We can't receive now," >+ " a buffer is already in the pipe\n", =5F=5Ffunc=5F=5F= ); >+ return; >+ } >+ >+ if (etsec->regs[RSTAT].value & 1 << (23 - ring=5Fnbr)) { >+ RING=5FDEBUG("%s: The ring is halted\n", =5F=5Ffunc=5F=5F); >+ return; >+ } >+ >+ if (etsec->regs[DMACTRL].value & DMACTRL=5FGRS) { >+ RING=5FDEBUG("%s: Graceful receive stop\n", =5F=5Ffunc=5F=5F); >+ return; >+ } >+ >+ if (!(etsec->regs[MACCFG1].value & MACCFG1=5FRX=5FEN)) { >+ RING=5FDEBUG("%s: MAC Receive not enabled\n", =5F=5Ffunc=5F=5F); >+ return; >+ } >+ >+ /* Don't drop short packets, just add padding (later) */ >+ >+ rx=5Finit=5Fframe(etsec, buf, size); >+ >+ walk=5Frx=5Fring(etsec, ring=5Fnbr); >+} >+ >+void walk=5Frx=5Fring(eTSEC *etsec, int ring=5Fnbr) >+{ >+ hwaddr ring=5Fbase =3D 0; >+ hwaddr bd=5Faddr =3D 0; >+ hwaddr start=5Fbd=5Faddr =3D 0; >+ eTSEC=5Frxtx=5Fbd bd; >+ uint16=5Ft bd=5Fflags; >+ size=5Ft remaining=5Fdata; >+ const uint8=5Ft *buf; >+ uint8=5Ft *tmp=5Fbuf; >+ size=5Ft size; >+ >+ if (etsec->rx=5Fbuffer=5Flen =3D=3D 0) { >+ /* No frame to send */ >+ RING=5FDEBUG("No frame to send\n"); >+ return; >+ } >+ >+ remaining=5Fdata =3D etsec->rx=5Fremaining=5Fdata + etsec->rx=5Fpaddi= ng; >+ buf =3D etsec->rx=5Fbuffer >+ + (etsec->rx=5Fbuffer=5Flen - etsec->rx=5Fremaining=5Fdata); >+ size =3D etsec->rx=5Fbuffer=5Flen + etsec->rx=5Fpadding; >+ >+ /* ring=5Fbase =3D (etsec->regs[RBASEH].value & 0xF) << 32; */ >+ ring=5Fbase +=3D etsec->regs[RBASE0 + ring=5Fnbr].value & ~0x7; >+ start=5Fbd=5Faddr =3D bd=5Faddr =3D etsec->regs[RBPTR0 + ring=5Fnbr]= .value & ~0x7; >+ >+ do { >+ read=5Fbuffer=5Fdescriptor(etsec, bd=5Faddr, &bd); >+ >+#ifdef DEBUG=5FBD >+ print=5Fbd(bd, >+ eTSEC=5FRECEIVE, >+ (bd=5Faddr - ring=5Fbase) / sizeof(eTSEC=5Frxtx=5Fbd)); >+ >+#endif /* DEBUG=5FBD */ >+ >+ /* Save flags before BD update */ >+ bd=5Fflags =3D bd.flags; >+ >+ if (bd=5Fflags & BD=5FRX=5FEMPTY) { >+ fill=5Frx=5Fbd(etsec, &bd, &buf, &remaining=5Fdata); >+ >+ if (etsec->rx=5Ffirst=5Fin=5Fframe) { >+ bd.flags |=3D BD=5FRX=5FFIRST; >+ etsec->rx=5Ffirst=5Fin=5Fframe =3D 0; >+ etsec->rx=5Ffirst=5Fbd =3D bd; >+ } >+ >+ /* Last in frame */ >+ if (remaining=5Fdata =3D=3D 0) { >+ >+ /* Clear flags */ >+ >+ bd.flags &=3D ~0x7ff; >+ >+ bd.flags |=3D BD=5FLAST; >+ >+ /* NOTE: non-octet aligned frame is impossible in qemu */ >+ >+ if (size >=3D etsec->regs[MAXFRM].value) { >+ /* frame length violation */ >+ printf("%s frame length violation: size:%d MAXFRM:%d\= n", >+ =5F=5Ffunc=5F=5F, size, etsec->regs[MAXFRM].va= lue); >+ >+ bd.flags |=3D BD=5FRX=5FLG; >+ } >+ >+ if (size < 64) { >+ /* Short frame */ >+ printf("%s Short frame: %d\n", =5F=5Ffunc=5F=5F, size= ); >+ bd.flags |=3D BD=5FRX=5FSH; >+ } >+ >+ /* TODO: Broadcast and Multicast */ >+ >+ if (bd.flags | BD=5FINTERRUPT) { >+ /* Set RXFx */ >+ etsec->regs[RSTAT].value |=3D 1 << (7 - ring=5Fnbr); >+ >+ /* Set IEVENT */ >+ ievent=5Fset(etsec, IEVENT=5FRXF); >+ } >+ >+ } else { >+ if (bd.flags | BD=5FINTERRUPT) { >+ /* Set IEVENT */ >+ ievent=5Fset(etsec, IEVENT=5FRXB); >+ } >+ } >+ >+ /* Write back BD after update */ >+ write=5Fbuffer=5Fdescriptor(etsec, bd=5Faddr, &bd); >+ } >+ >+ /* Wrap or next BD */ >+ if (bd=5Fflags & BD=5FWRAP) { >+ bd=5Faddr =3D ring=5Fbase; >+ } else { >+ bd=5Faddr +=3D sizeof(eTSEC=5Frxtx=5Fbd); >+ } >+ } while (remaining=5Fdata !=3D 0 >+ && (bd=5Fflags & BD=5FRX=5FEMPTY) >+ && bd=5Faddr !=3D start=5Fbd=5Faddr); >+ >+ /* Reset ring ptr */ >+ etsec->regs[RBPTR0 + ring=5Fnbr].value =3D bd=5Faddr; >+ >+ /* The frame is too large to fit in the Rx ring */ >+ if (remaining=5Fdata > 0) { >+ >+ /* Set RSTAT[QHLTx] */ >+ etsec->regs[RSTAT].value |=3D 1 << (23 - ring=5Fnbr); >+ >+ /* Save remaining data to send the end of the frame when the ring= will >+ * be restarted >+ */ >+ etsec->rx=5Fremaining=5Fdata =3D remaining=5Fdata; >+ >+ /* Copy the frame */ >+ tmp=5Fbuf =3D g=5Fmalloc(size); >+ memcpy(tmp=5Fbuf, etsec->rx=5Fbuffer, size); >+ etsec->rx=5Fbuffer =3D tmp=5Fbuf; >+ >+ RING=5FDEBUG("no empty RxBD available any more\n"); >+ } else { >+ etsec->rx=5Fbuffer=5Flen =3D 0; >+ etsec->rx=5Fbuffer =3D NULL; >+ } >+ >+ RING=5FDEBUG("eTSEC End of ring=5Fwrite: remaining=5Fdata:%u\n", rema= ining=5Fdata); >+} >--=20 >1.7.9.5 > > Hi: I'm very interesting in it, but I don't know how to create a eTSEC=20 device, I did a test as below: for(i =3D 0; i < nb=5Fnics; i++) { NICInfo *nd =3D &nd=5Ftable[i]; if (!nd->model) { nd->model =3D g=5Fstrdup("eTSEC"); } if(strcmp(nd->model, "eTSEC") =3D=3D 0) { etsec=5Fcreate(ETSEC0=5FREGS=5FOFFSET, ccsr=5Faddr=5Fspace, nd, mpic[0x1d], mpic[0x1e], mpic[0x22]); } } When I start the qemu, an error exists" qemu-system-ppc: Unsupported NIC mo= del: eTSEC" . Could you tell me how to create a eTSEC device? Thank you! -------------------------------------------------- =20 2013-07-15 =