#define GPT_TIMER_EN 0x20000000
+/*
+ * The MAC Interface Layer (MIL), within the MAC, contains a 2K Byte transmit
+ * and a 128 Byte receive FIFO which is separate from the TX and RX FIFOs.
+ */
+#define MIL_TXFIFO_SIZE 2048
+
enum tx_state {
TX_IDLE,
TX_B,
int32_t pad;
int32_t fifo_used;
int32_t len;
- uint8_t data[2048];
+ uint8_t data[MIL_TXFIFO_SIZE];
} LAN9118Packet;
static const VMStateDescription vmstate_lan9118_packet = {
VMSTATE_INT32(pad, LAN9118Packet),
VMSTATE_INT32(fifo_used, LAN9118Packet),
VMSTATE_INT32(len, LAN9118Packet),
- VMSTATE_UINT8_ARRAY(data, LAN9118Packet, 2048),
+ VMSTATE_UINT8_ARRAY(data, LAN9118Packet, MIL_TXFIFO_SIZE),
VMSTATE_END_OF_LIST()
}
};
return -1;
}
- if (size >= 2048 || size < 14) {
+ if (size >= MIL_TXFIFO_SIZE || size < 14) {
return -1;
}
/* Documentation is somewhat unclear on the ordering of bytes
in FIFO words. Empirical results show it to be little-endian.
*/
- /* TODO: FIFO overflow checking. */
while (n--) {
+ if (s->txp->len == MIL_TXFIFO_SIZE) {
+ /*
+ * No more space in the FIFO. The datasheet is not
+ * precise about this case. We choose what is easiest
+ * to model: the packet is truncated, and TXE is raised.
+ *
+ * Note, it could be a fragmented packet, but we currently
+ * do not handle that (see earlier TX_B case).
+ */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "MIL TX FIFO overrun, discarding %u byte%s\n",
+ n, n > 1 ? "s" : "");
+ s->int_sts |= TXE_INT;
+ break;
+ }
s->txp->data[s->txp->len] = val & 0xff;
s->txp->len++;
val >>= 8;