diff options
author | Govind Singh <govinds@qti.qualcomm.com> | 2017-12-21 04:00:52 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2017-12-27 05:05:44 -0500 |
commit | 3b0b55b19d1d46158c3156a42dcc0912bbfa3070 (patch) | |
tree | 7aaaf3b460680299bf057b43c1d89977884d3275 | |
parent | e3def6f7ddf88636febb12e1e3e86387a4ce5452 (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.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/htt_rx.c | 67 |
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 | ||
858 | struct 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 | |||
858 | struct htt_rx_in_ord_ind { | 865 | struct 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 | ||
411 | static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt *htt, | 411 | static 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 | ||
461 | static 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 | |||
461 | int ath10k_htt_rx_alloc(struct ath10k_htt *htt) | 510 | int 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; |