Commit 94410b78bed7b986eacddd64fbef84d95aa995d5
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
Showing
4 changed files
with
27 additions
and
8 deletions
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 | ð_readl, | 550 | ð_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(ð->phy); | 584 | tdk_init(ð->phy); |
570 | mdio_attach(ð->mdio_bus, ð->phy, eth->phyaddr); | 585 | mdio_attach(ð->mdio_bus, ð->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: |