qcacmn: Support HW Tx delay for MLO

Add delta_tqm, delta_tsf2 and mlo timestamp offset for BE.
These offsets are used to calculate hardware Tx completion delay.
delta_tsf2 and delta_tqm are updated during init. mlo timestamp
offset is updated whenever target sends the update event.

Also, adding CDP ops to set the offsets.

Change-Id: I55665982798c3a795481fa96c023bb851ea17476
CRs-Fixed: 3220906
Esse commit está contido em:
Ripan Deuri
2022-05-16 15:39:44 +05:30
commit de Madan Koyyalamudi
commit b8fadd7061
8 arquivos alterados com 285 adições e 1 exclusões

Ver arquivo

@@ -381,11 +381,51 @@ static void dp_mlo_setup_complete(struct cdp_mlo_ctxt *cdp_ml_ctxt)
}
}
static void dp_mlo_update_delta_tsf2(struct cdp_soc_t *soc_hdl,
uint8_t pdev_id, uint64_t delta_tsf2)
{
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
struct dp_pdev *pdev;
struct dp_pdev_be *be_pdev;
pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
pdev_id);
if (!pdev) {
dp_err("pdev is NULL for pdev_id %u", pdev_id);
return;
}
be_pdev = dp_get_be_pdev_from_dp_pdev(pdev);
be_pdev->delta_tsf2 = delta_tsf2;
}
static void dp_mlo_update_delta_tqm(struct cdp_soc_t *soc_hdl,
uint64_t delta_tqm)
{
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
be_soc->delta_tqm = delta_tqm;
}
static void dp_mlo_update_mlo_ts_offset(struct cdp_soc_t *soc_hdl,
uint64_t offset)
{
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
be_soc->mlo_tstamp_offset = offset;
}
static struct cdp_mlo_ops dp_mlo_ops = {
.mlo_soc_setup = dp_mlo_soc_setup,
.mlo_soc_teardown = dp_mlo_soc_teardown,
.update_mlo_ptnr_list = dp_update_mlo_ptnr_list,
.mlo_setup_complete = dp_mlo_setup_complete,
.mlo_update_delta_tsf2 = dp_mlo_update_delta_tsf2,
.mlo_update_delta_tqm = dp_mlo_update_delta_tqm,
.mlo_update_mlo_ts_offset = dp_mlo_update_mlo_ts_offset,
};
void dp_soc_mlo_fill_params(struct dp_soc *soc,
@@ -404,6 +444,57 @@ void dp_soc_mlo_fill_params(struct dp_soc *soc,
soc->cdp_soc.ops->mlo_ops = &dp_mlo_ops;
}
void dp_mlo_update_link_to_pdev_map(struct dp_soc *soc, struct dp_pdev *pdev)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
struct dp_pdev_be *be_pdev = dp_get_be_pdev_from_dp_pdev(pdev);
struct dp_mlo_ctxt *ml_ctxt = be_soc->ml_ctxt;
uint8_t link_id;
if (!be_soc->mlo_enabled)
return;
if (!ml_ctxt)
return;
link_id = be_pdev->mlo_link_id;
if (link_id < WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC) {
if (!ml_ctxt->link_to_pdev_map[link_id])
ml_ctxt->link_to_pdev_map[link_id] = be_pdev;
else
dp_alert("Attempt to update existing map for link %u",
link_id);
}
}
void dp_mlo_update_link_to_pdev_unmap(struct dp_soc *soc, struct dp_pdev *pdev)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
struct dp_pdev_be *be_pdev = dp_get_be_pdev_from_dp_pdev(pdev);
struct dp_mlo_ctxt *ml_ctxt = be_soc->ml_ctxt;
uint8_t link_id;
if (!be_soc->mlo_enabled)
return;
if (!ml_ctxt)
return;
link_id = be_pdev->mlo_link_id;
if (link_id < WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC)
ml_ctxt->link_to_pdev_map[link_id] = NULL;
}
static struct dp_pdev_be *
dp_mlo_get_be_pdev_from_link_id(struct dp_mlo_ctxt *ml_ctxt, uint8_t link_id)
{
if (link_id < WLAN_MAX_MLO_CHIPS * WLAN_MAX_MLO_LINKS_PER_SOC)
return ml_ctxt->link_to_pdev_map[link_id];
return NULL;
}
void dp_pdev_mlo_fill_params(struct dp_pdev *pdev,
struct cdp_pdev_attach_params *params)
{
@@ -655,3 +746,57 @@ struct dp_vdev *dp_mlo_get_mcast_primary_vdev(struct dp_soc_be *be_soc,
qdf_export_symbol(dp_mlo_get_mcast_primary_vdev);
#endif
static inline uint64_t dp_mlo_get_mlo_ts_offset(struct dp_pdev_be *be_pdev)
{
struct dp_soc *soc;
struct dp_pdev *pdev;
struct dp_soc_be *be_soc;
uint32_t mlo_offset;
pdev = &be_pdev->pdev;
soc = pdev->soc;
be_soc = dp_get_be_soc_from_dp_soc(soc);
mlo_offset = be_soc->mlo_tstamp_offset;
return mlo_offset;
}
int32_t dp_mlo_get_delta_tsf2_wrt_mlo_offset(struct dp_soc *soc,
uint8_t hw_link_id)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
struct dp_mlo_ctxt *ml_ctxt = be_soc->ml_ctxt;
struct dp_pdev_be *be_pdev;
int32_t delta_tsf2_mlo_offset;
int32_t mlo_offset, delta_tsf2;
if (!ml_ctxt)
return 0;
be_pdev = dp_mlo_get_be_pdev_from_link_id(ml_ctxt, hw_link_id);
if (!be_pdev)
return 0;
mlo_offset = dp_mlo_get_mlo_ts_offset(be_pdev);
delta_tsf2 = be_pdev->delta_tsf2;
delta_tsf2_mlo_offset = mlo_offset - delta_tsf2;
return delta_tsf2_mlo_offset;
}
int32_t dp_mlo_get_delta_tqm_wrt_mlo_offset(struct dp_soc *soc)
{
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
int32_t delta_tqm_mlo_offset;
int32_t mlo_offset, delta_tqm;
mlo_offset = be_soc->mlo_tstamp_offset;
delta_tqm = be_soc->delta_tqm;
delta_tqm_mlo_offset = mlo_offset - delta_tqm;
return delta_tqm_mlo_offset;
}