mirror of https://github.com/xemu-project/xemu.git
igb: Implement igb-specific oversize check
igb has a configurable size limit for LPE, and uses different limits depending on whether the packet is treated as a VLAN packet. 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>
This commit is contained in:
parent
6aa262f8e3
commit
bb97003e73
|
@ -980,16 +980,13 @@ igb_rx_l4_cso_enabled(IGBCore *core)
|
||||||
return !!(core->mac[RXCSUM] & E1000_RXCSUM_TUOFLD);
|
return !!(core->mac[RXCSUM] & E1000_RXCSUM_TUOFLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool igb_rx_is_oversized(IGBCore *core, const struct eth_header *ehdr,
|
||||||
igb_rx_is_oversized(IGBCore *core, uint16_t qn, size_t size)
|
size_t size, size_t vlan_num,
|
||||||
|
bool lpe, uint16_t rlpml)
|
||||||
{
|
{
|
||||||
uint16_t pool = qn % IGB_NUM_VM_POOLS;
|
size_t vlan_header_size = sizeof(struct vlan_header) * vlan_num;
|
||||||
bool lpe = !!(core->mac[VMOLR0 + pool] & E1000_VMOLR_LPE);
|
size_t header_size = sizeof(struct eth_header) + vlan_header_size;
|
||||||
int max_ethernet_lpe_size =
|
return lpe ? size + ETH_FCS_LEN > rlpml : size > header_size + ETH_MTU;
|
||||||
core->mac[VMOLR0 + pool] & E1000_VMOLR_RLPML_MASK;
|
|
||||||
int max_ethernet_vlan_size = 1522;
|
|
||||||
|
|
||||||
return size > (lpe ? max_ethernet_lpe_size : max_ethernet_vlan_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t igb_receive_assign(IGBCore *core, const L2Header *l2_header,
|
static uint16_t igb_receive_assign(IGBCore *core, const L2Header *l2_header,
|
||||||
|
@ -1002,6 +999,8 @@ static uint16_t igb_receive_assign(IGBCore *core, const L2Header *l2_header,
|
||||||
uint16_t queues = 0;
|
uint16_t queues = 0;
|
||||||
uint16_t oversized = 0;
|
uint16_t oversized = 0;
|
||||||
size_t vlan_num = 0;
|
size_t vlan_num = 0;
|
||||||
|
bool lpe;
|
||||||
|
uint16_t rlpml;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset(rss_info, 0, sizeof(E1000E_RSSInfo));
|
memset(rss_info, 0, sizeof(E1000E_RSSInfo));
|
||||||
|
@ -1021,6 +1020,14 @@ static uint16_t igb_receive_assign(IGBCore *core, const L2Header *l2_header,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lpe = !!(core->mac[RCTL] & E1000_RCTL_LPE);
|
||||||
|
rlpml = core->mac[RLPML];
|
||||||
|
if (!(core->mac[RCTL] & E1000_RCTL_SBP) &&
|
||||||
|
igb_rx_is_oversized(core, ehdr, size, vlan_num, lpe, rlpml)) {
|
||||||
|
trace_e1000x_rx_oversized(size);
|
||||||
|
return queues;
|
||||||
|
}
|
||||||
|
|
||||||
if (vlan_num &&
|
if (vlan_num &&
|
||||||
!e1000x_rx_vlan_filter(core->mac, l2_header->vlan + vlan_num - 1)) {
|
!e1000x_rx_vlan_filter(core->mac, l2_header->vlan + vlan_num - 1)) {
|
||||||
return queues;
|
return queues;
|
||||||
|
@ -1106,7 +1113,11 @@ static uint16_t igb_receive_assign(IGBCore *core, const L2Header *l2_header,
|
||||||
queues &= core->mac[VFRE];
|
queues &= core->mac[VFRE];
|
||||||
if (queues) {
|
if (queues) {
|
||||||
for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
|
for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
|
||||||
if ((queues & BIT(i)) && igb_rx_is_oversized(core, i, size)) {
|
lpe = !!(core->mac[VMOLR0 + i] & E1000_VMOLR_LPE);
|
||||||
|
rlpml = core->mac[VMOLR0 + i] & E1000_VMOLR_RLPML_MASK;
|
||||||
|
if ((queues & BIT(i)) &&
|
||||||
|
igb_rx_is_oversized(core, ehdr, size, vlan_num,
|
||||||
|
lpe, rlpml)) {
|
||||||
oversized |= BIT(i);
|
oversized |= BIT(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1662,11 +1673,6 @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
|
||||||
iov_to_buf(iov, iovcnt, iov_ofs, &buf, sizeof(buf.l2_header));
|
iov_to_buf(iov, iovcnt, iov_ofs, &buf, sizeof(buf.l2_header));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Discard oversized packets if !LPE and !SBP. */
|
|
||||||
if (e1000x_is_oversized(core->mac, size)) {
|
|
||||||
return orig_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
net_rx_pkt_set_packet_type(core->rx_pkt,
|
net_rx_pkt_set_packet_type(core->rx_pkt,
|
||||||
get_eth_packet_type(&buf.l2_header.eth));
|
get_eth_packet_type(&buf.l2_header.eth));
|
||||||
net_rx_pkt_set_protocols(core->rx_pkt, iov, iovcnt, iov_ofs);
|
net_rx_pkt_set_protocols(core->rx_pkt, iov, iovcnt, iov_ofs);
|
||||||
|
|
Loading…
Reference in New Issue