Commit 94410b78bed7b986eacddd64fbef84d95aa995d5

Authored by edgar_igl
1 parent 5ab09f33

ETRAX: Let the ethernet PHY report the current link-state.

* 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
@@ -304,10 +304,11 @@ void axisdev88_init (ram_addr_t ram_size, int vga_ram_size, @@ -304,10 +304,11 @@ void axisdev88_init (ram_addr_t ram_size, int vga_ram_size,
304 304
305 /* Add the two ethernet blocks. */ 305 /* Add the two ethernet blocks. */
306 nd_table[0].model = nd_table[0].model ? nd_table[0].model : "fseth"; 306 nd_table[0].model = nd_table[0].model ? nd_table[0].model : "fseth";
307 - eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000); 307 + eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000, 1);
308 if (nb_nics > 1) { 308 if (nb_nics > 1) {
309 nd_table[1].model = nd_table[1].model ? nd_table[1].model : "fseth"; 309 nd_table[1].model = nd_table[1].model ? nd_table[1].model : "fseth";
310 - eth[1] = etraxfs_eth_init(&nd_table[1], env, pic->irq + 26, 0x30036000); 310 + eth[1] = etraxfs_eth_init(&nd_table[1], env,
  311 + pic->irq + 26, 0x30036000, 2);
311 } 312 }
312 313
313 /* The DMA Connector block is missing, hardwire things for now. */ 314 /* The DMA Connector block is missing, hardwire things for now. */
hw/etraxfs.c
@@ -95,10 +95,11 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size, @@ -95,10 +95,11 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size,
95 95
96 /* Add the two ethernet blocks. */ 96 /* Add the two ethernet blocks. */
97 nd_table[0].model = nd_table[0].model ? nd_table[0].model : "fseth"; 97 nd_table[0].model = nd_table[0].model ? nd_table[0].model : "fseth";
98 - eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000); 98 + eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000, 1);
99 if (nb_nics > 1) { 99 if (nb_nics > 1) {
100 nd_table[1].model = nd_table[1].model ? nd_table[1].model : "fseth"; 100 nd_table[1].model = nd_table[1].model ? nd_table[1].model : "fseth";
101 - eth[1] = etraxfs_eth_init(&nd_table[1], env, pic->irq + 26, 0x30036000); 101 + eth[1] = etraxfs_eth_init(&nd_table[1], env,
  102 + pic->irq + 26, 0x30036000, 2);
102 } 103 }
103 104
104 /* The DMA Connector block is missing, hardwire things for now. */ 105 /* The DMA Connector block is missing, hardwire things for now. */
hw/etraxfs.h
@@ -37,6 +37,6 @@ struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base); @@ -37,6 +37,6 @@ struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base);
37 void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, qemu_irq *nmi, 37 void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, qemu_irq *nmi,
38 target_phys_addr_t base); 38 target_phys_addr_t base);
39 void *etraxfs_eth_init(NICInfo *nd, CPUState *env, 39 void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
40 - qemu_irq *irq, target_phys_addr_t base); 40 + qemu_irq *irq, target_phys_addr_t base, int phyaddr);
41 void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr, 41 void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr,
42 target_phys_addr_t base); 42 target_phys_addr_t base);
hw/etraxfs_eth.c
@@ -45,6 +45,8 @@ struct qemu_phy @@ -45,6 +45,8 @@ struct qemu_phy
45 { 45 {
46 uint32_t regs[32]; 46 uint32_t regs[32];
47 47
  48 + int link;
  49 +
48 unsigned int (*read)(struct qemu_phy *phy, unsigned int req); 50 unsigned int (*read)(struct qemu_phy *phy, unsigned int req);
49 void (*write)(struct qemu_phy *phy, unsigned int req, 51 void (*write)(struct qemu_phy *phy, unsigned int req,
50 unsigned int data); 52 unsigned int data);
@@ -59,13 +61,15 @@ static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req) @@ -59,13 +61,15 @@ static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req)
59 61
60 switch (regnum) { 62 switch (regnum) {
61 case 1: 63 case 1:
  64 + if (!phy->link)
  65 + break;
62 /* MR1. */ 66 /* MR1. */
63 /* Speeds and modes. */ 67 /* Speeds and modes. */
64 r |= (1 << 13) | (1 << 14); 68 r |= (1 << 13) | (1 << 14);
65 r |= (1 << 11) | (1 << 12); 69 r |= (1 << 11) | (1 << 12);
66 r |= (1 << 5); /* Autoneg complete. */ 70 r |= (1 << 5); /* Autoneg complete. */
67 r |= (1 << 3); /* Autoneg able. */ 71 r |= (1 << 3); /* Autoneg able. */
68 - r |= (1 << 2); /* Link. */ 72 + r |= (1 << 2); /* link. */
69 break; 73 break;
70 case 5: 74 case 5:
71 /* Link partner ability. 75 /* Link partner ability.
@@ -83,6 +87,9 @@ static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req) @@ -83,6 +87,9 @@ static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req)
83 int duplex = 0; 87 int duplex = 0;
84 int speed_100 = 0; 88 int speed_100 = 0;
85 89
  90 + if (!phy->link)
  91 + break;
  92 +
86 /* Are we advertising 100 half or 100 duplex ? */ 93 /* Are we advertising 100 half or 100 duplex ? */
87 speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF); 94 speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF);
88 speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL); 95 speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL);
@@ -125,6 +132,7 @@ tdk_init(struct qemu_phy *phy) @@ -125,6 +132,7 @@ tdk_init(struct qemu_phy *phy)
125 phy->regs[3] = 0xe400; 132 phy->regs[3] = 0xe400;
126 /* Autonegotiation advertisement reg. */ 133 /* Autonegotiation advertisement reg. */
127 phy->regs[4] = 0x01E1; 134 phy->regs[4] = 0x01E1;
  135 + phy->link = 1;
128 136
129 phy->read = tdk_read; 137 phy->read = tdk_read;
130 phy->write = tdk_write; 138 phy->write = tdk_write;
@@ -530,6 +538,13 @@ static int eth_tx_push(void *opaque, unsigned char *buf, int len) @@ -530,6 +538,13 @@ static int eth_tx_push(void *opaque, unsigned char *buf, int len)
530 return len; 538 return len;
531 } 539 }
532 540
  541 +static void eth_set_link(VLANClientState *vc)
  542 +{
  543 + struct fs_eth *eth = vc->opaque;
  544 + D(printf("%s %d\n", __func__, vc->link_down));
  545 + eth->phy.link = !vc->link_down;
  546 +}
  547 +
533 static CPUReadMemoryFunc *eth_read[] = { 548 static CPUReadMemoryFunc *eth_read[] = {
534 NULL, NULL, 549 NULL, NULL,
535 &eth_readl, 550 &eth_readl,
@@ -541,7 +556,7 @@ static CPUWriteMemoryFunc *eth_write[] = { @@ -541,7 +556,7 @@ static CPUWriteMemoryFunc *eth_write[] = {
541 }; 556 };
542 557
543 void *etraxfs_eth_init(NICInfo *nd, CPUState *env, 558 void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
544 - qemu_irq *irq, target_phys_addr_t base) 559 + qemu_irq *irq, target_phys_addr_t base, int phyaddr)
545 { 560 {
546 struct etraxfs_dma_client *dma = NULL; 561 struct etraxfs_dma_client *dma = NULL;
547 struct fs_eth *eth = NULL; 562 struct fs_eth *eth = NULL;
@@ -565,7 +580,7 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env, @@ -565,7 +580,7 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
565 eth->dma_in = dma + 1; 580 eth->dma_in = dma + 1;
566 581
567 /* Connect the phy. */ 582 /* Connect the phy. */
568 - eth->phyaddr = 1; 583 + eth->phyaddr = phyaddr & 0x1f;
569 tdk_init(&eth->phy); 584 tdk_init(&eth->phy);
570 mdio_attach(&eth->mdio_bus, &eth->phy, eth->phyaddr); 585 mdio_attach(&eth->mdio_bus, &eth->phy, eth->phyaddr);
571 586
@@ -574,6 +589,8 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env, @@ -574,6 +589,8 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
574 589
575 eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, 590 eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
576 eth_receive, eth_can_receive, eth); 591 eth_receive, eth_can_receive, eth);
  592 + eth->vc->opaque = eth;
  593 + eth->vc->link_status_changed = eth_set_link;
577 594
578 return dma; 595 return dma;
579 err: 596 err: