ETRAX: Let the ethernet PHY report the current link-state.
authoredgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 9 Jan 2009 00:04:35 +0000 (00:04 +0000)
committeredgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 9 Jan 2009 00:04:35 +0000 (00:04 +0000)
* PHY reports correct link-state.
* Allow the board description to assign separate addresses to each PHY.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6255 c046a42c-6fe2-441c-8c8c-71466251a162

hw/axis_dev88.c
hw/etraxfs.c
hw/etraxfs.h
hw/etraxfs_eth.c

index f7bdd1465bf8d082cd85bcb1a64d5a31a2d51c5b..c20524bd8cced1d6ac638fb902cb35bf4c81eb7d 100644 (file)
@@ -304,10 +304,11 @@ void axisdev88_init (ram_addr_t ram_size, int vga_ram_size,
 
     /* Add the two ethernet blocks.  */
     nd_table[0].model = nd_table[0].model ? nd_table[0].model : "fseth";
-    eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000);
+    eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000, 1);
     if (nb_nics > 1) {
         nd_table[1].model = nd_table[1].model ? nd_table[1].model : "fseth";
-        eth[1] = etraxfs_eth_init(&nd_table[1], env, pic->irq + 26, 0x30036000);
+        eth[1] = etraxfs_eth_init(&nd_table[1], env,
+                                  pic->irq + 26, 0x30036000, 2);
     }
 
     /* The DMA Connector block is missing, hardwire things for now.  */
index 01b5a6e6fe486d4f954f118ddad8aa14c3df08d8..01569bc1b995194af7399e8cb8c96f41a15b7768 100644 (file)
@@ -95,10 +95,11 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size,
 
     /* Add the two ethernet blocks.  */
     nd_table[0].model = nd_table[0].model ? nd_table[0].model : "fseth";
-    eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000);
+    eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000, 1);
     if (nb_nics > 1) {
         nd_table[1].model = nd_table[1].model ? nd_table[1].model : "fseth";
-        eth[1] = etraxfs_eth_init(&nd_table[1], env, pic->irq + 26, 0x30036000);
+        eth[1] = etraxfs_eth_init(&nd_table[1], env,
+                                  pic->irq + 26, 0x30036000, 2);
     }
 
     /* The DMA Connector block is missing, hardwire things for now.  */
index 0c9fdbb608e687e69d15c1bcb07f213981aee407..17dca29a446a25ba5062c7c9816de971c7ba3b78 100644 (file)
@@ -37,6 +37,6 @@ struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base);
 void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, qemu_irq *nmi,
                         target_phys_addr_t base);
 void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
-                       qemu_irq *irq, target_phys_addr_t base);
+                       qemu_irq *irq, target_phys_addr_t base, int phyaddr);
 void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr,
                       target_phys_addr_t base);
index 239e0d872c40e937fe9151d2ce1793f58e24433d..4ae97b11eb35feccd8d8939c15267494f706561b 100644 (file)
@@ -45,6 +45,8 @@ struct qemu_phy
 {
        uint32_t regs[32];
 
+       int link;
+
        unsigned int (*read)(struct qemu_phy *phy, unsigned int req);
        void (*write)(struct qemu_phy *phy, unsigned int req, 
                      unsigned int data);
@@ -59,13 +61,15 @@ static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req)
 
        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.  */
+                       r |= (1 << 2); /* link.  */
                        break;
                case 5:
                        /* Link partner ability.
@@ -83,6 +87,9 @@ static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req)
                        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);
@@ -125,6 +132,7 @@ tdk_init(struct qemu_phy *phy)
        phy->regs[3] = 0xe400;
        /* Autonegotiation advertisement reg.  */
        phy->regs[4] = 0x01E1;
+       phy->link = 1;
 
        phy->read = tdk_read;
        phy->write = tdk_write;
@@ -530,6 +538,13 @@ static int eth_tx_push(void *opaque, unsigned char *buf, int len)
        return len;
 }
 
+static void eth_set_link(VLANClientState *vc)
+{
+       struct fs_eth *eth = vc->opaque;
+       D(printf("%s %d\n", __func__, vc->link_down));
+       eth->phy.link = !vc->link_down;
+}
+
 static CPUReadMemoryFunc *eth_read[] = {
        NULL, NULL,
        &eth_readl,
@@ -541,7 +556,7 @@ static CPUWriteMemoryFunc *eth_write[] = {
 };
 
 void *etraxfs_eth_init(NICInfo *nd, CPUState *env, 
-                      qemu_irq *irq, target_phys_addr_t base)
+                      qemu_irq *irq, target_phys_addr_t base, int phyaddr)
 {
        struct etraxfs_dma_client *dma = NULL;  
        struct fs_eth *eth = NULL;
@@ -565,7 +580,7 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
        eth->dma_in = dma + 1;
 
        /* Connect the phy.  */
-       eth->phyaddr = 1;
+       eth->phyaddr = phyaddr & 0x1f;
        tdk_init(&eth->phy);
        mdio_attach(&eth->mdio_bus, &eth->phy, eth->phyaddr);
 
@@ -574,6 +589,8 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
 
        eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
                                       eth_receive, eth_can_receive, eth);
+       eth->vc->opaque = eth;
+       eth->vc->link_status_changed = eth_set_link;
 
        return dma;
   err: