diff options
| -rw-r--r-- | core/dp/txrx/ol_tx_desc.c | 47 | ||||
| -rw-r--r-- | core/dp/txrx/ol_tx_desc.h | 24 | ||||
| -rw-r--r-- | core/dp/txrx/ol_tx_send.c | 40 |
3 files changed, 72 insertions, 39 deletions
diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c index 08294827a010..c3f39316ae13 100644 --- a/core/dp/txrx/ol_tx_desc.c +++ b/core/dp/txrx/ol_tx_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,6 +33,7 @@ #include <ol_txrx_encap.h> /* OL_TX_RESTORE_HDR, etc */ #endif #include <ol_txrx.h> +#include <utils_api.h> #ifdef QCA_SUPPORT_TXDESC_SANITY_CHECKS static inline void ol_tx_desc_sanity_checks(struct ol_txrx_pdev_t *pdev, @@ -1003,4 +1004,48 @@ void ol_tso_num_seg_free(struct ol_txrx_pdev_t *pdev, pdev->tso_num_seg_pool.num_free++; qdf_spin_unlock_bh(&pdev->tso_num_seg_pool.tso_num_seg_mutex); } + +bool collect_tso_frags(struct ol_txrx_pdev_t *pdev, + struct qdf_tso_seg_elem_t *tso_seg, + qdf_nbuf_t netbuf) +{ + uint8_t frag_cnt, num_frags = 0; + int frag_len = 0; + uint32_t tcp_seq_num; + uint16_t ip_len; + + qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex); + + if (tso_seg->seg.num_frags > 0) + num_frags = tso_seg->seg.num_frags - 1; + + /*Num of frags in a tso seg cannot be less than 2 */ + if (num_frags < 1) { + qdf_print("ERROR: num of frags in tso segment is %d\n", + (num_frags + 1)); + qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex); + return false; + } + + tcp_seq_num = tso_seg->seg.tso_flags.tcp_seq_num; + tcp_seq_num = ani_cpu_to_be32(tcp_seq_num); + + ip_len = tso_seg->seg.tso_flags.ip_len; + ip_len = ani_cpu_to_be16(ip_len); + + for (frag_cnt = 0; frag_cnt < num_frags; frag_cnt++) { + qdf_mem_copy(qdf_nbuf_data(netbuf) + frag_len, + tso_seg->seg.tso_frags[frag_cnt].vaddr, + tso_seg->seg.tso_frags[frag_cnt].length); + frag_len += tso_seg->seg.tso_frags[frag_cnt].length; + } + + qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex); + + qdf_mem_copy((qdf_nbuf_data(netbuf) + IPV4_PKT_LEN_OFFSET), + &ip_len, sizeof(ip_len)); + qdf_mem_copy((qdf_nbuf_data(netbuf) + IPV4_TCP_SEQ_NUM_OFFSET), + &tcp_seq_num, sizeof(tcp_seq_num)); + return true; +} #endif diff --git a/core/dp/txrx/ol_tx_desc.h b/core/dp/txrx/ol_tx_desc.h index 6f920e4f0555..b29422ca0496 100644 --- a/core/dp/txrx/ol_tx_desc.h +++ b/core/dp/txrx/ol_tx_desc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2017, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -239,7 +239,20 @@ void ol_tso_num_seg_free(struct ol_txrx_pdev_t *pdev, void ol_free_remaining_tso_segs(ol_txrx_vdev_handle vdev, struct ol_txrx_msdu_info_t *msdu_info, bool is_tso_seg_mapping_done); - +/** + * collect_tso_frags() - collect all TSO fragments + * @pdev: The txrx pdev sending the data + * @tso_seg: The TSO segment element to be checked + * @netbuf: Target netbuf used to store all data from TSO fragments + * + * This function collects data contained in all TSO fragments related + * to a certain TSO segment element and put them into a single netbuf. + * + * Return: true if TSO fragments are really collected; false otherwise + */ +bool collect_tso_frags(struct ol_txrx_pdev_t *pdev, + struct qdf_tso_seg_elem_t *tso_seg, + qdf_nbuf_t netbuf); #else #define ol_tso_alloc_segment(pdev) /*no-op*/ #define ol_tso_free_segment(pdev, tso_seg) /*no-op*/ @@ -247,6 +260,13 @@ void ol_free_remaining_tso_segs(ol_txrx_vdev_handle vdev, #define ol_tso_num_seg_free(pdev, tso_num_seg) /*no-op*/ /*no-op*/ #define ol_free_remaining_tso_segs(vdev, msdu_info, is_tso_seg_mapping_done) +static inline +bool collect_tso_frags(struct ol_txrx_pdev_t *dev, + struct qdf_tso_seg_elem_t *tso_seg, + qdf_nbuf_t netbuf) +{ + return false; +} #endif /** diff --git a/core/dp/txrx/ol_tx_send.c b/core/dp/txrx/ol_tx_send.c index a1c433499fe2..66860a314865 100644 --- a/core/dp/txrx/ol_tx_send.c +++ b/core/dp/txrx/ol_tx_send.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -837,6 +837,7 @@ ol_tx_process_mon_tx_completion( int nbuf_len; struct qdf_tso_seg_elem_t *tso_seg = NULL; struct ol_mon_tx_status pkt_tx_status = {0}; + bool frags_collected = false; pkt_tx_status.status = status; pkt_tx_status.tx_retry_cnt = payload->tx_retry_cnt; @@ -881,44 +882,11 @@ ol_tx_process_mon_tx_completion( qdf_nbuf_put_tail(netbuf, nbuf_len); if (tx_desc->pkt_type == OL_TX_FRM_TSO) { - uint8_t frag_cnt, num_frags = 0; - int frag_len = 0; - uint32_t tcp_seq_num; - uint16_t ip_len; - - qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex); - - if (tso_seg->seg.num_frags > 0) - num_frags = tso_seg->seg.num_frags - 1; - - /*Num of frags in a tso seg cannot be less than 2 */ - if (num_frags < 1) { - qdf_print("ERROR: num of frags in tso segment is %d\n", - (num_frags + 1)); + frags_collected = collect_tso_frags(pdev, tso_seg, netbuf); + if (!frags_collected) { qdf_nbuf_free(netbuf); - qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex); return; } - - tcp_seq_num = tso_seg->seg.tso_flags.tcp_seq_num; - tcp_seq_num = ani_cpu_to_be32(tcp_seq_num); - - ip_len = tso_seg->seg.tso_flags.ip_len; - ip_len = ani_cpu_to_be16(ip_len); - - for (frag_cnt = 0; frag_cnt < num_frags; frag_cnt++) { - qdf_mem_copy(qdf_nbuf_data(netbuf) + frag_len, - tso_seg->seg.tso_frags[frag_cnt].vaddr, - tso_seg->seg.tso_frags[frag_cnt].length); - frag_len += tso_seg->seg.tso_frags[frag_cnt].length; - } - - qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex); - - qdf_mem_copy((qdf_nbuf_data(netbuf) + IPV4_PKT_LEN_OFFSET), - &ip_len, sizeof(ip_len)); - qdf_mem_copy((qdf_nbuf_data(netbuf) + IPV4_TCP_SEQ_NUM_OFFSET), - &tcp_seq_num, sizeof(tcp_seq_num)); } else { qdf_mem_copy(qdf_nbuf_data(netbuf), qdf_nbuf_data(tx_desc->netbuf), |
