qcacmn: Enable TSO Stats for Lithium based products
Add support to account for TSO jumbo packets on the Tx path and print the statistics using dumpStats 3. Change-Id: I6cc446df5c84e3ac436d922935fcd559e0704ec5 CRs-Fixed: 2356244
This commit is contained in:

committed by
nshrivas

parent
2b07141773
commit
8a4812f7fc
@@ -1165,7 +1165,8 @@ struct cdp_peer_ops {
|
||||
* @stats:
|
||||
*/
|
||||
struct cdp_mob_stats_ops {
|
||||
void (*clear_stats)(uint16_t bitmap);
|
||||
QDF_STATUS
|
||||
(*clear_stats)(struct cdp_soc *soc, uint8_t bitmap);
|
||||
int (*stats)(uint8_t vdev_id, char *buffer, unsigned buf_len);
|
||||
};
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2017,2019 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
|
||||
@@ -25,22 +25,23 @@
|
||||
#define _CDP_TXRX_STATS_H_
|
||||
#include <cdp_txrx_ops.h>
|
||||
|
||||
static inline void
|
||||
cdp_clear_stats(ol_txrx_soc_handle soc, uint16_t bitmap)
|
||||
static inline QDF_STATUS
|
||||
cdp_clear_stats(ol_txrx_soc_handle soc, uint8_t bitmap)
|
||||
{
|
||||
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (!soc->ops->mob_stats_ops ||
|
||||
!soc->ops->mob_stats_ops->clear_stats)
|
||||
return;
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
soc->ops->mob_stats_ops->clear_stats(bitmap);
|
||||
return soc->ops->mob_stats_ops->clear_stats((struct cdp_soc *)soc,
|
||||
bitmap);
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
@@ -23,6 +23,11 @@
|
||||
*/
|
||||
#ifndef _CDP_TXRX_STATS_STRUCT_H_
|
||||
#define _CDP_TXRX_STATS_STRUCT_H_
|
||||
|
||||
#ifdef FEATURE_TSO_STATS
|
||||
#include <qdf_types.h>
|
||||
#endif /* FEATURE_TSO_STATS */
|
||||
|
||||
#define TXRX_STATS_LEVEL_OFF 0
|
||||
#define TXRX_STATS_LEVEL_BASIC 1
|
||||
#define TXRX_STATS_LEVEL_FULL 2
|
||||
@@ -171,6 +176,15 @@ enum cdp_ru_index {
|
||||
RU_996_INDEX,
|
||||
};
|
||||
|
||||
#ifdef FEATURE_TSO_STATS
|
||||
/* Number of TSO Packet Statistics captured */
|
||||
#define CDP_MAX_TSO_PACKETS 5
|
||||
/* Information for Number of Segments for a TSO Packet captured */
|
||||
#define CDP_MAX_TSO_SEGMENTS 2
|
||||
/* Information for Number of Fragments for a TSO Segment captured */
|
||||
#define CDP_MAX_TSO_FRAGMENTS 6
|
||||
#endif /* FEATURE_TSO_STATS */
|
||||
|
||||
/* Different Packet Types */
|
||||
enum cdp_packet_type {
|
||||
DOT11_A = 0,
|
||||
@@ -444,6 +458,68 @@ struct cdp_tx_pkt_info {
|
||||
uint32_t mpdu_tried;
|
||||
};
|
||||
|
||||
#ifdef FEATURE_TSO_STATS
|
||||
/**
|
||||
* struct cdp_tso_seg_histogram - Segment histogram for TCP Packets
|
||||
* @segs_1: packets with single segments
|
||||
* @segs_2_5: packets with 2-5 segments
|
||||
* @segs_6_10: packets with 6-10 segments
|
||||
* @segs_11_15: packets with 11-15 segments
|
||||
* @segs_16_20: packets with 16-20 segments
|
||||
* @segs_20_plus: packets with 20 plus segments
|
||||
*/
|
||||
struct cdp_tso_seg_histogram {
|
||||
uint64_t segs_1;
|
||||
uint64_t segs_2_5;
|
||||
uint64_t segs_6_10;
|
||||
uint64_t segs_11_15;
|
||||
uint64_t segs_16_20;
|
||||
uint64_t segs_20_plus;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cdp_tso_packet_info - Stats for TSO segments within a TSO packet
|
||||
* @tso_seg: TSO Segment information
|
||||
* @num_seg: Number of segments
|
||||
* @tso_packet_len: Size of the tso packet
|
||||
* @tso_seg_idx: segment number
|
||||
*/
|
||||
struct cdp_tso_packet_info {
|
||||
struct qdf_tso_seg_t tso_seg[CDP_MAX_TSO_SEGMENTS];
|
||||
uint8_t num_seg;
|
||||
size_t tso_packet_len;
|
||||
uint32_t tso_seg_idx;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cdp_tso_info - stats for tso packets
|
||||
* @tso_packet_info: TSO packet information
|
||||
*/
|
||||
struct cdp_tso_info {
|
||||
struct cdp_tso_packet_info tso_packet_info[CDP_MAX_TSO_PACKETS];
|
||||
};
|
||||
#endif /* FEATURE_TSO_STATS */
|
||||
|
||||
/**
|
||||
* struct cdp_tso_stats - TSO stats information
|
||||
* @num_tso_pkts: Total number of TSO Packets
|
||||
* @tso_comp: Total tso packet completions
|
||||
* @dropped_host: TSO packets dropped by host
|
||||
* @dropped_target: TSO packets_dropped by target
|
||||
* @tso_info: Per TSO packet counters
|
||||
* @seg_histogram: TSO histogram stats
|
||||
*/
|
||||
struct cdp_tso_stats {
|
||||
struct cdp_pkt_info num_tso_pkts;
|
||||
uint32_t tso_comp;
|
||||
struct cdp_pkt_info dropped_host;
|
||||
uint32_t dropped_target;
|
||||
#ifdef FEATURE_TSO_STATS
|
||||
struct cdp_tso_info tso_info;
|
||||
struct cdp_tso_seg_histogram seg_histogram;
|
||||
#endif /* FEATURE_TSO_STATS */
|
||||
};
|
||||
|
||||
/* struct cdp_tx_stats - tx stats
|
||||
* @cdp_pkt_info comp_pkt: Pkt Info for which completions were received
|
||||
* @cdp_pkt_info ucast: Unicast Packet Count
|
||||
@@ -771,15 +847,6 @@ struct cdp_tx_ingress_stats {
|
||||
uint32_t invalid_raw_pkt_datatype;
|
||||
} raw;
|
||||
|
||||
/* TSO packets info */
|
||||
struct {
|
||||
uint32_t num_seg;
|
||||
struct cdp_pkt_info tso_pkt;
|
||||
struct cdp_pkt_info non_tso_pkts;
|
||||
struct cdp_pkt_info dropped_host;
|
||||
uint32_t dropped_target;
|
||||
} tso;
|
||||
|
||||
/* Scatter Gather packet info */
|
||||
struct {
|
||||
struct cdp_pkt_info sg_pkt;
|
||||
@@ -821,17 +888,20 @@ struct cdp_tx_ingress_stats {
|
||||
uint32_t cce_classified;
|
||||
uint32_t cce_classified_raw;
|
||||
struct cdp_pkt_info sniffer_rcvd;
|
||||
struct cdp_tso_stats tso_stats;
|
||||
};
|
||||
|
||||
/* struct cdp_vdev_stats - vdev stats structure
|
||||
* @tx_i: ingress tx stats
|
||||
* @tx: cdp tx stats
|
||||
* @rx: cdp rx stats
|
||||
* @tso_stats: tso stats
|
||||
*/
|
||||
struct cdp_vdev_stats {
|
||||
struct cdp_tx_ingress_stats tx_i;
|
||||
struct cdp_tx_stats tx;
|
||||
struct cdp_rx_stats rx;
|
||||
struct cdp_tso_stats tso_stats;
|
||||
};
|
||||
|
||||
/* struct cdp_peer_stats - peer stats structure
|
||||
@@ -1381,6 +1451,8 @@ struct cdp_pdev_stats {
|
||||
uint32_t data_rx_ppdu;
|
||||
uint32_t data_users[OFDMA_NUM_USERS];
|
||||
} ul_ofdma;
|
||||
|
||||
struct cdp_tso_stats tso_stats;
|
||||
};
|
||||
|
||||
#ifdef QCA_ENH_V3_STATS_SUPPORT
|
||||
|
@@ -315,7 +315,6 @@ while (0)
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#else
|
||||
#define DP_HIST_INIT()
|
||||
#define DP_HIST_PACKET_COUNT_INC(_pdev_id)
|
||||
@@ -323,7 +322,134 @@ while (0)
|
||||
#define DP_RX_HISTOGRAM_UPDATE(_pdev, _p_cntrs)
|
||||
#define DP_RX_HIST_STATS_PER_PDEV()
|
||||
#define DP_TX_HIST_STATS_PER_PDEV()
|
||||
#endif
|
||||
#endif /* DISABLE_DP_STATS */
|
||||
|
||||
#ifdef FEATURE_TSO_STATS
|
||||
/**
|
||||
* dp_init_tso_stats() - Clear tso stats
|
||||
* @pdev: pdev handle
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline
|
||||
void dp_init_tso_stats(struct dp_pdev *pdev)
|
||||
{
|
||||
if (pdev) {
|
||||
qdf_mem_zero(&((pdev)->stats.tso_stats),
|
||||
sizeof((pdev)->stats.tso_stats));
|
||||
qdf_atomic_init(&pdev->tso_idx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_stats_tso_segment_histogram_update() - TSO Segment Histogram
|
||||
* @pdev: pdev handle
|
||||
* @_p_cntrs: number of tso segments for a tso packet
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_stats_tso_segment_histogram_update(struct dp_pdev *pdev,
|
||||
uint8_t _p_cntrs);
|
||||
|
||||
/**
|
||||
* dp_tso_segment_update() - Collect tso segment information
|
||||
* @pdev: pdev handle
|
||||
* @stats_idx: tso packet number
|
||||
* @idx: tso segment number
|
||||
* @seg: tso segment
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tso_segment_update(struct dp_pdev *pdev,
|
||||
uint32_t stats_idx,
|
||||
uint8_t idx,
|
||||
struct qdf_tso_seg_t seg);
|
||||
|
||||
/**
|
||||
* dp_tso_packet_update() - TSO Packet information
|
||||
* @pdev: pdev handle
|
||||
* @stats_idx: tso packet number
|
||||
* @msdu: nbuf handle
|
||||
* @num_segs: tso segments
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tso_packet_update(struct dp_pdev *pdev, uint32_t stats_idx,
|
||||
qdf_nbuf_t msdu, uint16_t num_segs);
|
||||
|
||||
/**
|
||||
* dp_tso_segment_stats_update() - TSO Segment stats
|
||||
* @pdev: pdev handle
|
||||
* @stats_seg: tso segment list
|
||||
* @stats_idx: tso packet number
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tso_segment_stats_update(struct dp_pdev *pdev,
|
||||
struct qdf_tso_seg_elem_t *stats_seg,
|
||||
uint32_t stats_idx);
|
||||
|
||||
/**
|
||||
* dp_print_tso_stats() - dump tso statistics
|
||||
* @soc:soc handle
|
||||
* @level: verbosity level
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_print_tso_stats(struct dp_soc *soc,
|
||||
enum qdf_stats_verbosity_level level);
|
||||
|
||||
/**
|
||||
* dp_txrx_clear_tso_stats() - clear tso stats
|
||||
* @soc: soc handle
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_txrx_clear_tso_stats(struct dp_soc *soc);
|
||||
#else
|
||||
static inline
|
||||
void dp_init_tso_stats(struct dp_pdev *pdev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
void dp_stats_tso_segment_histogram_update(struct dp_pdev *pdev,
|
||||
uint8_t _p_cntrs)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
void dp_tso_segment_update(struct dp_pdev *pdev,
|
||||
uint32_t stats_idx,
|
||||
uint32_t idx,
|
||||
struct qdf_tso_seg_t seg)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
void dp_tso_packet_update(struct dp_pdev *pdev, uint32_t stats_idx,
|
||||
qdf_nbuf_t msdu, uint16_t num_segs)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
void dp_tso_segment_stats_update(struct dp_pdev *pdev,
|
||||
struct qdf_tso_seg_elem_t *stats_seg,
|
||||
uint32_t stats_idx)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
void dp_print_tso_stats(struct dp_soc *soc,
|
||||
enum qdf_stats_verbosity_level level)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
void dp_txrx_clear_tso_stats(struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
#endif /* FEATURE_TSO_STATS */
|
||||
|
||||
#define DP_HTT_T2H_HP_PIPE 5
|
||||
static inline void dp_update_pdev_stats(struct dp_pdev *tgtobj,
|
||||
@@ -478,9 +604,6 @@ static inline void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj,
|
||||
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.inspect_pkts);
|
||||
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.raw.raw_pkt);
|
||||
DP_STATS_AGGR(tgtobj, srcobj, tx_i.raw.dma_map_error);
|
||||
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.tso.tso_pkt);
|
||||
DP_STATS_AGGR(tgtobj, srcobj, tx_i.tso.dropped_host.num);
|
||||
DP_STATS_AGGR(tgtobj, srcobj, tx_i.tso.dropped_target);
|
||||
DP_STATS_AGGR(tgtobj, srcobj, tx_i.sg.dropped_host.num);
|
||||
DP_STATS_AGGR(tgtobj, srcobj, tx_i.sg.dropped_target);
|
||||
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.sg.sg_pkt);
|
||||
@@ -511,8 +634,6 @@ static inline void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj,
|
||||
tgtobj->stats.tx_i.dropped.desc_na.num +
|
||||
tgtobj->stats.tx_i.dropped.res_full;
|
||||
|
||||
tgtobj->stats.tx_i.tso.num_seg =
|
||||
srcobj->stats.tx_i.tso.num_seg;
|
||||
}
|
||||
|
||||
static inline void dp_update_vdev_stats(struct cdp_vdev_stats *tgtobj,
|
||||
|
@@ -3598,6 +3598,8 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
|
||||
|
||||
pdev->num_tx_allowed = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
|
||||
|
||||
dp_init_tso_stats(pdev);
|
||||
|
||||
if (dp_htt_ppdu_stats_attach(pdev) != QDF_STATUS_SUCCESS)
|
||||
goto fail1;
|
||||
|
||||
@@ -8328,7 +8330,7 @@ static QDF_STATUS dp_txrx_dump_stats(void *psoc, uint16_t value,
|
||||
break;
|
||||
|
||||
case CDP_TXRX_TSO_STATS:
|
||||
/* TODO: NOT IMPLEMENTED */
|
||||
dp_print_tso_stats(soc, level);
|
||||
break;
|
||||
|
||||
case CDP_DUMP_TX_FLOW_POOL_INFO:
|
||||
@@ -8353,6 +8355,38 @@ static QDF_STATUS dp_txrx_dump_stats(void *psoc, uint16_t value,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_txrx_clear_dump_stats() - clear dumpStats
|
||||
* @soc- soc handle
|
||||
* @value - stats option
|
||||
*
|
||||
* Return: 0 - Success, non-zero - failure
|
||||
*/
|
||||
static
|
||||
QDF_STATUS dp_txrx_clear_dump_stats(struct cdp_soc *psoc, uint8_t value)
|
||||
{
|
||||
struct dp_soc *soc =
|
||||
(struct dp_soc *)psoc;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
if (!soc) {
|
||||
dp_err("%s: soc is NULL", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
switch (value) {
|
||||
case CDP_TXRX_TSO_STATS:
|
||||
dp_txrx_clear_tso_stats(soc);
|
||||
break;
|
||||
|
||||
default:
|
||||
status = QDF_STATUS_E_INVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||
/**
|
||||
* dp_update_flow_control_parameters() - API to store datapath
|
||||
@@ -9531,7 +9565,7 @@ static struct cdp_ocb_ops dp_ops_ocb = {
|
||||
};
|
||||
|
||||
static struct cdp_mob_stats_ops dp_ops_mob_stats = {
|
||||
/* WIFI 3.0 DP NOT IMPLEMENTED YET */
|
||||
.clear_stats = dp_txrx_clear_dump_stats,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -4624,6 +4624,62 @@ dp_print_ring_stat_from_hal(struct dp_soc *soc, struct dp_srng *srng,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FEATURE_TSO_STATS
|
||||
/**
|
||||
* dp_print_tso_seg_stats - tso segment stats
|
||||
* @pdev: pdev handle
|
||||
* @id: tso packet id
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void dp_print_tso_seg_stats(struct dp_pdev *pdev, uint32_t id)
|
||||
{
|
||||
uint8_t num_seg;
|
||||
uint32_t segid;
|
||||
|
||||
/* TSO LEVEL 2 - SEGMENT INFO */
|
||||
num_seg = pdev->stats.tso_stats.tso_info.tso_packet_info[id].num_seg;
|
||||
for (segid = 0; segid < CDP_MAX_TSO_SEGMENTS && segid < num_seg; segid++) {
|
||||
DP_PRINT_STATS(
|
||||
"Segment id:[%u] fragments: %u | Segment Length %u | TCP Seq no.: %u | ip_id: %u",
|
||||
segid,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].num_frags,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].total_len,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.tcp_seq_num,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.ip_id);
|
||||
DP_PRINT_STATS(
|
||||
"fin: %u syn: %u rst: %u psh: %u ack: %u urg: %u ece: %u cwr: %u ns: %u",
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.fin,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.syn,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.rst,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.psh,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.ack,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.urg,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.ece,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.cwr,
|
||||
pdev->stats.tso_stats.tso_info.tso_packet_info[id]
|
||||
.tso_seg[segid].tso_flags.ns);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
void dp_print_tso_seg_stats(struct dp_pdev *pdev, uint32_t id)
|
||||
{
|
||||
}
|
||||
#endif /* FEATURE_TSO_STATS */
|
||||
|
||||
/**
|
||||
* dp_print_mon_ring_stats_from_hal() - Print stat for monitor rings based
|
||||
* on target
|
||||
@@ -5369,15 +5425,6 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev)
|
||||
pdev->stats.tx_i.sg.dropped_host.num);
|
||||
DP_PRINT_STATS(" Dropped By Target = %d",
|
||||
pdev->stats.tx_i.sg.dropped_target);
|
||||
DP_PRINT_STATS("TSO:");
|
||||
DP_PRINT_STATS(" Number of Segments = %d",
|
||||
pdev->stats.tx_i.tso.num_seg);
|
||||
DP_PRINT_STATS(" Packets = %d",
|
||||
pdev->stats.tx_i.tso.tso_pkt.num);
|
||||
DP_PRINT_STATS(" Bytes = %llu",
|
||||
pdev->stats.tx_i.tso.tso_pkt.bytes);
|
||||
DP_PRINT_STATS(" Dropped By Host = %d",
|
||||
pdev->stats.tx_i.tso.dropped_host.num);
|
||||
DP_PRINT_STATS("Mcast Enhancement:");
|
||||
DP_PRINT_STATS(" Packets = %d",
|
||||
pdev->stats.tx_i.mcast_en.mcast_pkt.num);
|
||||
@@ -5712,3 +5759,161 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
|
||||
DP_PRINT_STATS("REO Error(0-14):%s", reo_error);
|
||||
}
|
||||
|
||||
#ifdef FEATURE_TSO_STATS
|
||||
void dp_print_tso_stats(struct dp_soc *soc,
|
||||
enum qdf_stats_verbosity_level level)
|
||||
{
|
||||
uint8_t loop_pdev;
|
||||
uint32_t id;
|
||||
struct dp_pdev *pdev;
|
||||
|
||||
for (loop_pdev = 0; loop_pdev < soc->pdev_count; loop_pdev++) {
|
||||
pdev = soc->pdev_list[loop_pdev];
|
||||
DP_PRINT_STATS("TSO Statistics\n");
|
||||
DP_PRINT_STATS(
|
||||
"From stack: %d | Successful completions: %d | TSO Packets: %d | TSO Completions: %d",
|
||||
pdev->stats.tx_i.rcvd.num,
|
||||
pdev->stats.tx.tx_success.num,
|
||||
pdev->stats.tso_stats.num_tso_pkts.num,
|
||||
pdev->stats.tso_stats.tso_comp);
|
||||
|
||||
for (id = 0; id < CDP_MAX_TSO_PACKETS; id++) {
|
||||
/* TSO LEVEL 1 - PACKET INFO */
|
||||
DP_PRINT_STATS(
|
||||
"Packet_Id:[%u]: Packet Length %lu | No. of segments: %u",
|
||||
id,
|
||||
pdev->stats.tso_stats.tso_info
|
||||
.tso_packet_info[id].tso_packet_len,
|
||||
pdev->stats.tso_stats.tso_info
|
||||
.tso_packet_info[id].num_seg);
|
||||
/* TSO LEVEL 2 */
|
||||
if (level == QDF_STATS_VERBOSITY_LEVEL_HIGH)
|
||||
dp_print_tso_seg_stats(pdev, id);
|
||||
}
|
||||
|
||||
DP_PRINT_STATS(
|
||||
"TSO Histogram: Single: %llu | 2-5 segs: %llu | 6-10: %llu segs | 11-15 segs: %llu | 16-20 segs: %llu | 20+ segs: %llu",
|
||||
pdev->stats.tso_stats.seg_histogram.segs_1,
|
||||
pdev->stats.tso_stats.seg_histogram.segs_2_5,
|
||||
pdev->stats.tso_stats.seg_histogram.segs_6_10,
|
||||
pdev->stats.tso_stats.seg_histogram.segs_11_15,
|
||||
pdev->stats.tso_stats.seg_histogram.segs_16_20,
|
||||
pdev->stats.tso_stats.seg_histogram.segs_20_plus);
|
||||
}
|
||||
}
|
||||
|
||||
void dp_stats_tso_segment_histogram_update(struct dp_pdev *pdev,
|
||||
uint8_t _p_cntrs)
|
||||
{
|
||||
if (_p_cntrs == 1) {
|
||||
DP_STATS_INC(pdev,
|
||||
tso_stats.seg_histogram.segs_1, 1);
|
||||
} else if (_p_cntrs >= 2 && _p_cntrs <= 5) {
|
||||
DP_STATS_INC(pdev,
|
||||
tso_stats.seg_histogram.segs_2_5, 1);
|
||||
} else if (_p_cntrs > 5 && _p_cntrs <= 10) {
|
||||
DP_STATS_INC(pdev,
|
||||
tso_stats.seg_histogram.segs_6_10, 1);
|
||||
} else if (_p_cntrs > 10 && _p_cntrs <= 15) {
|
||||
DP_STATS_INC(pdev,
|
||||
tso_stats.seg_histogram.segs_11_15, 1);
|
||||
} else if (_p_cntrs > 15 && _p_cntrs <= 20) {
|
||||
DP_STATS_INC(pdev,
|
||||
tso_stats.seg_histogram.segs_16_20, 1);
|
||||
} else if (_p_cntrs > 20) {
|
||||
DP_STATS_INC(pdev,
|
||||
tso_stats.seg_histogram.segs_20_plus, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void dp_tso_segment_update(struct dp_pdev *pdev,
|
||||
uint32_t stats_idx,
|
||||
uint8_t idx,
|
||||
struct qdf_tso_seg_t seg)
|
||||
{
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].num_frags,
|
||||
seg.num_frags);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].total_len,
|
||||
seg.total_len);
|
||||
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.tso_enable,
|
||||
seg.tso_flags.tso_enable);
|
||||
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.fin,
|
||||
seg.tso_flags.fin);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.syn,
|
||||
seg.tso_flags.syn);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.rst,
|
||||
seg.tso_flags.rst);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.psh,
|
||||
seg.tso_flags.psh);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.ack,
|
||||
seg.tso_flags.ack);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.urg,
|
||||
seg.tso_flags.urg);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.ece,
|
||||
seg.tso_flags.ece);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.cwr,
|
||||
seg.tso_flags.cwr);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.ns,
|
||||
seg.tso_flags.ns);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.tcp_seq_num,
|
||||
seg.tso_flags.tcp_seq_num);
|
||||
DP_STATS_UPD(pdev, tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_seg[idx].tso_flags.ip_id,
|
||||
seg.tso_flags.ip_id);
|
||||
}
|
||||
|
||||
void dp_tso_packet_update(struct dp_pdev *pdev, uint32_t stats_idx,
|
||||
qdf_nbuf_t msdu, uint16_t num_segs)
|
||||
{
|
||||
DP_STATS_UPD(pdev,
|
||||
tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.num_seg,
|
||||
num_segs);
|
||||
|
||||
DP_STATS_UPD(pdev,
|
||||
tso_stats.tso_info.tso_packet_info[stats_idx]
|
||||
.tso_packet_len,
|
||||
qdf_nbuf_get_tcp_payload_len(msdu));
|
||||
}
|
||||
|
||||
void dp_tso_segment_stats_update(struct dp_pdev *pdev,
|
||||
struct qdf_tso_seg_elem_t *stats_seg,
|
||||
uint32_t stats_idx)
|
||||
{
|
||||
uint8_t tso_seg_idx = 0;
|
||||
|
||||
while (stats_seg && (tso_seg_idx < CDP_MAX_TSO_SEGMENTS)) {
|
||||
dp_tso_segment_update(pdev, stats_idx,
|
||||
tso_seg_idx,
|
||||
stats_seg->seg);
|
||||
++tso_seg_idx;
|
||||
stats_seg = stats_seg->next;
|
||||
}
|
||||
}
|
||||
|
||||
void dp_txrx_clear_tso_stats(struct dp_soc *soc)
|
||||
{
|
||||
uint8_t loop_pdev;
|
||||
struct dp_pdev *pdev;
|
||||
|
||||
for (loop_pdev = 0; loop_pdev < soc->pdev_count; loop_pdev++) {
|
||||
pdev = soc->pdev_list[loop_pdev];
|
||||
dp_init_tso_stats(pdev);
|
||||
}
|
||||
}
|
||||
#endif /* FEATURE_TSO_STATS */
|
||||
|
@@ -215,6 +215,7 @@ static void dp_tx_tso_desc_release(struct dp_soc *soc,
|
||||
dp_tso_num_seg_free(soc, tx_desc->pool_id,
|
||||
tx_desc->tso_num_desc);
|
||||
tx_desc->tso_num_desc = NULL;
|
||||
DP_STATS_INC(tx_desc->pdev, tso_stats.tso_comp, 1);
|
||||
}
|
||||
|
||||
/* Add the tso segment into the free list*/
|
||||
@@ -497,6 +498,28 @@ static void dp_tx_unmap_tso_seg_list(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FEATURE_TSO_STATS
|
||||
/**
|
||||
* dp_tso_get_stats_idx: Retrieve the tso packet id
|
||||
* @pdev - pdev handle
|
||||
*
|
||||
* Return: id
|
||||
*/
|
||||
static uint32_t dp_tso_get_stats_idx(struct dp_pdev *pdev)
|
||||
{
|
||||
uint32_t stats_idx;
|
||||
|
||||
stats_idx = (((uint32_t)qdf_atomic_inc_return(&pdev->tso_idx))
|
||||
% CDP_MAX_TSO_PACKETS);
|
||||
return stats_idx;
|
||||
}
|
||||
#else
|
||||
static int dp_tso_get_stats_idx(struct dp_pdev *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* FEATURE_TSO_STATS */
|
||||
|
||||
/**
|
||||
* dp_tx_free_remaining_tso_desc() - do dma unmap for tso segments if any,
|
||||
* free the tso segments descriptor and
|
||||
@@ -542,9 +565,9 @@ static QDF_STATUS dp_tx_prepare_tso(struct dp_vdev *vdev,
|
||||
struct qdf_tso_seg_elem_t *tso_seg;
|
||||
int num_seg = qdf_nbuf_get_tso_num_seg(msdu);
|
||||
struct dp_soc *soc = vdev->pdev->soc;
|
||||
struct dp_pdev *pdev = vdev->pdev;
|
||||
struct qdf_tso_info_t *tso_info;
|
||||
struct qdf_tso_num_seg_elem_t *tso_num_seg;
|
||||
|
||||
tso_info = &msdu_info->u.tso_info;
|
||||
tso_info->curr_seg = NULL;
|
||||
tso_info->tso_seg_list = NULL;
|
||||
@@ -605,6 +628,12 @@ static QDF_STATUS dp_tx_prepare_tso(struct dp_vdev *vdev,
|
||||
|
||||
tso_info->curr_seg = tso_info->tso_seg_list;
|
||||
|
||||
tso_info->msdu_stats_idx = dp_tso_get_stats_idx(pdev);
|
||||
dp_tso_packet_update(pdev, tso_info->msdu_stats_idx,
|
||||
msdu, msdu_info->num_seg);
|
||||
dp_tso_segment_stats_update(pdev, tso_info->tso_seg_list,
|
||||
tso_info->msdu_stats_idx);
|
||||
dp_stats_tso_segment_histogram_update(pdev, msdu_info->num_seg);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
@@ -2244,11 +2273,11 @@ qdf_nbuf_t dp_tx_send(struct cdp_vdev *vap_dev, qdf_nbuf_t nbuf)
|
||||
*/
|
||||
if (qdf_nbuf_is_tso(nbuf)) {
|
||||
dp_verbose_debug("TSO frame %pK", vdev);
|
||||
DP_STATS_INC_PKT(vdev, tx_i.tso.tso_pkt, 1,
|
||||
qdf_nbuf_len(nbuf));
|
||||
DP_STATS_INC_PKT(vdev->pdev, tso_stats.num_tso_pkts, 1,
|
||||
qdf_nbuf_len(nbuf));
|
||||
|
||||
if (dp_tx_prepare_tso(vdev, nbuf, &msdu_info)) {
|
||||
DP_STATS_INC_PKT(vdev, tx_i.tso.dropped_host, 1,
|
||||
DP_STATS_INC_PKT(vdev->pdev, tso_stats.dropped_host, 1,
|
||||
qdf_nbuf_len(nbuf));
|
||||
return nbuf;
|
||||
}
|
||||
|
@@ -1700,6 +1700,11 @@ struct dp_pdev {
|
||||
*/
|
||||
struct dp_rx_fst *rx_fst;
|
||||
#endif /* WLAN_SUPPORT_RX_FLOW_TAG */
|
||||
|
||||
#ifdef FEATURE_TSO_STATS
|
||||
/* TSO Id to index into TSO packet information */
|
||||
qdf_atomic_t tso_idx;
|
||||
#endif /* FEATURE_TSO_STATS */
|
||||
};
|
||||
|
||||
struct dp_peer;
|
||||
|
@@ -3148,6 +3148,17 @@ static inline void qdf_nbuf_unmap_tso_segment(qdf_device_t osdev,
|
||||
return __qdf_nbuf_unmap_tso_segment(osdev, tso_seg, is_last_seg);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_get_tcp_payload_len() - function to return the tso payload len
|
||||
* @nbuf: network buffer
|
||||
*
|
||||
* Return: size of the tso packet
|
||||
*/
|
||||
static inline size_t qdf_nbuf_get_tcp_payload_len(qdf_nbuf_t nbuf)
|
||||
{
|
||||
return __qdf_nbuf_get_tcp_payload_len(nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_get_tso_num_seg() - function to calculate the number
|
||||
* of TCP segments within the TSO jumbo packet
|
||||
|
@@ -1453,9 +1453,23 @@ void __qdf_nbuf_unmap_tso_segment(qdf_device_t osdev,
|
||||
bool is_last_seg);
|
||||
|
||||
#ifdef FEATURE_TSO
|
||||
/**
|
||||
* __qdf_nbuf_get_tcp_payload_len() - function to return the tcp
|
||||
* payload len
|
||||
* @skb: buffer
|
||||
*
|
||||
* Return: size
|
||||
*/
|
||||
size_t __qdf_nbuf_get_tcp_payload_len(struct sk_buff *skb);
|
||||
uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb);
|
||||
|
||||
#else
|
||||
static inline
|
||||
size_t __qdf_nbuf_get_tcp_payload_len(struct sk_buff *skb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb)
|
||||
{
|
||||
return 0;
|
||||
|
@@ -3138,6 +3138,19 @@ last_seg_free_first_frag:
|
||||
}
|
||||
qdf_export_symbol(__qdf_nbuf_unmap_tso_segment);
|
||||
|
||||
size_t __qdf_nbuf_get_tcp_payload_len(struct sk_buff *skb)
|
||||
{
|
||||
size_t packet_len;
|
||||
|
||||
packet_len = skb->len -
|
||||
((skb_transport_header(skb) - skb_mac_header(skb)) +
|
||||
tcp_hdrlen(skb));
|
||||
|
||||
return packet_len;
|
||||
}
|
||||
|
||||
qdf_export_symbol(__qdf_nbuf_get_tcp_payload_len);
|
||||
|
||||
/**
|
||||
* __qdf_nbuf_get_tso_num_seg() - function to divide a TSO nbuf
|
||||
* into segments
|
||||
|
Reference in New Issue
Block a user