aboutsummaryrefslogtreecommitdiff
path: root/hw/net/e1000.c
diff options
context:
space:
mode:
authorAkihiko Odaki <akihiko.odaki@daynix.com>2023-05-23 11:42:54 +0900
committerJason Wang <jasowang@redhat.com>2023-05-23 15:20:15 +0800
commitf3f9b726afba1f53663768603189e574f80b5907 (patch)
tree2456a6da87c01c6702a73385db16c2dbcca2bec5 /hw/net/e1000.c
parenta51db5802744b274ab40385dd9fe8354722fcc4d (diff)
e1000x: Fix BPRC and MPRC
Before this change, e1000 and the common code updated BPRC and MPRC depending on the matched filter, but e1000e and igb decided to update those counters by deriving the packet type independently. This inconsistency caused a multicast packet to be counted twice. Updating BPRC and MPRC depending on are fundamentally flawed anyway as a filter can be used for different types of packets. For example, it is possible to filter broadcast packets with MTA. Always determine what counters to update by inspecting the packets. Fixes: 3b27430177 ("e1000: Implementing various counters") Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Reviewed-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech> Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'hw/net/e1000.c')
-rw-r--r--hw/net/e1000.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 59bacb5d3b..18eb6d8876 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -826,12 +826,10 @@ receive_filter(E1000State *s, const uint8_t *buf, int size)
}
if (ismcast && (rctl & E1000_RCTL_MPE)) { /* promiscuous mcast */
- e1000x_inc_reg_if_not_full(s->mac_reg, MPRC);
return 1;
}
if (isbcast && (rctl & E1000_RCTL_BAM)) { /* broadcast enabled */
- e1000x_inc_reg_if_not_full(s->mac_reg, BPRC);
return 1;
}
@@ -922,6 +920,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
size_t desc_offset;
size_t desc_size;
size_t total_size;
+ eth_pkt_types_e pkt_type;
if (!e1000x_hw_rx_enabled(s->mac_reg)) {
return -1;
@@ -971,6 +970,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
size -= 4;
}
+ pkt_type = get_eth_packet_type(PKT_GET_ETH_HDR(filter_buf));
rdh_start = s->mac_reg[RDH];
desc_offset = 0;
total_size = size + e1000x_fcs_len(s->mac_reg);
@@ -1036,7 +1036,7 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
}
} while (desc_offset < total_size);
- e1000x_update_rx_total_stats(s->mac_reg, size, total_size);
+ e1000x_update_rx_total_stats(s->mac_reg, pkt_type, size, total_size);
n = E1000_ICS_RXT0;
if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])