qcacld-3.0: Add PTP timestamp socket options RX support

Host need to fill netbuf with qtime instead of tsf. So host first
need to set enable_ppdu_end to 1, so that FW will pass ppdu_end
contents to host, and host can translate tsf64_time into qtime.
The tsf64_time is new added to fw struture, so host will need
add it accordingly to struct hdd_adapter, and keep it updated
in time synchronization function <hdd_update_timestamp>.

Change-Id: Ib19ac1411c4e17624c012f188297c9f2122642d2
CRs-Fixed: 2444456
This commit is contained in:
Jiani Liu 2019-05-01 10:07:10 +08:00 • committed by nshrivas
commit a8fd170e7a
7 changed files with 159 additions and 3 deletions

View file

@ -43,6 +43,7 @@
#include <ol_htt_tx_api.h>
#include <ol_txrx_types.h>
#include <ol_tx_send.h>
#include <ol_htt_rx_api.h>
#include <htt_internal.h>
#include <wlan_policy_mgr_api.h>
@ -540,6 +541,7 @@ QDF_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev)
__func__, __LINE__);
}
htt_rx_enable_ppdu_end(&enable_ppdu_end);
HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, enable_hdr);
HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1);
HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, enable_ppdu_start);

View file

@ -422,3 +422,10 @@ void htt_deregister_rx_pkt_dump_callback(struct htt_pdev_t *pdev)
pdev->rx_pkt_dump_cb = NULL;
}
#endif
#ifdef WLAN_FEATURE_TSF_PLUS
void htt_rx_enable_ppdu_end(int *enable_ppdu_end)
{
*enable_ppdu_end = 1;
}
#endif

View file

@ -1007,4 +1007,18 @@ uint32_t htt_rx_amsdu_rx_in_order_get_pktlog(qdf_nbuf_t rx_ind_msg);
* Return: QDF_STATUS
*/
QDF_STATUS htt_rx_update_smmu_map(struct htt_pdev_t *pdev, bool map);
/** htt_tx_enable_ppdu_end
* @enable_ppdu_end - set it to 1 if WLAN_FEATURE_TSF_PLUS is defined,
* else do nothing
*/
#ifdef WLAN_FEATURE_TSF_PLUS
void htt_rx_enable_ppdu_end(int *enable_ppdu_end);
#else
static inline
void htt_rx_enable_ppdu_end(int *enable_ppdu_end)
{
}
#endif
#endif /* _OL_HTT_RX_API__H_ */

View file

@ -54,6 +54,7 @@
#include "pktlog_ac_fmt.h"
#include <cdp_txrx_handle.h>
#include <pld_common.h>
#include <htt_internal.h>
#ifndef OL_RX_INDICATION_MAX_RECORDS
#define OL_RX_INDICATION_MAX_RECORDS 2048
@ -1118,6 +1119,7 @@ ol_rx_filter(struct ol_txrx_vdev_t *vdev,
#endif
#ifdef WLAN_FEATURE_TSF_PLUS
#ifdef CONFIG_HL_SUPPORT
static inline void ol_rx_timestamp(struct cdp_cfg *cfg_pdev,
void *rx_desc, qdf_nbuf_t msdu)
{
@ -1135,6 +1137,32 @@ static inline void ol_rx_timestamp(struct cdp_cfg *cfg_pdev,
NSEC_PER_USEC);
}
#else
static inline void ol_rx_timestamp(struct cdp_cfg *cfg_pdev,
void *rx_desc, qdf_nbuf_t msdu)
{
struct htt_host_rx_desc_base *rx_mpdu_desc = rx_desc;
uint32_t tsf64_low32, tsf64_high32;
uint64_t tsf64, tsf64_ns;
if (!ol_cfg_is_ptp_rx_opt_enabled(cfg_pdev))
return;
if (!rx_mpdu_desc || !msdu)
return;
tsf64_low32 = rx_mpdu_desc->ppdu_end.wb_timestamp_lower_32;
tsf64_high32 = rx_mpdu_desc->ppdu_end.wb_timestamp_upper_32;
tsf64 = (uint64_t)tsf64_high32 << 32 | tsf64_low32;
if (tsf64 * NSEC_PER_USEC < tsf64)
tsf64_ns = 0;
else
tsf64_ns = tsf64 * NSEC_PER_USEC;
msdu->tstamp = ns_to_ktime(tsf64_ns);
}
#endif
#else
static inline void ol_rx_timestamp(struct cdp_cfg *cfg_pdev,
void *rx_desc, qdf_nbuf_t msdu)
{
@ -1425,6 +1453,8 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
uint32_t msdu_count;
uint8_t pktlog_bit;
uint32_t filled = 0;
struct htt_host_rx_desc_base *rx_desc;
qdf_nbuf_t loop_msdu;
if (tid >= OL_TXRX_NUM_EXT_TIDS) {
ol_txrx_err("invalid tid, %u", tid);
@ -1509,6 +1539,15 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev,
}
return;
}
/*Loop msdu to fill tstamp with tsf64 time in ol_rx_timestamp*/
loop_msdu = head_msdu;
while (loop_msdu) {
qdf_nbuf_t msdu = head_msdu;
rx_desc = htt_rx_msdu_desc_retrieve(pdev->htt_pdev, loop_msdu);
ol_rx_timestamp(pdev->ctrl_pdev, rx_desc, msdu);
loop_msdu = qdf_nbuf_next(loop_msdu);
}
peer->rx_opt_proc(vdev, peer, tid, head_msdu);
}

View file

@ -1230,6 +1230,8 @@ struct hdd_adapter {
uint64_t cur_target_time;
uint64_t cur_tsf_sync_soc_time;
uint64_t last_tsf_sync_soc_time;
uint64_t cur_target_global_tsf_time;
uint64_t last_target_global_tsf_time;
qdf_mc_timer_t host_capture_req_timer;
#ifdef WLAN_FEATURE_TSF_PLUS
/* spin lock for read/write timestamps */

View file

@ -664,6 +664,60 @@ static inline int32_t hdd_get_targettime_from_hosttime(
return ret;
}
/**
* hdd_get_soctime_from_tsf64time() - return get status
*
* @adapter: Adapter pointer
* @tsf64_time: current tsf64time, us
* @soc_time: current soc time(qtime), ns
*
* This function get current soc time from current tsf64 time
* Returun int32_t value to tell get success or fail.
*
* Return:
* 0: success
* other: fail
*
*/
static inline int32_t hdd_get_soctime_from_tsf64time(
struct hdd_adapter *adapter, uint64_t tsf64_time,
uint64_t *soc_time)
{
int32_t ret = -EINVAL;
uint64_t delta64_tsf64time;
uint64_t delta64_soctime;
bool in_cap_state;
in_cap_state = hdd_tsf_is_in_cap(adapter);
/*
* To avoid check the lock when it's not capturing tsf
* (the tstamp-pair won't be changed)
*/
if (in_cap_state)
qdf_spin_lock_bh(&adapter->host_target_sync_lock);
/* at present, target_time is 64bit (g_tsf64), us*/
if (tsf64_time > adapter->last_target_global_tsf_time)
delta64_tsf64time = tsf64_time -
adapter->last_target_global_tsf_time;
else {
if (in_cap_state)
qdf_spin_unlock_bh(&adapter->host_target_sync_lock);
return -EINVAL;
}
delta64_soctime = delta64_tsf64time * NSEC_PER_USEC;
/* soc_time (ns)*/
ret = hdd_uint64_plus(adapter->last_tsf_sync_soc_time,
delta64_soctime, soc_time);
if (in_cap_state)
qdf_spin_unlock_bh(&adapter->host_target_sync_lock);
return ret;
}
static inline
uint64_t hdd_get_monotonic_host_time(struct hdd_context *hdd_ctx)
{
@ -811,12 +865,16 @@ static void hdd_update_timestamp(struct hdd_adapter *adapter)
*/
case HDD_TS_STATUS_READY:
adapter->last_target_time = adapter->cur_target_time;
adapter->last_target_global_tsf_time =
adapter->cur_target_global_tsf_time;
adapter->last_tsf_sync_soc_time =
adapter->cur_tsf_sync_soc_time;
adapter->cur_target_time = 0;
adapter->cur_target_global_tsf_time = 0;
adapter->cur_tsf_sync_soc_time = 0;
hdd_info("ts-pair updated: target: %llu; Qtime: %llu",
hdd_info("ts-pair updated: target: %llu; g_target:%llu, Qtime: %llu",
adapter->last_target_time,
adapter->last_target_global_tsf_time,
adapter->last_tsf_sync_soc_time);
/*
@ -1171,6 +1229,7 @@ static enum hdd_tsf_op_result hdd_tsf_sync_deinit(struct hdd_adapter *adapter)
return HDD_TSF_OP_SUCC;
}
#ifdef CONFIG_HL_SUPPORT
static inline
enum hdd_tsf_op_result hdd_netbuf_timestamp(qdf_nbuf_t netbuf,
uint64_t target_time)
@ -1196,6 +1255,34 @@ enum hdd_tsf_op_result hdd_netbuf_timestamp(qdf_nbuf_t netbuf,
return HDD_TSF_OP_FAIL;
}
#else
static inline
enum hdd_tsf_op_result hdd_netbuf_timestamp(qdf_nbuf_t netbuf,
uint64_t target_time)
{
struct hdd_adapter *adapter;
struct net_device *net_dev = netbuf->dev;
if (!net_dev)
return HDD_TSF_OP_FAIL;
adapter = (struct hdd_adapter *)(netdev_priv(net_dev));
if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC &&
hdd_get_th_sync_status(adapter)) {
uint64_t tsf64_time = target_time;
uint64_t soc_time = 0;/*ns*/
int32_t ret = hdd_get_soctime_from_tsf64time(adapter,
tsf64_time, &soc_time);
if (!ret) {
netbuf->tstamp = soc_time;
return HDD_TSF_OP_SUCC;
}
}
return HDD_TSF_OP_FAIL;
}
#endif
int hdd_start_tsf_sync(struct hdd_adapter *adapter)
{
enum hdd_tsf_op_result ret;
@ -1819,12 +1906,13 @@ int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
adapter->cur_target_time = ((uint64_t)ptsf->tsf_high << 32 |
ptsf->tsf_low);
adapter->cur_target_global_tsf_time =
((uint64_t)ptsf->global_tsf_high << 32 |
ptsf->global_tsf_low);
tsf_sync_soc_time = ((uint64_t)ptsf->soc_timer_high << 32 |
ptsf->soc_timer_low);
adapter->cur_tsf_sync_soc_time =
qdf_log_timestamp_to_usecs(tsf_sync_soc_time) * NSEC_PER_USEC;
complete(&tsf_sync_get_completion_evt);
hdd_update_tsf(adapter, adapter->cur_target_time);
hdd_info("Vdev=%u, tsf_low=%u, tsf_high=%u ptsf->soc_timer_low=%u ptsf->soc_timer_high=%u",

View file

@ -4525,6 +4525,8 @@ struct sir_sme_ext_cng_chan_ind {
* @tsf_high: high 32bits of tsf
* @soc_timer_low: low 32bits of synced SOC timer value
* @soc_timer_high: high 32bits of synced SOC timer value
* @global_tsf_low: low 32bits of tsf64
* @global_tsf_high: high 32bits of tsf64
*
* driver use this struct to store the tsf info
*/
@ -4534,6 +4536,8 @@ struct stsf {
uint32_t tsf_high;
uint32_t soc_timer_low;
uint32_t soc_timer_high;
uint32_t global_tsf_low;
uint32_t global_tsf_high;
};
#define SIR_BCN_FLT_MAX_ELEMS_IE_LIST 8