qcacmn: Add data structures for SWLM

Add the necessary data structures for the
software latency manager.

Change-Id: Ibf55f0eef7ee6602b007de39a28f09c4622bd356
CRs-Fixed: 2769004
This commit is contained in:
Rakesh Pillai
2020-08-24 04:55:01 -07:00
committed by snandini
parent 4b6f9e082b
commit 21af5ba8cf
8 changed files with 213 additions and 5 deletions

View File

@@ -386,6 +386,11 @@ while (0)
#define DP_TX_HIST_STATS_PER_PDEV()
#endif /* DISABLE_DP_STATS */
#define FRAME_MASK_IPV4_ARP 1
#define FRAME_MASK_IPV4_DHCP 2
#define FRAME_MASK_IPV4_EAPOL 4
#define FRAME_MASK_IPV6_DHCP 8
#ifdef QCA_SUPPORT_PEER_ISOLATION
#define dp_get_peer_isolation(_peer) ((_peer)->isolation)
@@ -2393,4 +2398,29 @@ dp_pdev_htt_stats_dbgfs_deinit(struct dp_pdev *pdev)
{
}
#endif /* HTT_STATS_DEBUGFS_SUPPORT */
#ifndef WLAN_DP_FEATURE_SW_LATENCY_MGR
/**
* dp_soc_swlm_attach() - attach the software latency manager resources
* @soc: Datapath global soc handle
*
* Returns: QDF_STATUS
*/
static inline QDF_STATUS dp_soc_swlm_attach(struct dp_soc *soc)
{
return QDF_STATUS_SUCCESS;
}
/**
* dp_soc_swlm_detach() - detach the software latency manager resources
* @soc: Datapath global soc handle
*
* Returns: QDF_STATUS
*/
static inline QDF_STATUS dp_soc_swlm_detach(struct dp_soc *soc)
{
return QDF_STATUS_SUCCESS;
}
#endif /* !WLAN_DP_FEATURE_SW_LATENCY_MGR */
#endif /* #ifndef _DP_INTERNAL_H_ */

View File

@@ -4590,6 +4590,7 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc)
{
struct dp_soc *soc = (struct dp_soc *)txrx_soc;
dp_soc_swlm_detach(soc);
dp_soc_tx_desc_sw_pools_free(soc);
dp_soc_srng_free(soc);
dp_hw_link_desc_ring_free(soc);
@@ -11570,6 +11571,7 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
goto fail5;
}
dp_soc_swlm_attach(soc);
dp_soc_set_interrupt_mode(soc);
dp_soc_set_def_pdev(soc);

View File

@@ -2060,6 +2060,26 @@ dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num,
}
#endif
#ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
/**
* dp_rx_update_stats() - Update soc level rx packet count
* @soc: DP soc handle
* @nbuf: nbuf received
*
* Returns: none
*/
static inline void dp_rx_update_stats(struct dp_soc *soc,
qdf_nbuf_t nbuf)
{
DP_STATS_INC_PKT(soc, rx.ingress, 1,
QDF_NBUF_CB_RX_PKT_LEN(nbuf));
}
#else
static inline void dp_rx_update_stats(struct dp_soc *soc,
qdf_nbuf_t nbuf)
{
}
#endif
/**
* dp_rx_process() - Brain of the Rx processing functionality
* Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
@@ -2692,6 +2712,7 @@ done:
dp_rx_fill_gro_info(soc, rx_tlv_hdr, nbuf, &rx_ol_pkt_cnt);
dp_rx_update_stats(soc, nbuf);
DP_RX_LIST_APPEND(deliver_list_head,
deliver_list_tail,
nbuf);

View File

@@ -167,11 +167,6 @@ struct dp_rx_desc {
(((_cookie) & RX_DESC_COOKIE_INDEX_MASK) >> \
RX_DESC_COOKIE_INDEX_SHIFT)
#define FRAME_MASK_IPV4_ARP 1
#define FRAME_MASK_IPV4_DHCP 2
#define FRAME_MASK_IPV4_EAPOL 4
#define FRAME_MASK_IPV6_DHCP 8
#define dp_rx_add_to_free_desc_list(head, tail, new) \
__dp_rx_add_to_free_desc_list(head, tail, new, __func__)

View File

@@ -1130,6 +1130,25 @@ static void dp_tx_raw_prepare_unset(struct dp_soc *soc,
#define dp_vdev_peer_stats_update_protocol_cnt_tx(vdev_hdl, skb)
#endif
#ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
/**
* dp_tx_update_stats() - Update soc level tx stats
* @soc: DP soc handle
* @nbuf: packet being transmitted
*
* Returns: none
*/
static inline void dp_tx_update_stats(struct dp_soc *soc,
qdf_nbuf_t nbuf)
{
DP_STATS_INC_PKT(soc, tx.egress, 1, qdf_nbuf_len(nbuf));
}
#else
static inline void dp_tx_update_stats(struct dp_soc *soc,
qdf_nbuf_t nbuf)
{
}
#endif
/**
* dp_tx_hw_enqueue() - Enqueue to TCL HW for transmit
* @soc: DP Soc Handle
@@ -1273,6 +1292,7 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev,
dp_vdev_peer_stats_update_protocol_cnt_tx(vdev, tx_desc->nbuf);
hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc);
DP_STATS_INC_PKT(vdev, tx_i.processed, 1, tx_desc->length);
dp_tx_update_stats(soc, tx_desc->nbuf);
status = QDF_STATUS_SUCCESS;
ring_access_fail:

View File

@@ -813,6 +813,8 @@ struct dp_soc_stats {
/* SOC level TX stats */
struct {
/* Total packets transmitted */
struct cdp_pkt_info egress;
/* packets dropped on tx because of no peer */
struct cdp_pkt_info tx_invalid_peer;
/* descriptors in each tcl ring */
@@ -835,6 +837,8 @@ struct dp_soc_stats {
/* SOC level RX stats */
struct {
/* Total rx packets count */
struct cdp_pkt_info ingress;
/* Rx errors */
/* Total Packets in Rx Error ring */
uint32_t err_ring_pkts;
@@ -1121,6 +1125,113 @@ struct dp_last_op_info {
struct hal_buf_info reo_reinject_link_desc;
};
#ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
/**
* struct dp_swlm_tcl_data - params for tcl register write coalescing
* descision making
* @nbuf: TX packet
* @tid: tid for transmitting the current packet
*
* This structure contains the information required by the software
* latency manager to decide on whether to coalesc the current TCL
* register write or not.
*/
struct dp_swlm_tcl_data {
qdf_nbuf_t nbuf;
uint8_t tid;
};
/**
* union swlm_data - SWLM query data
* @tcl_data: data for TCL query in SWLM
*/
union swlm_data {
struct dp_swlm_tcl_data *tcl_data;
};
/**
* struct dp_swlm_ops - SWLM ops
* @tcl_should_coalesc: Should the current TCL register write be coalesced
* or not
*/
struct dp_swlm_ops {
int (*tcl_should_coalesc)(struct dp_soc *soc,
struct dp_swlm_tcl_data *tcl_data);
};
/**
* struct dp_swlm_stats - Stats for Software Latency manager.
* @tcl.timer_flush_success: Num TCL HP writes success from timer context
* @tcl.timer_flush_fail: Num TCL HP writes failure from timer context
* @tcl.tid_fail: Num TCL register write coalescing skips, since the pkt
* was being transmitted on a TID above coalescing threshold
* @tcl.sp_frames: Num TCL register write coalescing skips, since the pkt
* being transmitted was a special frame
* @tcl.bytes_thresh_reached: Num TCL HP writes flush after the coalescing
* bytes threshold was reached
* @tcl.time_thresh_reached: Num TCL HP writes flush after the coalescing
* session time expired
* @tcl.tput_criteria_fail: Num TCL HP writes coalescing fails, since the
* throughput did not meet session threshold
*/
struct dp_swlm_stats {
struct {
uint32_t timer_flush_success;
uint32_t timer_flush_fail;
uint32_t tid_fail;
uint32_t sp_frames;
uint32_t bytes_thresh_reached;
uint32_t time_thresh_reached;
uint32_t tput_criteria_fail;
} tcl;
};
/**
* struct dp_swlm_params: Parameters for different modules in the
* Software latency manager.
* @tcl.flush_timer: Timer for flushing the coalesced TCL HP writes
* @tcl.rx_traffic_thresh: Threshold for RX traffic, to begin TCL register
* write coalescing
* @tcl.tx_traffic_thresh: Threshold for TX traffic, to begin TCL register
* write coalescing
* @tcl.sampling_time: Sampling time to test the throughput threshold
* @tcl.sampling_session_tx_bytes: Num bytes transmitted in the sampling time
* @tcl.bytes_flush_thresh: Bytes threshold to flush the TCL HP register write
* @tcl.time_flush_thresh: Time threshold to flush the TCL HP register write
* @tcl.tx_thresh_multiplier: Multiplier to deduce the bytes threshold after
* which the TCL HP register is written, thereby
* ending the coalescing.
*/
struct dp_swlm_params {
struct {
qdf_timer_t flush_timer;
uint32_t rx_traffic_thresh;
uint32_t tx_traffic_thresh;
uint32_t sampling_time;
uint32_t sampling_session_tx_bytes;
uint32_t bytes_flush_thresh;
uint32_t time_flush_thresh;
uint32_t tx_thresh_multiplier;
} tcl;
};
/**
* struct dp_swlm - Software latency manager context
* @ops: SWLM ops pointers
* @is_enabled: SWLM enabled/disabled
* @stats: SWLM stats
* @params: SWLM SRNG params
* @tcl_flush_timer: flush timer for TCL register writes
*/
struct dp_swlm {
struct dp_swlm_ops *ops;
uint8_t is_enabled;
struct dp_swlm_stats stats;
struct dp_swlm_params params;
};
#endif
/* SOC level structure for data path */
struct dp_soc {
/**
@@ -1528,6 +1639,10 @@ struct dp_soc {
qdf_spinlock_t inactive_vdev_list_lock;
/* lock to protect vdev_id_map table*/
qdf_spinlock_t vdev_map_lock;
#ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
struct dp_swlm swlm;
#endif
};
#ifdef IPA_OFFLOAD

View File

@@ -984,6 +984,30 @@ hal_srng_access_start_unlocked(hal_soc_handle_t hal_soc_hdl,
return 0;
}
/**
* hal_srng_try_access_start - Try to start (locked) ring access
*
* @hal_soc: Opaque HAL SOC handle
* @hal_ring_hdl: Ring pointer (Source or Destination ring)
*
* Return: 0 on success; error on failure
*/
static inline int hal_srng_try_access_start(hal_soc_handle_t hal_soc_hdl,
hal_ring_handle_t hal_ring_hdl)
{
struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
if (qdf_unlikely(!hal_ring_hdl)) {
qdf_print("Error: Invalid hal_ring\n");
return -EINVAL;
}
if (!SRNG_TRY_LOCK(&(srng->lock)))
return -EINVAL;
return hal_srng_access_start_unlocked(hal_soc_hdl, hal_ring_hdl);
}
/**
* hal_srng_access_start - Start (locked) ring access
*

View File

@@ -209,6 +209,7 @@ enum hal_srng_dir {
#define hal_srng_lock_t qdf_spinlock_t
#define SRNG_LOCK_INIT(_lock) qdf_spinlock_create(_lock)
#define SRNG_LOCK(_lock) qdf_spin_lock_bh(_lock)
#define SRNG_TRY_LOCK(_lock) qdf_spin_trylock_bh(_lock)
#define SRNG_UNLOCK(_lock) qdf_spin_unlock_bh(_lock)
#define SRNG_LOCK_DESTROY(_lock) qdf_spinlock_destroy(_lock)