Commit 3b0b55b1 authored by Govind Singh's avatar Govind Singh Committed by Kalle Valo

ath10k: Add support for 64 bit HTT in-order indication msg

WCN3990 target use 64bit msdu address in htt in-order
indication message. Add support for 64 bit msdu address in
HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND message.
Signed-off-by: default avatarGovind Singh <govinds@qti.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent e3def6f7
...@@ -855,13 +855,23 @@ struct htt_rx_in_ord_msdu_desc { ...@@ -855,13 +855,23 @@ struct htt_rx_in_ord_msdu_desc {
u8 reserved; u8 reserved;
} __packed; } __packed;
struct htt_rx_in_ord_msdu_desc_ext {
__le64 msdu_paddr;
__le16 msdu_len;
u8 fw_desc;
u8 reserved;
} __packed;
struct htt_rx_in_ord_ind { struct htt_rx_in_ord_ind {
u8 info; u8 info;
__le16 peer_id; __le16 peer_id;
u8 vdev_id; u8 vdev_id;
u8 reserved; u8 reserved;
__le16 msdu_count; __le16 msdu_count;
struct htt_rx_in_ord_msdu_desc msdu_descs[0]; union {
struct htt_rx_in_ord_msdu_desc msdu_descs32[0];
struct htt_rx_in_ord_msdu_desc_ext msdu_descs64[0];
} __packed;
} __packed; } __packed;
#define HTT_RX_IN_ORD_IND_INFO_TID_MASK 0x0000001f #define HTT_RX_IN_ORD_IND_INFO_TID_MASK 0x0000001f
......
...@@ -408,12 +408,12 @@ static struct sk_buff *ath10k_htt_rx_pop_paddr(struct ath10k_htt *htt, ...@@ -408,12 +408,12 @@ static struct sk_buff *ath10k_htt_rx_pop_paddr(struct ath10k_htt *htt,
return msdu; return msdu;
} }
static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt *htt, static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
struct htt_rx_in_ord_ind *ev, struct htt_rx_in_ord_ind *ev,
struct sk_buff_head *list) struct sk_buff_head *list)
{ {
struct ath10k *ar = htt->ar; struct ath10k *ar = htt->ar;
struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs; struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs32;
struct htt_rx_desc *rxd; struct htt_rx_desc *rxd;
struct sk_buff *msdu; struct sk_buff *msdu;
int msdu_count; int msdu_count;
...@@ -458,6 +458,55 @@ static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt *htt, ...@@ -458,6 +458,55 @@ static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt *htt,
return 0; return 0;
} }
static int ath10k_htt_rx_pop_paddr64_list(struct ath10k_htt *htt,
struct htt_rx_in_ord_ind *ev,
struct sk_buff_head *list)
{
struct ath10k *ar = htt->ar;
struct htt_rx_in_ord_msdu_desc_ext *msdu_desc = ev->msdu_descs64;
struct htt_rx_desc *rxd;
struct sk_buff *msdu;
int msdu_count;
bool is_offload;
u64 paddr;
lockdep_assert_held(&htt->rx_ring.lock);
msdu_count = __le16_to_cpu(ev->msdu_count);
is_offload = !!(ev->info & HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK);
while (msdu_count--) {
paddr = __le64_to_cpu(msdu_desc->msdu_paddr);
msdu = ath10k_htt_rx_pop_paddr(htt, paddr);
if (!msdu) {
__skb_queue_purge(list);
return -ENOENT;
}
__skb_queue_tail(list, msdu);
if (!is_offload) {
rxd = (void *)msdu->data;
trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
skb_put(msdu, sizeof(*rxd));
skb_pull(msdu, sizeof(*rxd));
skb_put(msdu, __le16_to_cpu(msdu_desc->msdu_len));
if (!(__le32_to_cpu(rxd->attention.flags) &
RX_ATTENTION_FLAGS_MSDU_DONE)) {
ath10k_warn(htt->ar, "tried to pop an incomplete frame, oops!\n");
return -EIO;
}
}
msdu_desc++;
}
return 0;
}
int ath10k_htt_rx_alloc(struct ath10k_htt *htt) int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
{ {
struct ath10k *ar = htt->ar; struct ath10k *ar = htt->ar;
...@@ -1986,7 +2035,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) ...@@ -1986,7 +2035,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
"htt rx in ord vdev %i peer %i tid %i offload %i frag %i msdu count %i\n", "htt rx in ord vdev %i peer %i tid %i offload %i frag %i msdu count %i\n",
vdev_id, peer_id, tid, offload, frag, msdu_count); vdev_id, peer_id, tid, offload, frag, msdu_count);
if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs)) { if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs32)) {
ath10k_warn(ar, "dropping invalid in order rx indication\n"); ath10k_warn(ar, "dropping invalid in order rx indication\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1995,7 +2044,13 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) ...@@ -1995,7 +2044,13 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
* extracted and processed. * extracted and processed.
*/ */
__skb_queue_head_init(&list); __skb_queue_head_init(&list);
ret = ath10k_htt_rx_pop_paddr_list(htt, &resp->rx_in_ord_ind, &list); if (ar->hw_params.target_64bit)
ret = ath10k_htt_rx_pop_paddr64_list(htt, &resp->rx_in_ord_ind,
&list);
else
ret = ath10k_htt_rx_pop_paddr32_list(htt, &resp->rx_in_ord_ind,
&list);
if (ret < 0) { if (ret < 0) {
ath10k_warn(ar, "failed to pop paddr list: %d\n", ret); ath10k_warn(ar, "failed to pop paddr list: %d\n", ret);
htt->rx_confused = true; htt->rx_confused = true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment