@@ -335,6 +335,7 @@
#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
#define E1000_ICR_RXO 0x00000040 /* rx overrun */
#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
+#define E1000_ICR_RXDW 0x00000080 /* rx desc written back */
#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
@@ -378,6 +379,7 @@
#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+#define E1000_ICS_RXDW E1000_ICR_RXDW /* rx desc written back */
#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
@@ -407,6 +409,7 @@
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+#define E1000_IMS_RXDW E1000_ICR_RXDW /* rx desc written back */
#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
@@ -441,6 +444,7 @@
#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+#define E1000_IMC_RXDW E1000_ICR_RXDW /* rx desc written back */
#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
@@ -1498,7 +1498,7 @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
static const int maximum_ethernet_hdr_len = (ETH_HLEN + 4);
uint16_t queues = 0;
- uint32_t n = 0;
+ uint32_t icr_bits = 0;
uint8_t min_buf[ETH_ZLEN];
struct iovec min_iov;
struct eth_header *ehdr;
@@ -1508,7 +1508,7 @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
E1000E_RxRing rxr;
E1000E_RSSInfo rss_info;
size_t total_size;
- ssize_t retval;
+ ssize_t retval = 0;
int i;
trace_e1000e_rx_receive_iov(iovcnt);
@@ -1570,8 +1570,6 @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
total_size = net_rx_pkt_get_total_len(core->rx_pkt) +
e1000x_fcs_len(core->mac);
- retval = orig_size;
-
for (i = 0; i < IGB_NUM_QUEUES; i++) {
if (!(queues & BIT(i))) {
continue;
@@ -1579,11 +1577,12 @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
igb_rx_ring_init(core, &rxr, i);
if (!igb_has_rxbufs(core, rxr.i, total_size)) {
- retval = 0;
+ icr_bits |= E1000_ICS_RXO;
}
}
- if (retval) {
+ if (!icr_bits) {
+ retval = orig_size;
igb_rx_fix_l4_csum(core, core->rx_pkt);
for (i = 0; i < IGB_NUM_QUEUES; i++) {
@@ -1593,28 +1592,29 @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
}
igb_rx_ring_init(core, &rxr, i);
+
trace_e1000e_rx_rss_dispatched_to_queue(rxr.i->idx);
igb_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info);
/* Check if receive descriptor minimum threshold hit */
if (igb_rx_descr_threshold_hit(core, rxr.i)) {
- n |= E1000_ICS_RXDMT0;
+ icr_bits |= E1000_ICS_RXDMT0;
}
core->mac[EICR] |= igb_rx_wb_eic(core, rxr.i->idx);
- /* same as RXDW (rx descriptor written back)*/
- n = E1000_ICR_RXT0;
+ icr_bits |= E1000_ICR_RXDW;
}
+ }
- trace_e1000e_rx_written_to_guest(n);
+ if (icr_bits & E1000_ICR_RXDW) {
+ trace_e1000e_rx_written_to_guest(icr_bits);
} else {
- n = E1000_ICS_RXO;
- trace_e1000e_rx_not_written_to_guest(n);
+ trace_e1000e_rx_not_written_to_guest(icr_bits);
}
- trace_e1000e_rx_interrupt_set(n);
- igb_set_interrupt_cause(core, n);
+ trace_e1000e_rx_interrupt_set(icr_bits);
+ igb_set_interrupt_cause(core, icr_bits);
return retval;
}
IGB uses RXDW ICR bit to indicate that rx descriptor has been written back. This is the same as RXT0 bit in older HW. Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech> --- hw/net/e1000x_regs.h | 4 ++++ hw/net/igb_core.c | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 14 deletions(-)