From: Chiqijun chiqijun@huawei.com
driver inclusion category: bugfix bugzilla: 4472
-----------------------------------------------------------------------
Hinic only supports csum offloading of vxlan/ipip tunnel packets, for unsupported tunnel packets csum offloading, use the skb_checksum_help to do csum calculation and increase statistics.
Signed-off-by: Chiqijun chiqijun@huawei.com Reviewed-by: Zengweiliang zengweiliang.zengweiliang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- .../net/ethernet/huawei/hinic/hinic_ethtool.c | 1 + drivers/net/ethernet/huawei/hinic/hinic_tx.c | 25 +++++++++++++------ drivers/net/ethernet/huawei/hinic/hinic_tx.h | 1 + 3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c index 1a745cd38afd..0b9ce861c981 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c @@ -141,6 +141,7 @@ static struct hinic_stats hinic_tx_queue_stats_extern[] = { HINIC_TXQ_STAT(map_cpy_frag_err), HINIC_TXQ_STAT(map_frag_err), HINIC_TXQ_STAT(frag_size_err), + HINIC_TXQ_STAT(unknown_tunnel_pkt), };/*lint -restore*/
#define HINIC_FUNC_STAT(_stat_item) { \ diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.c b/drivers/net/ethernet/huawei/hinic/hinic_tx.c index b242b7ddde04..b556132a72af 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_tx.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.c @@ -94,6 +94,7 @@ void hinic_txq_clean_stats(struct hinic_txq_stats *txq_stats) txq_stats->map_cpy_frag_err = 0; txq_stats->map_frag_err = 0; txq_stats->frag_size_err = 0; + txq_stats->unknown_tunnel_pkt = 0; u64_stats_update_end(&txq_stats->syncp); }
@@ -336,8 +337,8 @@ static void get_inner_l4_info(struct sk_buff *skb, union hinic_l4 *l4, } }
-static int hinic_tx_csum(struct hinic_sq_task *task, u32 *queue_info, - struct sk_buff *skb) +static int hinic_tx_csum(struct hinic_txq *txq, struct hinic_sq_task *task, + u32 *queue_info, struct sk_buff *skb) { union hinic_ip ip; union hinic_l4 l4; @@ -378,19 +379,28 @@ static int hinic_tx_csum(struct hinic_sq_task *task, u32 *queue_info, hinic_task_set_outter_l3(task, l3_type, skb_network_header_len(skb));
- if (l4_proto == IPPROTO_UDP || l4_proto == IPPROTO_GRE) { + switch (l4_proto) { + case IPPROTO_UDP: l4_tunnel_len = skb_inner_network_offset(skb) - skb_transport_offset(skb); ip.hdr = skb_inner_network_header(skb); l4.hdr = skb_inner_transport_header(skb); network_hdr_len = skb_inner_network_header_len(skb); - } else { + break; + case IPPROTO_IPIP: + case IPPROTO_IPV6: tunnel_type = NOT_TUNNEL; l4_tunnel_len = 0;
ip.hdr = skb_inner_network_header(skb); l4.hdr = skb_transport_header(skb); network_hdr_len = skb_network_header_len(skb); + break; + default: + TXQ_STATS_INC(txq, unknown_tunnel_pkt); + /* Unsupport tunnel packet, disable csum offload */ + skb_checksum_help(skb); + return 0; }
hinic_task_set_tunnel_l4(task, tunnel_type, l4_tunnel_len); @@ -494,7 +504,8 @@ static int hinic_tso(struct hinic_sq_task *task, u32 *queue_info, return 1; }
-static enum tx_offload_type hinic_tx_offload(struct sk_buff *skb, +static enum tx_offload_type hinic_tx_offload(struct hinic_txq *txq, + struct sk_buff *skb, struct hinic_sq_task *task, u32 *queue_info, u8 avd_flag) { @@ -513,7 +524,7 @@ static enum tx_offload_type hinic_tx_offload(struct sk_buff *skb, } else if (tso_cs_en) { offload |= TX_OFFLOAD_TSO; } else { - tso_cs_en = hinic_tx_csum(task, queue_info, skb); + tso_cs_en = hinic_tx_csum(txq, task, queue_info, skb); if (tso_cs_en) offload |= TX_OFFLOAD_CSUM; } @@ -721,7 +732,7 @@ static netdev_tx_t hinic_send_one_skb(struct sk_buff *skb,
__get_pkt_stats(tx_info, skb);
- offload = hinic_tx_offload(skb, &wqe->task, &queue_info, avd_flag); + offload = hinic_tx_offload(txq, skb, &wqe->task, &queue_info, avd_flag); if (unlikely(offload == TX_OFFLOAD_INVALID)) { hinic_return_sq_wqe(nic_dev->hwdev, q_id, wqebb_cnt, owner); TXQ_STATS_INC(txq, offload_cow_skb_err); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_tx.h b/drivers/net/ethernet/huawei/hinic/hinic_tx.h index 8d95019528f9..3e7ff1538b99 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_tx.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_tx.h @@ -43,6 +43,7 @@ struct hinic_txq_stats { u64 map_cpy_frag_err; u64 map_frag_err; u64 frag_size_err; + u64 unknown_tunnel_pkt;
struct u64_stats_sync syncp; };