nfp: add CHECKSUM_COMPLETE support
authorJakub Kicinski <jakub.kicinski@netronome.com>
Tue, 16 May 2017 00:55:20 +0000 (17:55 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 16 May 2017 16:59:03 +0000 (12:59 -0400)
Introduce NFP_NET_CFG_CTRL_CSUM_COMPLETE capability and implement parsing
of CHECKSUM_COMPLETE metadata.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Edwin Peer <edwin.peer@netronome.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/nfp_net.h
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h

index c6b7141dc50d163a3714106f3bd521dbabcb4098..acd9811d08d149858db1ecd495697a3976024b3c 100644 (file)
@@ -292,9 +292,11 @@ struct nfp_net_rx_desc {
 #define NFP_NET_META_FIELD_MASK GENMASK(NFP_NET_META_FIELD_SIZE - 1, 0)
 
 struct nfp_meta_parsed {
-       u32 hash_type;
+       u8 hash_type;
+       u8 csum_type;
        u32 hash;
        u32 mark;
+       __wsum csum;
 };
 
 struct nfp_net_rx_hash {
index cc5a2eaef1560860e96d7e52240efa82d294da7d..d640b3331741f78bec7c7d10811bc7d28aa849ba 100644 (file)
@@ -1354,17 +1354,28 @@ static int nfp_net_rx_csum_has_errors(u16 flags)
  * @dp:  NFP Net data path struct
  * @r_vec: per-ring structure
  * @rxd: Pointer to RX descriptor
+ * @meta: Parsed metadata prepend
  * @skb: Pointer to SKB
  */
 static void nfp_net_rx_csum(struct nfp_net_dp *dp,
                            struct nfp_net_r_vector *r_vec,
-                           struct nfp_net_rx_desc *rxd, struct sk_buff *skb)
+                           struct nfp_net_rx_desc *rxd,
+                           struct nfp_meta_parsed *meta, struct sk_buff *skb)
 {
        skb_checksum_none_assert(skb);
 
        if (!(dp->netdev->features & NETIF_F_RXCSUM))
                return;
 
+       if (meta->csum_type) {
+               skb->ip_summed = meta->csum_type;
+               skb->csum = meta->csum;
+               u64_stats_update_begin(&r_vec->rx_sync);
+               r_vec->hw_csum_rx_ok++;
+               u64_stats_update_end(&r_vec->rx_sync);
+               return;
+       }
+
        if (nfp_net_rx_csum_has_errors(le16_to_cpu(rxd->rxd.flags))) {
                u64_stats_update_begin(&r_vec->rx_sync);
                r_vec->hw_csum_rx_error++;
@@ -1449,6 +1460,12 @@ nfp_net_parse_meta(struct net_device *netdev, struct nfp_meta_parsed *meta,
                        meta->mark = get_unaligned_be32(data);
                        data += 4;
                        break;
+               case NFP_NET_META_CSUM:
+                       meta->csum_type = CHECKSUM_COMPLETE;
+                       meta->csum =
+                               (__force __wsum)__get_unaligned_cpu32(data);
+                       data += 4;
+                       break;
                default:
                        return NULL;
                }
@@ -1712,7 +1729,7 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
                skb_record_rx_queue(skb, rx_ring->idx);
                skb->protocol = eth_type_trans(skb, dp->netdev);
 
-               nfp_net_rx_csum(dp, r_vec, rxd, skb);
+               nfp_net_rx_csum(dp, r_vec, rxd, &meta, skb);
 
                if (rxd->rxd.flags & PCIE_DESC_RX_VLAN)
                        __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
@@ -2712,9 +2729,9 @@ static int nfp_net_set_features(struct net_device *netdev,
 
        if (changed & NETIF_F_RXCSUM) {
                if (features & NETIF_F_RXCSUM)
-                       new_ctrl |= NFP_NET_CFG_CTRL_RXCSUM;
+                       new_ctrl |= nn->cap & NFP_NET_CFG_CTRL_RXCSUM_ANY;
                else
-                       new_ctrl &= ~NFP_NET_CFG_CTRL_RXCSUM;
+                       new_ctrl &= ~NFP_NET_CFG_CTRL_RXCSUM_ANY;
        }
 
        if (changed & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) {
@@ -3035,7 +3052,7 @@ void nfp_net_info(struct nfp_net *nn)
                nn->fw_ver.resv, nn->fw_ver.class,
                nn->fw_ver.major, nn->fw_ver.minor,
                nn->max_mtu);
-       nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+       nn_info(nn, "CAP: %#x %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
                nn->cap,
                nn->cap & NFP_NET_CFG_CTRL_PROMISC  ? "PROMISC "  : "",
                nn->cap & NFP_NET_CFG_CTRL_L2BC     ? "L2BCFILT " : "",
@@ -3055,7 +3072,9 @@ void nfp_net_info(struct nfp_net *nn)
                nn->cap & NFP_NET_CFG_CTRL_IRQMOD   ? "IRQMOD "   : "",
                nn->cap & NFP_NET_CFG_CTRL_VXLAN    ? "VXLAN "    : "",
                nn->cap & NFP_NET_CFG_CTRL_NVGRE    ? "NVGRE "    : "",
-               nfp_net_ebpf_capable(nn)            ? "BPF "      : "");
+               nfp_net_ebpf_capable(nn)            ? "BPF "      : "",
+               nn->cap & NFP_NET_CFG_CTRL_CSUM_COMPLETE ?
+                                                     "RXCSUM_COMPLETE " : "");
 }
 
 /**
@@ -3246,9 +3265,9 @@ int nfp_net_netdev_init(struct net_device *netdev)
         * supported.  By default we enable most features.
         */
        netdev->hw_features = NETIF_F_HIGHDMA;
-       if (nn->cap & NFP_NET_CFG_CTRL_RXCSUM) {
+       if (nn->cap & NFP_NET_CFG_CTRL_RXCSUM_ANY) {
                netdev->hw_features |= NETIF_F_RXCSUM;
-               nn->dp.ctrl |= NFP_NET_CFG_CTRL_RXCSUM;
+               nn->dp.ctrl |= nn->cap & NFP_NET_CFG_CTRL_RXCSUM_ANY;
        }
        if (nn->cap & NFP_NET_CFG_CTRL_TXCSUM) {
                netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
index a049c5d6839dc1404355b5f706d140e837e941a3..df75b8dc361768f18a8f1d2a1c9a2525753deb96 100644 (file)
@@ -71,6 +71,7 @@
 #define NFP_NET_META_FIELD_SIZE                4
 #define NFP_NET_META_HASH              1 /* next field carries hash type */
 #define NFP_NET_META_MARK              2
+#define NFP_NET_META_CSUM              6 /* checksum complete type */
 
 /**
  * Hash type pre-pended when a RSS hash was computed
 #define   NFP_NET_CFG_CTRL_BPF           (0x1 << 27) /* BPF offload capable */
 #define   NFP_NET_CFG_CTRL_LSO2                  (0x1 << 28) /* LSO/TSO (version 2) */
 #define   NFP_NET_CFG_CTRL_RSS2                  (0x1 << 29) /* RSS (version 2) */
+#define   NFP_NET_CFG_CTRL_CSUM_COMPLETE  (0x1 << 30) /* Checksum complete */
 
 #define NFP_NET_CFG_CTRL_LSO_ANY       (NFP_NET_CFG_CTRL_LSO | \
                                         NFP_NET_CFG_CTRL_LSO2)
 #define NFP_NET_CFG_CTRL_RSS_ANY       (NFP_NET_CFG_CTRL_RSS | \
                                         NFP_NET_CFG_CTRL_RSS2)
-#define NFP_NET_CFG_CTRL_CHAIN_META    NFP_NET_CFG_CTRL_RSS2
+#define NFP_NET_CFG_CTRL_RXCSUM_ANY    (NFP_NET_CFG_CTRL_RXCSUM | \
+                                        NFP_NET_CFG_CTRL_CSUM_COMPLETE)
+#define NFP_NET_CFG_CTRL_CHAIN_META    (NFP_NET_CFG_CTRL_RSS2 | \
+                                        NFP_NET_CFG_CTRL_CSUM_COMPLETE)
 
 #define NFP_NET_CFG_UPDATE              0x0004
 #define   NFP_NET_CFG_UPDATE_GEN          (0x1 <<  0) /* General update */