|
@@ -37,6 +37,7 @@
|
|
|
#include <net/busy_poll.h>
|
|
|
#include <net/ip6_checksum.h>
|
|
|
#include <net/page_pool.h>
|
|
|
+#include <net/inet_ecn.h>
|
|
|
#include "en.h"
|
|
|
#include "en_tc.h"
|
|
|
#include "eswitch.h"
|
|
@@ -690,12 +691,29 @@ static inline void mlx5e_skb_set_hash(struct mlx5_cqe64 *cqe,
|
|
|
skb_set_hash(skb, be32_to_cpu(cqe->rss_hash_result), ht);
|
|
|
}
|
|
|
|
|
|
-static inline bool is_last_ethertype_ip(struct sk_buff *skb, int *network_depth)
|
|
|
+static inline bool is_last_ethertype_ip(struct sk_buff *skb, int *network_depth,
|
|
|
+ __be16 *proto)
|
|
|
{
|
|
|
- __be16 ethertype = ((struct ethhdr *)skb->data)->h_proto;
|
|
|
+ *proto = ((struct ethhdr *)skb->data)->h_proto;
|
|
|
+ *proto = __vlan_get_protocol(skb, *proto, network_depth);
|
|
|
+ return (*proto == htons(ETH_P_IP) || *proto == htons(ETH_P_IPV6));
|
|
|
+}
|
|
|
+
|
|
|
+static inline void mlx5e_enable_ecn(struct mlx5e_rq *rq, struct sk_buff *skb)
|
|
|
+{
|
|
|
+ int network_depth = 0;
|
|
|
+ __be16 proto;
|
|
|
+ void *ip;
|
|
|
+ int rc;
|
|
|
|
|
|
- ethertype = __vlan_get_protocol(skb, ethertype, network_depth);
|
|
|
- return (ethertype == htons(ETH_P_IP) || ethertype == htons(ETH_P_IPV6));
|
|
|
+ if (unlikely(!is_last_ethertype_ip(skb, &network_depth, &proto)))
|
|
|
+ return;
|
|
|
+
|
|
|
+ ip = skb->data + network_depth;
|
|
|
+ rc = ((proto == htons(ETH_P_IP)) ? IP_ECN_set_ce((struct iphdr *)ip) :
|
|
|
+ IP6_ECN_set_ce(skb, (struct ipv6hdr *)ip));
|
|
|
+
|
|
|
+ rq->stats->ecn_mark += !!rc;
|
|
|
}
|
|
|
|
|
|
static __be32 mlx5e_get_fcs(struct sk_buff *skb)
|
|
@@ -745,6 +763,7 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
|
|
|
{
|
|
|
struct mlx5e_rq_stats *stats = rq->stats;
|
|
|
int network_depth = 0;
|
|
|
+ __be16 proto;
|
|
|
|
|
|
if (unlikely(!(netdev->features & NETIF_F_RXCSUM)))
|
|
|
goto csum_none;
|
|
@@ -755,7 +774,7 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (likely(is_last_ethertype_ip(skb, &network_depth))) {
|
|
|
+ if (likely(is_last_ethertype_ip(skb, &network_depth, &proto))) {
|
|
|
skb->ip_summed = CHECKSUM_COMPLETE;
|
|
|
skb->csum = csum_unfold((__force __sum16)cqe->check_sum);
|
|
|
if (network_depth > ETH_HLEN)
|
|
@@ -790,6 +809,8 @@ csum_none:
|
|
|
stats->csum_none++;
|
|
|
}
|
|
|
|
|
|
+#define MLX5E_CE_BIT_MASK 0x80
|
|
|
+
|
|
|
static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
|
|
|
u32 cqe_bcnt,
|
|
|
struct mlx5e_rq *rq,
|
|
@@ -834,6 +855,10 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
|
|
|
skb->mark = be32_to_cpu(cqe->sop_drop_qpn) & MLX5E_TC_FLOW_ID_MASK;
|
|
|
|
|
|
mlx5e_handle_csum(netdev, cqe, rq, skb, !!lro_num_seg);
|
|
|
+ /* checking CE bit in cqe - MSB in ml_path field */
|
|
|
+ if (unlikely(cqe->ml_path & MLX5E_CE_BIT_MASK))
|
|
|
+ mlx5e_enable_ecn(rq, skb);
|
|
|
+
|
|
|
skb->protocol = eth_type_trans(skb, netdev);
|
|
|
}
|
|
|
|