@@ -85,6 +85,7 @@ enum {
NETIF_F_HW_MACSEC_BIT, /* Offload MACsec operations */
NETIF_F_HW_TCP_DDP_BIT, /* TCP direct data placement offload */
+ NETIF_F_HW_TCP_DDP_CRC_RX_BIT, /* TCP DDP CRC RX offload */
/*
* Add your fresh new feature above and remember to update
@@ -159,6 +160,7 @@ enum {
#define NETIF_F_GSO_FRAGLIST __NETIF_F(GSO_FRAGLIST)
#define NETIF_F_HW_MACSEC __NETIF_F(HW_MACSEC)
#define NETIF_F_HW_TCP_DDP __NETIF_F(HW_TCP_DDP)
+#define NETIF_F_HW_TCP_DDP_CRC_RX __NETIF_F(HW_TCP_DDP_CRC_RX)
/* Finds the next feature with the highest number of the range of start till 0.
*/
@@ -683,6 +683,7 @@ typedef unsigned char *sk_buff_data_t;
* CHECKSUM_UNNECESSARY (max 3)
* @dst_pending_confirm: need to confirm neighbour
* @decrypted: Decrypted SKB
+ * @ddp_crc: NIC is responsible for PDU's CRC computation and verification
* @napi_id: id of the NAPI struct this skb came from
* @sender_cpu: (aka @napi_id) source CPU in XPS
* @secmark: security marking
@@ -858,6 +859,10 @@ struct sk_buff {
#ifdef CONFIG_TLS_DEVICE
__u8 decrypted:1;
#endif
+#ifdef CONFIG_TCP_DDP_CRC
+ __u8 ddp_crc:1;
+#endif
+
#ifdef CONFIG_NET_SCHED
__u16 tc_index; /* traffic control index */
@@ -465,6 +465,14 @@ config TCP_DDP
NVMe-TCP/iSCSI, to request the NIC to place TCP payload data
of a command response directly into kernel pages.
+config TCP_DDP_CRC
+ bool "TCP direct data placement CRC offload"
+ default n
+ help
+ Direct Data Placement (DDP) CRC32C offload for TCP enables ULP, such as
+ NVMe-TCP/iSCSI, to request the NIC to calculate/verify the data digest
+ of commands as they go through the NIC. Thus avoiding the costly
+ per-byte overhead.
endif # if NET
@@ -69,6 +69,7 @@ const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
[NETIF_F_GRO_FRAGLIST_BIT] = "rx-gro-list",
[NETIF_F_HW_MACSEC_BIT] = "macsec-hw-offload",
[NETIF_F_HW_TCP_DDP_BIT] = "tcp-ddp-offload",
+ [NETIF_F_HW_TCP_DDP_CRC_RX_BIT] = "tcp-ddp-crc-rx-offload",
};
const char
@@ -5128,6 +5128,9 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, struct rb_root *root,
memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
#ifdef CONFIG_TLS_DEVICE
nskb->decrypted = skb->decrypted;
+#endif
+#ifdef CONFIG_TCP_DDP_CRC
+ nskb->ddp_crc = skb->ddp_crc;
#endif
TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start;
if (list)
@@ -5161,6 +5164,10 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, struct rb_root *root,
#ifdef CONFIG_TLS_DEVICE
if (skb->decrypted != nskb->decrypted)
goto end;
+#endif
+#ifdef CONFIG_TCP_DDP_CRC
+ if (skb->ddp_crc != nskb->ddp_crc)
+ goto end;
#endif
}
}
@@ -1807,6 +1807,9 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
TCP_SKB_CB(skb)->tcp_flags) & (TCPHDR_ECE | TCPHDR_CWR)) ||
#ifdef CONFIG_TLS_DEVICE
tail->decrypted != skb->decrypted ||
+#endif
+#ifdef CONFIG_TCP_DDP_CRC
+ tail->ddp_crc != skb->ddp_crc ||
#endif
thtail->doff != th->doff ||
memcmp(thtail + 1, th + 1, hdrlen - sizeof(*th)))
@@ -262,6 +262,9 @@ struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb)
#ifdef CONFIG_TLS_DEVICE
flush |= p->decrypted ^ skb->decrypted;
#endif
+#ifdef CONFIG_TCP_DDP_CRC
+ flush |= p->ddp_crc ^ skb->ddp_crc;
+#endif
if (flush || skb_gro_receive(p, skb)) {
mss = 1;