diff options
author | Stefan Weil <weil@mail.berlios.de> | 2010-03-02 22:37:53 +0100 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2010-03-03 13:34:07 +0200 |
commit | e824012bc2d935073cb72fe32f3471441af9fc32 (patch) | |
tree | a7683652a908dac6dc203be96529a3b3b4dad378 /hw | |
parent | e715c8e84ccf262eb56c9ba76f509dfa52f2a918 (diff) |
eepro100: Support RNR interrupt
The RNR interrupt is triggered under these conditions:
* the RU is not ready to receive a frame due to missing resources
* the RU is ready and a RU abort command was requested
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/eepro100.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/hw/eepro100.c b/hw/eepro100.c index 7eaa8768e6..40d8db5f86 100644 --- a/hw/eepro100.c +++ b/hw/eepro100.c @@ -120,7 +120,7 @@ #define RU_NOP 0x0000 #define RX_START 0x0001 #define RX_RESUME 0x0002 -#define RX_ABORT 0x0004 +#define RU_ABORT 0x0004 #define RX_ADDR_LOAD 0x0006 #define RX_RESUMENR 0x0007 #define INT_MASK 0x0100 @@ -426,13 +426,11 @@ static void eepro100_fr_interrupt(EEPRO100State * s) eepro100_interrupt(s, 0x40); } -#if 0 static void eepro100_rnr_interrupt(EEPRO100State * s) { /* RU is not ready. */ eepro100_interrupt(s, 0x10); } -#endif static void eepro100_mdi_interrupt(EEPRO100State * s) { @@ -1065,6 +1063,13 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val) } set_ru_state(s, ru_ready); break; + case RU_ABORT: + /* RU abort. */ + if (get_ru_state(s) == ru_ready) { + eepro100_rnr_interrupt(s); + } + set_ru_state(s, ru_idle); + break; case RX_ADDR_LOAD: /* Load RU base. */ TRACE(OTHER, logout("val=0x%02x (RU base address)\n", val)); @@ -1747,6 +1752,8 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size if (get_ru_state(s) != ru_ready) { /* No resources available. */ logout("no resources, state=%u\n", get_ru_state(s)); + /* TODO: RNR interrupt only at first failed frame? */ + eepro100_rnr_interrupt(s); s->statistics.rx_resource_errors++; //~ assert(!"no resources"); return -1; |