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 304  
305 305 /* Add the two ethernet blocks. */
306 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 308 if (nb_nics > 1) {
309 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 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 95  
96 96 /* Add the two ethernet blocks. */
97 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 99 if (nb_nics > 1) {
100 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 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 37 void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, qemu_irq *nmi,
38 38 target_phys_addr_t base);
39 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 41 void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr,
42 42 target_phys_addr_t base);
... ...
hw/etraxfs_eth.c
... ... @@ -45,6 +45,8 @@ struct qemu_phy
45 45 {
46 46 uint32_t regs[32];
47 47  
  48 + int link;
  49 +
48 50 unsigned int (*read)(struct qemu_phy *phy, unsigned int req);
49 51 void (*write)(struct qemu_phy *phy, unsigned int req,
50 52 unsigned int data);
... ... @@ -59,13 +61,15 @@ static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req)
59 61  
60 62 switch (regnum) {
61 63 case 1:
  64 + if (!phy->link)
  65 + break;
62 66 /* MR1. */
63 67 /* Speeds and modes. */
64 68 r |= (1 << 13) | (1 << 14);
65 69 r |= (1 << 11) | (1 << 12);
66 70 r |= (1 << 5); /* Autoneg complete. */
67 71 r |= (1 << 3); /* Autoneg able. */
68   - r |= (1 << 2); /* Link. */
  72 + r |= (1 << 2); /* link. */
69 73 break;
70 74 case 5:
71 75 /* Link partner ability.
... ... @@ -83,6 +87,9 @@ static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req)
83 87 int duplex = 0;
84 88 int speed_100 = 0;
85 89  
  90 + if (!phy->link)
  91 + break;
  92 +
86 93 /* Are we advertising 100 half or 100 duplex ? */
87 94 speed_100 = !!(phy->regs[4] & ADVERTISE_100HALF);
88 95 speed_100 |= !!(phy->regs[4] & ADVERTISE_100FULL);
... ... @@ -125,6 +132,7 @@ tdk_init(struct qemu_phy *phy)
125 132 phy->regs[3] = 0xe400;
126 133 /* Autonegotiation advertisement reg. */
127 134 phy->regs[4] = 0x01E1;
  135 + phy->link = 1;
128 136  
129 137 phy->read = tdk_read;
130 138 phy->write = tdk_write;
... ... @@ -530,6 +538,13 @@ static int eth_tx_push(void *opaque, unsigned char *buf, int len)
530 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 548 static CPUReadMemoryFunc *eth_read[] = {
534 549 NULL, NULL,
535 550 &eth_readl,
... ... @@ -541,7 +556,7 @@ static CPUWriteMemoryFunc *eth_write[] = {
541 556 };
542 557  
543 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 561 struct etraxfs_dma_client *dma = NULL;
547 562 struct fs_eth *eth = NULL;
... ... @@ -565,7 +580,7 @@ void *etraxfs_eth_init(NICInfo *nd, CPUState *env,
565 580 eth->dma_in = dma + 1;
566 581  
567 582 /* Connect the phy. */
568   - eth->phyaddr = 1;
  583 + eth->phyaddr = phyaddr & 0x1f;
569 584 tdk_init(&eth->phy);
570 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 589  
575 590 eth->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
576 591 eth_receive, eth_can_receive, eth);
  592 + eth->vc->opaque = eth;
  593 + eth->vc->link_status_changed = eth_set_link;
577 594  
578 595 return dma;
579 596 err:
... ...