diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 069bffe789..28f7cb95ea 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -3816,6 +3816,19 @@ static inline qdf_size_t qdf_nbuf_get_data_len(qdf_nbuf_t nbuf) return __qdf_nbuf_get_data_len(nbuf); } +/** + * qdf_nbuf_get_end_offset() - Return the size of the nbuf from + * head pointer to end pointer + * @nbuf: qdf_nbuf_t + * + * Return: size of network buffer from head pointer to end + * pointer + */ +static inline qdf_size_t qdf_nbuf_get_end_offset(qdf_nbuf_t nbuf) +{ + return __qdf_nbuf_get_end_offset(nbuf); +} + #ifdef NBUF_FRAG_MEMORY_DEBUG #define qdf_nbuf_move_frag_page_offset(f, i, o) \ @@ -4002,6 +4015,26 @@ void qdf_nbuf_release_track_lock(uint32_t index, QDF_NBUF_TRACK *qdf_nbuf_get_track_tbl(uint32_t index); #endif /* MEMORY_DEBUG */ +#ifdef CONFIG_WLAN_SYSFS_MEM_STATS +/** + * qdf_record_nbuf_nbytes() - add or subtract the size of the nbuf + * from the total skb mem and DP tx/rx skb mem + * @nbytes: number of bytes + * @dir: direction + * @is_mapped: is mapped or unmapped memory + * + * Return: none + */ +void qdf_record_nbuf_nbytes( + uint32_t nbytes, qdf_dma_dir_t dir, bool is_mapped); + +#else /* CONFIG_WLAN_SYSFS_MEM_STATS */ +static inline void qdf_record_nbuf_nbytes( + int nbytes, qdf_dma_dir_t dir, bool is_mapped) +{ +} +#endif /* CONFIG_WLAN_SYSFS_MEM_STATS */ + #ifdef CONFIG_NBUF_AP_PLATFORM #include #else diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index b9351baa92..5d34ad0736 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/qdf/linux/src/i_qdf_nbuf.h @@ -2236,6 +2236,19 @@ static inline void __qdf_nbuf_orphan(struct sk_buff *skb) return skb_orphan(skb); } +/** + * __qdf_nbuf_get_end_offset() - Return the size of the nbuf from + * head pointer to end pointer + * @nbuf: qdf_nbuf_t + * + * Return: size of network buffer from head pointer to end + * pointer + */ +static inline unsigned int __qdf_nbuf_get_end_offset(__qdf_nbuf_t nbuf) +{ + return skb_end_offset(nbuf); +} + #ifdef CONFIG_WLAN_SYSFS_MEM_STATS /** * __qdf_record_nbuf_nbytes() - add or subtract the size of the nbuf @@ -2311,7 +2324,8 @@ static inline QDF_STATUS __qdf_nbuf_map_nbytes_single( ret = dma_mapping_error(osdev->dev, paddr) ? QDF_STATUS_E_FAULT : QDF_STATUS_SUCCESS; if (QDF_IS_STATUS_SUCCESS(ret)) - __qdf_record_nbuf_nbytes(nbytes, dir, true); + __qdf_record_nbuf_nbytes(__qdf_nbuf_get_end_offset(buf), + dir, true); return ret; } #endif @@ -2339,7 +2353,8 @@ __qdf_nbuf_unmap_nbytes_single(qdf_device_t osdev, struct sk_buff *buf, qdf_dma_addr_t paddr = QDF_NBUF_CB_PADDR(buf); if (qdf_likely(paddr)) { - __qdf_record_nbuf_nbytes(nbytes, dir, false); + __qdf_record_nbuf_nbytes( + __qdf_nbuf_get_end_offset(buf), dir, false); dma_unmap_single(osdev->dev, paddr, nbytes, __qdf_dma_dir_to_os(dir)); return; diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index bd96da30bb..ef7d62adde 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -1088,7 +1088,7 @@ __qdf_nbuf_map_single(qdf_device_t osdev, qdf_nbuf_t buf, qdf_dma_dir_t dir) skb_end_pointer(buf) - buf->data, __qdf_dma_dir_to_os(dir)); __qdf_record_nbuf_nbytes( - __qdf_nbuf_get_data_len(buf), dir, true); + __qdf_nbuf_get_end_offset(buf), dir, true); return dma_mapping_error(osdev->dev, paddr) ? QDF_STATUS_E_FAILURE : QDF_STATUS_SUCCESS; @@ -1114,7 +1114,7 @@ void __qdf_nbuf_unmap_single(qdf_device_t osdev, qdf_nbuf_t buf, { if (QDF_NBUF_CB_PADDR(buf)) { __qdf_record_nbuf_nbytes( - __qdf_nbuf_get_data_len(buf), dir, false); + __qdf_nbuf_get_end_offset(buf), dir, false); dma_unmap_single(osdev->dev, QDF_NBUF_CB_PADDR(buf), skb_end_pointer(buf) - buf->data, __qdf_dma_dir_to_os(dir)); @@ -3211,6 +3211,66 @@ static uint8_t qdf_nbuf_adj_tso_frag(struct sk_buff *skb) } #endif +#ifdef CONFIG_WLAN_SYSFS_MEM_STATS +void qdf_record_nbuf_nbytes( + uint32_t nbytes, qdf_dma_dir_t dir, bool is_mapped) +{ + __qdf_record_nbuf_nbytes(nbytes, dir, is_mapped); +} + +qdf_export_symbol(qdf_record_nbuf_nbytes); + +#endif /* CONFIG_WLAN_SYSFS_MEM_STATS */ + +/** + * qdf_nbuf_tso_map_frag() - Map TSO segment + * @osdev: qdf device handle + * @tso_frag_vaddr: addr of tso fragment + * @nbytes: number of bytes + * @dir: direction + * + * Map TSO segment and for MCL record the amount of memory mapped + * + * Return: DMA address of mapped TSO fragment in success and + * NULL in case of DMA mapping failure + */ +static inline qdf_dma_addr_t qdf_nbuf_tso_map_frag( + qdf_device_t osdev, void *tso_frag_vaddr, + uint32_t nbytes, qdf_dma_dir_t dir) +{ + qdf_dma_addr_t tso_frag_paddr = 0; + + tso_frag_paddr = dma_map_single(osdev->dev, tso_frag_vaddr, + nbytes, __qdf_dma_dir_to_os(dir)); + if (unlikely(dma_mapping_error(osdev->dev, tso_frag_paddr))) { + qdf_err("DMA mapping error!"); + qdf_assert_always(0); + return 0; + } + qdf_record_nbuf_nbytes(nbytes, dir, true); + return tso_frag_paddr; +} + +/** + * qdf_nbuf_tso_unmap_frag() - Unmap TSO segment + * @osdev: qdf device handle + * @tso_frag_paddr: DMA addr of tso fragment + * @dir: direction + * @nbytes: number of bytes + * + * Unmap TSO segment and for MCL record the amount of memory mapped + * + * Return: None + */ +static inline void qdf_nbuf_tso_unmap_frag( + qdf_device_t osdev, qdf_dma_addr_t tso_frag_paddr, + uint32_t nbytes, qdf_dma_dir_t dir) +{ + qdf_record_nbuf_nbytes(nbytes, dir, false); + dma_unmap_single(osdev->dev, tso_frag_paddr, + nbytes, __qdf_dma_dir_to_os(dir)); +} + /** * __qdf_nbuf_get_tso_cmn_seg_info() - get TSO common * information @@ -3258,16 +3318,12 @@ static uint8_t __qdf_nbuf_get_tso_cmn_seg_info(qdf_device_t osdev, tso_info->eit_hdr = skb->data; tso_info->eit_hdr_len = (skb_transport_header(skb) - skb_mac_header(skb)) + tcp_hdrlen(skb); - tso_info->eit_hdr_dma_map_addr = dma_map_single(osdev->dev, - tso_info->eit_hdr, - tso_info->eit_hdr_len, - DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(osdev->dev, - tso_info->eit_hdr_dma_map_addr))) { - qdf_err("DMA mapping error!"); - qdf_assert(0); + tso_info->eit_hdr_dma_map_addr = qdf_nbuf_tso_map_frag( + osdev, tso_info->eit_hdr, + tso_info->eit_hdr_len, + QDF_DMA_TO_DEVICE); + if (qdf_unlikely(!tso_info->eit_hdr_dma_map_addr)) return 1; - } if (tso_info->ethproto == htons(ETH_P_IP)) { /* inlcude IPv4 header length for IPV4 (total length) */ @@ -3411,16 +3467,13 @@ uint32_t __qdf_nbuf_get_tso_info(qdf_device_t osdev, struct sk_buff *skb, tso_frag_len = min(skb_frag_len, tso_seg_size); if (tso_frag_len != 0) { - tso_frag_paddr = dma_map_single(osdev->dev, - tso_frag_vaddr, tso_frag_len, DMA_TO_DEVICE); + tso_frag_paddr = qdf_nbuf_tso_map_frag( + osdev, tso_frag_vaddr, tso_frag_len, + QDF_DMA_TO_DEVICE); + if (qdf_unlikely(!tso_frag_paddr)) + return 0; } - if (unlikely(dma_mapping_error(osdev->dev, - tso_frag_paddr))) { - qdf_err("DMA mapping error!"); - qdf_assert_always(0); - return 0; - } TSO_DEBUG("%s[%d] skb frag len %d tso frag len %d\n", __func__, __LINE__, skb_frag_len, tso_frag_len); num_seg = tso_info->num_segs; @@ -3545,17 +3598,12 @@ uint32_t __qdf_nbuf_get_tso_info(qdf_device_t osdev, struct sk_buff *skb, return 0; } - tso_frag_paddr = - dma_map_single(osdev->dev, - tso_frag_vaddr, - tso_frag_len, - DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(osdev->dev, - tso_frag_paddr))) { - qdf_err("DMA mapping error!"); - qdf_assert_always(0); + tso_frag_paddr = qdf_nbuf_tso_map_frag( + osdev, tso_frag_vaddr, + tso_frag_len, + QDF_DMA_TO_DEVICE); + if (qdf_unlikely(!tso_frag_paddr)) return 0; - } } TSO_DEBUG("%s tcp_seq_num: %u", __func__, curr_seg->seg.tso_flags.tcp_seq_num); @@ -3613,10 +3661,11 @@ void __qdf_nbuf_unmap_tso_segment(qdf_device_t osdev, qdf_assert(0); return; } - dma_unmap_single(osdev->dev, - tso_seg->seg.tso_frags[num_frags].paddr, - tso_seg->seg.tso_frags[num_frags].length, - __qdf_dma_dir_to_os(QDF_DMA_TO_DEVICE)); + qdf_nbuf_tso_unmap_frag( + osdev, + tso_seg->seg.tso_frags[num_frags].paddr, + tso_seg->seg.tso_frags[num_frags].length, + QDF_DMA_TO_DEVICE); tso_seg->seg.tso_frags[num_frags].paddr = 0; num_frags--; qdf_tso_seg_dbg_record(tso_seg, TSOSEG_LOC_UNMAPTSO); @@ -3630,10 +3679,10 @@ last_seg_free_first_frag: qdf_assert(0); return; } - dma_unmap_single(osdev->dev, - tso_seg->seg.tso_frags[0].paddr, - tso_seg->seg.tso_frags[0].length, - __qdf_dma_dir_to_os(QDF_DMA_TO_DEVICE)); + qdf_nbuf_tso_unmap_frag(osdev, + tso_seg->seg.tso_frags[0].paddr, + tso_seg->seg.tso_frags[0].length, + QDF_DMA_TO_DEVICE); tso_seg->seg.tso_frags[0].paddr = 0; qdf_tso_seg_dbg_record(tso_seg, TSOSEG_LOC_UNMAPLAST); }