net/mlx5e: Support RX CHECKSUM_COMPLETE
Only for packets with first ethertype set to IPv4/6 for now. Signed-off-by: Achiad Shochat <achiad@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
3c2d18ef22
Коммит
bbceefce9a
|
@ -94,6 +94,7 @@ static const char vport_strings[][ETH_GSTRING_LEN] = {
|
||||||
"lro_bytes",
|
"lro_bytes",
|
||||||
"rx_csum_good",
|
"rx_csum_good",
|
||||||
"rx_csum_none",
|
"rx_csum_none",
|
||||||
|
"rx_csum_sw",
|
||||||
"tx_csum_offload",
|
"tx_csum_offload",
|
||||||
"tx_queue_stopped",
|
"tx_queue_stopped",
|
||||||
"tx_queue_wake",
|
"tx_queue_wake",
|
||||||
|
@ -131,13 +132,14 @@ struct mlx5e_vport_stats {
|
||||||
u64 lro_bytes;
|
u64 lro_bytes;
|
||||||
u64 rx_csum_good;
|
u64 rx_csum_good;
|
||||||
u64 rx_csum_none;
|
u64 rx_csum_none;
|
||||||
|
u64 rx_csum_sw;
|
||||||
u64 tx_csum_offload;
|
u64 tx_csum_offload;
|
||||||
u64 tx_queue_stopped;
|
u64 tx_queue_stopped;
|
||||||
u64 tx_queue_wake;
|
u64 tx_queue_wake;
|
||||||
u64 tx_queue_dropped;
|
u64 tx_queue_dropped;
|
||||||
u64 rx_wqe_err;
|
u64 rx_wqe_err;
|
||||||
|
|
||||||
#define NUM_VPORT_COUNTERS 31
|
#define NUM_VPORT_COUNTERS 32
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char pport_strings[][ETH_GSTRING_LEN] = {
|
static const char pport_strings[][ETH_GSTRING_LEN] = {
|
||||||
|
@ -217,6 +219,7 @@ struct mlx5e_pport_stats {
|
||||||
static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
|
static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
|
||||||
"packets",
|
"packets",
|
||||||
"csum_none",
|
"csum_none",
|
||||||
|
"csum_sw",
|
||||||
"lro_packets",
|
"lro_packets",
|
||||||
"lro_bytes",
|
"lro_bytes",
|
||||||
"wqe_err"
|
"wqe_err"
|
||||||
|
@ -225,10 +228,11 @@ static const char rq_stats_strings[][ETH_GSTRING_LEN] = {
|
||||||
struct mlx5e_rq_stats {
|
struct mlx5e_rq_stats {
|
||||||
u64 packets;
|
u64 packets;
|
||||||
u64 csum_none;
|
u64 csum_none;
|
||||||
|
u64 csum_sw;
|
||||||
u64 lro_packets;
|
u64 lro_packets;
|
||||||
u64 lro_bytes;
|
u64 lro_bytes;
|
||||||
u64 wqe_err;
|
u64 wqe_err;
|
||||||
#define NUM_RQ_STATS 5
|
#define NUM_RQ_STATS 6
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char sq_stats_strings[][ETH_GSTRING_LEN] = {
|
static const char sq_stats_strings[][ETH_GSTRING_LEN] = {
|
||||||
|
|
|
@ -149,6 +149,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
|
||||||
s->lro_packets = 0;
|
s->lro_packets = 0;
|
||||||
s->lro_bytes = 0;
|
s->lro_bytes = 0;
|
||||||
s->rx_csum_none = 0;
|
s->rx_csum_none = 0;
|
||||||
|
s->rx_csum_sw = 0;
|
||||||
s->rx_wqe_err = 0;
|
s->rx_wqe_err = 0;
|
||||||
for (i = 0; i < priv->params.num_channels; i++) {
|
for (i = 0; i < priv->params.num_channels; i++) {
|
||||||
rq_stats = &priv->channel[i]->rq.stats;
|
rq_stats = &priv->channel[i]->rq.stats;
|
||||||
|
@ -156,6 +157,7 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
|
||||||
s->lro_packets += rq_stats->lro_packets;
|
s->lro_packets += rq_stats->lro_packets;
|
||||||
s->lro_bytes += rq_stats->lro_bytes;
|
s->lro_bytes += rq_stats->lro_bytes;
|
||||||
s->rx_csum_none += rq_stats->csum_none;
|
s->rx_csum_none += rq_stats->csum_none;
|
||||||
|
s->rx_csum_sw += rq_stats->csum_sw;
|
||||||
s->rx_wqe_err += rq_stats->wqe_err;
|
s->rx_wqe_err += rq_stats->wqe_err;
|
||||||
|
|
||||||
for (j = 0; j < priv->params.num_tc; j++) {
|
for (j = 0; j < priv->params.num_tc; j++) {
|
||||||
|
@ -241,7 +243,8 @@ void mlx5e_update_stats(struct mlx5e_priv *priv)
|
||||||
|
|
||||||
/* Update calculated offload counters */
|
/* Update calculated offload counters */
|
||||||
s->tx_csum_offload = s->tx_packets - tx_offload_none;
|
s->tx_csum_offload = s->tx_packets - tx_offload_none;
|
||||||
s->rx_csum_good = s->rx_packets - s->rx_csum_none;
|
s->rx_csum_good = s->rx_packets - s->rx_csum_none -
|
||||||
|
s->rx_csum_sw;
|
||||||
|
|
||||||
mlx5e_update_pport_counters(priv);
|
mlx5e_update_pport_counters(priv);
|
||||||
free_out:
|
free_out:
|
||||||
|
|
|
@ -151,6 +151,38 @@ static inline void mlx5e_skb_set_hash(struct mlx5_cqe64 *cqe,
|
||||||
skb_set_hash(skb, be32_to_cpu(cqe->rss_hash_result), ht);
|
skb_set_hash(skb, be32_to_cpu(cqe->rss_hash_result), ht);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool is_first_ethertype_ip(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
__be16 ethertype = ((struct ethhdr *)skb->data)->h_proto;
|
||||||
|
|
||||||
|
return (ethertype == htons(ETH_P_IP) || ethertype == htons(ETH_P_IPV6));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mlx5e_handle_csum(struct net_device *netdev,
|
||||||
|
struct mlx5_cqe64 *cqe,
|
||||||
|
struct mlx5e_rq *rq,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
if (unlikely(!(netdev->features & NETIF_F_RXCSUM)))
|
||||||
|
goto csum_none;
|
||||||
|
|
||||||
|
if (likely(cqe->hds_ip_ext & CQE_L4_OK)) {
|
||||||
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
|
} else if (is_first_ethertype_ip(skb)) {
|
||||||
|
skb->ip_summed = CHECKSUM_COMPLETE;
|
||||||
|
skb->csum = csum_unfold(cqe->check_sum);
|
||||||
|
rq->stats.csum_sw++;
|
||||||
|
} else {
|
||||||
|
goto csum_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
csum_none:
|
||||||
|
skb->ip_summed = CHECKSUM_NONE;
|
||||||
|
rq->stats.csum_none++;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
|
static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
|
||||||
struct mlx5e_rq *rq,
|
struct mlx5e_rq *rq,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
|
@ -169,15 +201,7 @@ static inline void mlx5e_build_rx_skb(struct mlx5_cqe64 *cqe,
|
||||||
rq->stats.lro_bytes += cqe_bcnt;
|
rq->stats.lro_bytes += cqe_bcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (likely(netdev->features & NETIF_F_RXCSUM) &&
|
mlx5e_handle_csum(netdev, cqe, rq, skb);
|
||||||
(cqe->hds_ip_ext & CQE_L2_OK) &&
|
|
||||||
(cqe->hds_ip_ext & CQE_L3_OK) &&
|
|
||||||
(cqe->hds_ip_ext & CQE_L4_OK)) {
|
|
||||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
||||||
} else {
|
|
||||||
skb->ip_summed = CHECKSUM_NONE;
|
|
||||||
rq->stats.csum_none++;
|
|
||||||
}
|
|
||||||
|
|
||||||
skb->protocol = eth_type_trans(skb, netdev);
|
skb->protocol = eth_type_trans(skb, netdev);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче