aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGovind Singh <govinds@qti.qualcomm.com>2017-12-21 04:00:52 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2017-12-27 05:05:44 -0500
commit3b0b55b19d1d46158c3156a42dcc0912bbfa3070 (patch)
tree7aaaf3b460680299bf057b43c1d89977884d3275
parente3def6f7ddf88636febb12e1e3e86387a4ce5452 (diff)
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: Govind Singh <govinds@qti.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h12
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c67
2 files changed, 72 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 7bd93d627f6b..626f7e2c1669 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -855,13 +855,23 @@ struct htt_rx_in_ord_msdu_desc {
855 u8 reserved; 855 u8 reserved;
856} __packed; 856} __packed;
857 857
858struct htt_rx_in_ord_msdu_desc_ext {
859 __le64 msdu_paddr;
860 __le16 msdu_len;
861 u8 fw_desc;
862 u8 reserved;
863} __packed;
864
858struct htt_rx_in_ord_ind { 865struct htt_rx_in_ord_ind {
859 u8 info; 866 u8 info;
860 __le16 peer_id; 867 __le16 peer_id;
861 u8 vdev_id; 868 u8 vdev_id;
862 u8 reserved; 869 u8 reserved;
863 __le16 msdu_count; 870 __le16 msdu_count;
864 struct htt_rx_in_ord_msdu_desc msdu_descs[0]; 871 union {
872 struct htt_rx_in_ord_msdu_desc msdu_descs32[0];
873 struct htt_rx_in_ord_msdu_desc_ext msdu_descs64[0];
874 } __packed;
865} __packed; 875} __packed;
866 876
867#define HTT_RX_IN_ORD_IND_INFO_TID_MASK 0x0000001f 877#define HTT_RX_IN_ORD_IND_INFO_TID_MASK 0x0000001f
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 620ed7dca836..4038902d0caa 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -408,12 +408,12 @@ static struct sk_buff *ath10k_htt_rx_pop_paddr(struct ath10k_htt *htt,
408 return msdu; 408 return msdu;
409} 409}
410 410
411static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt *htt, 411static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
412 struct htt_rx_in_ord_ind *ev, 412 struct htt_rx_in_ord_ind *ev,
413 struct sk_buff_head *list) 413 struct sk_buff_head *list)
414{ 414{
415 struct ath10k *ar = htt->ar; 415 struct ath10k *ar = htt->ar;
416 struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs; 416 struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs32;
417 struct htt_rx_desc *rxd; 417 struct htt_rx_desc *rxd;
418 struct sk_buff *msdu; 418 struct sk_buff *msdu;
419 int msdu_count; 419 int msdu_count;
@@ -458,6 +458,55 @@ static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt *htt,
458 return 0; 458 return 0;
459} 459}
460 460
461static int ath10k_htt_rx_pop_paddr64_list(struct ath10k_htt *htt,
462 struct htt_rx_in_ord_ind *ev,
463 struct sk_buff_head *list)
464{
465 struct ath10k *ar = htt->ar;
466 struct htt_rx_in_ord_msdu_desc_ext *msdu_desc = ev->msdu_descs64;
467 struct htt_rx_desc *rxd;
468 struct sk_buff *msdu;
469 int msdu_count;
470 bool is_offload;
471 u64 paddr;
472
473 lockdep_assert_held(&htt->rx_ring.lock);
474
475 msdu_count = __le16_to_cpu(ev->msdu_count);
476 is_offload = !!(ev->info & HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK);
477
478 while (msdu_count--) {
479 paddr = __le64_to_cpu(msdu_desc->msdu_paddr);
480 msdu = ath10k_htt_rx_pop_paddr(htt, paddr);
481 if (!msdu) {
482 __skb_queue_purge(list);
483 return -ENOENT;
484 }
485
486 __skb_queue_tail(list, msdu);
487
488 if (!is_offload) {
489 rxd = (void *)msdu->data;
490
491 trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
492
493 skb_put(msdu, sizeof(*rxd));
494 skb_pull(msdu, sizeof(*rxd));
495 skb_put(msdu, __le16_to_cpu(msdu_desc->msdu_len));
496
497 if (!(__le32_to_cpu(rxd->attention.flags) &
498 RX_ATTENTION_FLAGS_MSDU_DONE)) {
499 ath10k_warn(htt->ar, "tried to pop an incomplete frame, oops!\n");
500 return -EIO;
501 }
502 }
503
504 msdu_desc++;
505 }
506
507 return 0;
508}
509
461int ath10k_htt_rx_alloc(struct ath10k_htt *htt) 510int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
462{ 511{
463 struct ath10k *ar = htt->ar; 512 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 "htt rx in ord vdev %i peer %i tid %i offload %i frag %i msdu count %i\n", 2035 "htt rx in ord vdev %i peer %i tid %i offload %i frag %i msdu count %i\n",
1987 vdev_id, peer_id, tid, offload, frag, msdu_count); 2036 vdev_id, peer_id, tid, offload, frag, msdu_count);
1988 2037
1989 if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs)) { 2038 if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs32)) {
1990 ath10k_warn(ar, "dropping invalid in order rx indication\n"); 2039 ath10k_warn(ar, "dropping invalid in order rx indication\n");
1991 return -EINVAL; 2040 return -EINVAL;
1992 } 2041 }
@@ -1995,7 +2044,13 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
1995 * extracted and processed. 2044 * extracted and processed.
1996 */ 2045 */
1997 __skb_queue_head_init(&list); 2046 __skb_queue_head_init(&list);
1998 ret = ath10k_htt_rx_pop_paddr_list(htt, &resp->rx_in_ord_ind, &list); 2047 if (ar->hw_params.target_64bit)
2048 ret = ath10k_htt_rx_pop_paddr64_list(htt, &resp->rx_in_ord_ind,
2049 &list);
2050 else
2051 ret = ath10k_htt_rx_pop_paddr32_list(htt, &resp->rx_in_ord_ind,
2052 &list);
2053
1999 if (ret < 0) { 2054 if (ret < 0) {
2000 ath10k_warn(ar, "failed to pop paddr list: %d\n", ret); 2055 ath10k_warn(ar, "failed to pop paddr list: %d\n", ret);
2001 htt->rx_confused = true; 2056 htt->rx_confused = true;