Skip to content

Commit

Permalink
igb: RX descriptors guest writting refactoring
Browse files Browse the repository at this point in the history
Refactoring is done in preparation for support of multiple advanced
descriptors RX modes, especially packet-split modes.

Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
  • Loading branch information
Tomasz Dzieciol authored and jasowang committed Sep 18, 2023
1 parent a86aee7 commit ec82ad7
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 88 deletions.
170 changes: 88 additions & 82 deletions hw/net/igb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1281,15 +1281,11 @@ igb_verify_csum_in_sw(IGBCore *core,
}

static void
igb_build_rx_metadata(IGBCore *core,
struct NetRxPkt *pkt,
bool is_eop,
const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
uint16_t *pkt_info, uint16_t *hdr_info,
uint32_t *rss,
uint32_t *status_flags,
uint16_t *ip_id,
uint16_t *vlan_tag)
igb_build_rx_metadata_common(IGBCore *core,
struct NetRxPkt *pkt,
bool is_eop,
uint32_t *status_flags,
uint16_t *vlan_tag)
{
struct virtio_net_hdr *vhdr;
bool hasip4, hasip6, csum_valid;
Expand All @@ -1298,7 +1294,6 @@ igb_build_rx_metadata(IGBCore *core,
*status_flags = E1000_RXD_STAT_DD;

/* No additional metadata needed for non-EOP descriptors */
/* TODO: EOP apply only to status so don't skip whole function. */
if (!is_eop) {
goto func_exit;
}
Expand All @@ -1315,59 +1310,6 @@ igb_build_rx_metadata(IGBCore *core,
trace_e1000e_rx_metadata_vlan(*vlan_tag);
}

/* Packet parsing results */
if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) != 0) {
if (rss_info->enabled) {
*rss = cpu_to_le32(rss_info->hash);
trace_igb_rx_metadata_rss(*rss);
}
} else if (hasip4) {
*status_flags |= E1000_RXD_STAT_IPIDV;
*ip_id = cpu_to_le16(net_rx_pkt_get_ip_id(pkt));
trace_e1000e_rx_metadata_ip_id(*ip_id);
}

if (pkt_info) {
*pkt_info = rss_info->enabled ? rss_info->type : 0;

if (etqf < 8) {
*pkt_info |= (BIT(11) | etqf) << 4;
} else {
if (hasip4) {
*pkt_info |= E1000_ADVRXD_PKT_IP4;
}

if (hasip6) {
*pkt_info |= E1000_ADVRXD_PKT_IP6;
}

switch (l4hdr_proto) {
case ETH_L4_HDR_PROTO_TCP:
*pkt_info |= E1000_ADVRXD_PKT_TCP;
break;

case ETH_L4_HDR_PROTO_UDP:
*pkt_info |= E1000_ADVRXD_PKT_UDP;
break;

case ETH_L4_HDR_PROTO_SCTP:
*pkt_info |= E1000_ADVRXD_PKT_SCTP;
break;

default:
break;
}
}
}

if (hdr_info) {
*hdr_info = 0;
}

if (ts) {
*status_flags |= BIT(16);
}

/* RX CSO information */
if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) {
trace_e1000e_rx_metadata_ipv6_sum_disabled();
Expand Down Expand Up @@ -1423,43 +1365,108 @@ igb_build_rx_metadata(IGBCore *core,
static inline void
igb_write_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc,
struct NetRxPkt *pkt,
const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
const E1000E_RSSInfo *rss_info,
uint16_t length)
{
uint32_t status_flags, rss;
uint16_t ip_id;
uint32_t status_flags;

assert(!rss_info->enabled);

memset(desc, 0, sizeof(*desc));
desc->length = cpu_to_le16(length);
desc->csum = 0;
igb_build_rx_metadata_common(core, pkt, pkt != NULL,
&status_flags,
&desc->special);

igb_build_rx_metadata(core, pkt, pkt != NULL,
rss_info, etqf, ts,
NULL, NULL, &rss,
&status_flags, &ip_id,
&desc->special);
desc->errors = (uint8_t) (le32_to_cpu(status_flags) >> 24);
desc->status = (uint8_t) le32_to_cpu(status_flags);
}

static uint16_t
igb_rx_desc_get_packet_type(IGBCore *core, struct NetRxPkt *pkt, uint16_t etqf)
{
uint16_t pkt_type;
bool hasip4, hasip6;
EthL4HdrProto l4hdr_proto;

if (etqf < 8) {
pkt_type = BIT(11) | etqf;
return pkt_type;
}

net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);

if (hasip6 && !(core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
pkt_type = E1000_ADVRXD_PKT_IP6;
} else if (hasip4) {
pkt_type = E1000_ADVRXD_PKT_IP4;
} else {
pkt_type = 0;
}

switch (l4hdr_proto) {
case ETH_L4_HDR_PROTO_TCP:
pkt_type |= E1000_ADVRXD_PKT_TCP;
break;
case ETH_L4_HDR_PROTO_UDP:
pkt_type |= E1000_ADVRXD_PKT_UDP;
break;
case ETH_L4_HDR_PROTO_SCTP:
pkt_type |= E1000_ADVRXD_PKT_SCTP;
break;
default:
break;
}

return pkt_type;
}

static inline void
igb_write_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
struct NetRxPkt *pkt,
const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
uint16_t length)
{
bool hasip4, hasip6;
EthL4HdrProto l4hdr_proto;
uint16_t rss_type = 0, pkt_type;
bool eop = (pkt != NULL);
uint32_t adv_desc_status_error = 0;
memset(&desc->wb, 0, sizeof(desc->wb));

desc->wb.upper.length = cpu_to_le16(length);
igb_build_rx_metadata_common(core, pkt, eop,
&desc->wb.upper.status_error,
&desc->wb.upper.vlan);

if (!eop) {
return;
}

net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);

if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) != 0) {
if (rss_info->enabled) {
desc->wb.lower.hi_dword.rss = cpu_to_le32(rss_info->hash);
rss_type = rss_info->type;
trace_igb_rx_metadata_rss(desc->wb.lower.hi_dword.rss, rss_type);
}
} else if (hasip4) {
adv_desc_status_error |= E1000_RXD_STAT_IPIDV;
desc->wb.lower.hi_dword.csum_ip.ip_id =
cpu_to_le16(net_rx_pkt_get_ip_id(pkt));
trace_e1000e_rx_metadata_ip_id(
desc->wb.lower.hi_dword.csum_ip.ip_id);
}

if (ts) {
adv_desc_status_error |= BIT(16);
}

igb_build_rx_metadata(core, pkt, pkt != NULL,
rss_info, etqf, ts,
&desc->wb.lower.lo_dword.pkt_info,
&desc->wb.lower.lo_dword.hdr_info,
&desc->wb.lower.hi_dword.rss,
&desc->wb.upper.status_error,
&desc->wb.lower.hi_dword.csum_ip.ip_id,
&desc->wb.upper.vlan);
pkt_type = igb_rx_desc_get_packet_type(core, pkt, etqf);
trace_e1000e_rx_metadata_pkt_type(pkt_type);
desc->wb.lower.lo_dword.pkt_info = cpu_to_le16(rss_type | (pkt_type << 4));
desc->wb.upper.status_error |= cpu_to_le32(adv_desc_status_error);
}

static inline void
Expand All @@ -1468,8 +1475,7 @@ igb_write_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
uint16_t etqf, bool ts, uint16_t length)
{
if (igb_rx_use_legacy_descriptor(core)) {
igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info,
etqf, ts, length);
igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, length);
} else {
igb_write_adv_rx_descr(core, &desc->adv, pkt, rss_info,
etqf, ts, length);
Expand Down
10 changes: 5 additions & 5 deletions hw/net/igb_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -692,11 +692,11 @@ union e1000_adv_rx_desc {

#define E1000_STATUS_NUM_VFS_SHIFT 14

#define E1000_ADVRXD_PKT_IP4 BIT(4)
#define E1000_ADVRXD_PKT_IP6 BIT(6)
#define E1000_ADVRXD_PKT_TCP BIT(8)
#define E1000_ADVRXD_PKT_UDP BIT(9)
#define E1000_ADVRXD_PKT_SCTP BIT(10)
#define E1000_ADVRXD_PKT_IP4 BIT(0)
#define E1000_ADVRXD_PKT_IP6 BIT(2)
#define E1000_ADVRXD_PKT_TCP BIT(4)
#define E1000_ADVRXD_PKT_UDP BIT(5)
#define E1000_ADVRXD_PKT_SCTP BIT(6)

static inline uint8_t igb_ivar_entry_rx(uint8_t i)
{
Expand Down
4 changes: 3 additions & 1 deletion hw/net/trace-events
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ igb_link_set_ext_params(bool asd_check, bool speed_select_bypass, bool pfrstd) "
igb_rx_desc_buff_size(uint32_t b) "buffer size: %u"
igb_rx_desc_buff_write(uint64_t addr, uint16_t offset, const void* source, uint32_t len) "addr: 0x%"PRIx64", offset: %u, from: %p, length: %u"

igb_rx_metadata_rss(uint32_t rss) "RSS data: 0x%X"
igb_rx_metadata_rss(uint32_t rss, uint16_t rss_pkt_type) "RSS data: rss: 0x%X, rss_pkt_type: 0x%X"

igb_irq_icr_clear_gpie_nsicr(void) "Clearing ICR on read due to GPIE.NSICR enabled"
igb_irq_set_iam(uint32_t icr) "Update IAM: 0x%x"
Expand All @@ -295,6 +295,8 @@ igb_irq_eitr_set(uint32_t eitr_num, uint32_t val) "EITR[%u] = 0x%x"
igb_set_pfmailbox(uint32_t vf_num, uint32_t val) "PFMailbox[%d]: 0x%x"
igb_set_vfmailbox(uint32_t vf_num, uint32_t val) "VFMailbox[%d]: 0x%x"

igb_wrn_rx_desc_modes_not_supp(int desc_type) "Not supported descriptor type: %d"

# igbvf.c
igbvf_wrn_io_addr_unknown(uint64_t addr) "IO unknown register 0x%"PRIx64

Expand Down

0 comments on commit ec82ad7

Please sign in to comment.