qcacld-3.0: time stamp msdu with precise rx/tx time
Get tx/rx tsf time for each msdu, and then time stamp the msdu with the corresponding host time. Change-Id: I7af80318b60c28d53e95fbe545e82da4191544b6 CRs-Fixed: 2057693
This commit is contained in:
@@ -96,6 +96,15 @@ ol_usb_extra_initialization(struct ol_context *ol_ctx)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WLAN_FEATURE_TSF_PLUS)
|
||||||
|
#define SDIO_HI_ACS_FLAGS (HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET | \
|
||||||
|
HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE)
|
||||||
|
#else
|
||||||
|
#define SDIO_HI_ACS_FLAGS (HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET | \
|
||||||
|
HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET | \
|
||||||
|
HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*Setting SDIO block size, mbox ISR yield limit for SDIO based HIF*/
|
/*Setting SDIO block size, mbox ISR yield limit for SDIO based HIF*/
|
||||||
static
|
static
|
||||||
QDF_STATUS ol_sdio_extra_initialization(struct ol_context *ol_ctx)
|
QDF_STATUS ol_sdio_extra_initialization(struct ol_context *ol_ctx)
|
||||||
@@ -163,9 +172,7 @@ QDF_STATUS ol_sdio_extra_initialization(struct ol_context *ol_ctx)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
param |= (HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET|
|
param |= SDIO_HI_ACS_FLAGS;
|
||||||
HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET|
|
|
||||||
HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE);
|
|
||||||
|
|
||||||
bmi_write_memory(hif_hia_item_address(target_type,
|
bmi_write_memory(hif_hia_item_address(target_type,
|
||||||
offsetof(struct host_interest_s,
|
offsetof(struct host_interest_s,
|
||||||
|
@@ -681,7 +681,7 @@ void htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
|
ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
|
||||||
status, msg_word + 1);
|
status, msg_word);
|
||||||
HTT_TX_SCHED(pdev);
|
HTT_TX_SCHED(pdev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -905,7 +905,7 @@ void htt_t2h_msg_handler_fast(void *context, qdf_nbuf_t *cmpl_msdus,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
|
ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
|
||||||
status, msg_word + 1);
|
status, msg_word);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2011-2014,2016-2017 The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||||
*
|
*
|
||||||
@@ -66,4 +66,28 @@ void ol_register_packetdump_callback(tp_ol_packetdump_cb ol_tx_packetdump_cb,
|
|||||||
tp_ol_packetdump_cb ol_rx_packetdump_cb);
|
tp_ol_packetdump_cb ol_rx_packetdump_cb);
|
||||||
void ol_deregister_packetdump_callback(void);
|
void ol_deregister_packetdump_callback(void);
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_TSF_PLUS
|
||||||
|
typedef int (*tp_ol_timestamp_cb)(qdf_nbuf_t netbuf, uint64_t target_time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ol_register_timestamp_callback() - set callbacks for timestamp tx msdu.
|
||||||
|
* @ol_tx_timestamp_cb: callback function for time stamp tx msdu
|
||||||
|
*
|
||||||
|
* This function register timestamp callback, the callback will
|
||||||
|
* be called when tx a msdu
|
||||||
|
*
|
||||||
|
* Return: nothing
|
||||||
|
*/
|
||||||
|
void ol_register_timestamp_callback(tp_ol_timestamp_cb ol_tx_timestamp_cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ol_deregister_timestamp_callback() - reset callbacks for timestamp
|
||||||
|
* tx msdu to NULL.
|
||||||
|
*
|
||||||
|
* This function reset the timestamp callbacks for tx
|
||||||
|
*
|
||||||
|
* Return: nothing
|
||||||
|
*/
|
||||||
|
void ol_deregister_timestamp_callback(void);
|
||||||
|
#endif
|
||||||
#endif /* _OL_TXRX_API__H_ */
|
#endif /* _OL_TXRX_API__H_ */
|
||||||
|
@@ -150,14 +150,12 @@ enum htt_tx_status {
|
|||||||
* @param num_msdus - how many MSDUs are referenced by the tx completion
|
* @param num_msdus - how many MSDUs are referenced by the tx completion
|
||||||
* message
|
* message
|
||||||
* @param status - whether transmission was successful
|
* @param status - whether transmission was successful
|
||||||
* @param tx_msdu_id_iterator - abstract method of finding the IDs for the
|
* @param msg_word - the tx completion message
|
||||||
* individual MSDUs referenced by the tx completion message, via the
|
|
||||||
* htt_tx_compl_desc_id API function
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
|
ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
|
||||||
int num_msdus,
|
int num_msdus,
|
||||||
enum htt_tx_status status, void *tx_msdu_id_iterator);
|
enum htt_tx_status status, void *msg_word);
|
||||||
|
|
||||||
void ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits);
|
void ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits);
|
||||||
|
|
||||||
|
@@ -1135,6 +1135,25 @@ ol_rx_filter(struct ol_txrx_vdev_t *vdev,
|
|||||||
return FILTER_STATUS_REJECT;
|
return FILTER_STATUS_REJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_TSF_PLUS
|
||||||
|
static inline void ol_rx_timestamp(void *rx_desc, qdf_nbuf_t msdu)
|
||||||
|
{
|
||||||
|
struct htt_rx_ppdu_desc_t *rx_ppdu_desc;
|
||||||
|
|
||||||
|
if (!rx_desc || !msdu)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rx_ppdu_desc = (struct htt_rx_ppdu_desc_t *)((uint8_t *)(rx_desc) -
|
||||||
|
HTT_RX_IND_HL_BYTES + HTT_RX_IND_HDR_PREFIX_BYTES);
|
||||||
|
msdu->tstamp = ns_to_ktime((u_int64_t)rx_ppdu_desc->tsf32 *
|
||||||
|
NSEC_PER_USEC);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void ol_rx_timestamp(void *rx_desc, qdf_nbuf_t msdu)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
ol_rx_deliver(struct ol_txrx_vdev_t *vdev,
|
ol_rx_deliver(struct ol_txrx_vdev_t *vdev,
|
||||||
struct ol_txrx_peer_t *peer, unsigned int tid,
|
struct ol_txrx_peer_t *peer, unsigned int tid,
|
||||||
@@ -1315,6 +1334,8 @@ DONE:
|
|||||||
OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc,
|
OL_RX_ERR_STATISTICS_1(pdev, vdev, peer, rx_desc,
|
||||||
OL_RX_ERR_NONE);
|
OL_RX_ERR_NONE);
|
||||||
TXRX_STATS_MSDU_INCR(vdev->pdev, rx.delivered, msdu);
|
TXRX_STATS_MSDU_INCR(vdev->pdev, rx.delivered, msdu);
|
||||||
|
|
||||||
|
ol_rx_timestamp(rx_desc, msdu);
|
||||||
OL_TXRX_LIST_APPEND(deliver_list_head,
|
OL_TXRX_LIST_APPEND(deliver_list_head,
|
||||||
deliver_list_tail, msdu);
|
deliver_list_tail, msdu);
|
||||||
}
|
}
|
||||||
|
@@ -555,6 +555,65 @@ void ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits)
|
|||||||
ol_tx_flow_ct_unpause_os_q(pdev);
|
ol_tx_flow_ct_unpause_os_q(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_TSF_PLUS
|
||||||
|
static inline struct htt_tx_compl_ind_append_tx_tstamp *ol_tx_get_txtstamps(
|
||||||
|
u_int32_t *msg_word, int num_msdus)
|
||||||
|
{
|
||||||
|
u_int32_t has_tx_tsf;
|
||||||
|
u_int32_t has_retry;
|
||||||
|
struct htt_tx_compl_ind_append_tx_tstamp *txtstamp_list = NULL;
|
||||||
|
struct htt_tx_compl_ind_append_retries *retry_list = NULL;
|
||||||
|
int offset_dwords;
|
||||||
|
|
||||||
|
has_tx_tsf = HTT_TX_COMPL_IND_APPEND1_GET(*msg_word);
|
||||||
|
if (num_msdus <= 0 || !has_tx_tsf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
offset_dwords = 1 + ((num_msdus + 1) >> 1);
|
||||||
|
|
||||||
|
has_retry = HTT_TX_COMPL_IND_APPEND_GET(*msg_word);
|
||||||
|
if (has_retry) {
|
||||||
|
int retry_index = 0;
|
||||||
|
int width_for_each_retry =
|
||||||
|
(sizeof(struct htt_tx_compl_ind_append_retries) +
|
||||||
|
3) >> 2;
|
||||||
|
|
||||||
|
retry_list = (struct htt_tx_compl_ind_append_retries *)
|
||||||
|
(msg_word + offset_dwords);
|
||||||
|
while (retry_list) {
|
||||||
|
if (retry_list[retry_index++].flag == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset_dwords += retry_index * width_for_each_retry;
|
||||||
|
}
|
||||||
|
txtstamp_list = (struct htt_tx_compl_ind_append_tx_tstamp *)
|
||||||
|
(msg_word + offset_dwords);
|
||||||
|
|
||||||
|
return txtstamp_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ol_tx_timestamp(ol_txrx_pdev_handle pdev,
|
||||||
|
qdf_nbuf_t netbuf, u_int64_t ts)
|
||||||
|
{
|
||||||
|
if (!netbuf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pdev->ol_tx_timestamp_cb)
|
||||||
|
pdev->ol_tx_timestamp_cb(netbuf, ts);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline struct htt_tx_compl_ind_append_tx_tstamp *ol_tx_get_txtstamps(
|
||||||
|
u_int32_t *msg_word, int num_msdus)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ol_tx_timestamp(ol_txrx_pdev_handle pdev,
|
||||||
|
qdf_nbuf_t netbuf, u_int64_t ts)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WARNING: ol_tx_inspect_handler()'s bahavior is similar to that of
|
* WARNING: ol_tx_inspect_handler()'s bahavior is similar to that of
|
||||||
* ol_tx_completion_handler().
|
* ol_tx_completion_handler().
|
||||||
@@ -564,16 +623,18 @@ void ol_tx_credit_completion_handler(ol_txrx_pdev_handle pdev, int credits)
|
|||||||
void
|
void
|
||||||
ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
|
ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
|
||||||
int num_msdus,
|
int num_msdus,
|
||||||
enum htt_tx_status status, void *tx_desc_id_iterator)
|
enum htt_tx_status status, void *msg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint16_t *desc_ids = (uint16_t *) tx_desc_id_iterator;
|
|
||||||
uint16_t tx_desc_id;
|
uint16_t tx_desc_id;
|
||||||
struct ol_tx_desc_t *tx_desc;
|
struct ol_tx_desc_t *tx_desc;
|
||||||
uint32_t byte_cnt = 0;
|
uint32_t byte_cnt = 0;
|
||||||
qdf_nbuf_t netbuf;
|
qdf_nbuf_t netbuf;
|
||||||
tp_ol_packetdump_cb packetdump_cb;
|
tp_ol_packetdump_cb packetdump_cb;
|
||||||
uint32_t is_tx_desc_freed = 0;
|
uint32_t is_tx_desc_freed = 0;
|
||||||
|
struct htt_tx_compl_ind_append_tx_tstamp *txtstamp_list = NULL;
|
||||||
|
u_int32_t *msg_word = (u_int32_t *)msg;
|
||||||
|
u_int16_t *desc_ids = (u_int16_t *)(msg_word + 1);
|
||||||
|
|
||||||
union ol_tx_desc_list_elem_t *lcl_freelist = NULL;
|
union ol_tx_desc_list_elem_t *lcl_freelist = NULL;
|
||||||
union ol_tx_desc_list_elem_t *tx_desc_last = NULL;
|
union ol_tx_desc_list_elem_t *tx_desc_last = NULL;
|
||||||
@@ -581,12 +642,20 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
|
|||||||
TAILQ_INIT(&tx_descs);
|
TAILQ_INIT(&tx_descs);
|
||||||
|
|
||||||
ol_tx_delay_compute(pdev, status, desc_ids, num_msdus);
|
ol_tx_delay_compute(pdev, status, desc_ids, num_msdus);
|
||||||
|
if (status == htt_tx_status_ok)
|
||||||
|
txtstamp_list = ol_tx_get_txtstamps(msg_word, num_msdus);
|
||||||
|
|
||||||
for (i = 0; i < num_msdus; i++) {
|
for (i = 0; i < num_msdus; i++) {
|
||||||
tx_desc_id = desc_ids[i];
|
tx_desc_id = desc_ids[i];
|
||||||
tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
|
tx_desc = ol_tx_desc_find(pdev, tx_desc_id);
|
||||||
tx_desc->status = status;
|
tx_desc->status = status;
|
||||||
netbuf = tx_desc->netbuf;
|
netbuf = tx_desc->netbuf;
|
||||||
|
|
||||||
|
if (txtstamp_list)
|
||||||
|
ol_tx_timestamp(pdev, netbuf,
|
||||||
|
(u_int64_t)txtstamp_list->timestamp[i]
|
||||||
|
);
|
||||||
|
|
||||||
QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE);
|
QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE);
|
||||||
|
|
||||||
if (tx_desc->pkt_type != OL_TX_FRM_TSO) {
|
if (tx_desc->pkt_type != OL_TX_FRM_TSO) {
|
||||||
@@ -1309,3 +1378,27 @@ void ol_deregister_packetdump_callback(void)
|
|||||||
pdev->ol_tx_packetdump_cb = NULL;
|
pdev->ol_tx_packetdump_cb = NULL;
|
||||||
pdev->ol_rx_packetdump_cb = NULL;
|
pdev->ol_rx_packetdump_cb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_TSF_PLUS
|
||||||
|
void ol_register_timestamp_callback(tp_ol_timestamp_cb ol_tx_timestamp_cb)
|
||||||
|
{
|
||||||
|
ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
|
||||||
|
|
||||||
|
if (!pdev) {
|
||||||
|
ol_txrx_err("%s: pdev is NULL", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pdev->ol_tx_timestamp_cb = ol_tx_timestamp_cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ol_deregister_timestamp_callback(void)
|
||||||
|
{
|
||||||
|
ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX);
|
||||||
|
|
||||||
|
if (!pdev) {
|
||||||
|
ol_txrx_err("%s: pdev is NULL", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pdev->ol_tx_timestamp_cb = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -676,6 +676,10 @@ struct ol_txrx_pdev_t {
|
|||||||
tp_ol_packetdump_cb ol_tx_packetdump_cb;
|
tp_ol_packetdump_cb ol_tx_packetdump_cb;
|
||||||
tp_ol_packetdump_cb ol_rx_packetdump_cb;
|
tp_ol_packetdump_cb ol_rx_packetdump_cb;
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_TSF_PLUS
|
||||||
|
tp_ol_timestamp_cb ol_tx_timestamp_cb;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint16_t pool_size;
|
uint16_t pool_size;
|
||||||
uint16_t num_free;
|
uint16_t num_free;
|
||||||
|
@@ -831,6 +831,8 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_init(hdd_context_t *hdd_ctx)
|
|||||||
hdd_err("Failed to register irq handler: %d", ret);
|
hdd_err("Failed to register irq handler: %d", ret);
|
||||||
return HDD_TSF_OP_FAIL;
|
return HDD_TSF_OP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ol_register_timestamp_callback(hdd_tx_timestamp);
|
||||||
return HDD_TSF_OP_SUCC;
|
return HDD_TSF_OP_SUCC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -839,6 +841,7 @@ enum hdd_tsf_op_result wlan_hdd_tsf_plus_deinit(hdd_context_t *hdd_ctx)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ol_deregister_timestamp_callback();
|
||||||
ret = cnss_common_unregister_tsf_captured_handler(
|
ret = cnss_common_unregister_tsf_captured_handler(
|
||||||
hdd_ctx->parent_dev,
|
hdd_ctx->parent_dev,
|
||||||
(void *)hdd_ctx);
|
(void *)hdd_ctx);
|
||||||
|
@@ -63,6 +63,7 @@
|
|||||||
#include <cdp_txrx_handle.h>
|
#include <cdp_txrx_handle.h>
|
||||||
#include "wlan_hdd_rx_monitor.h"
|
#include "wlan_hdd_rx_monitor.h"
|
||||||
#include "wlan_hdd_power.h"
|
#include "wlan_hdd_power.h"
|
||||||
|
#include <wlan_hdd_tsf.h>
|
||||||
|
|
||||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||||
/*
|
/*
|
||||||
@@ -1253,6 +1254,7 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
|
|||||||
*/
|
*/
|
||||||
qdf_net_buf_debug_release_skb(skb);
|
qdf_net_buf_debug_release_skb(skb);
|
||||||
|
|
||||||
|
hdd_rx_timestamp(skb, ktime_to_us(skb->tstamp));
|
||||||
if (HDD_LRO_NO_RX ==
|
if (HDD_LRO_NO_RX ==
|
||||||
hdd_lro_rx(pHddCtx, pAdapter, skb)) {
|
hdd_lro_rx(pHddCtx, pAdapter, skb)) {
|
||||||
if (hdd_napi_enabled(HDD_NAPI_ANY) &&
|
if (hdd_napi_enabled(HDD_NAPI_ANY) &&
|
||||||
@@ -1267,7 +1269,6 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
|
|||||||
else
|
else
|
||||||
++pAdapter->hdd_stats.hddTxRxStats.
|
++pAdapter->hdd_stats.hddTxRxStats.
|
||||||
rxRefused[cpu_index];
|
rxRefused[cpu_index];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
++pAdapter->hdd_stats.hddTxRxStats.
|
++pAdapter->hdd_stats.hddTxRxStats.
|
||||||
rxDelivered[cpu_index];
|
rxDelivered[cpu_index];
|
||||||
|
Reference in New Issue
Block a user