From df25d1f117fd368ea44d4aa5c4d6172dbb1a761c Mon Sep 17 00:00:00 2001 From: Anilkumar Kolli Date: Tue, 24 Mar 2020 12:11:26 +0530 Subject: [PATCH 1174/1179] ath11k: add qcn9000 dp rx support Signed-off-by: Anilkumar Kolli --- drivers/net/wireless/ath/ath11k/dp_rx.c | 624 ++++++++++++++++++------------ drivers/net/wireless/ath/ath11k/hal.h | 2 - drivers/net/wireless/ath/ath11k/hw.c | 529 +++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/hw.h | 36 ++ drivers/net/wireless/ath/ath11k/rx_desc.h | 212 +++++++++- 5 files changed, 1148 insertions(+), 255 deletions(-) --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -18,101 +18,108 @@ #define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ) -static u8 *ath11k_dp_rx_h_80211_hdr(struct hal_rx_desc *desc) +static u8 *ath11k_dp_rx_h_80211_hdr(struct ath11k_base *ab, struct hal_rx_desc *desc) { - return desc->hdr_status; + return ab->hw_params.hw_ops->rx_desc_get_hdr_status(desc); } -static enum hal_encrypt_type ath11k_dp_rx_h_mpdu_start_enctype(struct hal_rx_desc *desc) +static enum hal_encrypt_type ath11k_dp_rx_h_mpdu_start_enctype(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - if (!(__le32_to_cpu(desc->mpdu_start.info1) & - RX_MPDU_START_INFO1_ENCRYPT_INFO_VALID)) + if (!ab->hw_params.hw_ops->rx_desc_encrypt_valid(desc)) return HAL_ENCRYPT_TYPE_OPEN; - return FIELD_GET(RX_MPDU_START_INFO2_ENC_TYPE, - __le32_to_cpu(desc->mpdu_start.info2)); + return ab->hw_params.hw_ops->rx_desc_get_encrypt_type(desc); } -static u8 ath11k_dp_rx_h_msdu_start_decap_type(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_msdu_start_decap_type(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MSDU_START_INFO2_DECAP_FORMAT, - __le32_to_cpu(desc->msdu_start.info2)); + return ab->hw_params.hw_ops->rx_desc_get_decap_type(desc); } -static u8 ath11k_dp_rx_h_msdu_start_mesh_ctl_present(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_msdu_start_mesh_ctl_present(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MSDU_START_INFO2_MESH_CTRL_PRESENT, - __le32_to_cpu(desc->msdu_start.info2)); + return ab->hw_params.hw_ops->rx_desc_get_mesh_ctl(desc); } -static bool ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(struct hal_rx_desc *desc) +static bool ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_CTRL_VALID, - __le32_to_cpu(desc->mpdu_start.info1)); + return ab->hw_params.hw_ops->rx_desc_get_mpdu_seq_ctl_vld(desc); } -static bool ath11k_dp_rx_h_mpdu_start_fc_valid(struct hal_rx_desc *desc) +static bool ath11k_dp_rx_h_mpdu_start_fc_valid(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_FCTRL_VALID, - __le32_to_cpu(desc->mpdu_start.info1)); + return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc); } -static bool ath11k_dp_rx_h_mpdu_start_more_frags(struct sk_buff *skb) +static bool ath11k_dp_rx_h_mpdu_start_more_frags(struct ath11k_base *ab, + struct sk_buff *skb) { struct ieee80211_hdr *hdr; - hdr = (struct ieee80211_hdr *)(skb->data + HAL_RX_DESC_SIZE); + hdr = (struct ieee80211_hdr *)(skb->data + ab->hw_params.hal_desc_sz); return ieee80211_has_morefrags(hdr->frame_control); } -static u16 ath11k_dp_rx_h_mpdu_start_frag_no(struct sk_buff *skb) +static u16 ath11k_dp_rx_h_mpdu_start_frag_no(struct ath11k_base *ab, + struct sk_buff *skb) { struct ieee80211_hdr *hdr; - hdr = (struct ieee80211_hdr *)(skb->data + HAL_RX_DESC_SIZE); + hdr = (struct ieee80211_hdr *)(skb->data + ab->hw_params.hal_desc_sz); return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; } -static u16 ath11k_dp_rx_h_mpdu_start_seq_no(struct hal_rx_desc *desc) +static u16 ath11k_dp_rx_h_mpdu_start_seq_no(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_NUM, - __le32_to_cpu(desc->mpdu_start.info1)); + return ab->hw_params.hw_ops->rx_desc_get_mpdu_start_seq_no(desc); } -static bool ath11k_dp_rx_h_attn_msdu_done(struct hal_rx_desc *desc) +static void *ath11k_dp_rx_get_attention(struct ath11k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hw_params.hw_ops->rx_desc_get_attention(desc); +} + +static bool ath11k_dp_rx_h_attn_msdu_done(struct rx_attention *attn) { return !!FIELD_GET(RX_ATTENTION_INFO2_MSDU_DONE, - __le32_to_cpu(desc->attention.info2)); + __le32_to_cpu(attn->info2)); } -static bool ath11k_dp_rx_h_attn_first_mpdu(struct hal_rx_desc *desc) +static bool ath11k_dp_rx_h_attn_first_mpdu(struct rx_attention *attn) { return !!FIELD_GET(RX_ATTENTION_INFO1_FIRST_MPDU, - __le32_to_cpu(desc->attention.info1)); + __le32_to_cpu(attn->info1)); } -static bool ath11k_dp_rx_h_attn_l4_cksum_fail(struct hal_rx_desc *desc) +static bool ath11k_dp_rx_h_attn_l4_cksum_fail(struct rx_attention *attn) { return !!FIELD_GET(RX_ATTENTION_INFO1_TCP_UDP_CKSUM_FAIL, - __le32_to_cpu(desc->attention.info1)); + __le32_to_cpu(attn->info1)); } -static bool ath11k_dp_rx_h_attn_ip_cksum_fail(struct hal_rx_desc *desc) +static bool ath11k_dp_rx_h_attn_ip_cksum_fail(struct rx_attention *attn) { return !!FIELD_GET(RX_ATTENTION_INFO1_IP_CKSUM_FAIL, - __le32_to_cpu(desc->attention.info1)); + __le32_to_cpu(attn->info1)); } -static bool ath11k_dp_rx_h_attn_is_decrypted(struct hal_rx_desc *desc) +static bool ath11k_dp_rx_h_attn_is_decrypted(struct rx_attention *attn) { return (FIELD_GET(RX_ATTENTION_INFO2_DCRYPT_STATUS_CODE, - __le32_to_cpu(desc->attention.info2)) == + __le32_to_cpu(attn->info2)) == RX_DESC_DECRYPT_STATUS_CODE_OK); } -static u32 ath11k_dp_rx_h_attn_mpdu_err(struct hal_rx_desc *desc) +static u32 ath11k_dp_rx_h_attn_mpdu_err(struct rx_attention *attn) { - u32 info = __le32_to_cpu(desc->attention.info1); + u32 info = __le32_to_cpu(attn->info1); u32 errmap = 0; if (info & RX_ATTENTION_INFO1_FCS_ERR) @@ -139,138 +146,144 @@ static u32 ath11k_dp_rx_h_attn_mpdu_err( return errmap; } -static u16 ath11k_dp_rx_h_msdu_start_msdu_len(struct hal_rx_desc *desc) +static u16 ath11k_dp_rx_h_msdu_start_msdu_len(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MSDU_START_INFO1_MSDU_LENGTH, - __le32_to_cpu(desc->msdu_start.info1)); + return ab->hw_params.hw_ops->rx_desc_get_msdu_len(desc); } -static u8 ath11k_dp_rx_h_msdu_start_sgi(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_msdu_start_sgi(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MSDU_START_INFO3_SGI, - __le32_to_cpu(desc->msdu_start.info3)); + return ab->hw_params.hw_ops->rx_desc_get_msdu_sgi(desc); } -static u8 ath11k_dp_rx_h_msdu_start_rate_mcs(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_msdu_start_rate_mcs(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MSDU_START_INFO3_RATE_MCS, - __le32_to_cpu(desc->msdu_start.info3)); + return ab->hw_params.hw_ops->rx_desc_get_msdu_rate_mcs(desc); } -static u8 ath11k_dp_rx_h_msdu_start_rx_bw(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_msdu_start_rx_bw(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MSDU_START_INFO3_RECV_BW, - __le32_to_cpu(desc->msdu_start.info3)); + return ab->hw_params.hw_ops->rx_desc_get_msdu_rx_bw(desc); } -static u32 ath11k_dp_rx_h_msdu_start_freq(struct hal_rx_desc *desc) +static u32 ath11k_dp_rx_h_msdu_start_freq(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return __le32_to_cpu(desc->msdu_start.phy_meta_data); + return ab->hw_params.hw_ops->rx_desc_get_msdu_freq(desc); } -static u8 ath11k_dp_rx_h_msdu_start_pkt_type(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_msdu_start_pkt_type(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MSDU_START_INFO3_PKT_TYPE, - __le32_to_cpu(desc->msdu_start.info3)); + return ab->hw_params.hw_ops->rx_desc_get_msdu_pkt_type(desc); } -static u8 ath11k_dp_rx_h_msdu_start_nss(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_msdu_start_nss(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - u8 mimo_ss_bitmap = FIELD_GET(RX_MSDU_START_INFO3_MIMO_SS_BITMAP, - __le32_to_cpu(desc->msdu_start.info3)); - - return hweight8(mimo_ss_bitmap); + return hweight8(ab->hw_params.hw_ops->rx_desc_get_msdu_nss(desc)); } -static u8 ath11k_dp_rx_h_mpdu_start_tid(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_mpdu_start_tid(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MPDU_START_INFO2_TID, - __le32_to_cpu(desc->mpdu_start.info2)); + return ab->hw_params.hw_ops->rx_desc_get_mpdu_tid(desc); } -static u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct hal_rx_desc *desc) +static u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return __le16_to_cpu(desc->mpdu_start.sw_peer_id); + return ab->hw_params.hw_ops->rx_desc_get_mpdu_peer_id(desc); } -static u8 ath11k_dp_rx_h_msdu_end_l3pad(struct hal_rx_desc *desc) +static u8 ath11k_dp_rx_h_msdu_end_l3pad(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return FIELD_GET(RX_MSDU_END_INFO2_L3_HDR_PADDING, - __le32_to_cpu(desc->msdu_end.info2)); + return ab->hw_params.hw_ops->rx_desc_get_l3_pad_bytes(desc); } -static bool ath11k_dp_rx_h_msdu_end_first_msdu(struct hal_rx_desc *desc) +static bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return !!FIELD_GET(RX_MSDU_END_INFO2_FIRST_MSDU, - __le32_to_cpu(desc->msdu_end.info2)); + return ab->hw_params.hw_ops->rx_desc_get_first_msdu(desc); } -static bool ath11k_dp_rx_h_msdu_end_last_msdu(struct hal_rx_desc *desc) +static bool ath11k_dp_rx_h_msdu_end_last_msdu(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return !!FIELD_GET(RX_MSDU_END_INFO2_LAST_MSDU, - __le32_to_cpu(desc->msdu_end.info2)); + return ab->hw_params.hw_ops->rx_desc_get_last_msdu(desc); } -static void ath11k_dp_rx_desc_end_tlv_copy(struct hal_rx_desc *fdesc, +static void ath11k_dp_rx_desc_end_tlv_copy(struct ath11k_base *ab, + struct hal_rx_desc *fdesc, struct hal_rx_desc *ldesc) { - memcpy((u8 *)&fdesc->msdu_end, (u8 *)&ldesc->msdu_end, - sizeof(struct rx_msdu_end)); - memcpy((u8 *)&fdesc->attention, (u8 *)&ldesc->attention, - sizeof(struct rx_attention)); - memcpy((u8 *)&fdesc->mpdu_end, (u8 *)&ldesc->mpdu_end, - sizeof(struct rx_mpdu_end)); + ab->hw_params.hw_ops->rx_desc_copy_attn_end_tlv(fdesc, ldesc); } -static u32 ath11k_dp_rxdesc_get_mpdulen_err(struct hal_rx_desc *rx_desc) +static u32 ath11k_dp_rxdesc_get_mpdulen_err(struct rx_attention *attn) { - struct rx_attention *rx_attn; - - rx_attn = &rx_desc->attention; - - return FIELD_GET(RX_ATTENTION_INFO1_MPDU_LEN_ERR, - __le32_to_cpu(rx_attn->info1)); + return FIELD_GET(RX_ATTENTION_INFO1_MPDU_LEN_ERR, __le32_to_cpu(attn->info1)); } -static u32 ath11k_dp_rxdesc_get_decap_format(struct hal_rx_desc *rx_desc) +static bool ath11k_dp_rxdesc_mpdu_valid(struct ath11k_base *ab, + struct hal_rx_desc *rx_desc) { - struct rx_msdu_start *rx_msdu_start; + u32 tlv_tag; - rx_msdu_start = &rx_desc->msdu_start; + tlv_tag = ab->hw_params.hw_ops->rx_desc_get_mpdu_start_tag(rx_desc); - return FIELD_GET(RX_MSDU_START_INFO2_DECAP_FORMAT, - __le32_to_cpu(rx_msdu_start->info2)); + return tlv_tag == HAL_RX_MPDU_START ? true : false; +} + +static u32 ath11k_dp_rxdesc_get_ppduid(struct ath11k_base *ab, + struct hal_rx_desc *rx_desc) +{ + return ab->hw_params.hw_ops->rx_desc_get_mpdu_ppdu_id(rx_desc); } -static u8 *ath11k_dp_rxdesc_get_80211hdr(struct hal_rx_desc *rx_desc) +static bool ath11k_dp_rx_h_attn_is_mcbc(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - u8 *rx_pkt_hdr; + struct rx_attention *rx_attention; + bool is_mcast_bcast = false; - rx_pkt_hdr = &rx_desc->hdr_status[0]; + if (ath11k_dp_rx_h_msdu_end_first_msdu(ab, desc)){ + rx_attention = ath11k_dp_rx_get_attention(ab, desc);; + is_mcast_bcast = !!FIELD_GET(RX_ATTENTION_INFO1_MCAST_BCAST, + __le32_to_cpu(rx_attention->info1)); + } - return rx_pkt_hdr; + return is_mcast_bcast; } -static bool ath11k_dp_rxdesc_mpdu_valid(struct hal_rx_desc *rx_desc) +static bool ath11k_dp_rxdesc_get_mpdu_addr2_valid(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - u32 tlv_tag; - - tlv_tag = FIELD_GET(HAL_TLV_HDR_TAG, - __le32_to_cpu(rx_desc->mpdu_start_tag)); + return ab->hw_params.hw_ops->rx_desc_get_mpdu_addr2_valid(desc); +} - return tlv_tag == HAL_RX_MPDU_START ? true : false; +static u8 *ath11k_dp_rxdesc_get_mpdu_addr2(struct ath11k_base *ab, + struct hal_rx_desc *desc) +{ + return ab->hw_params.hw_ops->rx_desc_get_mpdu_addr2(desc); } -static u32 ath11k_dp_rxdesc_get_ppduid(struct hal_rx_desc *rx_desc) +static bool ath11k_dp_rxdesc_msdu_end_da_is_mcbc(struct ath11k_base *ab, + struct hal_rx_desc *desc) { - return __le16_to_cpu(rx_desc->mpdu_start.phy_ppdu_id); + return ab->hw_params.hw_ops->rx_desc_msdu_da_mcbc(desc); } -static bool ath11k_dp_rx_h_attn_is_mcbc(struct hal_rx_desc *desc) +static void ath11k_dp_rxdesc_set_msdu_len(struct ath11k_base *ab, + struct hal_rx_desc *desc, + u16 len) { - return ath11k_dp_rx_h_msdu_end_first_msdu(desc) && - (!!FIELD_GET(RX_ATTENTION_INFO1_MCAST_BCAST, - __le32_to_cpu(desc->attention.info1))); + ab->hw_params.hw_ops->rx_desc_set_msdu_len(desc, len); } /* Returns number of Rx buffers replenished */ @@ -1744,15 +1757,14 @@ static int ath11k_dp_rx_msdu_coalesce(st struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(first); int buf_first_hdr_len, buf_first_len; struct hal_rx_desc *ldesc; - int space_extra; - int rem_len; - int buf_len; + int space_extra, rem_len, buf_len; + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; /* As the msdu is spread across multiple rx buffers, * find the offset to the start of msdu for computing * the length of the msdu in the first buffer. */ - buf_first_hdr_len = HAL_RX_DESC_SIZE + l3pad_bytes; + buf_first_hdr_len = hal_rx_desc_sz + l3pad_bytes; buf_first_len = DP_RX_BUFFER_SIZE - buf_first_hdr_len; if (WARN_ON_ONCE(msdu_len <= buf_first_len)) { @@ -1762,8 +1774,8 @@ static int ath11k_dp_rx_msdu_coalesce(st } ldesc = (struct hal_rx_desc *)last->data; - rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(ldesc); - rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(ldesc); + rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(ar->ab, ldesc); + rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(ar->ab, ldesc); /* MSDU spans over multiple buffers because the length of the MSDU * exceeds DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE. So assume the data @@ -1775,7 +1787,7 @@ static int ath11k_dp_rx_msdu_coalesce(st /* When an MSDU spread over multiple buffers attention, MSDU_END and * MPDU_END tlvs are valid only in the last buffer. Copy those tlvs. */ - ath11k_dp_rx_desc_end_tlv_copy(rxcb->rx_desc, ldesc); + ath11k_dp_rx_desc_end_tlv_copy(ar->ab, rxcb->rx_desc, ldesc); space_extra = msdu_len - (buf_first_len + skb_tailroom(first)); if (space_extra > 0 && @@ -1796,18 +1808,18 @@ static int ath11k_dp_rx_msdu_coalesce(st while ((skb = __skb_dequeue(msdu_list)) != NULL && rem_len > 0) { rxcb = ATH11K_SKB_RXCB(skb); if (rxcb->is_continuation) - buf_len = DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE; + buf_len = DP_RX_BUFFER_SIZE - hal_rx_desc_sz; else buf_len = rem_len; - if (buf_len > (DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE)) { + if (buf_len > (DP_RX_BUFFER_SIZE - hal_rx_desc_sz)) { WARN_ON_ONCE(1); dev_kfree_skb_any(skb); return -EINVAL; } - skb_put(skb, buf_len + HAL_RX_DESC_SIZE); - skb_pull(skb, HAL_RX_DESC_SIZE); + skb_put(skb, buf_len + hal_rx_desc_sz); + skb_pull(skb, hal_rx_desc_sz); skb_copy_from_linear_data(skb, skb_put(first, buf_len), buf_len); dev_kfree_skb_any(skb); @@ -1842,33 +1854,35 @@ static void ath11k_dp_dump_msdu_info(str struct ath11k_skb_rxcb *rxcb) { bool ip_csum_fail, l4_csum_fail, is_decrypted; - u32 decap_format, err_bitmap, l2_hdr_offset; + u32 err_bitmap, l2_hdr_offset; bool mpdu_len_err, msdu_done, first_mpdu; enum hal_encrypt_type enctype; - u8 *hdr_status; + u8 *hdr_status, decap_format; + struct rx_attention *rx_attention; u16 msdu_len; int i; - hdr_status = ath11k_dp_rx_h_80211_hdr(rx_desc); - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc); - rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(rx_desc); - rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(rx_desc); + hdr_status = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc); + msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, rx_desc); + rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(ar->ab, rx_desc); + rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(ar->ab, rx_desc); + rx_attention = ath11k_dp_rx_get_attention(ar->ab, rx_desc); if (rxcb->is_first_msdu) { - decap_format = ath11k_dp_rxdesc_get_decap_format(rx_desc); - mpdu_len_err = !!ath11k_dp_rxdesc_get_mpdulen_err(rx_desc); - first_mpdu = ath11k_dp_rx_h_attn_first_mpdu(rx_desc); + decap_format = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc); + mpdu_len_err = !!ath11k_dp_rxdesc_get_mpdulen_err(rx_attention); + first_mpdu = ath11k_dp_rx_h_attn_first_mpdu(rx_attention); } - ip_csum_fail = ath11k_dp_rx_h_attn_ip_cksum_fail(rx_desc); - l4_csum_fail = ath11k_dp_rx_h_attn_l4_cksum_fail(rx_desc); - is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc); - enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc); - err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_desc); + ip_csum_fail = ath11k_dp_rx_h_attn_ip_cksum_fail(rx_attention); + l4_csum_fail = ath11k_dp_rx_h_attn_l4_cksum_fail(rx_attention); + is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_attention); + enctype = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc); + err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention); if (rxcb->is_last_msdu) { - msdu_done = ath11k_dp_rx_h_attn_msdu_done(rx_desc); - l2_hdr_offset = ath11k_dp_rx_h_msdu_end_l3pad(rx_desc); + msdu_done = ath11k_dp_rx_h_attn_msdu_done(rx_attention); + l2_hdr_offset = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, rx_desc); } ath11k_info(ar->ab, "first msdu %d last msdu %d msdu len %u decap format %u mpdu_len_err %d first_mpdu %d ip_csum_fail %d l4_csum_fail %d decrypte %d encryption type %u error bitmap %u msdu_done %d l2_hdr_offset %u\n", @@ -1882,13 +1896,15 @@ static void ath11k_dp_dump_msdu_info(str ath11k_info(ar->ab, "\n"); } -static void ath11k_dp_rx_h_csum_offload(struct sk_buff *msdu) +static void ath11k_dp_rx_h_csum_offload(struct ath11k *ar, struct sk_buff *msdu) { struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + struct rx_attention *rx_attention; bool ip_csum_fail, l4_csum_fail; - ip_csum_fail = ath11k_dp_rx_h_attn_ip_cksum_fail(rxcb->rx_desc); - l4_csum_fail = ath11k_dp_rx_h_attn_l4_cksum_fail(rxcb->rx_desc); + rx_attention = ath11k_dp_rx_get_attention(ar->ab, rxcb->rx_desc); + ip_csum_fail = ath11k_dp_rx_h_attn_ip_cksum_fail(rx_attention); + l4_csum_fail = ath11k_dp_rx_h_attn_l4_cksum_fail(rx_attention); msdu->ip_summed = (ip_csum_fail || l4_csum_fail) ? CHECKSUM_NONE : CHECKSUM_UNNECESSARY; @@ -2019,7 +2035,7 @@ static void ath11k_dp_rx_h_undecap_nwifi qos_ctl = rxcb->tid; - if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(rxcb->rx_desc)) + if (ath11k_dp_rx_h_msdu_start_mesh_ctl_present(ar->ab, rxcb->rx_desc)) qos_ctl |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT; /* TODO Add other QoS ctl fields when required */ @@ -2123,7 +2139,7 @@ static void *ath11k_dp_rx_h_find_rfc1042 bool is_amsdu; is_amsdu = !(rxcb->is_first_msdu && rxcb->is_last_msdu); - hdr = (struct ieee80211_hdr *)ath11k_dp_rx_h_80211_hdr(rxcb->rx_desc); + hdr = (struct ieee80211_hdr *)ath11k_dp_rx_h_80211_hdr(ar->ab, rxcb->rx_desc); rfc1042 = hdr; if (rxcb->is_first_msdu) { @@ -2205,7 +2221,7 @@ static void ath11k_dp_rx_h_undecap_snap( */ rx_desc = (void *)msdu->data - sizeof(*rx_desc); - l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(rx_desc); + l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, rx_desc); skb_put(msdu, l3_pad_bytes); skb_pull(msdu, sizeof(struct ath11k_dp_amsdu_subframe_hdr) + l3_pad_bytes); @@ -2232,8 +2248,8 @@ static void ath11k_dp_rx_h_undecap(struc u8 *first_hdr; u8 decap; - first_hdr = ath11k_dp_rx_h_80211_hdr(rx_desc); - decap = ath11k_dp_rx_h_msdu_start_decap_type(rx_desc); + first_hdr = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc); + decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc); switch (decap) { case DP_RX_DECAP_TYPE_NATIVE_WIFI: @@ -2265,6 +2281,8 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); struct hal_rx_desc *rx_desc = rxcb->rx_desc; struct ath11k_peer *peer = NULL; + const u8 *addr; + lockdep_assert_held(&ab->base_lock); if (rxcb->peer_id) peer = ath11k_peer_find_by_id(ab, rxcb->peer_id); @@ -2272,9 +2290,14 @@ ath11k_dp_rx_h_find_peer(struct ath11k_b return peer; if (!rx_desc || - !(rx_desc->mpdu_start.info1 & RX_MPDU_START_INFO1_MAC_ADDR2_VALID)) - return NULL; - peer = ath11k_peer_find_by_addr(ab, rx_desc->mpdu_start.addr2); + !ath11k_dp_rxdesc_get_mpdu_addr2_valid(ab, rx_desc)) + return NULL; + + addr = ath11k_dp_rxdesc_get_mpdu_addr2(ab, rx_desc); + if (!addr) + return NULL; + + peer = ath11k_peer_find_by_addr(ab, addr); return peer; } @@ -2289,15 +2312,16 @@ static void ath11k_dp_rx_h_mpdu(struct a struct ath11k_skb_rxcb *rxcb; struct ieee80211_hdr *hdr; struct ath11k_peer *peer; + struct rx_attention *rx_attention; u32 err_bitmap; /* PN for multicast packets will be checked in mac80211 */ rxcb = ATH11K_SKB_RXCB(msdu); - rxcb->is_mcbc = fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(rx_desc); + rxcb->is_mcbc = fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc); if (rxcb->is_mcbc) { - rxcb->peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(rx_desc); - rxcb->seq_no = ath11k_dp_rx_h_mpdu_start_seq_no(rx_desc); + rxcb->peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, rx_desc); + rxcb->seq_no = ath11k_dp_rx_h_mpdu_start_seq_no(ar->ab, rx_desc); } spin_lock_bh(&ar->ab->base_lock); @@ -2308,14 +2332,15 @@ static void ath11k_dp_rx_h_mpdu(struct a else enctype = peer->sec_type; } else { - enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc); + enctype = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc); } spin_unlock_bh(&ar->ab->base_lock); - err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_desc); + rx_attention = ath11k_dp_rx_get_attention(ar->ab, rx_desc); + err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention); if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap) - is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc); + is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_attention); /* Clear per-MPDU flags while leaving per-PPDU flags intact */ rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | @@ -2340,14 +2365,14 @@ static void ath11k_dp_rx_h_mpdu(struct a RX_FLAG_PN_VALIDATED; } - ath11k_dp_rx_h_csum_offload(msdu); + ath11k_dp_rx_h_csum_offload(ar, msdu); ath11k_dp_rx_h_undecap(ar, msdu, rx_desc, enctype, rx_status, is_decrypted); if (!is_decrypted || fill_crypto_hdr) return; - if (ath11k_dp_rx_h_msdu_start_decap_type(rx_desc) != + if (ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc) != DP_RX_DECAP_TYPE_ETHERNET2_DIX) { hdr = (void *)msdu->data; hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); @@ -2364,11 +2389,11 @@ static void ath11k_dp_rx_h_rate(struct a u8 sgi; bool is_cck; - pkt_type = ath11k_dp_rx_h_msdu_start_pkt_type(rx_desc); - bw = ath11k_dp_rx_h_msdu_start_rx_bw(rx_desc); - rate_mcs = ath11k_dp_rx_h_msdu_start_rate_mcs(rx_desc); - nss = ath11k_dp_rx_h_msdu_start_nss(rx_desc); - sgi = ath11k_dp_rx_h_msdu_start_sgi(rx_desc); + pkt_type = ath11k_dp_rx_h_msdu_start_pkt_type(ar->ab, rx_desc); + bw = ath11k_dp_rx_h_msdu_start_rx_bw(ar->ab, rx_desc); + rate_mcs = ath11k_dp_rx_h_msdu_start_rate_mcs(ar->ab, rx_desc); + nss = ath11k_dp_rx_h_msdu_start_nss(ar->ab, rx_desc); + sgi = ath11k_dp_rx_h_msdu_start_sgi(ar->ab, rx_desc); switch (pkt_type) { case RX_MSDU_START_PKT_TYPE_11A: @@ -2434,7 +2459,7 @@ static void ath11k_dp_rx_h_ppdu(struct a rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; - channel_num = ath11k_dp_rx_h_msdu_start_freq(rx_desc); + channel_num = ath11k_dp_rx_h_msdu_start_freq(ar->ab, rx_desc); if (channel_num >= 1 && channel_num <= 14) { rx_status->band = NL80211_BAND_2GHZ; @@ -2481,7 +2506,8 @@ static void ath11k_dp_rx_deliver_msdu(st } if (!(status->flag & RX_FLAG_ONLY_MONITOR)) - decap = ath11k_dp_rx_h_msdu_start_decap_type(rxcb->rx_desc); + decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rxcb->rx_desc); + spin_lock_bh(&ar->ab->base_lock); peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu); if (peer && peer->sta) @@ -2489,12 +2515,12 @@ static void ath11k_dp_rx_deliver_msdu(st spin_unlock_bh(&ar->ab->base_lock); ath11k_dbg(ar->ab, ATH11K_DBG_DATA, - "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", + "rx skb %pK len %u peer %pM %hhu %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", msdu, msdu->len, peer ? peer->addr : NULL, rxcb->tid, - (rxcb->rx_desc->msdu_end.info2 & RX_MSDU_END_INFO2_DA_IS_MCBC) ? "mcast" : "ucast", + (ath11k_dp_rxdesc_msdu_end_da_is_mcbc(ar->ab, rxcb->rx_desc)) ? "mcast" : "ucast", rxcb->seq_no, (status->encoding == RX_ENC_LEGACY) ? "legacy" : "", (status->encoding == RX_ENC_HT) ? "ht" : "", @@ -2536,11 +2562,13 @@ static int ath11k_dp_rx_process_msdu(str struct ieee80211_rx_status *rx_status) { struct hal_rx_desc *rx_desc, *lrx_desc; + struct rx_attention *rx_attention; struct ath11k_skb_rxcb *rxcb; struct sk_buff *last_buf; u8 l3_pad_bytes; u16 msdu_len; int ret; + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; last_buf = ath11k_dp_rx_get_msdu_last_buf(msdu_list, msdu); if (!last_buf) { @@ -2552,7 +2580,8 @@ static int ath11k_dp_rx_process_msdu(str rx_desc = (struct hal_rx_desc *)msdu->data; lrx_desc = (struct hal_rx_desc *)last_buf->data; - if (!ath11k_dp_rx_h_attn_msdu_done(lrx_desc)) { + rx_attention = ath11k_dp_rx_get_attention(ar->ab, lrx_desc); + if (!ath11k_dp_rx_h_attn_msdu_done(rx_attention)) { ath11k_warn(ar->ab, "msdu_done bit in attention is not set\n"); ret = -EIO; goto free_out; @@ -2560,13 +2589,13 @@ static int ath11k_dp_rx_process_msdu(str rxcb = ATH11K_SKB_RXCB(msdu); rxcb->rx_desc = rx_desc; - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc); - l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(lrx_desc); + msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, rx_desc); + l3_pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, lrx_desc); if (rxcb->is_frag) { - skb_pull(msdu, HAL_RX_DESC_SIZE); + skb_pull(msdu, hal_rx_desc_sz); } else if (!rxcb->is_continuation) { - if ((msdu_len + l3_pad_bytes + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) { + if ((msdu_len + l3_pad_bytes + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { ath11k_warn(ar->ab, "invalid msdu len %u\n", msdu_len); ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rxcb->rx_desc, @@ -2574,8 +2603,8 @@ static int ath11k_dp_rx_process_msdu(str ath11k_dp_dump_msdu_info(ar, rxcb->rx_desc, rxcb); goto free_out; } - skb_put(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes + msdu_len); - skb_pull(msdu, HAL_RX_DESC_SIZE + l3_pad_bytes); + skb_put(msdu, hal_rx_desc_sz + l3_pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3_pad_bytes); } else { ret = ath11k_dp_rx_msdu_coalesce(ar, msdu_list, msdu, last_buf, @@ -3483,16 +3512,17 @@ static int ath11k_dp_rx_h_verify_tkip_mi u8 mic[IEEE80211_CCMP_MIC_LEN]; int head_len, tail_len, ret; size_t data_len; - u32 hdr_len; + u32 hdr_len, hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; u8 *key, *data; u8 key_idx; - if (ath11k_dp_rx_h_mpdu_start_enctype(rx_desc) != HAL_ENCRYPT_TYPE_TKIP_MIC) + if (ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc) != + HAL_ENCRYPT_TYPE_TKIP_MIC) return 0; - hdr = (struct ieee80211_hdr *)(msdu->data + HAL_RX_DESC_SIZE); + hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); hdr_len = ieee80211_hdrlen(hdr->frame_control); - head_len = hdr_len + HAL_RX_DESC_SIZE + IEEE80211_TKIP_IV_LEN; + head_len = hdr_len + hal_rx_desc_sz + IEEE80211_TKIP_IV_LEN; tail_len = IEEE80211_CCMP_MIC_LEN + IEEE80211_TKIP_ICV_LEN + FCS_LEN; if (!is_multicast_ether_addr(hdr->addr1)) @@ -3518,7 +3548,7 @@ mic_fail: rxs->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_MMIC_STRIPPED | RX_FLAG_IV_STRIPPED | RX_FLAG_DECRYPTED; - skb_pull(msdu, HAL_RX_DESC_SIZE); + skb_pull(msdu, hal_rx_desc_sz); ath11k_dp_rx_h_ppdu(ar, rx_desc, rxs); ath11k_dp_rx_h_undecap(ar, msdu, rx_desc, @@ -3533,11 +3563,12 @@ static void ath11k_dp_rx_h_undecap_frag( struct ieee80211_hdr *hdr; size_t hdr_len; size_t crypto_len; + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; if (!flags) return; - hdr = (struct ieee80211_hdr *)(msdu->data + HAL_RX_DESC_SIZE); + hdr = (struct ieee80211_hdr *)(msdu->data + hal_rx_desc_sz); if (flags & RX_FLAG_MIC_STRIPPED) skb_trim(msdu, msdu->len - @@ -3551,8 +3582,8 @@ static void ath11k_dp_rx_h_undecap_frag( hdr_len = ieee80211_hdrlen(hdr->frame_control); crypto_len = ath11k_dp_rx_crypto_param_len(ar, enctype); - memmove((void *)msdu->data + HAL_RX_DESC_SIZE + crypto_len, - (void *)msdu->data + HAL_RX_DESC_SIZE, hdr_len); + memmove((void *)msdu->data + hal_rx_desc_sz + crypto_len, + (void *)msdu->data + hal_rx_desc_sz, hdr_len); skb_pull(msdu, crypto_len); } } @@ -3565,11 +3596,12 @@ static int ath11k_dp_rx_h_defrag(struct struct hal_rx_desc *rx_desc; struct sk_buff *skb, *first_frag, *last_frag; struct ieee80211_hdr *hdr; + struct rx_attention *rx_attention; enum hal_encrypt_type enctype; bool is_decrypted = false; int msdu_len = 0; int extra_space; - u32 flags; + u32 flags, hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; first_frag = skb_peek(&rx_tid->rx_frags); last_frag = skb_peek_tail(&rx_tid->rx_frags); @@ -3577,11 +3609,13 @@ static int ath11k_dp_rx_h_defrag(struct skb_queue_walk(&rx_tid->rx_frags, skb) { flags = 0; rx_desc = (struct hal_rx_desc *)skb->data; - hdr = (struct ieee80211_hdr *)(skb->data + HAL_RX_DESC_SIZE); + hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); - enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc); - if (enctype != HAL_ENCRYPT_TYPE_OPEN) - is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc); + enctype = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc); + if (enctype != HAL_ENCRYPT_TYPE_OPEN) { + rx_attention = ath11k_dp_rx_get_attention(ar->ab, rx_desc); + is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_attention); + } if (is_decrypted) { if (skb != first_frag) @@ -3597,7 +3631,7 @@ static int ath11k_dp_rx_h_defrag(struct ath11k_dp_rx_h_undecap_frag(ar, skb, enctype, flags); if (skb != first_frag) - skb_pull(skb, HAL_RX_DESC_SIZE + + skb_pull(skb, hal_rx_desc_sz + ieee80211_hdrlen(hdr->frame_control)); msdu_len += skb->len; } @@ -3613,7 +3647,7 @@ static int ath11k_dp_rx_h_defrag(struct dev_kfree_skb_any(skb); } - hdr = (struct ieee80211_hdr *)(first_frag->data + HAL_RX_DESC_SIZE); + hdr = (struct ieee80211_hdr *)(first_frag->data + hal_rx_desc_sz); hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_MOREFRAGS); ATH11K_SKB_RXCB(first_frag)->is_frag = 1; @@ -3639,10 +3673,10 @@ static int ath11k_dp_rx_h_defrag_reo_rei struct hal_srng *srng; dma_addr_t paddr; u32 desc_bank, msdu_info, mpdu_info; - u32 dst_idx, cookie; - u32 *msdu_len_offset; + u32 dst_idx, cookie, hal_rx_desc_sz; int ret, buf_id; + hal_rx_desc_sz = ab->hw_params.hal_desc_sz; link_desc_banks = ab->dp.link_desc_banks; reo_dest_ring = rx_tid->dst_ring_desc; @@ -3657,17 +3691,15 @@ static int ath11k_dp_rx_h_defrag_reo_rei FIELD_PREP(RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU, 1) | FIELD_PREP(RX_MSDU_DESC_INFO0_MSDU_CONTINUATION, 0) | FIELD_PREP(RX_MSDU_DESC_INFO0_MSDU_LENGTH, - defrag_skb->len - HAL_RX_DESC_SIZE) | + defrag_skb->len - hal_rx_desc_sz) | FIELD_PREP(RX_MSDU_DESC_INFO0_REO_DEST_IND, dst_idx) | FIELD_PREP(RX_MSDU_DESC_INFO0_VALID_SA, 1) | FIELD_PREP(RX_MSDU_DESC_INFO0_VALID_DA, 1); msdu0->rx_msdu_info.info0 = msdu_info; /* change msdu len in hal rx desc */ - msdu_len_offset = (u32 *)&rx_desc->msdu_start; - *msdu_len_offset &= ~(RX_MSDU_START_INFO1_MSDU_LENGTH); - *msdu_len_offset |= defrag_skb->len - HAL_RX_DESC_SIZE; - + ath11k_dp_rxdesc_set_msdu_len(ab, rx_desc, defrag_skb->len - hal_rx_desc_sz); + paddr = dma_map_single(ab->dev, defrag_skb->data, defrag_skb->len + skb_tailroom(defrag_skb), DMA_FROM_DEVICE); @@ -3739,24 +3771,26 @@ err_unmap_dma: return ret; } -static int ath11k_dp_rx_h_cmp_frags(struct sk_buff *a, struct sk_buff *b) +static int ath11k_dp_rx_h_cmp_frags(struct ath11k *ar, + struct sk_buff *a, struct sk_buff *b) { int frag1, frag2; - frag1 = ath11k_dp_rx_h_mpdu_start_frag_no(a); - frag2 = ath11k_dp_rx_h_mpdu_start_frag_no(b); + frag1 = ath11k_dp_rx_h_mpdu_start_frag_no(ar->ab, a); + frag2 = ath11k_dp_rx_h_mpdu_start_frag_no(ar->ab, b); return frag1 - frag2; } -static void ath11k_dp_rx_h_sort_frags(struct sk_buff_head *frag_list, +static void ath11k_dp_rx_h_sort_frags(struct ath11k *ar, + struct sk_buff_head *frag_list, struct sk_buff *cur_frag) { struct sk_buff *skb; int cmp; skb_queue_walk(frag_list, skb) { - cmp = ath11k_dp_rx_h_cmp_frags(skb, cur_frag); + cmp = ath11k_dp_rx_h_cmp_frags(ar, skb, cur_frag); if (cmp < 0) continue; __skb_queue_before(frag_list, skb, cur_frag); @@ -3765,14 +3799,15 @@ static void ath11k_dp_rx_h_sort_frags(st __skb_queue_tail(frag_list, cur_frag); } -static u64 ath11k_dp_rx_h_get_pn(struct sk_buff *skb) +static u64 ath11k_dp_rx_h_get_pn(struct ath11k *ar, struct sk_buff *skb) { struct ieee80211_hdr *hdr; u64 pn = 0; u8 *ehdr; + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; - hdr = (struct ieee80211_hdr *)(skb->data + HAL_RX_DESC_SIZE); - ehdr = skb->data + HAL_RX_DESC_SIZE + ieee80211_hdrlen(hdr->frame_control); + hdr = (struct ieee80211_hdr *)(skb->data + hal_rx_desc_sz); + ehdr = skb->data + hal_rx_desc_sz + ieee80211_hdrlen(hdr->frame_control); pn = ehdr[0]; pn |= (u64)ehdr[1] << 8; @@ -3796,19 +3831,19 @@ ath11k_dp_rx_h_defrag_validate_incr_pn(s first_frag = skb_peek(&rx_tid->rx_frags); desc = (struct hal_rx_desc *)first_frag->data; - encrypt_type = ath11k_dp_rx_h_mpdu_start_enctype(desc); + encrypt_type = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, desc); if (encrypt_type != HAL_ENCRYPT_TYPE_CCMP_128 && encrypt_type != HAL_ENCRYPT_TYPE_CCMP_256 && encrypt_type != HAL_ENCRYPT_TYPE_GCMP_128 && encrypt_type != HAL_ENCRYPT_TYPE_AES_GCMP_256) return true; - last_pn = ath11k_dp_rx_h_get_pn(first_frag); + last_pn = ath11k_dp_rx_h_get_pn(ar, first_frag); skb_queue_walk(&rx_tid->rx_frags, skb) { if (skb == first_frag) continue; - cur_pn = ath11k_dp_rx_h_get_pn(skb); + cur_pn = ath11k_dp_rx_h_get_pn(ar, skb); if (cur_pn != last_pn + 1) return false; last_pn = cur_pn; @@ -3832,14 +3867,14 @@ static int ath11k_dp_rx_frag_h_mpdu(stru bool more_frags; rx_desc = (struct hal_rx_desc *)msdu->data; - peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(rx_desc); - tid = ath11k_dp_rx_h_mpdu_start_tid(rx_desc); - seqno = ath11k_dp_rx_h_mpdu_start_seq_no(rx_desc); - frag_no = ath11k_dp_rx_h_mpdu_start_frag_no(msdu); - more_frags = ath11k_dp_rx_h_mpdu_start_more_frags(msdu); + peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, rx_desc); + tid = ath11k_dp_rx_h_mpdu_start_tid(ar->ab, rx_desc); + seqno = ath11k_dp_rx_h_mpdu_start_seq_no(ar->ab, rx_desc); + frag_no = ath11k_dp_rx_h_mpdu_start_frag_no(ar->ab, msdu); + more_frags = ath11k_dp_rx_h_mpdu_start_more_frags(ar->ab, msdu); - if (!ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(rx_desc) || - !ath11k_dp_rx_h_mpdu_start_fc_valid(rx_desc) || + if (!ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(ar->ab, rx_desc) || + !ath11k_dp_rx_h_mpdu_start_fc_valid(ar->ab, rx_desc) || tid > IEEE80211_NUM_TIDS) return -EINVAL; @@ -3877,7 +3912,7 @@ static int ath11k_dp_rx_frag_h_mpdu(stru if (frag_no > __fls(rx_tid->rx_frag_bitmap)) __skb_queue_tail(&rx_tid->rx_frags, msdu); else - ath11k_dp_rx_h_sort_frags(&rx_tid->rx_frags, msdu); + ath11k_dp_rx_h_sort_frags(ar, &rx_tid->rx_frags, msdu); rx_tid->rx_frag_bitmap |= BIT(frag_no); if (!more_frags) @@ -3943,6 +3978,7 @@ ath11k_dp_process_rx_err_buf(struct ath1 struct ath11k_skb_rxcb *rxcb; struct hal_rx_desc *rx_desc; u16 msdu_len; + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; spin_lock_bh(&rx_ring->idr_lock); msdu = idr_find(&rx_ring->bufs_idr, buf_id); @@ -3978,8 +4014,8 @@ ath11k_dp_process_rx_err_buf(struct ath1 } rx_desc = (struct hal_rx_desc *)msdu->data; - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(rx_desc); - if ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE) { + msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, rx_desc); + if ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE) { ath11k_warn(ar->ab, "invalid msdu len %u\n", msdu_len); ath11k_dbg_dump(ar->ab, ATH11K_DBG_DATA, NULL, "", rx_desc, sizeof(struct hal_rx_desc)); @@ -3988,7 +4024,7 @@ ath11k_dp_process_rx_err_buf(struct ath1 goto exit; } - skb_put(msdu, HAL_RX_DESC_SIZE + msdu_len); + skb_put(msdu, hal_rx_desc_sz + msdu_len); if (ath11k_dp_rx_frag_h_mpdu(ar, msdu, ring_desc)) { dev_kfree_skb_any(msdu); @@ -4122,7 +4158,7 @@ static void ath11k_dp_rx_null_q_desc_sg_ int n_buffs; n_buffs = DIV_ROUND_UP(msdu_len, - (DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE)); + (DP_RX_BUFFER_SIZE - ar->ab->hw_params.hal_desc_sz)); skb_queue_walk_safe(msdu_list, skb, tmp) { rxcb = ATH11K_SKB_RXCB(skb); @@ -4143,19 +4179,22 @@ static int ath11k_dp_rx_h_null_q_desc(st { u16 msdu_len; struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; + struct rx_attention *rx_attention; u8 l3pad_bytes; struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(desc); + msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc); - if (!rxcb->is_frag && ((msdu_len + HAL_RX_DESC_SIZE) > DP_RX_BUFFER_SIZE)) { + if (!rxcb->is_frag && ((msdu_len + hal_rx_desc_sz) > DP_RX_BUFFER_SIZE)) { /* First buffer will be freed by the caller, so deduct it's length */ - msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - HAL_RX_DESC_SIZE); + msdu_len = msdu_len - (DP_RX_BUFFER_SIZE - hal_rx_desc_sz); ath11k_dp_rx_null_q_desc_sg_drop(ar, msdu_len, msdu_list); return -EINVAL; } - if (!ath11k_dp_rx_h_attn_msdu_done(desc)) { + rx_attention = ath11k_dp_rx_get_attention(ar->ab, desc); + if (!ath11k_dp_rx_h_attn_msdu_done(rx_attention)) { ath11k_warn(ar->ab, "msdu_done bit not set in null_q_des processing\n"); __skb_queue_purge(msdu_list); @@ -4171,25 +4210,25 @@ static int ath11k_dp_rx_h_null_q_desc(st * This error can show up both in a REO destination or WBM release ring. */ - rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(desc); - rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(desc); + rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(ar->ab, desc); + rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(ar->ab, desc); if (rxcb->is_frag) { - skb_pull(msdu, HAL_RX_DESC_SIZE); + skb_pull(msdu, hal_rx_desc_sz); } else { - l3pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(desc); + l3pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, desc); - if ((HAL_RX_DESC_SIZE + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) + if ((hal_rx_desc_sz + l3pad_bytes + msdu_len) > DP_RX_BUFFER_SIZE) return -EINVAL; - skb_put(msdu, HAL_RX_DESC_SIZE + l3pad_bytes + msdu_len); - skb_pull(msdu, HAL_RX_DESC_SIZE + l3pad_bytes); + skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); } ath11k_dp_rx_h_ppdu(ar, desc, status); ath11k_dp_rx_h_mpdu(ar, msdu, desc, status); - rxcb->tid = ath11k_dp_rx_h_mpdu_start_tid(desc); + rxcb->tid = ath11k_dp_rx_h_mpdu_start_tid(ar->ab, desc); /* Please note that caller will having the access to msdu and completing * rx with mac80211. Need not worry about cleaning up amsdu_list. @@ -4237,14 +4276,15 @@ static void ath11k_dp_rx_h_tkip_mic_err( struct hal_rx_desc *desc = (struct hal_rx_desc *)msdu->data; u8 l3pad_bytes; struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu); + u32 hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz; - rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(desc); - rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(desc); + rxcb->is_first_msdu = ath11k_dp_rx_h_msdu_end_first_msdu(ar->ab, desc); + rxcb->is_last_msdu = ath11k_dp_rx_h_msdu_end_last_msdu(ar->ab, desc); - l3pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(desc); - msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(desc); - skb_put(msdu, HAL_RX_DESC_SIZE + l3pad_bytes + msdu_len); - skb_pull(msdu, HAL_RX_DESC_SIZE + l3pad_bytes); + l3pad_bytes = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, desc); + msdu_len = ath11k_dp_rx_h_msdu_start_msdu_len(ar->ab, desc); + skb_put(msdu, hal_rx_desc_sz + l3pad_bytes + msdu_len); + skb_pull(msdu, hal_rx_desc_sz + l3pad_bytes); ath11k_dp_rx_h_ppdu(ar, desc, status); @@ -4936,10 +4976,10 @@ ath11k_dp_rx_mon_mpdu_pop(struct ath11k rx_desc = (struct hal_rx_desc *)msdu->data; rx_pkt_offset = sizeof(struct hal_rx_desc); - l2_hdr_offset = ath11k_dp_rx_h_msdu_end_l3pad(rx_desc); + l2_hdr_offset = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, rx_desc); if (is_first_msdu) { - if (!ath11k_dp_rxdesc_mpdu_valid(rx_desc)) { + if (!ath11k_dp_rxdesc_mpdu_valid(ar->ab, rx_desc)) { drop_mpdu = true; dev_kfree_skb_any(msdu); msdu = NULL; @@ -4948,7 +4988,7 @@ ath11k_dp_rx_mon_mpdu_pop(struct ath11k } msdu_ppdu_id = - ath11k_dp_rxdesc_get_ppduid(rx_desc); + ath11k_dp_rxdesc_get_ppduid(ar->ab, rx_desc); if (ath11k_dp_rx_mon_comp_ppduid(msdu_ppdu_id, ppdu_id, @@ -5010,12 +5050,13 @@ next_msdu: return rx_bufs_used; } -static void ath11k_dp_rx_msdus_set_payload(struct sk_buff *msdu) +static void ath11k_dp_rx_msdus_set_payload(struct ath11k *ar, struct sk_buff *msdu) { u32 rx_pkt_offset, l2_hdr_offset; - rx_pkt_offset = sizeof(struct hal_rx_desc); - l2_hdr_offset = ath11k_dp_rx_h_msdu_end_l3pad((struct hal_rx_desc *)msdu->data); + rx_pkt_offset = ar->ab->hw_params.hal_desc_sz; + l2_hdr_offset = ath11k_dp_rx_h_msdu_end_l3pad(ar->ab, + (struct hal_rx_desc *)msdu->data); skb_pull(msdu, rx_pkt_offset + l2_hdr_offset); } @@ -5026,11 +5067,12 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11 struct ieee80211_rx_status *rxs) { struct sk_buff *msdu, *mpdu_buf, *prev_buf; - u32 decap_format; + u8 decap_format; struct hal_rx_desc *rx_desc; char *hdr_desc; u8 *dest; struct ieee80211_hdr_3addr *wh; + struct rx_attention *rx_attention; static u32 pkt_type = 0; @@ -5043,21 +5085,22 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11 rx_desc = (struct hal_rx_desc *)head_msdu->data; - if (ath11k_dp_rxdesc_get_mpdulen_err(rx_desc)) + rx_attention = ath11k_dp_rx_get_attention(ar->ab, rx_desc); + if (ath11k_dp_rxdesc_get_mpdulen_err(rx_attention)) return NULL; - decap_format = ath11k_dp_rxdesc_get_decap_format(rx_desc); + decap_format = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc); ath11k_dp_rx_h_ppdu(ar, rx_desc, rxs); if (decap_format == DP_RX_DECAP_TYPE_RAW) { - ath11k_dp_rx_msdus_set_payload(head_msdu); + ath11k_dp_rx_msdus_set_payload(ar, head_msdu); prev_buf = head_msdu; msdu = head_msdu->next; while (msdu) { - ath11k_dp_rx_msdus_set_payload(msdu); + ath11k_dp_rx_msdus_set_payload(ar, msdu); prev_buf = msdu; msdu = msdu->next; @@ -5070,7 +5113,7 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11 u8 qos_pkt = 0; rx_desc = (struct hal_rx_desc *)head_msdu->data; - hdr_desc = ath11k_dp_rxdesc_get_80211hdr(rx_desc); + hdr_desc = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc); /* Base size */ wh = (struct ieee80211_hdr_3addr *)hdr_desc; @@ -5081,7 +5124,7 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11 msdu = head_msdu; while (msdu) { - ath11k_dp_rx_msdus_set_payload(msdu); + ath11k_dp_rx_msdus_set_payload(ar, msdu); if (qos_pkt) { dest = skb_push(msdu, sizeof(__le16)); if (!dest) --- a/drivers/net/wireless/ath/ath11k/hal.h +++ b/drivers/net/wireless/ath/ath11k/hal.h @@ -281,8 +281,6 @@ struct ath11k_base; #define HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE 0x000fffff #define HAL_RXDMA_RING_MAX_SIZE 0x0000ffff -#define HAL_RX_DESC_SIZE (sizeof(struct hal_rx_desc)) - /* Add any other errors here and return them in * ath11k_hal_rx_desc_get_err(). */ --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -167,6 +167,178 @@ static void ath11k_tx_mesh_enable_qca807 true); } +static bool ath11k_rx_desc_get_first_msdu_qca8074(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MSDU_END_INFO2_FIRST_MSDU, + __le32_to_cpu(desc->u.ipq8074.msdu_end.info2)); +} + +static bool ath11k_rx_desc_get_last_msdu_qca8074(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MSDU_END_INFO2_LAST_MSDU, + __le32_to_cpu(desc->u.ipq8074.msdu_end.info2)); +} + +static u8 ath11k_rx_desc_get_l3_pad_bytes_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_END_INFO2_L3_HDR_PADDING, + __le32_to_cpu(desc->u.ipq8074.msdu_end.info2)); +} + +static u8 *ath11k_rx_desc_get_hdr_status_qca8074(struct hal_rx_desc *desc) +{ + return desc->u.ipq8074.hdr_status; +} + +static bool ath11k_rx_desc_encrypt_valid_qca8074(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) & + RX_MPDU_START_INFO1_ENCRYPT_INFO_VALID; +} + +static u32 ath11k_rx_desc_get_encrypt_type_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MPDU_START_INFO2_ENC_TYPE, + __le32_to_cpu(desc->u.ipq8074.mpdu_start.info2)); +} + +static u8 ath11k_rx_desc_get_decap_type_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO2_DECAP_FORMAT, + __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); +} + +static u8 ath11k_rx_desc_get_mesh_ctl_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO2_MESH_CTRL_PRESENT, + __le32_to_cpu(desc->u.ipq8074.msdu_start.info2)); +} + +static bool ath11k_rx_desc_get_mpdu_seq_ctl_vld_qca8074(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_CTRL_VALID, + __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)); +} + +static bool ath11k_rx_desc_get_mpdu_fc_valid_qca8074(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MPDU_START_INFO1_MPDU_FCTRL_VALID, + __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)); +} + +static u16 ath11k_rx_desc_get_mpdu_start_seq_no_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MPDU_START_INFO1_MPDU_SEQ_NUM, + __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)); +} + +static u16 ath11k_rx_desc_get_msdu_len_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO1_MSDU_LENGTH, + __le32_to_cpu(desc->u.ipq8074.msdu_start.info1)); +} + +static u8 ath11k_rx_desc_get_msdu_sgi_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_SGI, + __le32_to_cpu(desc->u.ipq8074.msdu_start.info3)); +} + +static u8 ath11k_rx_desc_get_msdu_rate_mcs_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_RATE_MCS, + __le32_to_cpu(desc->u.ipq8074.msdu_start.info3)); +} + +static u8 ath11k_rx_desc_get_msdu_rx_bw_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_RECV_BW, + __le32_to_cpu(desc->u.ipq8074.msdu_start.info3)); +} + +static u32 ath11k_rx_desc_get_msdu_freq_qca8074(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.ipq8074.msdu_start.phy_meta_data); +} + +static u8 ath11k_rx_desc_get_msdu_pkt_type_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_PKT_TYPE, + __le32_to_cpu(desc->u.ipq8074.msdu_start.info3)); +} + +static u8 ath11k_rx_desc_get_msdu_nss_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_MIMO_SS_BITMAP, + __le32_to_cpu(desc->u.ipq8074.msdu_start.info3)); +} + +static u8 ath11k_rx_desc_get_mpdu_tid_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MPDU_START_INFO2_TID, + __le32_to_cpu(desc->u.ipq8074.mpdu_start.info2)); +} + +static u16 ath11k_rx_desc_get_mpdu_peer_id_qca8074(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.ipq8074.mpdu_start.sw_peer_id); +} + +static void ath11k_rx_desc_copy_attn_end_qca8074(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + memcpy((u8 *)&fdesc->u.ipq8074.msdu_end, (u8 *)&ldesc->u.ipq8074.msdu_end, + sizeof(struct rx_msdu_end_ipq8074)); + memcpy((u8 *)&fdesc->u.ipq8074.attention, (u8 *)&ldesc->u.ipq8074.attention, + sizeof(struct rx_attention)); + memcpy((u8 *)&fdesc->u.ipq8074.mpdu_end, (u8 *)&ldesc->u.ipq8074.mpdu_end, + sizeof(struct rx_mpdu_end)); +} + +static u32 ath11k_rx_desc_get_mpdu_start_tag_qca8074(struct hal_rx_desc *desc) +{ + return FIELD_GET(HAL_TLV_HDR_TAG, + __le32_to_cpu(desc->u.ipq8074.mpdu_start_tag)); +} + +static u32 ath11k_rx_desc_get_mpdu_ppdu_id_qca8074(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.ipq8074.mpdu_start.phy_ppdu_id); +} + +static bool ath11k_rx_desc_get_mpdu_addr2_valid_qca8074(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MPDU_START_INFO1_MAC_ADDR2_VALID, + __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1)); +} + +static u8 *ath11k_rx_desc_get_mpdu_addr2_qca8074(struct hal_rx_desc *desc) +{ + return desc->u.ipq8074.mpdu_start.addr2; +} + +static bool ath11k_rx_desc_msdu_da_mcbc_qca8074(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MSDU_END_INFO2_DA_IS_MCBC, + __le32_to_cpu(desc->u.ipq8074.msdu_end.info2)); +} + +static void ath11k_rx_desc_set_msdu_len_qca8074(struct hal_rx_desc *desc, u16 len) +{ + u32 info = __le32_to_cpu(desc->u.ipq8074.msdu_start.info1); + + info &= ~RX_MSDU_START_INFO1_MSDU_LENGTH; + info |= FIELD_PREP(RX_MSDU_START_INFO1_MSDU_LENGTH, len); + + desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info); +} + +static +struct rx_attention *ath11k_rx_desc_get_attention_qca8074(struct hal_rx_desc *desc) +{ + return &desc->u.ipq8074.attention; +} + static u8 ath11k_qca6018_hw_mac_from_pdev_id(struct ath11k_base *ab, int pdev_idx) { @@ -180,18 +352,274 @@ static void ath11k_tx_mesh_enable_qcn900 true); } +static bool ath11k_rx_desc_get_first_msdu_qcn9000(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MSDU_END_INFO4_FIRST_MSDU, + __le16_to_cpu(desc->u.qcn9000.msdu_end.info4)); +} + +static bool ath11k_rx_desc_get_last_msdu_qcn9000(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MSDU_END_INFO4_LAST_MSDU, + __le16_to_cpu(desc->u.qcn9000.msdu_end.info4)); +} + +static u8 ath11k_rx_desc_get_l3_pad_bytes_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_END_INFO4_L3_HDR_PADDING, + __le16_to_cpu(desc->u.qcn9000.msdu_end.info4)); +} + +static u8 *ath11k_rx_desc_get_hdr_status_qcn9000(struct hal_rx_desc *desc) +{ + return desc->u.qcn9000.hdr_status; +} + +static bool ath11k_rx_desc_encrypt_valid_qcn9000(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcn9000.mpdu_start.info11) & + RX_MPDU_START_INFO11_ENCRYPT_INFO_VALID; +} + +static u32 ath11k_rx_desc_get_encrypt_type_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MPDU_START_INFO9_ENC_TYPE, + __le32_to_cpu(desc->u.qcn9000.mpdu_start.info9)); +} + +static u8 ath11k_rx_desc_get_decap_type_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO2_DECAP_FORMAT, + __le32_to_cpu(desc->u.qcn9000.msdu_start.info2)); +} + +static u8 ath11k_rx_desc_get_mesh_ctl_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO2_MESH_CTRL_PRESENT, + __le32_to_cpu(desc->u.qcn9000.msdu_start.info2)); +} + +static bool ath11k_rx_desc_get_mpdu_seq_ctl_vld_qcn9000(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MPDU_START_INFO11_MPDU_SEQ_CTRL_VALID, + __le32_to_cpu(desc->u.qcn9000.mpdu_start.info11)); +} + +static bool ath11k_rx_desc_get_mpdu_fc_valid_qcn9000(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MPDU_START_INFO11_MPDU_FCTRL_VALID, + __le32_to_cpu(desc->u.qcn9000.mpdu_start.info11)); +} + +static u16 ath11k_rx_desc_get_mpdu_start_seq_no_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MPDU_START_INFO11_MPDU_SEQ_NUM, + __le32_to_cpu(desc->u.qcn9000.mpdu_start.info11)); +} + +static u16 ath11k_rx_desc_get_msdu_len_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO1_MSDU_LENGTH, + __le32_to_cpu(desc->u.qcn9000.msdu_start.info1)); +} + +static u8 ath11k_rx_desc_get_msdu_sgi_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_SGI, + __le32_to_cpu(desc->u.qcn9000.msdu_start.info3)); +} + +static u8 ath11k_rx_desc_get_msdu_rate_mcs_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_RATE_MCS, + __le32_to_cpu(desc->u.qcn9000.msdu_start.info3)); +} + +static u8 ath11k_rx_desc_get_msdu_rx_bw_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_RECV_BW, + __le32_to_cpu(desc->u.qcn9000.msdu_start.info3)); +} + +static u32 ath11k_rx_desc_get_msdu_freq_qcn9000(struct hal_rx_desc *desc) +{ + return __le32_to_cpu(desc->u.qcn9000.msdu_start.phy_meta_data); +} + +static u8 ath11k_rx_desc_get_msdu_pkt_type_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_PKT_TYPE, + __le32_to_cpu(desc->u.qcn9000.msdu_start.info3)); +} + +static u8 ath11k_rx_desc_get_msdu_nss_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MSDU_START_INFO3_MIMO_SS_BITMAP, + __le32_to_cpu(desc->u.qcn9000.msdu_start.info3)); +} + +static u8 ath11k_rx_desc_get_mpdu_tid_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(RX_MPDU_START_INFO9_TID, + __le32_to_cpu(desc->u.qcn9000.mpdu_start.info9)); +} + +static u16 ath11k_rx_desc_get_mpdu_peer_id_qcn9000(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcn9000.mpdu_start.sw_peer_id); +} + +static void ath11k_rx_desc_copy_attn_end_qcn9000(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc) +{ + memcpy((u8 *)&fdesc->u.qcn9000.msdu_end, (u8 *)&ldesc->u.qcn9000.msdu_end, + sizeof(struct rx_msdu_end_qcn9000)); + memcpy((u8 *)&fdesc->u.qcn9000.attention, (u8 *)&ldesc->u.qcn9000.attention, + sizeof(struct rx_attention)); + memcpy((u8 *)&fdesc->u.qcn9000.mpdu_end, (u8 *)&ldesc->u.qcn9000.mpdu_end, + sizeof(struct rx_mpdu_end)); +} + +static u32 ath11k_rx_desc_get_mpdu_start_tag_qcn9000(struct hal_rx_desc *desc) +{ + return FIELD_GET(HAL_TLV_HDR_TAG, + __le32_to_cpu(desc->u.qcn9000.mpdu_start_tag)); +} + +static u32 ath11k_rx_desc_get_mpdu_ppdu_id_qcn9000(struct hal_rx_desc *desc) +{ + return __le16_to_cpu(desc->u.qcn9000.mpdu_start.phy_ppdu_id); +} + +static bool ath11k_rx_desc_get_mpdu_addr2_valid_qcn9000(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MPDU_START_INFO11_MAC_ADDR2_VALID, + __le32_to_cpu(desc->u.qcn9000.mpdu_start.info11)); +} + +static u8 *ath11k_rx_desc_get_mpdu_addr2_qcn9000(struct hal_rx_desc *desc) +{ + return desc->u.qcn9000.mpdu_start.addr2; +} + +static bool ath11k_rx_desc_msdu_da_mcbc_qcn9000(struct hal_rx_desc *desc) +{ + return !!FIELD_GET(RX_MSDU_END_INFO4_DA_IS_MCBC, + __le16_to_cpu(desc->u.qcn9000.msdu_end.info4)); +} + +static void ath11k_rx_desc_set_msdu_len_qcn9000(struct hal_rx_desc *desc, u16 len) +{ + u32 info = __le32_to_cpu(desc->u.qcn9000.msdu_start.info1); + + info &= ~RX_MSDU_START_INFO1_MSDU_LENGTH; + info |= FIELD_PREP(RX_MSDU_START_INFO1_MSDU_LENGTH, len); + + desc->u.qcn9000.msdu_start.info1 = __cpu_to_le32(info); +} + +static +struct rx_attention *ath11k_rx_desc_get_attention_qcn9000(struct hal_rx_desc *desc) +{ + return &desc->u.qcn9000.attention; +} + const struct ath11k_hw_ops ath11k_qca8074_ops = { .get_hw_mac_from_pdev_id = ath11k_qca8074_hw_mac_from_pdev_id, .tx_mesh_enable = ath11k_tx_mesh_enable_qca8074, + .rx_desc_get_first_msdu = ath11k_rx_desc_get_first_msdu_qca8074, + .rx_desc_get_last_msdu = ath11k_rx_desc_get_last_msdu_qca8074, + .rx_desc_get_l3_pad_bytes = ath11k_rx_desc_get_l3_pad_bytes_qca8074, + .rx_desc_get_hdr_status = ath11k_rx_desc_get_hdr_status_qca8074, + .rx_desc_encrypt_valid = ath11k_rx_desc_encrypt_valid_qca8074, + .rx_desc_get_encrypt_type = ath11k_rx_desc_get_encrypt_type_qca8074, + .rx_desc_get_decap_type = ath11k_rx_desc_get_decap_type_qca8074, + .rx_desc_get_mesh_ctl = ath11k_rx_desc_get_mesh_ctl_qca8074, + .rx_desc_get_mpdu_seq_ctl_vld = ath11k_rx_desc_get_mpdu_seq_ctl_vld_qca8074, + .rx_desc_get_mpdu_fc_valid = ath11k_rx_desc_get_mpdu_fc_valid_qca8074, + .rx_desc_get_mpdu_start_seq_no = ath11k_rx_desc_get_mpdu_start_seq_no_qca8074, + .rx_desc_get_msdu_len = ath11k_rx_desc_get_msdu_len_qca8074, + .rx_desc_get_msdu_sgi = ath11k_rx_desc_get_msdu_sgi_qca8074, + .rx_desc_get_msdu_rate_mcs = ath11k_rx_desc_get_msdu_rate_mcs_qca8074, + .rx_desc_get_msdu_rx_bw = ath11k_rx_desc_get_msdu_rx_bw_qca8074, + .rx_desc_get_msdu_freq = ath11k_rx_desc_get_msdu_freq_qca8074, + .rx_desc_get_msdu_pkt_type = ath11k_rx_desc_get_msdu_pkt_type_qca8074, + .rx_desc_get_msdu_nss = ath11k_rx_desc_get_msdu_nss_qca8074, + .rx_desc_get_mpdu_tid = ath11k_rx_desc_get_mpdu_tid_qca8074, + .rx_desc_get_mpdu_peer_id = ath11k_rx_desc_get_mpdu_peer_id_qca8074, + .rx_desc_copy_attn_end_tlv = ath11k_rx_desc_copy_attn_end_qca8074, + .rx_desc_get_mpdu_start_tag = ath11k_rx_desc_get_mpdu_start_tag_qca8074, + .rx_desc_get_mpdu_ppdu_id = ath11k_rx_desc_get_mpdu_ppdu_id_qca8074, + .rx_desc_get_mpdu_addr2_valid = ath11k_rx_desc_get_mpdu_addr2_valid_qca8074, + .rx_desc_get_mpdu_addr2 = ath11k_rx_desc_get_mpdu_addr2_qca8074, + .rx_desc_msdu_da_mcbc = ath11k_rx_desc_msdu_da_mcbc_qca8074, + .rx_desc_set_msdu_len = ath11k_rx_desc_set_msdu_len_qca8074, + .rx_desc_get_attention = ath11k_rx_desc_get_attention_qca8074, }; const struct ath11k_hw_ops ath11k_qca6018_ops = { .get_hw_mac_from_pdev_id = ath11k_qca6018_hw_mac_from_pdev_id, .tx_mesh_enable = ath11k_tx_mesh_enable_qca8074, + .rx_desc_get_first_msdu = ath11k_rx_desc_get_first_msdu_qca8074, + .rx_desc_get_last_msdu = ath11k_rx_desc_get_last_msdu_qca8074, + .rx_desc_get_l3_pad_bytes = ath11k_rx_desc_get_l3_pad_bytes_qca8074, + .rx_desc_get_hdr_status = ath11k_rx_desc_get_hdr_status_qca8074, + .rx_desc_encrypt_valid = ath11k_rx_desc_encrypt_valid_qca8074, + .rx_desc_get_encrypt_type = ath11k_rx_desc_get_encrypt_type_qca8074, + .rx_desc_get_decap_type = ath11k_rx_desc_get_decap_type_qca8074, + .rx_desc_get_mesh_ctl = ath11k_rx_desc_get_mesh_ctl_qca8074, + .rx_desc_get_mpdu_seq_ctl_vld = ath11k_rx_desc_get_mpdu_seq_ctl_vld_qca8074, + .rx_desc_get_mpdu_fc_valid = ath11k_rx_desc_get_mpdu_fc_valid_qca8074, + .rx_desc_get_mpdu_start_seq_no = ath11k_rx_desc_get_mpdu_start_seq_no_qca8074, + .rx_desc_get_msdu_len = ath11k_rx_desc_get_msdu_len_qca8074, + .rx_desc_get_msdu_sgi = ath11k_rx_desc_get_msdu_sgi_qca8074, + .rx_desc_get_msdu_rate_mcs = ath11k_rx_desc_get_msdu_rate_mcs_qca8074, + .rx_desc_get_msdu_rx_bw = ath11k_rx_desc_get_msdu_rx_bw_qca8074, + .rx_desc_get_msdu_freq = ath11k_rx_desc_get_msdu_freq_qca8074, + .rx_desc_get_msdu_pkt_type = ath11k_rx_desc_get_msdu_pkt_type_qca8074, + .rx_desc_get_msdu_nss = ath11k_rx_desc_get_msdu_nss_qca8074, + .rx_desc_get_mpdu_tid = ath11k_rx_desc_get_mpdu_tid_qca8074, + .rx_desc_get_mpdu_peer_id = ath11k_rx_desc_get_mpdu_peer_id_qca8074, + .rx_desc_copy_attn_end_tlv = ath11k_rx_desc_copy_attn_end_qca8074, + .rx_desc_get_mpdu_start_tag = ath11k_rx_desc_get_mpdu_start_tag_qca8074, + .rx_desc_get_mpdu_ppdu_id = ath11k_rx_desc_get_mpdu_ppdu_id_qca8074, + .rx_desc_get_mpdu_addr2_valid = ath11k_rx_desc_get_mpdu_addr2_valid_qca8074, + .rx_desc_get_mpdu_addr2 = ath11k_rx_desc_get_mpdu_addr2_qca8074, + .rx_desc_msdu_da_mcbc = ath11k_rx_desc_msdu_da_mcbc_qca8074, + .rx_desc_set_msdu_len = ath11k_rx_desc_set_msdu_len_qca8074, + .rx_desc_get_attention = ath11k_rx_desc_get_attention_qca8074, }; const struct ath11k_hw_ops ath11k_qcn9000_ops = { .get_hw_mac_from_pdev_id = ath11k_qca6018_hw_mac_from_pdev_id, .tx_mesh_enable = ath11k_tx_mesh_enable_qcn9000, + .rx_desc_get_first_msdu = ath11k_rx_desc_get_first_msdu_qcn9000, + .rx_desc_get_last_msdu = ath11k_rx_desc_get_last_msdu_qcn9000, + .rx_desc_get_l3_pad_bytes = ath11k_rx_desc_get_l3_pad_bytes_qcn9000, + .rx_desc_get_hdr_status = ath11k_rx_desc_get_hdr_status_qcn9000, + .rx_desc_encrypt_valid = ath11k_rx_desc_encrypt_valid_qcn9000, + .rx_desc_get_encrypt_type = ath11k_rx_desc_get_encrypt_type_qcn9000, + .rx_desc_get_decap_type = ath11k_rx_desc_get_decap_type_qcn9000, + .rx_desc_get_mesh_ctl = ath11k_rx_desc_get_mesh_ctl_qcn9000, + .rx_desc_get_mpdu_seq_ctl_vld = ath11k_rx_desc_get_mpdu_seq_ctl_vld_qcn9000, + .rx_desc_get_mpdu_fc_valid = ath11k_rx_desc_get_mpdu_fc_valid_qcn9000, + .rx_desc_get_mpdu_start_seq_no = ath11k_rx_desc_get_mpdu_start_seq_no_qcn9000, + .rx_desc_get_msdu_len = ath11k_rx_desc_get_msdu_len_qcn9000, + .rx_desc_get_msdu_sgi = ath11k_rx_desc_get_msdu_sgi_qcn9000, + .rx_desc_get_msdu_rate_mcs = ath11k_rx_desc_get_msdu_rate_mcs_qcn9000, + .rx_desc_get_msdu_rx_bw = ath11k_rx_desc_get_msdu_rx_bw_qcn9000, + .rx_desc_get_msdu_freq = ath11k_rx_desc_get_msdu_freq_qcn9000, + .rx_desc_get_msdu_pkt_type = ath11k_rx_desc_get_msdu_pkt_type_qcn9000, + .rx_desc_get_msdu_nss = ath11k_rx_desc_get_msdu_nss_qcn9000, + .rx_desc_get_mpdu_tid = ath11k_rx_desc_get_mpdu_tid_qcn9000, + .rx_desc_get_mpdu_peer_id = ath11k_rx_desc_get_mpdu_peer_id_qcn9000, + .rx_desc_copy_attn_end_tlv = ath11k_rx_desc_copy_attn_end_qcn9000, + .rx_desc_get_mpdu_start_tag = ath11k_rx_desc_get_mpdu_start_tag_qcn9000, + .rx_desc_get_mpdu_ppdu_id = ath11k_rx_desc_get_mpdu_ppdu_id_qcn9000, + .rx_desc_get_mpdu_addr2_valid = ath11k_rx_desc_get_mpdu_addr2_valid_qcn9000, + .rx_desc_get_mpdu_addr2 = ath11k_rx_desc_get_mpdu_addr2_qcn9000, + .rx_desc_msdu_da_mcbc = ath11k_rx_desc_msdu_da_mcbc_qcn9000, + .rx_desc_set_msdu_len = ath11k_rx_desc_set_msdu_len_qcn9000, + .rx_desc_get_attention = ath11k_rx_desc_get_attention_qcn9000, }; --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -118,6 +118,35 @@ struct ath11k_hw_ops { void (*tx_mesh_enable)(struct ath11k_base *ab, struct hal_tcl_data_cmd *tcl_cmd); + bool (*rx_desc_get_first_msdu)(struct hal_rx_desc *desc); + bool (*rx_desc_get_last_msdu)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_l3_pad_bytes)(struct hal_rx_desc *desc); + u8 *(*rx_desc_get_hdr_status)(struct hal_rx_desc *desc); + bool (*rx_desc_encrypt_valid)(struct hal_rx_desc *desc); + u32 (*rx_desc_get_encrypt_type)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_decap_type)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_mesh_ctl)(struct hal_rx_desc *desc); + bool (*rx_desc_get_mpdu_seq_ctl_vld)(struct hal_rx_desc *desc); + bool (*rx_desc_get_mpdu_fc_valid)(struct hal_rx_desc *desc); + u16 (*rx_desc_get_mpdu_start_seq_no)(struct hal_rx_desc *desc); + u16 (*rx_desc_get_msdu_len)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_msdu_sgi)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_msdu_rate_mcs)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_msdu_rx_bw)(struct hal_rx_desc *desc); + u32 (*rx_desc_get_msdu_freq)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_msdu_pkt_type)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_msdu_nss)(struct hal_rx_desc *desc); + u8 (*rx_desc_get_mpdu_tid)(struct hal_rx_desc *desc); + u16 (*rx_desc_get_mpdu_peer_id)(struct hal_rx_desc *desc); + void (*rx_desc_copy_attn_end_tlv)(struct hal_rx_desc *fdesc, + struct hal_rx_desc *ldesc); + u32 (*rx_desc_get_mpdu_start_tag)(struct hal_rx_desc *desc); + u32 (*rx_desc_get_mpdu_ppdu_id)(struct hal_rx_desc *desc); + bool (*rx_desc_get_mpdu_addr2_valid)(struct hal_rx_desc *desc); + u8* (*rx_desc_get_mpdu_addr2)(struct hal_rx_desc *desc); + bool (*rx_desc_msdu_da_mcbc)(struct hal_rx_desc *desc); + void (*rx_desc_set_msdu_len)(struct hal_rx_desc *desc, u16 len); + struct rx_attention *(*rx_desc_get_attention)(struct hal_rx_desc *desc); }; enum ath11k_bus { @@ -140,7 +169,7 @@ struct ath11k_hw_params { } fw; u8 spectral_fft_sz; bool credit_flow; - + u32 hal_desc_sz; const struct ath11k_hw_ops *hw_ops; }; --- a/drivers/net/wireless/ath/ath11k/rx_desc.h +++ b/drivers/net/wireless/ath/ath11k/rx_desc.h @@ -414,7 +414,7 @@ struct rx_attention { #define RX_MPDU_START_RAW_MPDU BIT(0) -struct rx_mpdu_start { +struct rx_mpdu_start_ipq8074 { __le16 info0; __le16 phy_ppdu_id; __le16 ast_index; @@ -440,6 +440,112 @@ struct rx_mpdu_start { __le32 raw; } __packed; +#define RX_MPDU_START_INFO7_REO_DEST_IND GENMASK(4, 0) +#define RX_MPDU_START_INFO7_LMAC_PEER_ID_MSB GENMASK(6, 5) +#define RX_MPDU_START_INFO7_FLOW_ID_TOEPLITZ BIT(7) +#define RX_MPDU_START_INFO7_PKT_SEL_FP_UCAST_DATA BIT(8) +#define RX_MPDU_START_INFO7_PKT_SEL_FP_MCAST_DATA BIT(9) +#define RX_MPDU_START_INFO7_PKT_SEL_FP_CTRL_BAR BIT(10) +#define RX_MPDU_START_INFO7_RXDMA0_SRC_RING_SEL GENMASK(12, 11) +#define RX_MPDU_START_INFO7_RXDMA0_DST_RING_SEL GENMASK(14, 13) + +#define RX_MPDU_START_INFO8_REO_QUEUE_DESC_HI GENMASK(7, 0) +#define RX_MPDU_START_INFO8_RECV_QUEUE_NUM GENMASK(23, 8) +#define RX_MPDU_START_INFO8_PRE_DELIM_ERR_WARN BIT(24) +#define RX_MPDU_START_INFO8_FIRST_DELIM_ERR BIT(25) + +#define RX_MPDU_START_INFO9_EPD_EN BIT(0) +#define RX_MPDU_START_INFO9_ALL_FRAME_ENCPD BIT(1) +#define RX_MPDU_START_INFO9_ENC_TYPE GENMASK(5, 2) +#define RX_MPDU_START_INFO9_VAR_WEP_KEY_WIDTH GENMASK(7, 6) +#define RX_MPDU_START_INFO9_MESH_STA GENMASK(9, 8) +#define RX_MPDU_START_INFO9_BSSID_HIT BIT(10) +#define RX_MPDU_START_INFO9_BSSID_NUM GENMASK(14, 11) +#define RX_MPDU_START_INFO9_TID GENMASK(18, 15) + +#define RX_MPDU_START_INFO10_RXPCU_MPDU_FLTR GENMASK(1, 0) +#define RX_MPDU_START_INFO10_SW_FRAME_GRP_ID GENMASK(8, 2) +#define RX_MPDU_START_INFO10_NDP_FRAME BIT(9) +#define RX_MPDU_START_INFO10_PHY_ERR BIT(10) +#define RX_MPDU_START_INFO10_PHY_ERR_MPDU_HDR BIT(11) +#define RX_MPDU_START_INFO10_PROTO_VER_ERR BIT(12) +#define RX_MPDU_START_INFO10_AST_LOOKUP_VALID BIT(13) + +#define RX_MPDU_START_INFO11_MPDU_FCTRL_VALID BIT(0) +#define RX_MPDU_START_INFO11_MPDU_DUR_VALID BIT(1) +#define RX_MPDU_START_INFO11_MAC_ADDR1_VALID BIT(2) +#define RX_MPDU_START_INFO11_MAC_ADDR2_VALID BIT(3) +#define RX_MPDU_START_INFO11_MAC_ADDR3_VALID BIT(4) +#define RX_MPDU_START_INFO11_MAC_ADDR4_VALID BIT(5) +#define RX_MPDU_START_INFO11_MPDU_SEQ_CTRL_VALID BIT(6) +#define RX_MPDU_START_INFO11_MPDU_QOS_CTRL_VALID BIT(7) +#define RX_MPDU_START_INFO11_MPDU_HT_CTRL_VALID BIT(8) +#define RX_MPDU_START_INFO11_ENCRYPT_INFO_VALID BIT(9) +#define RX_MPDU_START_INFO11_MPDU_FRAG_NUMBER GENMASK(13, 10) +#define RX_MPDU_START_INFO11_MORE_FRAG_FLAG BIT(14) +#define RX_MPDU_START_INFO11_FROM_DS BIT(16) +#define RX_MPDU_START_INFO11_TO_DS BIT(17) +#define RX_MPDU_START_INFO11_ENCRYPTED BIT(18) +#define RX_MPDU_START_INFO11_MPDU_RETRY BIT(19) +#define RX_MPDU_START_INFO11_MPDU_SEQ_NUM GENMASK(31, 20) + +#define RX_MPDU_START_INFO12_KEY_ID GENMASK(7, 0) +#define RX_MPDU_START_INFO12_NEW_PEER_ENTRY BIT(8) +#define RX_MPDU_START_INFO12_DECRYPT_NEEDED BIT(9) +#define RX_MPDU_START_INFO12_DECAP_TYPE GENMASK(11, 10) +#define RX_MPDU_START_INFO12_VLAN_TAG_C_PADDING BIT(12) +#define RX_MPDU_START_INFO12_VLAN_TAG_S_PADDING BIT(13) +#define RX_MPDU_START_INFO12_STRIP_VLAN_TAG_C BIT(14) +#define RX_MPDU_START_INFO12_STRIP_VLAN_TAG_S BIT(15) +#define RX_MPDU_START_INFO12_PRE_DELIM_COUNT GENMASK(27, 16) +#define RX_MPDU_START_INFO12_AMPDU_FLAG BIT(28) +#define RX_MPDU_START_INFO12_BAR_FRAME BIT(29) +#define RX_MPDU_START_INFO12_RAW_MPDU BIT(30) + +#define RX_MPDU_START_INFO13_MPDU_LEN GENMASK(13, 0) +#define RX_MPDU_START_INFO13_FIRST_MPDU BIT(14) +#define RX_MPDU_START_INFO13_MCAST_BCAST BIT(15) +#define RX_MPDU_START_INFO13_AST_IDX_NOT_FOUND BIT(16) +#define RX_MPDU_START_INFO13_AST_IDX_TIMEOUT BIT(17) +#define RX_MPDU_START_INFO13_POWER_MGMT BIT(18) +#define RX_MPDU_START_INFO13_NON_QOS BIT(19) +#define RX_MPDU_START_INFO13_NULL_DATA BIT(20) +#define RX_MPDU_START_INFO13_MGMT_TYPE BIT(21) +#define RX_MPDU_START_INFO13_CTRL_TYPE BIT(22) +#define RX_MPDU_START_INFO13_MORE_DATA BIT(23) +#define RX_MPDU_START_INFO13_EOSP BIT(24) +#define RX_MPDU_START_INFO13_FRAGMENT BIT(25) +#define RX_MPDU_START_INFO13_ORDER BIT(26) +#define RX_MPDU_START_INFO13_UAPSD_TRIGGER BIT(27) +#define RX_MPDU_START_INFO13_ENCRYPT_REQUIRED BIT(28) +#define RX_MPDU_START_INFO13_DIRECTED BIT(29) +#define RX_MPDU_START_INFO13_AMSDU_PRESENT BIT(30) + +struct rx_mpdu_start_qcn9000 { + __le32 info7; + __le32 reo_queue_desc_lo; + __le32 info8; + __le32 pn[4]; + __le32 info9; + __le32 peer_meta_data; + __le16 info10; + __le16 phy_ppdu_id; + __le16 ast_index; + __le16 sw_peer_id; + __le32 info11; + __le32 info12; + __le32 info13; + __le16 frame_ctrl; + __le16 duration; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctrl; + u8 addr4[ETH_ALEN]; + __le16 qos_ctrl; + __le32 ht_ctrl; +} __packed; + /* rx_mpdu_start * * rxpcu_mpdu_filter_in_category @@ -672,7 +778,7 @@ enum rx_msdu_start_reception_type { #define RX_MSDU_START_INFO3_RECEPTION_TYPE GENMASK(23, 21) #define RX_MSDU_START_INFO3_MIMO_SS_BITMAP GENMASK(31, 24) -struct rx_msdu_start { +struct rx_msdu_start_ipq8074 { __le16 info0; __le16 phy_ppdu_id; __le32 info1; @@ -684,6 +790,20 @@ struct rx_msdu_start { __le32 phy_meta_data; } __packed; +struct rx_msdu_start_qcn9000 { + __le16 info0; + __le16 phy_ppdu_id; + __le32 info1; + __le32 info2; + __le32 toeplitz_hash; + __le32 flow_id_toeplitz; + __le32 info3; + __le32 ppdu_start_timestamp; + __le32 phy_meta_data; + __le16 vlan_ctag_c1; + __le16 vlan_stag_c1; +} __packed; + /* rx_msdu_start * * rxpcu_mpdu_filter_in_category @@ -894,7 +1014,7 @@ struct rx_msdu_start { #define RX_MSDU_END_INFO5_REO_DEST_IND GENMASK(5, 1) #define RX_MSDU_END_INFO5_FLOW_IDX GENMASK(25, 6) -struct rx_msdu_end { +struct rx_msdu_end_ipq8074 { __le16 info0; __le16 phy_ppdu_id; __le16 ip_hdr_cksum; @@ -917,6 +1037,58 @@ struct rx_msdu_end { __le16 sa_sw_peer_id; } __packed; +#define RX_MSDU_END_MPDU_LENGTH_INFO GENMASK(13, 0) + +#define RX_MSDU_END_INFO2_DA_OFFSET GENMASK(5, 0) +#define RX_MSDU_END_INFO2_SA_OFFSET GENMASK(11, 6) +#define RX_MSDU_END_INFO2_DA_OFFSET_VALID BIT(12) +#define RX_MSDU_END_INFO2_SA_OFFSET_VALID BIT(13) +#define RX_MSDU_END_INFO2_L3_TYPE GENMASK(31, 16) + +#define RX_MSDU_END_INFO4_SA_IDX_TIMEOUT BIT(0) +#define RX_MSDU_END_INFO4_DA_IDX_TIMEOUT BIT(1) +#define RX_MSDU_END_INFO4_MSDU_LIMIT_ERR BIT(2) +#define RX_MSDU_END_INFO4_FLOW_IDX_TIMEOUT BIT(3) +#define RX_MSDU_END_INFO4_FLOW_IDX_INVALID BIT(4) +#define RX_MSDU_END_INFO4_WIFI_PARSER_ERR BIT(5) +#define RX_MSDU_END_INFO4_AMSDU_PARSER_ERR BIT(6) +#define RX_MSDU_END_INFO4_SA_IS_VALID BIT(7) +#define RX_MSDU_END_INFO4_DA_IS_VALID BIT(8) +#define RX_MSDU_END_INFO4_DA_IS_MCBC BIT(9) +#define RX_MSDU_END_INFO4_L3_HDR_PADDING GENMASK(11, 10) +#define RX_MSDU_END_INFO4_FIRST_MSDU BIT(12) +#define RX_MSDU_END_INFO4_LAST_MSDU BIT(13) + +#define RX_MSDU_END_INFO6_AGGR_COUNT GENMASK(7, 0) +#define RX_MSDU_END_INFO6_FLOW_AGGR_CONTN BIT(8) +#define RX_MSDU_END_INFO6_FISA_TIMEOUT BIT(9) + +struct rx_msdu_end_qcn9000 { + __le16 info0; + __le16 phy_ppdu_id; + __le16 ip_hdr_cksum; + __le16 mpdu_length_info; + __le32 info1; + __le32 rule_indication[2]; + __le32 info2; + __le32 ipv6_options_crc; + __le32 tcp_seq_num; + __le32 tcp_ack_num; + __le16 info3; + __le16 window_size; + __le16 tcp_udp_cksum; + __le16 info4; + __le16 sa_idx; + __le16 da_idx; + __le32 info5; + __le32 fse_metadata; + __le16 cce_metadata; + __le16 sa_sw_peer_id; + __le32 info6; + __le16 cum_l4_cksum; + __le16 cum_ip_length; +} __packed; + /* rx_msdu_end * * rxpcu_mpdu_filter_in_category @@ -1190,16 +1362,16 @@ struct rx_mpdu_end { #define HAL_RX_DESC_HDR_STATUS_LEN 120 -struct hal_rx_desc { +struct hal_rx_desc_ipq8074 { __le32 msdu_end_tag; - struct rx_msdu_end msdu_end; + struct rx_msdu_end_ipq8074 msdu_end; __le32 rx_attn_tag; struct rx_attention attention; __le32 msdu_start_tag; - struct rx_msdu_start msdu_start; + struct rx_msdu_start_ipq8074 msdu_start; u8 rx_padding0[HAL_RX_DESC_PADDING0_BYTES]; __le32 mpdu_start_tag; - struct rx_mpdu_start mpdu_start; + struct rx_mpdu_start_ipq8074 mpdu_start; __le32 mpdu_end_tag; struct rx_mpdu_end mpdu_end; u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; @@ -1209,6 +1381,32 @@ struct hal_rx_desc { u8 msdu_payload[0]; } __packed; +struct hal_rx_desc_qcn9000 { + __le32 msdu_end_tag; + struct rx_msdu_end_qcn9000 msdu_end; + __le32 rx_attn_tag; + struct rx_attention attention; + __le32 msdu_start_tag; + struct rx_msdu_start_qcn9000 msdu_start; + u8 rx_padding0[HAL_RX_DESC_PADDING0_BYTES]; + __le32 mpdu_start_tag; + struct rx_mpdu_start_qcn9000 mpdu_start; + __le32 mpdu_end_tag; + struct rx_mpdu_end mpdu_end; + u8 rx_padding1[HAL_RX_DESC_PADDING1_BYTES]; + __le32 hdr_status_tag; + __le32 phy_ppdu_id; + u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN]; + u8 msdu_payload[0]; +} __packed; + +struct hal_rx_desc { + union { + struct hal_rx_desc_ipq8074 ipq8074; + struct hal_rx_desc_qcn9000 qcn9000; + } u; +} __packed; + #define MAX_USER_POS 8 #define MAX_MU_GROUP_ID 64 #define MAX_MU_GROUP_SHOW 16 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -42,6 +42,7 @@ static const struct ath11k_hw_params ath .caldb_addr = 0x4BA00000, .bdf_sz = ATH11K_QMI_BDF_MAX_SIZE, .caldb_sz = ATH11K_QMI_CALDB_SIZE_IPQ807X, + .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .hw_ops = &ath11k_qca8074_ops, .credit_flow = false, }, @@ -59,6 +60,7 @@ static const struct ath11k_hw_params ath .caldb_addr = 0x4B500000, .bdf_sz = ATH11K_QMI_BDF_MAX_SIZE, .caldb_sz = ATH11K_QMI_CALDB_SIZE_IPQ807X, + .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), .hw_ops = &ath11k_qca6018_ops, .credit_flow = false, }, @@ -75,6 +77,7 @@ static const struct ath11k_hw_params ath .caldb_addr = 0x57700000, .bdf_sz = ATH11K_QMI_HOST_FWADDR_SZ_QCN9000, .caldb_sz = ATH11K_QMI_CALDB_SIZE_QCN9000, + .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9000), .hw_ops = &ath11k_qcn9000_ops, .credit_flow = false, }, @@ -834,11 +837,44 @@ static void ath11k_core_restart(struct w } complete(&ab->driver_recovery); } +static int ath11k_check_hw_param(struct ath11k_base *ab, + const struct ath11k_hw_params *hw_params) +{ + const struct ath11k_hw_ops *hw_ops; + + if (!hw_params->hw_ops) { + ath11k_err(ab, "invalid hw ops in hw version: 0x%x\n", ab->hw_rev); + return -EINVAL; + } + + hw_ops = hw_params->hw_ops; + + if (WARN_ON(!hw_ops->get_hw_mac_from_pdev_id || !hw_ops->tx_mesh_enable || + !hw_ops->rx_desc_get_first_msdu || !hw_ops->rx_desc_get_last_msdu || + !hw_ops->rx_desc_get_l3_pad_bytes || !hw_ops->rx_desc_get_hdr_status || + !hw_ops->rx_desc_encrypt_valid || !hw_ops->rx_desc_get_encrypt_type || + !hw_ops->rx_desc_get_decap_type || !hw_ops->rx_desc_get_mesh_ctl || + !hw_ops->rx_desc_get_mpdu_seq_ctl_vld || !hw_ops->rx_desc_get_mpdu_fc_valid || + !hw_ops->rx_desc_get_mpdu_start_seq_no || !hw_ops->rx_desc_get_msdu_len || + !hw_ops->rx_desc_get_msdu_sgi || !hw_ops->rx_desc_get_msdu_rate_mcs || + !hw_ops->rx_desc_get_msdu_rx_bw || !hw_ops->rx_desc_get_msdu_freq || + !hw_ops->rx_desc_get_msdu_pkt_type || !hw_ops->rx_desc_get_msdu_nss || + !hw_ops->rx_desc_get_mpdu_tid || !hw_ops->rx_desc_get_mpdu_peer_id || + !hw_ops->rx_desc_copy_attn_end_tlv || !hw_ops->rx_desc_get_mpdu_start_tag || + !hw_ops->rx_desc_get_mpdu_ppdu_id || !hw_ops->rx_desc_get_mpdu_addr2_valid || + !hw_ops->rx_desc_get_mpdu_addr2 || !hw_ops->rx_desc_msdu_da_mcbc || + !hw_ops->rx_desc_set_msdu_len || !hw_ops->rx_desc_get_attention)) { + ath11k_err(ab, "Unsupported hw ops in hw version: 0x%x\n", ab->hw_rev); + return -EINVAL; + } + + return 0; +} static int ath11k_init_hw_params(struct ath11k_base *ab) { const struct ath11k_hw_params *uninitialized_var(hw_params); - int i; + int i, ret; for (i = 0; i < ARRAY_SIZE(ath11k_hw_params_list); i++) { hw_params = &ath11k_hw_params_list[i]; @@ -852,6 +888,12 @@ static int ath11k_init_hw_params(struct return -EINVAL; } + ret = ath11k_check_hw_param(ab, hw_params); + if (ret) { + ath11k_err(ab, "hw praram check failed hardware version: 0x%x\n", ab->hw_rev); + return -EINVAL; + } + ab->hw_params = *hw_params; ath11k_dbg(ab, ATH11K_DBG_BOOT, "Hardware name %s\n", ab->hw_params.name); --- a/drivers/net/wireless/ath/ath11k/hal_tx.c +++ b/drivers/net/wireless/ath/ath11k/hal_tx.c @@ -74,7 +74,7 @@ void ath11k_hal_tx_cmd_desc_setup(struct ti->bss_ast_hash); tcl_cmd->info4 = 0; - if (ti->enable_mesh && ab->hw_params.hw_ops->tx_mesh_enable) + if (ti->enable_mesh) ab->hw_params.hw_ops->tx_mesh_enable(ab, tcl_cmd); }