Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 30 additions & 12 deletions drivers/net/wireless/ath/ath12k/hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -828,8 +828,8 @@ void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len)
{
struct hal_tlv_64_hdr *tlv64 = tlv;

tlv64->tl = le64_encode_bits(tag, HAL_TLV_HDR_TAG) |
le64_encode_bits(len, HAL_TLV_HDR_LEN);
tlv64->tl = le64_encode_bits(tag, HAL_TLV_64_HDR_TAG) |
le64_encode_bits(len, HAL_TLV_64_HDR_LEN);

return tlv64->value;
}
Expand All @@ -846,26 +846,44 @@ void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len)
}
EXPORT_SYMBOL(ath12k_hal_encode_tlv32_hdr);

u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc)
void *ath12k_hal_decode_tlv64_hdr(void *tlv, u16 *tag, u16 *len, u16 *usrid)
{
struct hal_tlv_64_hdr *tlv64 = tlv;
u16 tag;

tag = le64_get_bits(tlv64->tl, HAL_SRNG_TLV_HDR_TAG);
*desc = tlv64->value;
if (tag)
*tag = le64_get_bits(tlv64->tl, HAL_TLV_64_HDR_TAG);
if (len)
*len = le64_get_bits(tlv64->tl, HAL_TLV_64_HDR_LEN);
if (usrid)
*usrid = le64_get_bits(tlv64->tl, HAL_TLV_64_USR_ID);

return tag;
return tlv64->value;
}
EXPORT_SYMBOL(ath12k_hal_decode_tlv64_hdr);

u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc)
void *ath12k_hal_decode_tlv32_hdr(void *tlv, u16 *tag, u16 *len, u16 *usrid)
{
struct hal_tlv_hdr *tlv32 = tlv;
u16 tag;

tag = le32_get_bits(tlv32->tl, HAL_SRNG_TLV_HDR_TAG);
*desc = tlv32->value;
if (tag)
*tag = le32_get_bits(tlv32->tl, HAL_TLV_HDR_TAG);
if (len)
*len = le32_get_bits(tlv32->tl, HAL_TLV_HDR_LEN);
if (usrid)
*usrid = le32_get_bits(tlv32->tl, HAL_TLV_USR_ID);

return tag;
return tlv32->value;
}
EXPORT_SYMBOL(ath12k_hal_decode_tlv32_hdr);

u32 ath12k_hal_get_tlv64_hdr_align(void)
{
return HAL_TLV_64_ALIGN;
}
EXPORT_SYMBOL(ath12k_hal_get_tlv64_hdr_align);

u32 ath12k_hal_get_tlv32_hdr_align(void)
{
return HAL_TLV_ALIGN;
}
EXPORT_SYMBOL(ath12k_hal_get_tlv32_hdr_align);
13 changes: 7 additions & 6 deletions drivers/net/wireless/ath/ath12k/hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1439,10 +1439,12 @@ struct hal_ops {
u8 *rbm, u32 *msdu_cnt);
void *(*reo_cmd_enc_tlv_hdr)(void *tlv, u64 tag, u64 len);
u16 (*reo_status_dec_tlv_hdr)(void *tlv, void **desc);
void *(*mon_rx_status_dec_tlv_hdr)(void *tlv, u16 *tag, u16 *len, u16 *usrid);
u32 (*get_tlv_hdr_align)(void);
};

#define HAL_TLV_HDR_TAG GENMASK(9, 1)
#define HAL_TLV_HDR_LEN GENMASK(25, 10)
#define HAL_TLV_HDR_LEN GENMASK(21, 10)
#define HAL_TLV_USR_ID GENMASK(31, 26)

#define HAL_TLV_ALIGN 4
Expand All @@ -1462,9 +1464,6 @@ struct hal_tlv_64_hdr {
u8 value[];
} __packed;

#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1)
#define HAL_SRNG_TLV_HDR_LEN GENMASK(25, 10)

dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab,
struct hal_srng *srng);
dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab,
Expand Down Expand Up @@ -1554,6 +1553,8 @@ void ath12k_hal_rx_reo_ent_buf_paddr_get(struct ath12k_hal *hal, void *rx_desc,
u8 *rbm, u32 *msdu_cnt);
void *ath12k_hal_encode_tlv64_hdr(void *tlv, u64 tag, u64 len);
void *ath12k_hal_encode_tlv32_hdr(void *tlv, u64 tag, u64 len);
u16 ath12k_hal_decode_tlv64_hdr(void *tlv, void **desc);
u16 ath12k_hal_decode_tlv32_hdr(void *tlv, void **desc);
void *ath12k_hal_decode_tlv64_hdr(void *tlv, u16 *tag, u16 *len, u16 *usrid);
void *ath12k_hal_decode_tlv32_hdr(void *tlv, u16 *tag, u16 *len, u16 *usrid);
u32 ath12k_hal_get_tlv64_hdr_align(void);
u32 ath12k_hal_get_tlv32_hdr_align(void);
#endif
59 changes: 30 additions & 29 deletions drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1565,16 +1565,17 @@ ath12k_wifi7_dp_mon_parse_status_msdu_end(struct ath12k_mon_data *pmon,
static enum hal_rx_mon_status
ath12k_wifi7_dp_mon_rx_parse_status_tlv(struct ath12k_pdev_dp *dp_pdev,
struct ath12k_mon_data *pmon,
const struct hal_tlv_64_hdr *tlv)
const void *tlv)
{
struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
const void *tlv_data = tlv->value;
u32 info[7], userid;
u16 tlv_tag, tlv_len;
struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev);
struct ath12k_hal *hal = &ar->ab->hal;
u16 tlv_tag, tlv_len, userid;
void *tlv_data;
u32 info[7];

tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG);
tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN);
userid = le64_get_bits(tlv->tl, HAL_TLV_64_USR_ID);
tlv_data = hal->ops->mon_rx_status_dec_tlv_hdr((void *)tlv, &tlv_tag,
&tlv_len, &userid);

if (ppdu_info->tlv_aggr.in_progress && ppdu_info->tlv_aggr.tlv_tag != tlv_tag) {
ath12k_wifi7_dp_mon_parse_eht_sig_hdr(ppdu_info,
Expand Down Expand Up @@ -2931,11 +2932,12 @@ static enum dp_mon_status_buf_state
ath12k_wifi7_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng,
struct dp_rxdma_mon_ring *rx_ring)
{
struct ath12k_hal *hal = &ab->hal;
struct ath12k_skb_rxcb *rxcb;
struct hal_tlv_64_hdr *tlv;
struct sk_buff *skb;
void *status_desc;
dma_addr_t paddr;
u16 tlv_tag;
u32 cookie;
int buf_id;
u8 rbm;
Expand All @@ -2960,8 +2962,8 @@ ath12k_wifi7_dp_rx_mon_buf_done(struct ath12k_base *ab, struct hal_srng *srng,
skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);

tlv = (struct hal_tlv_64_hdr *)skb->data;
if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) != HAL_RX_STATUS_BUFFER_DONE)
hal->ops->mon_rx_status_dec_tlv_hdr(skb->data, &tlv_tag, NULL, NULL);
if (tlv_tag != HAL_RX_STATUS_BUFFER_DONE)
return DP_MON_STATUS_NO_DMA;

return DP_MON_STATUS_REPLINISH;
Expand All @@ -2973,41 +2975,40 @@ ath12k_wifi7_dp_mon_parse_rx_dest(struct ath12k_pdev_dp *dp_pdev,
struct sk_buff *skb)
{
struct ath12k *ar = ath12k_pdev_dp_to_ar(dp_pdev);
struct hal_tlv_64_hdr *tlv;
struct ath12k_hal *hal = &ar->ab->hal;
u8 *tlv_value, *tlv = skb->data;
struct ath12k_skb_rxcb *rxcb;
enum hal_rx_mon_status hal_status;
u16 tlv_tag, tlv_len;
u8 *ptr = skb->data;
u32 tlv_hdr_len;

tlv_hdr_len = hal->ops->get_tlv_hdr_align();

do {
tlv = (struct hal_tlv_64_hdr *)ptr;
tlv_tag = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_TAG);
tlv_value = hal->ops->mon_rx_status_dec_tlv_hdr(tlv, &tlv_tag,
&tlv_len, NULL);

/* The actual length of PPDU_END is the combined length of many PHY
* TLVs that follow. Skip the TLV header and
* rx_rxpcu_classification_overview that follows the header to get to
* next TLV.
*/

if (tlv_tag == HAL_RX_PPDU_END)
tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview);
else
tlv_len = le64_get_bits(tlv->tl, HAL_TLV_64_HDR_LEN);

hal_status = ath12k_wifi7_dp_mon_rx_parse_status_tlv(dp_pdev, pmon,
tlv);

if (ar->monitor_started && ar->ab->hw_params->rxdma1_enable &&
ath12k_wifi7_dp_mon_parse_rx_dest_tlv(dp_pdev, pmon, hal_status,
tlv->value))
tlv_value))
return HAL_RX_MON_STATUS_PPDU_DONE;

ptr += sizeof(*tlv) + tlv_len;
ptr = PTR_ALIGN(ptr, HAL_TLV_64_ALIGN);
tlv = PTR_ALIGN(tlv + tlv_len + tlv_hdr_len, tlv_hdr_len);

if ((ptr - skb->data) > skb->len)
if (unlikely(tlv - skb->data > skb->len ||
skb->len - (tlv - skb->data) < tlv_hdr_len))
break;

} while ((hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE) ||
(hal_status == HAL_RX_MON_STATUS_BUF_ADDR) ||
(hal_status == HAL_RX_MON_STATUS_MPDU_START) ||
Expand Down Expand Up @@ -3057,15 +3058,16 @@ ath12k_wifi7_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id,
int buf_id, srng_id, num_buffs_reaped = 0;
enum dp_mon_status_buf_state reap_status;
struct dp_rxdma_mon_ring *rx_ring;
struct ath12k_hal *hal = &ab->hal;
struct ath12k_mon_data *pmon;
struct ath12k_skb_rxcb *rxcb;
struct hal_tlv_64_hdr *tlv;
void *rx_mon_status_desc;
struct hal_srng *srng;
struct ath12k_dp *dp;
struct sk_buff *skb;
struct ath12k *ar;
dma_addr_t paddr;
u16 tlv_tag;
u32 cookie;
u8 rbm;

Expand Down Expand Up @@ -3110,14 +3112,13 @@ ath12k_wifi7_dp_rx_reap_mon_status_ring(struct ath12k_base *ab, int mac_id,
skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);

tlv = (struct hal_tlv_64_hdr *)skb->data;
if (le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG) !=
HAL_RX_STATUS_BUFFER_DONE) {
hal->ops->mon_rx_status_dec_tlv_hdr(skb->data, &tlv_tag,
NULL, NULL);
if (tlv_tag != HAL_RX_STATUS_BUFFER_DONE) {
pmon->buf_state = DP_MON_STATUS_NO_DMA;
ath12k_warn(ab,
"mon status DONE not set %llx, buf_id %d\n",
le64_get_bits(tlv->tl, HAL_TLV_HDR_TAG),
buf_id);
"mon status DONE not set %x, buf_id %d\n",
tlv_tag, buf_id);
/* RxDMA status done bit might not be set even
* though tp is moved by HW.
*/
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/wireless/ath/ath12k/wifi7/hal_qcc2072.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ static u16 ath12k_hal_reo_status_dec_tlv_hdr_qcc2072(void *tlv, void **desc)
struct hal_reo_get_queue_stats_status_qcc2072 *status_tlv;
u16 tag;

tag = ath12k_hal_decode_tlv32_hdr(tlv, (void **)&status_tlv);
status_tlv = ath12k_hal_decode_tlv32_hdr(tlv, &tag, NULL, NULL);
/*
* actual desc of REO status entry starts after tlv32_padding,
* see hal_reo_get_queue_stats_status_qcc2072
Expand Down Expand Up @@ -490,6 +490,8 @@ const struct hal_ops hal_qcc2072_ops = {
.rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
.reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv32_hdr,
.reo_status_dec_tlv_hdr = ath12k_hal_reo_status_dec_tlv_hdr_qcc2072,
.mon_rx_status_dec_tlv_hdr = ath12k_hal_decode_tlv32_hdr,
.get_tlv_hdr_align = ath12k_hal_get_tlv32_hdr_align,
};

u32 ath12k_hal_rx_desc_get_mpdu_start_offset_qcc2072(void)
Expand Down
13 changes: 12 additions & 1 deletion drivers/net/wireless/ath/ath12k/wifi7/hal_qcn9274.c
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,15 @@ void ath12k_hal_extract_rx_desc_data_qcn9274(struct hal_rx_desc_data *rx_desc_da
rx_desc_data->err_bitmap = ath12k_hal_rx_h_mpdu_err_qcn9274(rx_desc);
}

static u16 ath12k_hal_reo_status_dec_tlv_hdr_qcn9274(void *tlv, void **desc)
{
u16 tag;

*desc = ath12k_hal_decode_tlv64_hdr(tlv, &tag, NULL, NULL);

return tag;
}

const struct ath12k_hw_hal_params ath12k_hw_hal_params_qcn9274 = {
.rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM,
.wbm2sw_cc_enable = HAL_WBM_SW_COOKIE_CONV_CFG_WBM2SW0_EN |
Expand Down Expand Up @@ -1122,5 +1131,7 @@ const struct hal_ops hal_qcn9274_ops = {
.rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get,
.rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
.reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr,
.reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
.reo_status_dec_tlv_hdr = ath12k_hal_reo_status_dec_tlv_hdr_qcn9274,
.mon_rx_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
.get_tlv_hdr_align = ath12k_hal_get_tlv64_hdr_align,
};
13 changes: 12 additions & 1 deletion drivers/net/wireless/ath/ath12k/wifi7/hal_wcn7850.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,15 @@ int ath12k_hal_srng_create_config_wcn7850(struct ath12k_hal *hal)
return 0;
}

static u16 ath12k_hal_reo_status_dec_tlv_hdr_wcn7850(void *tlv, void **desc)
{
u16 tag;

*desc = ath12k_hal_decode_tlv64_hdr(tlv, &tag, NULL, NULL);

return tag;
}

const struct ath12k_hal_tcl_to_wbm_rbm_map
ath12k_hal_tcl_to_wbm_rbm_map_wcn7850[DP_TCL_NUM_RING_MAX] = {
{
Expand Down Expand Up @@ -805,5 +814,7 @@ const struct hal_ops hal_wcn7850_ops = {
.rx_msdu_list_get = ath12k_wifi7_hal_rx_msdu_list_get,
.rx_reo_ent_buf_paddr_get = ath12k_wifi7_hal_rx_reo_ent_buf_paddr_get,
.reo_cmd_enc_tlv_hdr = ath12k_hal_encode_tlv64_hdr,
.reo_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
.reo_status_dec_tlv_hdr = ath12k_hal_reo_status_dec_tlv_hdr_wcn7850,
.mon_rx_status_dec_tlv_hdr = ath12k_hal_decode_tlv64_hdr,
.get_tlv_hdr_align = ath12k_hal_get_tlv64_hdr_align,
};