diff options
author | Akihiko Odaki <akihiko.odaki@daynix.com> | 2023-05-23 11:43:28 +0900 |
---|---|---|
committer | Jason Wang <jasowang@redhat.com> | 2023-05-23 15:20:15 +0800 |
commit | f199b13bc113c46eaddcf9f375d13f1e400b4e35 (patch) | |
tree | f14f3367c05576ce18ed00d6e3cc9e2cbbd3f51a /hw/net | |
parent | 907209e3111dd62a553a19319b422ff8aba5b9c0 (diff) | |
download | qemu-f199b13bc113c46eaddcf9f375d13f1e400b4e35.zip qemu-f199b13bc113c46eaddcf9f375d13f1e400b4e35.tar.gz qemu-f199b13bc113c46eaddcf9f375d13f1e400b4e35.tar.bz2 |
igb: Implement Tx SCTP CSO
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')
-rw-r--r-- | hw/net/igb_core.c | 12 | ||||
-rw-r--r-- | hw/net/net_tx_pkt.c | 18 | ||||
-rw-r--r-- | hw/net/net_tx_pkt.h | 8 |
3 files changed, 33 insertions, 5 deletions
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c index 95d46d6..5eacf1c 100644 --- a/hw/net/igb_core.c +++ b/hw/net/igb_core.c @@ -440,8 +440,9 @@ igb_tx_insert_vlan(IGBCore *core, uint16_t qn, struct igb_tx *tx, static bool igb_setup_tx_offloads(IGBCore *core, struct igb_tx *tx) { + uint32_t idx = (tx->first_olinfo_status >> 4) & 1; + if (tx->first_cmd_type_len & E1000_ADVTXD_DCMD_TSE) { - uint32_t idx = (tx->first_olinfo_status >> 4) & 1; uint32_t mss = tx->ctx[idx].mss_l4len_idx >> E1000_ADVTXD_MSS_SHIFT; if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, mss)) { return false; @@ -452,10 +453,11 @@ igb_setup_tx_offloads(IGBCore *core, struct igb_tx *tx) return true; } - if (tx->first_olinfo_status & E1000_ADVTXD_POTS_TXSM) { - if (!net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0)) { - return false; - } + if ((tx->first_olinfo_status & E1000_ADVTXD_POTS_TXSM) && + !((tx->ctx[idx].type_tucmd_mlhl & E1000_ADVTXD_TUCMD_L4T_SCTP) ? + net_tx_pkt_update_sctp_checksum(tx->tx_pkt) : + net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0))) { + return false; } if (tx->first_olinfo_status & E1000_ADVTXD_POTS_IXSM) { diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c index af8f77a..2e5f58b 100644 --- a/hw/net/net_tx_pkt.c +++ b/hw/net/net_tx_pkt.c @@ -16,6 +16,7 @@ */ #include "qemu/osdep.h" +#include "qemu/crc32c.h" #include "net/eth.h" #include "net/checksum.h" #include "net/tap.h" @@ -135,6 +136,23 @@ void net_tx_pkt_update_ip_checksums(struct NetTxPkt *pkt) pkt->virt_hdr.csum_offset, &csum, sizeof(csum)); } +bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt) +{ + uint32_t csum = 0; + struct iovec *pl_start_frag = pkt->vec + NET_TX_PKT_PL_START_FRAG; + + if (iov_from_buf(pl_start_frag, pkt->payload_frags, 8, &csum, sizeof(csum)) < sizeof(csum)) { + return false; + } + + csum = cpu_to_le32(iov_crc32c(0xffffffff, pl_start_frag, pkt->payload_frags)); + if (iov_from_buf(pl_start_frag, pkt->payload_frags, 8, &csum, sizeof(csum)) < sizeof(csum)) { + return false; + } + + return true; +} + static void net_tx_pkt_calculate_hdr_len(struct NetTxPkt *pkt) { pkt->hdr_len = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len + diff --git a/hw/net/net_tx_pkt.h b/hw/net/net_tx_pkt.h index 4d7233e..0a716e7 100644 --- a/hw/net/net_tx_pkt.h +++ b/hw/net/net_tx_pkt.h @@ -117,6 +117,14 @@ void net_tx_pkt_update_ip_checksums(struct NetTxPkt *pkt); void net_tx_pkt_update_ip_hdr_checksum(struct NetTxPkt *pkt); /** + * Calculate the SCTP checksum. + * + * @pkt: packet + * + */ +bool net_tx_pkt_update_sctp_checksum(struct NetTxPkt *pkt); + +/** * get length of all populated data. * * @pkt: packet |