Message ID | 1358957730-17897-2-git-send-email-grant.likely@secretlab.ca |
---|---|
State | New |
Headers | show |
On Wed, Jan 23, 2013 at 04:15:25PM +0000, Grant Likely wrote: > This is a trivial patch to harmonize the coding style on > hw/etraxfs_eth.c. This is in preparation to split off the bitbang mdio > code into a separate file. I applied this one, thanks. > > Cc: Peter Maydell <peter.maydell@linaro.org> > Cc: Paul Brook <paul@codesourcery.com> > Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com> > Cc: Anthony Liguori <aliguori@us.ibm.com> > Cc: Andreas Färber <afaerber@suse.de> > Signed-off-by: Grant Likely <grant.likely@secretlab.ca> > --- > hw/etraxfs_eth.c | 922 +++++++++++++++++++++++++++--------------------------- > 1 file changed, 466 insertions(+), 456 deletions(-) > > diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c > index ec23fa6..0b474c0 100644 > --- a/hw/etraxfs_eth.c > +++ b/hw/etraxfs_eth.c > @@ -35,582 +35,592 @@ > #define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ > #define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ > > -/* > - * The MDIO extensions in the TDK PHY model were reversed engineered from the > +/* > + * The MDIO extensions in the TDK PHY model were reversed engineered from the > * linux driver (PHYID and Diagnostics reg). > * TODO: Add friendly names for the register nums. > */ > struct qemu_phy > { > - uint32_t regs[32]; > + uint32_t regs[32]; > > - int link; > + int link; > > - unsigned int (*read)(struct qemu_phy *phy, unsigned int req); > - void (*write)(struct qemu_phy *phy, unsigned int req, > - unsigned int data); > + unsigned int (*read)(struct qemu_phy *phy, unsigned int req); > + void (*write)(struct qemu_phy *phy, unsigned int req, unsigned int data); > }; > > static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req) > { > - int regnum; > - unsigned r = 0; > - > - regnum = req & 0x1f; > - > - switch (regnum) { > - case 1: > - if (!phy->link) > - break; > - /* MR1. */ > - /* Speeds and modes. */ > - r |= (1 << 13) | (1 << 14); > - r |= (1 << 11) | (1 << 12); > - r |= (1 << 5); /* Autoneg complete. */ > - r |= (1 << 3); /* Autoneg able. */ > - r |= (1 << 2); /* link. */ > - break; > - case 5: > - /* Link partner ability. > - We are kind; always agree with whatever best mode > - the guest advertises. */ > - r = 1 << 14; /* Success. */ > - /* Copy advertised modes. */ > - r |= phy->regs[4] & (15 << 5); > - /* Autoneg support. */ > - r |= 1; > - break; > - case 18: > - { > - /* Diagnostics reg. */ > - int duplex = 0; > - int speed_100 = 0; > - > - if (!phy->link) > - break; > - > - /* Are we advertising 100 half or 100 duplex ? */ > - speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF); > - speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL); > - > - /* Are we advertising 10 duplex or 100 duplex ? */ > - duplex = !!(phy->regs[4] & ADVERTISE_100FULL); > - duplex |= !!(phy->regs[4] & ADVERTISE_10FULL); > - r = (speed_100 << 10) | (duplex << 11); > - } > - break; > - > - default: > - r = phy->regs[regnum]; > - break; > - } > - D(printf("\n%s %x = reg[%d]\n", __func__, r, regnum)); > - return r; > + int regnum; > + unsigned r = 0; > + > + regnum = req & 0x1f; > + > + switch (regnum) { > + case 1: > + if (!phy->link) { > + break; > + } > + /* MR1. */ > + /* Speeds and modes. */ > + r |= (1 << 13) | (1 << 14); > + r |= (1 << 11) | (1 << 12); > + r |= (1 << 5); /* Autoneg complete. */ > + r |= (1 << 3); /* Autoneg able. */ > + r |= (1 << 2); /* link. */ > + break; > + case 5: > + /* Link partner ability. > + We are kind; always agree with whatever best mode > + the guest advertises. */ > + r = 1 << 14; /* Success. */ > + /* Copy advertised modes. */ > + r |= phy->regs[4] & (15 << 5); > + /* Autoneg support. */ > + r |= 1; > + break; > + case 18: > + { > + /* Diagnostics reg. */ > + int duplex = 0; > + int speed_100 = 0; > + > + if (!phy->link) { > + break; > + } > + > + /* Are we advertising 100 half or 100 duplex ? */ > + speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF); > + speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL); > + > + /* Are we advertising 10 duplex or 100 duplex ? */ > + duplex = !!(phy->regs[4] & ADVERTISE_100FULL); > + duplex |= !!(phy->regs[4] & ADVERTISE_10FULL); > + r = (speed_100 << 10) | (duplex << 11); > + } > + break; > + > + default: > + r = phy->regs[regnum]; > + break; > + } > + D(printf("\n%s %x = reg[%d]\n", __func__, r, regnum)); > + return r; > } > > -static void > +static void > tdk_write(struct qemu_phy *phy, unsigned int req, unsigned int data) > { > - int regnum; > - > - regnum = req & 0x1f; > - D(printf("%s reg[%d] = %x\n", __func__, regnum, data)); > - switch (regnum) { > - default: > - phy->regs[regnum] = data; > - break; > - } > + int regnum; > + > + regnum = req & 0x1f; > + D(printf("%s reg[%d] = %x\n", __func__, regnum, data)); > + switch (regnum) { > + default: > + phy->regs[regnum] = data; > + break; > + } > } > > -static void > +static void > tdk_init(struct qemu_phy *phy) > { > - phy->regs[0] = 0x3100; > - /* PHY Id. */ > - phy->regs[2] = 0x0300; > - phy->regs[3] = 0xe400; > - /* Autonegotiation advertisement reg. */ > - phy->regs[4] = 0x01E1; > - phy->link = 1; > - > - phy->read = tdk_read; > - phy->write = tdk_write; > + phy->regs[0] = 0x3100; > + /* PHY Id. */ > + phy->regs[2] = 0x0300; > + phy->regs[3] = 0xe400; > + /* Autonegotiation advertisement reg. */ > + phy->regs[4] = 0x01E1; > + phy->link = 1; > + > + phy->read = tdk_read; > + phy->write = tdk_write; > } > > struct qemu_mdio > { > - /* bus. */ > - int mdc; > - int mdio; > - > - /* decoder. */ > - enum { > - PREAMBLE, > - SOF, > - OPC, > - ADDR, > - REQ, > - TURNAROUND, > - DATA > - } state; > - unsigned int drive; > - > - unsigned int cnt; > - unsigned int addr; > - unsigned int opc; > - unsigned int req; > - unsigned int data; > - > - struct qemu_phy *devs[32]; > + /* bus. */ > + int mdc; > + int mdio; > + > + /* decoder. */ > + enum { > + PREAMBLE, > + SOF, > + OPC, > + ADDR, > + REQ, > + TURNAROUND, > + DATA > + } state; > + unsigned int drive; > + > + unsigned int cnt; > + unsigned int addr; > + unsigned int opc; > + unsigned int req; > + unsigned int data; > + > + struct qemu_phy *devs[32]; > }; > > -static void > +static void > mdio_attach(struct qemu_mdio *bus, struct qemu_phy *phy, unsigned int addr) > { > - bus->devs[addr & 0x1f] = phy; > + bus->devs[addr & 0x1f] = phy; > } > > #ifdef USE_THIS_DEAD_CODE > -static void > +static void > mdio_detach(struct qemu_mdio *bus, struct qemu_phy *phy, unsigned int addr) > { > - bus->devs[addr & 0x1f] = NULL; > + bus->devs[addr & 0x1f] = NULL; > } > #endif > > static void mdio_read_req(struct qemu_mdio *bus) > { > - struct qemu_phy *phy; > - > - phy = bus->devs[bus->addr]; > - if (phy && phy->read) > - bus->data = phy->read(phy, bus->req); > - else > - bus->data = 0xffff; > + struct qemu_phy *phy; > + > + phy = bus->devs[bus->addr]; > + if (phy && phy->read) { > + bus->data = phy->read(phy, bus->req); > + } else { > + bus->data = 0xffff; > + } > } > > static void mdio_write_req(struct qemu_mdio *bus) > { > - struct qemu_phy *phy; > + struct qemu_phy *phy; > > - phy = bus->devs[bus->addr]; > - if (phy && phy->write) > - phy->write(phy, bus->req, bus->data); > + phy = bus->devs[bus->addr]; > + if (phy && phy->write) { > + phy->write(phy, bus->req, bus->data); > + } > } > > static void mdio_cycle(struct qemu_mdio *bus) > { > - bus->cnt++; > + bus->cnt++; > > - D(printf("mdc=%d mdio=%d state=%d cnt=%d drv=%d\n", > - bus->mdc, bus->mdio, bus->state, bus->cnt, bus->drive)); > + D(printf("mdc=%d mdio=%d state=%d cnt=%d drv=%d\n", > + bus->mdc, bus->mdio, bus->state, bus->cnt, bus->drive)); > #if 0 > - if (bus->mdc) > - printf("%d", bus->mdio); > + if (bus->mdc) { > + printf("%d", bus->mdio); > + } > #endif > - switch (bus->state) > - { > - case PREAMBLE: > - if (bus->mdc) { > - if (bus->cnt >= (32 * 2) && !bus->mdio) { > - bus->cnt = 0; > - bus->state = SOF; > - bus->data = 0; > - } > - } > - break; > - case SOF: > - if (bus->mdc) { > - if (bus->mdio != 1) > - printf("WARNING: no SOF\n"); > - if (bus->cnt == 1*2) { > - bus->cnt = 0; > - bus->opc = 0; > - bus->state = OPC; > - } > - } > - break; > - case OPC: > - if (bus->mdc) { > - bus->opc <<= 1; > - bus->opc |= bus->mdio & 1; > - if (bus->cnt == 2*2) { > - bus->cnt = 0; > - bus->addr = 0; > - bus->state = ADDR; > - } > - } > - break; > - case ADDR: > - if (bus->mdc) { > - bus->addr <<= 1; > - bus->addr |= bus->mdio & 1; > - > - if (bus->cnt == 5*2) { > - bus->cnt = 0; > - bus->req = 0; > - bus->state = REQ; > - } > - } > - break; > - case REQ: > - if (bus->mdc) { > - bus->req <<= 1; > - bus->req |= bus->mdio & 1; > - if (bus->cnt == 5*2) { > - bus->cnt = 0; > - bus->state = TURNAROUND; > - } > - } > - break; > - case TURNAROUND: > - if (bus->mdc && bus->cnt == 2*2) { > - bus->mdio = 0; > - bus->cnt = 0; > - > - if (bus->opc == 2) { > - bus->drive = 1; > - mdio_read_req(bus); > - bus->mdio = bus->data & 1; > - } > - bus->state = DATA; > - } > - break; > - case DATA: > - if (!bus->mdc) { > - if (bus->drive) { > - bus->mdio = !!(bus->data & (1 << 15)); > - bus->data <<= 1; > - } > - } else { > - if (!bus->drive) { > - bus->data <<= 1; > - bus->data |= bus->mdio; > - } > - if (bus->cnt == 16 * 2) { > - bus->cnt = 0; > - bus->state = PREAMBLE; > - if (!bus->drive) > - mdio_write_req(bus); > - bus->drive = 0; > - } > - } > - break; > - default: > - break; > - } > + switch (bus->state) { > + case PREAMBLE: > + if (bus->mdc) { > + if (bus->cnt >= (32 * 2) && !bus->mdio) { > + bus->cnt = 0; > + bus->state = SOF; > + bus->data = 0; > + } > + } > + break; > + case SOF: > + if (bus->mdc) { > + if (bus->mdio != 1) { > + printf("WARNING: no SOF\n"); > + } > + if (bus->cnt == 1*2) { > + bus->cnt = 0; > + bus->opc = 0; > + bus->state = OPC; > + } > + } > + break; > + case OPC: > + if (bus->mdc) { > + bus->opc <<= 1; > + bus->opc |= bus->mdio & 1; > + if (bus->cnt == 2*2) { > + bus->cnt = 0; > + bus->addr = 0; > + bus->state = ADDR; > + } > + } > + break; > + case ADDR: > + if (bus->mdc) { > + bus->addr <<= 1; > + bus->addr |= bus->mdio & 1; > + > + if (bus->cnt == 5*2) { > + bus->cnt = 0; > + bus->req = 0; > + bus->state = REQ; > + } > + } > + break; > + case REQ: > + if (bus->mdc) { > + bus->req <<= 1; > + bus->req |= bus->mdio & 1; > + if (bus->cnt == 5*2) { > + bus->cnt = 0; > + bus->state = TURNAROUND; > + } > + } > + break; > + case TURNAROUND: > + if (bus->mdc && bus->cnt == 2*2) { > + bus->mdio = 0; > + bus->cnt = 0; > + > + if (bus->opc == 2) { > + bus->drive = 1; > + mdio_read_req(bus); > + bus->mdio = bus->data & 1; > + } > + bus->state = DATA; > + } > + break; > + case DATA: > + if (!bus->mdc) { > + if (bus->drive) { > + bus->mdio = !!(bus->data & (1 << 15)); > + bus->data <<= 1; > + } > + } else { > + if (!bus->drive) { > + bus->data <<= 1; > + bus->data |= bus->mdio; > + } > + if (bus->cnt == 16 * 2) { > + bus->cnt = 0; > + bus->state = PREAMBLE; > + if (!bus->drive) { > + mdio_write_req(bus); > + } > + bus->drive = 0; > + } > + } > + break; > + default: > + break; > + } > } > > /* ETRAX-FS Ethernet MAC block starts here. */ > > -#define RW_MA0_LO 0x00 > -#define RW_MA0_HI 0x01 > -#define RW_MA1_LO 0x02 > -#define RW_MA1_HI 0x03 > -#define RW_GA_LO 0x04 > -#define RW_GA_HI 0x05 > -#define RW_GEN_CTRL 0x06 > -#define RW_REC_CTRL 0x07 > -#define RW_TR_CTRL 0x08 > -#define RW_CLR_ERR 0x09 > -#define RW_MGM_CTRL 0x0a > -#define R_STAT 0x0b > -#define FS_ETH_MAX_REGS 0x17 > +#define RW_MA0_LO 0x00 > +#define RW_MA0_HI 0x01 > +#define RW_MA1_LO 0x02 > +#define RW_MA1_HI 0x03 > +#define RW_GA_LO 0x04 > +#define RW_GA_HI 0x05 > +#define RW_GEN_CTRL 0x06 > +#define RW_REC_CTRL 0x07 > +#define RW_TR_CTRL 0x08 > +#define RW_CLR_ERR 0x09 > +#define RW_MGM_CTRL 0x0a > +#define R_STAT 0x0b > +#define FS_ETH_MAX_REGS 0x17 > > struct fs_eth > { > - SysBusDevice busdev; > - MemoryRegion mmio; > - NICState *nic; > - NICConf conf; > - > - /* Two addrs in the filter. */ > - uint8_t macaddr[2][6]; > - uint32_t regs[FS_ETH_MAX_REGS]; > - > - union { > - void *vdma_out; > - struct etraxfs_dma_client *dma_out; > - }; > - union { > - void *vdma_in; > - struct etraxfs_dma_client *dma_in; > - }; > - > - /* MDIO bus. */ > - struct qemu_mdio mdio_bus; > - unsigned int phyaddr; > - int duplex_mismatch; > - > - /* PHY. */ > - struct qemu_phy phy; > + SysBusDevice busdev; > + MemoryRegion mmio; > + NICState *nic; > + NICConf conf; > + > + /* Two addrs in the filter. */ > + uint8_t macaddr[2][6]; > + uint32_t regs[FS_ETH_MAX_REGS]; > + > + union { > + void *vdma_out; > + struct etraxfs_dma_client *dma_out; > + }; > + union { > + void *vdma_in; > + struct etraxfs_dma_client *dma_in; > + }; > + > + /* MDIO bus. */ > + struct qemu_mdio mdio_bus; > + unsigned int phyaddr; > + int duplex_mismatch; > + > + /* PHY. */ > + struct qemu_phy phy; > }; > > static void eth_validate_duplex(struct fs_eth *eth) > { > - struct qemu_phy *phy; > - unsigned int phy_duplex; > - unsigned int mac_duplex; > - int new_mm = 0; > - > - phy = eth->mdio_bus.devs[eth->phyaddr]; > - phy_duplex = !!(phy->read(phy, 18) & (1 << 11)); > - mac_duplex = !!(eth->regs[RW_REC_CTRL] & 128); > - > - if (mac_duplex != phy_duplex) > - new_mm = 1; > - > - if (eth->regs[RW_GEN_CTRL] & 1) { > - if (new_mm != eth->duplex_mismatch) { > - if (new_mm) > - printf("HW: WARNING " > - "ETH duplex mismatch MAC=%d PHY=%d\n", > - mac_duplex, phy_duplex); > - else > - printf("HW: ETH duplex ok.\n"); > - } > - eth->duplex_mismatch = new_mm; > - } > + struct qemu_phy *phy; > + unsigned int phy_duplex; > + unsigned int mac_duplex; > + int new_mm = 0; > + > + phy = eth->mdio_bus.devs[eth->phyaddr]; > + phy_duplex = !!(phy->read(phy, 18) & (1 << 11)); > + mac_duplex = !!(eth->regs[RW_REC_CTRL] & 128); > + > + if (mac_duplex != phy_duplex) { > + new_mm = 1; > + } > + > + if (eth->regs[RW_GEN_CTRL] & 1) { > + if (new_mm != eth->duplex_mismatch) { > + if (new_mm) { > + printf("HW: WARNING ETH duplex mismatch MAC=%d PHY=%d\n", > + mac_duplex, phy_duplex); > + } else { > + printf("HW: ETH duplex ok.\n"); > + } > + } > + eth->duplex_mismatch = new_mm; > + } > } > > static uint64_t > eth_read(void *opaque, hwaddr addr, unsigned int size) > { > - struct fs_eth *eth = opaque; > - uint32_t r = 0; > - > - addr >>= 2; > - > - switch (addr) { > - case R_STAT: > - r = eth->mdio_bus.mdio & 1; > - break; > - default: > - r = eth->regs[addr]; > - D(printf ("%s %x\n", __func__, addr * 4)); > - break; > - } > - return r; > + struct fs_eth *eth = opaque; > + uint32_t r = 0; > + > + addr >>= 2; > + > + switch (addr) { > + case R_STAT: > + r = eth->mdio_bus.mdio & 1; > + break; > + default: > + r = eth->regs[addr]; > + D(printf("%s %x\n", __func__, addr * 4)); > + break; > + } > + return r; > } > > static void eth_update_ma(struct fs_eth *eth, int ma) > { > - int reg; > - int i = 0; > - > - ma &= 1; > - > - reg = RW_MA0_LO; > - if (ma) > - reg = RW_MA1_LO; > - > - eth->macaddr[ma][i++] = eth->regs[reg]; > - eth->macaddr[ma][i++] = eth->regs[reg] >> 8; > - eth->macaddr[ma][i++] = eth->regs[reg] >> 16; > - eth->macaddr[ma][i++] = eth->regs[reg] >> 24; > - eth->macaddr[ma][i++] = eth->regs[reg + 1]; > - eth->macaddr[ma][i] = eth->regs[reg + 1] >> 8; > - > - D(printf("set mac%d=%x.%x.%x.%x.%x.%x\n", ma, > - eth->macaddr[ma][0], eth->macaddr[ma][1], > - eth->macaddr[ma][2], eth->macaddr[ma][3], > - eth->macaddr[ma][4], eth->macaddr[ma][5])); > + int reg; > + int i = 0; > + > + ma &= 1; > + > + reg = RW_MA0_LO; > + if (ma) { > + reg = RW_MA1_LO; > + } > + > + eth->macaddr[ma][i++] = eth->regs[reg]; > + eth->macaddr[ma][i++] = eth->regs[reg] >> 8; > + eth->macaddr[ma][i++] = eth->regs[reg] >> 16; > + eth->macaddr[ma][i++] = eth->regs[reg] >> 24; > + eth->macaddr[ma][i++] = eth->regs[reg + 1]; > + eth->macaddr[ma][i] = eth->regs[reg + 1] >> 8; > + > + D(printf("set mac%d=%x.%x.%x.%x.%x.%x\n", ma, > + eth->macaddr[ma][0], eth->macaddr[ma][1], > + eth->macaddr[ma][2], eth->macaddr[ma][3], > + eth->macaddr[ma][4], eth->macaddr[ma][5])); > } > > static void > eth_write(void *opaque, hwaddr addr, > uint64_t val64, unsigned int size) > { > - struct fs_eth *eth = opaque; > - uint32_t value = val64; > - > - addr >>= 2; > - switch (addr) > - { > - case RW_MA0_LO: > - case RW_MA0_HI: > - eth->regs[addr] = value; > - eth_update_ma(eth, 0); > - break; > - case RW_MA1_LO: > - case RW_MA1_HI: > - eth->regs[addr] = value; > - eth_update_ma(eth, 1); > - break; > - > - case RW_MGM_CTRL: > - /* Attach an MDIO/PHY abstraction. */ > - if (value & 2) > - eth->mdio_bus.mdio = value & 1; > - if (eth->mdio_bus.mdc != (value & 4)) { > - mdio_cycle(ð->mdio_bus); > - eth_validate_duplex(eth); > - } > - eth->mdio_bus.mdc = !!(value & 4); > - eth->regs[addr] = value; > - break; > - > - case RW_REC_CTRL: > - eth->regs[addr] = value; > - eth_validate_duplex(eth); > - break; > - > - default: > - eth->regs[addr] = value; > - D(printf ("%s %x %x\n", > - __func__, addr, value)); > - break; > - } > + struct fs_eth *eth = opaque; > + uint32_t value = val64; > + > + addr >>= 2; > + switch (addr) { > + case RW_MA0_LO: > + case RW_MA0_HI: > + eth->regs[addr] = value; > + eth_update_ma(eth, 0); > + break; > + case RW_MA1_LO: > + case RW_MA1_HI: > + eth->regs[addr] = value; > + eth_update_ma(eth, 1); > + break; > + > + case RW_MGM_CTRL: > + /* Attach an MDIO/PHY abstraction. */ > + if (value & 2) { > + eth->mdio_bus.mdio = value & 1; > + } > + if (eth->mdio_bus.mdc != (value & 4)) { > + mdio_cycle(ð->mdio_bus); > + eth_validate_duplex(eth); > + } > + eth->mdio_bus.mdc = !!(value & 4); > + eth->regs[addr] = value; > + break; > + > + case RW_REC_CTRL: > + eth->regs[addr] = value; > + eth_validate_duplex(eth); > + break; > + > + default: > + eth->regs[addr] = value; > + D(printf("%s %x %x\n", __func__, addr, value)); > + break; > + } > } > > /* The ETRAX FS has a groupt address table (GAT) which works like a k=1 bloom > - filter dropping group addresses we have not joined. The filter has 64 > - bits (m). The has function is a simple nible xor of the group addr. */ > + filter dropping group addresses we have not joined. The filter has 64 > + bits (m). The has function is a simple nible xor of the group addr. */ > static int eth_match_groupaddr(struct fs_eth *eth, const unsigned char *sa) > { > - unsigned int hsh; > - int m_individual = eth->regs[RW_REC_CTRL] & 4; > - int match; > - > - /* First bit on the wire of a MAC address signals multicast or > - physical address. */ > - if (!m_individual && !(sa[0] & 1)) > - return 0; > - > - /* Calculate the hash index for the GA registers. */ > - hsh = 0; > - hsh ^= (*sa) & 0x3f; > - hsh ^= ((*sa) >> 6) & 0x03; > - ++sa; > - hsh ^= ((*sa) << 2) & 0x03c; > - hsh ^= ((*sa) >> 4) & 0xf; > - ++sa; > - hsh ^= ((*sa) << 4) & 0x30; > - hsh ^= ((*sa) >> 2) & 0x3f; > - ++sa; > - hsh ^= (*sa) & 0x3f; > - hsh ^= ((*sa) >> 6) & 0x03; > - ++sa; > - hsh ^= ((*sa) << 2) & 0x03c; > - hsh ^= ((*sa) >> 4) & 0xf; > - ++sa; > - hsh ^= ((*sa) << 4) & 0x30; > - hsh ^= ((*sa) >> 2) & 0x3f; > - > - hsh &= 63; > - if (hsh > 31) > - match = eth->regs[RW_GA_HI] & (1 << (hsh - 32)); > - else > - match = eth->regs[RW_GA_LO] & (1 << hsh); > - D(printf("hsh=%x ga=%x.%x mtch=%d\n", hsh, > - eth->regs[RW_GA_HI], eth->regs[RW_GA_LO], match)); > - return match; > + unsigned int hsh; > + int m_individual = eth->regs[RW_REC_CTRL] & 4; > + int match; > + > + /* First bit on the wire of a MAC address signals multicast or > + physical address. */ > + if (!m_individual && !(sa[0] & 1)) { > + return 0; > + } > + > + /* Calculate the hash index for the GA registers. */ > + hsh = 0; > + hsh ^= (*sa) & 0x3f; > + hsh ^= ((*sa) >> 6) & 0x03; > + ++sa; > + hsh ^= ((*sa) << 2) & 0x03c; > + hsh ^= ((*sa) >> 4) & 0xf; > + ++sa; > + hsh ^= ((*sa) << 4) & 0x30; > + hsh ^= ((*sa) >> 2) & 0x3f; > + ++sa; > + hsh ^= (*sa) & 0x3f; > + hsh ^= ((*sa) >> 6) & 0x03; > + ++sa; > + hsh ^= ((*sa) << 2) & 0x03c; > + hsh ^= ((*sa) >> 4) & 0xf; > + ++sa; > + hsh ^= ((*sa) << 4) & 0x30; > + hsh ^= ((*sa) >> 2) & 0x3f; > + > + hsh &= 63; > + if (hsh > 31) { > + match = eth->regs[RW_GA_HI] & (1 << (hsh - 32)); > + } else { > + match = eth->regs[RW_GA_LO] & (1 << hsh); > + } > + D(printf("hsh=%x ga=%x.%x mtch=%d\n", hsh, > + eth->regs[RW_GA_HI], eth->regs[RW_GA_LO], match)); > + return match; > } > > static int eth_can_receive(NetClientState *nc) > { > - return 1; > + return 1; > } > > static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size) > { > - unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; > - struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; > - int use_ma0 = eth->regs[RW_REC_CTRL] & 1; > - int use_ma1 = eth->regs[RW_REC_CTRL] & 2; > - int r_bcast = eth->regs[RW_REC_CTRL] & 8; > - > - if (size < 12) > - return -1; > - > - D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n", > - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], > - use_ma0, use_ma1, r_bcast)); > - > - /* Does the frame get through the address filters? */ > - if ((!use_ma0 || memcmp(buf, eth->macaddr[0], 6)) > - && (!use_ma1 || memcmp(buf, eth->macaddr[1], 6)) > - && (!r_bcast || memcmp(buf, sa_bcast, 6)) > - && !eth_match_groupaddr(eth, buf)) > - return size; > - > - /* FIXME: Find another way to pass on the fake csum. */ > - etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1); > + unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; > + struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; > + int use_ma0 = eth->regs[RW_REC_CTRL] & 1; > + int use_ma1 = eth->regs[RW_REC_CTRL] & 2; > + int r_bcast = eth->regs[RW_REC_CTRL] & 8; > + > + if (size < 12) { > + return -1; > + } > + > + D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n", > + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], > + use_ma0, use_ma1, r_bcast)); > + > + /* Does the frame get through the address filters? */ > + if ((!use_ma0 || memcmp(buf, eth->macaddr[0], 6)) > + && (!use_ma1 || memcmp(buf, eth->macaddr[1], 6)) > + && (!r_bcast || memcmp(buf, sa_bcast, 6)) > + && !eth_match_groupaddr(eth, buf)) { > + return size; > + } > + > + /* FIXME: Find another way to pass on the fake csum. */ > + etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1); > > return size; > } > > static int eth_tx_push(void *opaque, unsigned char *buf, int len, bool eop) > { > - struct fs_eth *eth = opaque; > + struct fs_eth *eth = opaque; > > - D(printf("%s buf=%p len=%d\n", __func__, buf, len)); > - qemu_send_packet(ð->nic->nc, buf, len); > - return len; > + D(printf("%s buf=%p len=%d\n", __func__, buf, len)); > + qemu_send_packet(ð->nic->nc, buf, len); > + return len; > } > > static void eth_set_link(NetClientState *nc) > { > - struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; > - D(printf("%s %d\n", __func__, nc->link_down)); > - eth->phy.link = !nc->link_down; > + struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; > + D(printf("%s %d\n", __func__, nc->link_down)); > + eth->phy.link = !nc->link_down; > } > > static const MemoryRegionOps eth_ops = { > - .read = eth_read, > - .write = eth_write, > - .endianness = DEVICE_LITTLE_ENDIAN, > - .valid = { > - .min_access_size = 4, > - .max_access_size = 4 > - } > + .read = eth_read, > + .write = eth_write, > + .endianness = DEVICE_LITTLE_ENDIAN, > + .valid = { > + .min_access_size = 4, > + .max_access_size = 4 > + } > }; > > static void eth_cleanup(NetClientState *nc) > { > - struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; > + struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; > > - /* Disconnect the client. */ > - eth->dma_out->client.push = NULL; > - eth->dma_out->client.opaque = NULL; > - eth->dma_in->client.opaque = NULL; > - eth->dma_in->client.pull = NULL; > + /* Disconnect the client. */ > + eth->dma_out->client.push = NULL; > + eth->dma_out->client.opaque = NULL; > + eth->dma_in->client.opaque = NULL; > + eth->dma_in->client.pull = NULL; > g_free(eth); > } > > static NetClientInfo net_etraxfs_info = { > - .type = NET_CLIENT_OPTIONS_KIND_NIC, > - .size = sizeof(NICState), > - .can_receive = eth_can_receive, > - .receive = eth_receive, > - .cleanup = eth_cleanup, > - .link_status_changed = eth_set_link, > + .type = NET_CLIENT_OPTIONS_KIND_NIC, > + .size = sizeof(NICState), > + .can_receive = eth_can_receive, > + .receive = eth_receive, > + .cleanup = eth_cleanup, > + .link_status_changed = eth_set_link, > }; > > static int fs_eth_init(SysBusDevice *dev) > { > - struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev); > + struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev); > > - if (!s->dma_out || !s->dma_in) { > - hw_error("Unconnected ETRAX-FS Ethernet MAC.\n"); > - } > + if (!s->dma_out || !s->dma_in) { > + hw_error("Unconnected ETRAX-FS Ethernet MAC.\n"); > + } > > - s->dma_out->client.push = eth_tx_push; > - s->dma_out->client.opaque = s; > - s->dma_in->client.opaque = s; > - s->dma_in->client.pull = NULL; > + s->dma_out->client.push = eth_tx_push; > + s->dma_out->client.opaque = s; > + s->dma_in->client.opaque = s; > + s->dma_in->client.pull = NULL; > > - memory_region_init_io(&s->mmio, ð_ops, s, "etraxfs-eth", 0x5c); > - sysbus_init_mmio(dev, &s->mmio); > + memory_region_init_io(&s->mmio, ð_ops, s, "etraxfs-eth", 0x5c); > + sysbus_init_mmio(dev, &s->mmio); > > - qemu_macaddr_default_if_unset(&s->conf.macaddr); > - s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, > - object_get_typename(OBJECT(s)), dev->qdev.id, s); > - qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); > + qemu_macaddr_default_if_unset(&s->conf.macaddr); > + s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, > + object_get_typename(OBJECT(s)), dev->qdev.id, s); > + qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); > > - tdk_init(&s->phy); > - mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr); > - return 0; > + tdk_init(&s->phy); > + mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr); > + return 0; > } > > static Property etraxfs_eth_properties[] = { > -- > 1.7.10.4 >
Am 23.01.2013 17:15, schrieb Grant Likely: > This is a trivial patch to harmonize the coding style on > hw/etraxfs_eth.c. This is in preparation to split off the bitbang mdio > code into a separate file. > > Cc: Peter Maydell <peter.maydell@linaro.org> > Cc: Paul Brook <paul@codesourcery.com> > Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com> > Cc: Anthony Liguori <aliguori@us.ibm.com> > Cc: Andreas Färber <afaerber@suse.de> > Signed-off-by: Grant Likely <grant.likely@secretlab.ca> In the future please don't prefix patches with "trivial: " - if they're truely trivial and the code is unmaintained (i.e., not in this case) you should cc qemu-trivial@nongnu.org instead. "extraxfs_eth: ..." as subject would've been sufficient. Cheers, Andreas
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c index ec23fa6..0b474c0 100644 --- a/hw/etraxfs_eth.c +++ b/hw/etraxfs_eth.c @@ -35,582 +35,592 @@ #define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ #define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ -/* - * The MDIO extensions in the TDK PHY model were reversed engineered from the +/* + * The MDIO extensions in the TDK PHY model were reversed engineered from the * linux driver (PHYID and Diagnostics reg). * TODO: Add friendly names for the register nums. */ struct qemu_phy { - uint32_t regs[32]; + uint32_t regs[32]; - int link; + int link; - unsigned int (*read)(struct qemu_phy *phy, unsigned int req); - void (*write)(struct qemu_phy *phy, unsigned int req, - unsigned int data); + unsigned int (*read)(struct qemu_phy *phy, unsigned int req); + void (*write)(struct qemu_phy *phy, unsigned int req, unsigned int data); }; static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req) { - int regnum; - unsigned r = 0; - - regnum = req & 0x1f; - - switch (regnum) { - case 1: - if (!phy->link) - break; - /* MR1. */ - /* Speeds and modes. */ - r |= (1 << 13) | (1 << 14); - r |= (1 << 11) | (1 << 12); - r |= (1 << 5); /* Autoneg complete. */ - r |= (1 << 3); /* Autoneg able. */ - r |= (1 << 2); /* link. */ - break; - case 5: - /* Link partner ability. - We are kind; always agree with whatever best mode - the guest advertises. */ - r = 1 << 14; /* Success. */ - /* Copy advertised modes. */ - r |= phy->regs[4] & (15 << 5); - /* Autoneg support. */ - r |= 1; - break; - case 18: - { - /* Diagnostics reg. */ - int duplex = 0; - int speed_100 = 0; - - if (!phy->link) - break; - - /* Are we advertising 100 half or 100 duplex ? */ - speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF); - speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL); - - /* Are we advertising 10 duplex or 100 duplex ? */ - duplex = !!(phy->regs[4] & ADVERTISE_100FULL); - duplex |= !!(phy->regs[4] & ADVERTISE_10FULL); - r = (speed_100 << 10) | (duplex << 11); - } - break; - - default: - r = phy->regs[regnum]; - break; - } - D(printf("\n%s %x = reg[%d]\n", __func__, r, regnum)); - return r; + int regnum; + unsigned r = 0; + + regnum = req & 0x1f; + + switch (regnum) { + case 1: + if (!phy->link) { + break; + } + /* MR1. */ + /* Speeds and modes. */ + r |= (1 << 13) | (1 << 14); + r |= (1 << 11) | (1 << 12); + r |= (1 << 5); /* Autoneg complete. */ + r |= (1 << 3); /* Autoneg able. */ + r |= (1 << 2); /* link. */ + break; + case 5: + /* Link partner ability. + We are kind; always agree with whatever best mode + the guest advertises. */ + r = 1 << 14; /* Success. */ + /* Copy advertised modes. */ + r |= phy->regs[4] & (15 << 5); + /* Autoneg support. */ + r |= 1; + break; + case 18: + { + /* Diagnostics reg. */ + int duplex = 0; + int speed_100 = 0; + + if (!phy->link) { + break; + } + + /* Are we advertising 100 half or 100 duplex ? */ + speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF); + speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL); + + /* Are we advertising 10 duplex or 100 duplex ? */ + duplex = !!(phy->regs[4] & ADVERTISE_100FULL); + duplex |= !!(phy->regs[4] & ADVERTISE_10FULL); + r = (speed_100 << 10) | (duplex << 11); + } + break; + + default: + r = phy->regs[regnum]; + break; + } + D(printf("\n%s %x = reg[%d]\n", __func__, r, regnum)); + return r; } -static void +static void tdk_write(struct qemu_phy *phy, unsigned int req, unsigned int data) { - int regnum; - - regnum = req & 0x1f; - D(printf("%s reg[%d] = %x\n", __func__, regnum, data)); - switch (regnum) { - default: - phy->regs[regnum] = data; - break; - } + int regnum; + + regnum = req & 0x1f; + D(printf("%s reg[%d] = %x\n", __func__, regnum, data)); + switch (regnum) { + default: + phy->regs[regnum] = data; + break; + } } -static void +static void tdk_init(struct qemu_phy *phy) { - phy->regs[0] = 0x3100; - /* PHY Id. */ - phy->regs[2] = 0x0300; - phy->regs[3] = 0xe400; - /* Autonegotiation advertisement reg. */ - phy->regs[4] = 0x01E1; - phy->link = 1; - - phy->read = tdk_read; - phy->write = tdk_write; + phy->regs[0] = 0x3100; + /* PHY Id. */ + phy->regs[2] = 0x0300; + phy->regs[3] = 0xe400; + /* Autonegotiation advertisement reg. */ + phy->regs[4] = 0x01E1; + phy->link = 1; + + phy->read = tdk_read; + phy->write = tdk_write; } struct qemu_mdio { - /* bus. */ - int mdc; - int mdio; - - /* decoder. */ - enum { - PREAMBLE, - SOF, - OPC, - ADDR, - REQ, - TURNAROUND, - DATA - } state; - unsigned int drive; - - unsigned int cnt; - unsigned int addr; - unsigned int opc; - unsigned int req; - unsigned int data; - - struct qemu_phy *devs[32]; + /* bus. */ + int mdc; + int mdio; + + /* decoder. */ + enum { + PREAMBLE, + SOF, + OPC, + ADDR, + REQ, + TURNAROUND, + DATA + } state; + unsigned int drive; + + unsigned int cnt; + unsigned int addr; + unsigned int opc; + unsigned int req; + unsigned int data; + + struct qemu_phy *devs[32]; }; -static void +static void mdio_attach(struct qemu_mdio *bus, struct qemu_phy *phy, unsigned int addr) { - bus->devs[addr & 0x1f] = phy; + bus->devs[addr & 0x1f] = phy; } #ifdef USE_THIS_DEAD_CODE -static void +static void mdio_detach(struct qemu_mdio *bus, struct qemu_phy *phy, unsigned int addr) { - bus->devs[addr & 0x1f] = NULL; + bus->devs[addr & 0x1f] = NULL; } #endif static void mdio_read_req(struct qemu_mdio *bus) { - struct qemu_phy *phy; - - phy = bus->devs[bus->addr]; - if (phy && phy->read) - bus->data = phy->read(phy, bus->req); - else - bus->data = 0xffff; + struct qemu_phy *phy; + + phy = bus->devs[bus->addr]; + if (phy && phy->read) { + bus->data = phy->read(phy, bus->req); + } else { + bus->data = 0xffff; + } } static void mdio_write_req(struct qemu_mdio *bus) { - struct qemu_phy *phy; + struct qemu_phy *phy; - phy = bus->devs[bus->addr]; - if (phy && phy->write) - phy->write(phy, bus->req, bus->data); + phy = bus->devs[bus->addr]; + if (phy && phy->write) { + phy->write(phy, bus->req, bus->data); + } } static void mdio_cycle(struct qemu_mdio *bus) { - bus->cnt++; + bus->cnt++; - D(printf("mdc=%d mdio=%d state=%d cnt=%d drv=%d\n", - bus->mdc, bus->mdio, bus->state, bus->cnt, bus->drive)); + D(printf("mdc=%d mdio=%d state=%d cnt=%d drv=%d\n", + bus->mdc, bus->mdio, bus->state, bus->cnt, bus->drive)); #if 0 - if (bus->mdc) - printf("%d", bus->mdio); + if (bus->mdc) { + printf("%d", bus->mdio); + } #endif - switch (bus->state) - { - case PREAMBLE: - if (bus->mdc) { - if (bus->cnt >= (32 * 2) && !bus->mdio) { - bus->cnt = 0; - bus->state = SOF; - bus->data = 0; - } - } - break; - case SOF: - if (bus->mdc) { - if (bus->mdio != 1) - printf("WARNING: no SOF\n"); - if (bus->cnt == 1*2) { - bus->cnt = 0; - bus->opc = 0; - bus->state = OPC; - } - } - break; - case OPC: - if (bus->mdc) { - bus->opc <<= 1; - bus->opc |= bus->mdio & 1; - if (bus->cnt == 2*2) { - bus->cnt = 0; - bus->addr = 0; - bus->state = ADDR; - } - } - break; - case ADDR: - if (bus->mdc) { - bus->addr <<= 1; - bus->addr |= bus->mdio & 1; - - if (bus->cnt == 5*2) { - bus->cnt = 0; - bus->req = 0; - bus->state = REQ; - } - } - break; - case REQ: - if (bus->mdc) { - bus->req <<= 1; - bus->req |= bus->mdio & 1; - if (bus->cnt == 5*2) { - bus->cnt = 0; - bus->state = TURNAROUND; - } - } - break; - case TURNAROUND: - if (bus->mdc && bus->cnt == 2*2) { - bus->mdio = 0; - bus->cnt = 0; - - if (bus->opc == 2) { - bus->drive = 1; - mdio_read_req(bus); - bus->mdio = bus->data & 1; - } - bus->state = DATA; - } - break; - case DATA: - if (!bus->mdc) { - if (bus->drive) { - bus->mdio = !!(bus->data & (1 << 15)); - bus->data <<= 1; - } - } else { - if (!bus->drive) { - bus->data <<= 1; - bus->data |= bus->mdio; - } - if (bus->cnt == 16 * 2) { - bus->cnt = 0; - bus->state = PREAMBLE; - if (!bus->drive) - mdio_write_req(bus); - bus->drive = 0; - } - } - break; - default: - break; - } + switch (bus->state) { + case PREAMBLE: + if (bus->mdc) { + if (bus->cnt >= (32 * 2) && !bus->mdio) { + bus->cnt = 0; + bus->state = SOF; + bus->data = 0; + } + } + break; + case SOF: + if (bus->mdc) { + if (bus->mdio != 1) { + printf("WARNING: no SOF\n"); + } + if (bus->cnt == 1*2) { + bus->cnt = 0; + bus->opc = 0; + bus->state = OPC; + } + } + break; + case OPC: + if (bus->mdc) { + bus->opc <<= 1; + bus->opc |= bus->mdio & 1; + if (bus->cnt == 2*2) { + bus->cnt = 0; + bus->addr = 0; + bus->state = ADDR; + } + } + break; + case ADDR: + if (bus->mdc) { + bus->addr <<= 1; + bus->addr |= bus->mdio & 1; + + if (bus->cnt == 5*2) { + bus->cnt = 0; + bus->req = 0; + bus->state = REQ; + } + } + break; + case REQ: + if (bus->mdc) { + bus->req <<= 1; + bus->req |= bus->mdio & 1; + if (bus->cnt == 5*2) { + bus->cnt = 0; + bus->state = TURNAROUND; + } + } + break; + case TURNAROUND: + if (bus->mdc && bus->cnt == 2*2) { + bus->mdio = 0; + bus->cnt = 0; + + if (bus->opc == 2) { + bus->drive = 1; + mdio_read_req(bus); + bus->mdio = bus->data & 1; + } + bus->state = DATA; + } + break; + case DATA: + if (!bus->mdc) { + if (bus->drive) { + bus->mdio = !!(bus->data & (1 << 15)); + bus->data <<= 1; + } + } else { + if (!bus->drive) { + bus->data <<= 1; + bus->data |= bus->mdio; + } + if (bus->cnt == 16 * 2) { + bus->cnt = 0; + bus->state = PREAMBLE; + if (!bus->drive) { + mdio_write_req(bus); + } + bus->drive = 0; + } + } + break; + default: + break; + } } /* ETRAX-FS Ethernet MAC block starts here. */ -#define RW_MA0_LO 0x00 -#define RW_MA0_HI 0x01 -#define RW_MA1_LO 0x02 -#define RW_MA1_HI 0x03 -#define RW_GA_LO 0x04 -#define RW_GA_HI 0x05 -#define RW_GEN_CTRL 0x06 -#define RW_REC_CTRL 0x07 -#define RW_TR_CTRL 0x08 -#define RW_CLR_ERR 0x09 -#define RW_MGM_CTRL 0x0a -#define R_STAT 0x0b -#define FS_ETH_MAX_REGS 0x17 +#define RW_MA0_LO 0x00 +#define RW_MA0_HI 0x01 +#define RW_MA1_LO 0x02 +#define RW_MA1_HI 0x03 +#define RW_GA_LO 0x04 +#define RW_GA_HI 0x05 +#define RW_GEN_CTRL 0x06 +#define RW_REC_CTRL 0x07 +#define RW_TR_CTRL 0x08 +#define RW_CLR_ERR 0x09 +#define RW_MGM_CTRL 0x0a +#define R_STAT 0x0b +#define FS_ETH_MAX_REGS 0x17 struct fs_eth { - SysBusDevice busdev; - MemoryRegion mmio; - NICState *nic; - NICConf conf; - - /* Two addrs in the filter. */ - uint8_t macaddr[2][6]; - uint32_t regs[FS_ETH_MAX_REGS]; - - union { - void *vdma_out; - struct etraxfs_dma_client *dma_out; - }; - union { - void *vdma_in; - struct etraxfs_dma_client *dma_in; - }; - - /* MDIO bus. */ - struct qemu_mdio mdio_bus; - unsigned int phyaddr; - int duplex_mismatch; - - /* PHY. */ - struct qemu_phy phy; + SysBusDevice busdev; + MemoryRegion mmio; + NICState *nic; + NICConf conf; + + /* Two addrs in the filter. */ + uint8_t macaddr[2][6]; + uint32_t regs[FS_ETH_MAX_REGS]; + + union { + void *vdma_out; + struct etraxfs_dma_client *dma_out; + }; + union { + void *vdma_in; + struct etraxfs_dma_client *dma_in; + }; + + /* MDIO bus. */ + struct qemu_mdio mdio_bus; + unsigned int phyaddr; + int duplex_mismatch; + + /* PHY. */ + struct qemu_phy phy; }; static void eth_validate_duplex(struct fs_eth *eth) { - struct qemu_phy *phy; - unsigned int phy_duplex; - unsigned int mac_duplex; - int new_mm = 0; - - phy = eth->mdio_bus.devs[eth->phyaddr]; - phy_duplex = !!(phy->read(phy, 18) & (1 << 11)); - mac_duplex = !!(eth->regs[RW_REC_CTRL] & 128); - - if (mac_duplex != phy_duplex) - new_mm = 1; - - if (eth->regs[RW_GEN_CTRL] & 1) { - if (new_mm != eth->duplex_mismatch) { - if (new_mm) - printf("HW: WARNING " - "ETH duplex mismatch MAC=%d PHY=%d\n", - mac_duplex, phy_duplex); - else - printf("HW: ETH duplex ok.\n"); - } - eth->duplex_mismatch = new_mm; - } + struct qemu_phy *phy; + unsigned int phy_duplex; + unsigned int mac_duplex; + int new_mm = 0; + + phy = eth->mdio_bus.devs[eth->phyaddr]; + phy_duplex = !!(phy->read(phy, 18) & (1 << 11)); + mac_duplex = !!(eth->regs[RW_REC_CTRL] & 128); + + if (mac_duplex != phy_duplex) { + new_mm = 1; + } + + if (eth->regs[RW_GEN_CTRL] & 1) { + if (new_mm != eth->duplex_mismatch) { + if (new_mm) { + printf("HW: WARNING ETH duplex mismatch MAC=%d PHY=%d\n", + mac_duplex, phy_duplex); + } else { + printf("HW: ETH duplex ok.\n"); + } + } + eth->duplex_mismatch = new_mm; + } } static uint64_t eth_read(void *opaque, hwaddr addr, unsigned int size) { - struct fs_eth *eth = opaque; - uint32_t r = 0; - - addr >>= 2; - - switch (addr) { - case R_STAT: - r = eth->mdio_bus.mdio & 1; - break; - default: - r = eth->regs[addr]; - D(printf ("%s %x\n", __func__, addr * 4)); - break; - } - return r; + struct fs_eth *eth = opaque; + uint32_t r = 0; + + addr >>= 2; + + switch (addr) { + case R_STAT: + r = eth->mdio_bus.mdio & 1; + break; + default: + r = eth->regs[addr]; + D(printf("%s %x\n", __func__, addr * 4)); + break; + } + return r; } static void eth_update_ma(struct fs_eth *eth, int ma) { - int reg; - int i = 0; - - ma &= 1; - - reg = RW_MA0_LO; - if (ma) - reg = RW_MA1_LO; - - eth->macaddr[ma][i++] = eth->regs[reg]; - eth->macaddr[ma][i++] = eth->regs[reg] >> 8; - eth->macaddr[ma][i++] = eth->regs[reg] >> 16; - eth->macaddr[ma][i++] = eth->regs[reg] >> 24; - eth->macaddr[ma][i++] = eth->regs[reg + 1]; - eth->macaddr[ma][i] = eth->regs[reg + 1] >> 8; - - D(printf("set mac%d=%x.%x.%x.%x.%x.%x\n", ma, - eth->macaddr[ma][0], eth->macaddr[ma][1], - eth->macaddr[ma][2], eth->macaddr[ma][3], - eth->macaddr[ma][4], eth->macaddr[ma][5])); + int reg; + int i = 0; + + ma &= 1; + + reg = RW_MA0_LO; + if (ma) { + reg = RW_MA1_LO; + } + + eth->macaddr[ma][i++] = eth->regs[reg]; + eth->macaddr[ma][i++] = eth->regs[reg] >> 8; + eth->macaddr[ma][i++] = eth->regs[reg] >> 16; + eth->macaddr[ma][i++] = eth->regs[reg] >> 24; + eth->macaddr[ma][i++] = eth->regs[reg + 1]; + eth->macaddr[ma][i] = eth->regs[reg + 1] >> 8; + + D(printf("set mac%d=%x.%x.%x.%x.%x.%x\n", ma, + eth->macaddr[ma][0], eth->macaddr[ma][1], + eth->macaddr[ma][2], eth->macaddr[ma][3], + eth->macaddr[ma][4], eth->macaddr[ma][5])); } static void eth_write(void *opaque, hwaddr addr, uint64_t val64, unsigned int size) { - struct fs_eth *eth = opaque; - uint32_t value = val64; - - addr >>= 2; - switch (addr) - { - case RW_MA0_LO: - case RW_MA0_HI: - eth->regs[addr] = value; - eth_update_ma(eth, 0); - break; - case RW_MA1_LO: - case RW_MA1_HI: - eth->regs[addr] = value; - eth_update_ma(eth, 1); - break; - - case RW_MGM_CTRL: - /* Attach an MDIO/PHY abstraction. */ - if (value & 2) - eth->mdio_bus.mdio = value & 1; - if (eth->mdio_bus.mdc != (value & 4)) { - mdio_cycle(ð->mdio_bus); - eth_validate_duplex(eth); - } - eth->mdio_bus.mdc = !!(value & 4); - eth->regs[addr] = value; - break; - - case RW_REC_CTRL: - eth->regs[addr] = value; - eth_validate_duplex(eth); - break; - - default: - eth->regs[addr] = value; - D(printf ("%s %x %x\n", - __func__, addr, value)); - break; - } + struct fs_eth *eth = opaque; + uint32_t value = val64; + + addr >>= 2; + switch (addr) { + case RW_MA0_LO: + case RW_MA0_HI: + eth->regs[addr] = value; + eth_update_ma(eth, 0); + break; + case RW_MA1_LO: + case RW_MA1_HI: + eth->regs[addr] = value; + eth_update_ma(eth, 1); + break; + + case RW_MGM_CTRL: + /* Attach an MDIO/PHY abstraction. */ + if (value & 2) { + eth->mdio_bus.mdio = value & 1; + } + if (eth->mdio_bus.mdc != (value & 4)) { + mdio_cycle(ð->mdio_bus); + eth_validate_duplex(eth); + } + eth->mdio_bus.mdc = !!(value & 4); + eth->regs[addr] = value; + break; + + case RW_REC_CTRL: + eth->regs[addr] = value; + eth_validate_duplex(eth); + break; + + default: + eth->regs[addr] = value; + D(printf("%s %x %x\n", __func__, addr, value)); + break; + } } /* The ETRAX FS has a groupt address table (GAT) which works like a k=1 bloom - filter dropping group addresses we have not joined. The filter has 64 - bits (m). The has function is a simple nible xor of the group addr. */ + filter dropping group addresses we have not joined. The filter has 64 + bits (m). The has function is a simple nible xor of the group addr. */ static int eth_match_groupaddr(struct fs_eth *eth, const unsigned char *sa) { - unsigned int hsh; - int m_individual = eth->regs[RW_REC_CTRL] & 4; - int match; - - /* First bit on the wire of a MAC address signals multicast or - physical address. */ - if (!m_individual && !(sa[0] & 1)) - return 0; - - /* Calculate the hash index for the GA registers. */ - hsh = 0; - hsh ^= (*sa) & 0x3f; - hsh ^= ((*sa) >> 6) & 0x03; - ++sa; - hsh ^= ((*sa) << 2) & 0x03c; - hsh ^= ((*sa) >> 4) & 0xf; - ++sa; - hsh ^= ((*sa) << 4) & 0x30; - hsh ^= ((*sa) >> 2) & 0x3f; - ++sa; - hsh ^= (*sa) & 0x3f; - hsh ^= ((*sa) >> 6) & 0x03; - ++sa; - hsh ^= ((*sa) << 2) & 0x03c; - hsh ^= ((*sa) >> 4) & 0xf; - ++sa; - hsh ^= ((*sa) << 4) & 0x30; - hsh ^= ((*sa) >> 2) & 0x3f; - - hsh &= 63; - if (hsh > 31) - match = eth->regs[RW_GA_HI] & (1 << (hsh - 32)); - else - match = eth->regs[RW_GA_LO] & (1 << hsh); - D(printf("hsh=%x ga=%x.%x mtch=%d\n", hsh, - eth->regs[RW_GA_HI], eth->regs[RW_GA_LO], match)); - return match; + unsigned int hsh; + int m_individual = eth->regs[RW_REC_CTRL] & 4; + int match; + + /* First bit on the wire of a MAC address signals multicast or + physical address. */ + if (!m_individual && !(sa[0] & 1)) { + return 0; + } + + /* Calculate the hash index for the GA registers. */ + hsh = 0; + hsh ^= (*sa) & 0x3f; + hsh ^= ((*sa) >> 6) & 0x03; + ++sa; + hsh ^= ((*sa) << 2) & 0x03c; + hsh ^= ((*sa) >> 4) & 0xf; + ++sa; + hsh ^= ((*sa) << 4) & 0x30; + hsh ^= ((*sa) >> 2) & 0x3f; + ++sa; + hsh ^= (*sa) & 0x3f; + hsh ^= ((*sa) >> 6) & 0x03; + ++sa; + hsh ^= ((*sa) << 2) & 0x03c; + hsh ^= ((*sa) >> 4) & 0xf; + ++sa; + hsh ^= ((*sa) << 4) & 0x30; + hsh ^= ((*sa) >> 2) & 0x3f; + + hsh &= 63; + if (hsh > 31) { + match = eth->regs[RW_GA_HI] & (1 << (hsh - 32)); + } else { + match = eth->regs[RW_GA_LO] & (1 << hsh); + } + D(printf("hsh=%x ga=%x.%x mtch=%d\n", hsh, + eth->regs[RW_GA_HI], eth->regs[RW_GA_LO], match)); + return match; } static int eth_can_receive(NetClientState *nc) { - return 1; + return 1; } static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size) { - unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; - int use_ma0 = eth->regs[RW_REC_CTRL] & 1; - int use_ma1 = eth->regs[RW_REC_CTRL] & 2; - int r_bcast = eth->regs[RW_REC_CTRL] & 8; - - if (size < 12) - return -1; - - D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], - use_ma0, use_ma1, r_bcast)); - - /* Does the frame get through the address filters? */ - if ((!use_ma0 || memcmp(buf, eth->macaddr[0], 6)) - && (!use_ma1 || memcmp(buf, eth->macaddr[1], 6)) - && (!r_bcast || memcmp(buf, sa_bcast, 6)) - && !eth_match_groupaddr(eth, buf)) - return size; - - /* FIXME: Find another way to pass on the fake csum. */ - etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1); + unsigned char sa_bcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; + int use_ma0 = eth->regs[RW_REC_CTRL] & 1; + int use_ma1 = eth->regs[RW_REC_CTRL] & 2; + int r_bcast = eth->regs[RW_REC_CTRL] & 8; + + if (size < 12) { + return -1; + } + + D(printf("%x.%x.%x.%x.%x.%x ma=%d %d bc=%d\n", + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], + use_ma0, use_ma1, r_bcast)); + + /* Does the frame get through the address filters? */ + if ((!use_ma0 || memcmp(buf, eth->macaddr[0], 6)) + && (!use_ma1 || memcmp(buf, eth->macaddr[1], 6)) + && (!r_bcast || memcmp(buf, sa_bcast, 6)) + && !eth_match_groupaddr(eth, buf)) { + return size; + } + + /* FIXME: Find another way to pass on the fake csum. */ + etraxfs_dmac_input(eth->dma_in, (void *)buf, size + 4, 1); return size; } static int eth_tx_push(void *opaque, unsigned char *buf, int len, bool eop) { - struct fs_eth *eth = opaque; + struct fs_eth *eth = opaque; - D(printf("%s buf=%p len=%d\n", __func__, buf, len)); - qemu_send_packet(ð->nic->nc, buf, len); - return len; + D(printf("%s buf=%p len=%d\n", __func__, buf, len)); + qemu_send_packet(ð->nic->nc, buf, len); + return len; } static void eth_set_link(NetClientState *nc) { - struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; - D(printf("%s %d\n", __func__, nc->link_down)); - eth->phy.link = !nc->link_down; + struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; + D(printf("%s %d\n", __func__, nc->link_down)); + eth->phy.link = !nc->link_down; } static const MemoryRegionOps eth_ops = { - .read = eth_read, - .write = eth_write, - .endianness = DEVICE_LITTLE_ENDIAN, - .valid = { - .min_access_size = 4, - .max_access_size = 4 - } + .read = eth_read, + .write = eth_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } }; static void eth_cleanup(NetClientState *nc) { - struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; + struct fs_eth *eth = DO_UPCAST(NICState, nc, nc)->opaque; - /* Disconnect the client. */ - eth->dma_out->client.push = NULL; - eth->dma_out->client.opaque = NULL; - eth->dma_in->client.opaque = NULL; - eth->dma_in->client.pull = NULL; + /* Disconnect the client. */ + eth->dma_out->client.push = NULL; + eth->dma_out->client.opaque = NULL; + eth->dma_in->client.opaque = NULL; + eth->dma_in->client.pull = NULL; g_free(eth); } static NetClientInfo net_etraxfs_info = { - .type = NET_CLIENT_OPTIONS_KIND_NIC, - .size = sizeof(NICState), - .can_receive = eth_can_receive, - .receive = eth_receive, - .cleanup = eth_cleanup, - .link_status_changed = eth_set_link, + .type = NET_CLIENT_OPTIONS_KIND_NIC, + .size = sizeof(NICState), + .can_receive = eth_can_receive, + .receive = eth_receive, + .cleanup = eth_cleanup, + .link_status_changed = eth_set_link, }; static int fs_eth_init(SysBusDevice *dev) { - struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev); + struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev); - if (!s->dma_out || !s->dma_in) { - hw_error("Unconnected ETRAX-FS Ethernet MAC.\n"); - } + if (!s->dma_out || !s->dma_in) { + hw_error("Unconnected ETRAX-FS Ethernet MAC.\n"); + } - s->dma_out->client.push = eth_tx_push; - s->dma_out->client.opaque = s; - s->dma_in->client.opaque = s; - s->dma_in->client.pull = NULL; + s->dma_out->client.push = eth_tx_push; + s->dma_out->client.opaque = s; + s->dma_in->client.opaque = s; + s->dma_in->client.pull = NULL; - memory_region_init_io(&s->mmio, ð_ops, s, "etraxfs-eth", 0x5c); - sysbus_init_mmio(dev, &s->mmio); + memory_region_init_io(&s->mmio, ð_ops, s, "etraxfs-eth", 0x5c); + sysbus_init_mmio(dev, &s->mmio); - qemu_macaddr_default_if_unset(&s->conf.macaddr); - s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, - object_get_typename(OBJECT(s)), dev->qdev.id, s); - qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf, + object_get_typename(OBJECT(s)), dev->qdev.id, s); + qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); - tdk_init(&s->phy); - mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr); - return 0; + tdk_init(&s->phy); + mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr); + return 0; } static Property etraxfs_eth_properties[] = {
This is a trivial patch to harmonize the coding style on hw/etraxfs_eth.c. This is in preparation to split off the bitbang mdio code into a separate file. Cc: Peter Maydell <peter.maydell@linaro.org> Cc: Paul Brook <paul@codesourcery.com> Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com> Cc: Anthony Liguori <aliguori@us.ibm.com> Cc: Andreas Färber <afaerber@suse.de> Signed-off-by: Grant Likely <grant.likely@secretlab.ca> --- hw/etraxfs_eth.c | 922 +++++++++++++++++++++++++++--------------------------- 1 file changed, 466 insertions(+), 456 deletions(-)