From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Khs6y-0003hY-An for qemu-devel@nongnu.org; Mon, 22 Sep 2008 16:34:24 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Khs6x-0003hC-Ha for qemu-devel@nongnu.org; Mon, 22 Sep 2008 16:34:23 -0400 Received: from [199.232.76.173] (port=54738 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Khs6x-0003h5-8b for qemu-devel@nongnu.org; Mon, 22 Sep 2008 16:34:23 -0400 Received: from savannah.gnu.org ([199.232.41.3]:49100 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Khs6w-0005KU-IF for qemu-devel@nongnu.org; Mon, 22 Sep 2008 16:34:23 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1Khs6t-0001Mn-Ij for qemu-devel@nongnu.org; Mon, 22 Sep 2008 20:34:19 +0000 Received: from edgar_igl by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1Khs6t-0001Mj-98 for qemu-devel@nongnu.org; Mon, 22 Sep 2008 20:34:19 +0000 MIME-Version: 1.0 Errors-To: edgar_igl Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: "Edgar E. Iglesias" Message-Id: Date: Mon, 22 Sep 2008 20:34:19 +0000 Subject: [Qemu-devel] [5300] ETRAX-FS: Correct ethernet PHY diagnostics register reads. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 5300 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5300 Author: edgar_igl Date: 2008-09-22 20:34:18 +0000 (Mon, 22 Sep 2008) Log Message: ----------- ETRAX-FS: Correct ethernet PHY diagnostics register reads. * Correct ethernet PHY diagnostics register reads. * Add friendly names for the speed/duplex fields. * Report duplex mismatches between MAC and PHY. Modified Paths: -------------- trunk/hw/etraxfs_eth.c Modified: trunk/hw/etraxfs_eth.c =================================================================== --- trunk/hw/etraxfs_eth.c 2008-09-22 19:50:28 UTC (rev 5299) +++ trunk/hw/etraxfs_eth.c 2008-09-22 20:34:18 UTC (rev 5300) @@ -30,6 +30,12 @@ #define D(x) +/* Advertisement control register. */ +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ +#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 * linux driver (PHYID and Diagnostics reg). @@ -78,9 +84,12 @@ int speed_100 = 0; /* Are we advertising 100 half or 100 duplex ? */ - speed_100 = !!(phy->regs[4] & 0x180); + 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] & 0x180); + duplex = !!(phy->regs[4] & ADVERTISE_100FULL); + duplex |= !!(phy->regs[4] & ADVERTISE_10FULL); r = (speed_100 << 10) | (duplex << 11); } break; @@ -322,10 +331,40 @@ /* 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; + } +} + static uint32_t eth_rinvalid (void *opaque, target_phys_addr_t addr) { struct fs_eth *eth = opaque; @@ -418,11 +457,18 @@ /* Attach an MDIO/PHY abstraction. */ if (value & 2) eth->mdio_bus.mdio = value & 1; - if (eth->mdio_bus.mdc != (value & 4)) + if (eth->mdio_bus.mdc != (value & 4)) { mdio_cycle(ð->mdio_bus); + eth_validate_duplex(eth); + } eth->mdio_bus.mdc = !!(value & 4); 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", @@ -591,8 +637,9 @@ eth->dma_in = dma + 1; /* Connect the phy. */ + eth->phyaddr = 1; tdk_init(ð->phy); - mdio_attach(ð->mdio_bus, ð->phy, 0x1); + mdio_attach(ð->mdio_bus, ð->phy, eth->phyaddr); eth->ethregs = cpu_register_io_memory(0, eth_read, eth_write, eth); cpu_register_physical_memory (base, 0x5c, eth->ethregs);