@@ -86,6 +86,7 @@ enum {
NETIF_F_HW_MACSEC_BIT, /* Offload MACsec operations */
NETIF_F_GRO_UDP_FWD_BIT, /* Allow UDP GRO for forwarding */
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
@@ -161,6 +162,7 @@ enum {
#define NETIF_F_HW_MACSEC __NETIF_F(HW_MACSEC)
#define NETIF_F_GRO_UDP_FWD __NETIF_F(GRO_UDP_FWD)
#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.
*/
@@ -1943,7 +1943,7 @@ struct net_device {
const struct tlsdev_ops *tlsdev_ops;
#endif
-#ifdef CONFIG_TCP_DDP
+#if IS_ENABLED(CONFIG_TCP_DDP) || IS_ENABLED(CONFIG_TCP_DDP_CRC)
const struct tcp_ddp_dev_ops *tcp_ddp_ops;
#endif
@@ -861,7 +861,7 @@ struct sk_buff {
#ifdef CONFIG_TLS_DEVICE
__u8 decrypted:1;
#endif
-#ifdef CONFIG_TCP_DDP
+#if defined(CONFIG_TCP_DDP) || defined(CONFIG_TCP_DDP_CRC)
__u8 ddp_crc:1;
#endif
@@ -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
@@ -70,6 +70,7 @@ const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
[NETIF_F_HW_MACSEC_BIT] = "macsec-hw-offload",
[NETIF_F_GRO_UDP_FWD_BIT] = "rx-udp-gro-forwarding",
[NETIF_F_HW_TCP_DDP_BIT] = "tcp-ddp-offload",
+ [NETIF_F_HW_TCP_DDP_CRC_RX_BIT] = "tcp-ddp-crc-rx-offload",
};
const char
@@ -5150,7 +5150,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, struct rb_root *root,
#ifdef CONFIG_TLS_DEVICE
nskb->decrypted = skb->decrypted;
#endif
-#ifdef CONFIG_TCP_DDP
+#if defined(CONFIG_TCP_DDP) || defined(CONFIG_TCP_DDP_CRC)
nskb->ddp_crc = skb->ddp_crc;
#endif
TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start;
@@ -5186,7 +5186,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list, struct rb_root *root,
if (skb->decrypted != nskb->decrypted)
goto end;
#endif
-#ifdef CONFIG_TCP_DDP
+#if defined(CONFIG_TCP_DDP) || defined(CONFIG_TCP_DDP_CRC)
if (skb->ddp_crc != nskb->ddp_crc)
goto end;
@@ -1811,7 +1811,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
#ifdef CONFIG_TLS_DEVICE
tail->decrypted != skb->decrypted ||
#endif
-#ifdef CONFIG_TCP_DDP
+#if defined(CONFIG_TCP_DDP) || defined(CONFIG_TCP_DDP_CRC)
tail->ddp_crc != skb->ddp_crc ||
#endif
thtail->doff != th->doff ||
@@ -262,7 +262,7 @@ 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
+#if defined(CONFIG_TCP_DDP) || defined(CONFIG_TCP_DDP_CRC)
flush |= p->ddp_crc ^ skb->ddp_crc;
#endif