* Peter Maydell (peter.mayd...@linaro.org) wrote: > Packet transmission for the stellaris ethernet controller can be triggered > in one of two ways: > * by setting a threshold value in the THR register; when the FIFO > fill level reaches the threshold, the h/w starts transmitting. > Software has to finish filling the FIFO before the transmit > process completes to avoid a (silent) underrun > * by software writing to the TR register to explicitly trigger > transmission > > Since QEMU transmits packets instantaneously (from the guest's > point of view), implement "transmit based on threshold" with > our existing mechanism of "transmit as soon as we have the whole > packet", with the additional wrinkle that we don't transmit if > the packet size is below the specified threshold, and implement > "transmit by specific request" properly. > > Signed-off-by: Peter Maydell <peter.mayd...@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dgilb...@redhat.com> > --- > hw/net/stellaris_enet.c | 17 +++++++++++++++-- > 1 file changed, 15 insertions(+), 2 deletions(-) > > diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c > index 47787fd..db6e43e 100644 > --- a/hw/net/stellaris_enet.c > +++ b/hw/net/stellaris_enet.c > @@ -109,6 +109,15 @@ static inline bool > stellaris_txpacket_complete(stellaris_enet_state *s) > return s->tx_fifo_len >= framelen; > } > > +/* Return true if the TX FIFO threshold is enabled and the FIFO > + * has filled enough to reach it. > + */ > +static inline bool stellaris_tx_thr_reached(stellaris_enet_state *s) > +{ > + return (s->thr < 0x3f && > + (s->tx_fifo_len >= 4 * (s->thr * 8 + 1))); > +} > + > /* Send the packet currently in the TX FIFO */ > static void stellaris_enet_send(stellaris_enet_state *s) > { > @@ -309,7 +318,7 @@ static void stellaris_enet_write(void *opaque, hwaddr > offset, > s->tx_fifo[s->tx_fifo_len++] = value >> 24; > } > > - if (stellaris_txpacket_complete(s)) { > + if (stellaris_tx_thr_reached(s) && stellaris_txpacket_complete(s)) { > stellaris_enet_send(s); > } > break; > @@ -338,9 +347,13 @@ static void stellaris_enet_write(void *opaque, hwaddr > offset, > case 0x2c: /* MTXD */ > s->mtxd = value & 0xff; > break; > + case 0x38: /* TR */ > + if (value & 1) { > + stellaris_enet_send(s); > + } > + break; > case 0x30: /* MRXD */ > case 0x34: /* NP */ > - case 0x38: /* TR */ > /* Ignored. */ > case 0x3c: /* Undocuented: Timestamp? */ > /* Ignored. */ > -- > 1.9.0 > -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK