diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 03ca50970b49..08baf7bf2af2 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -16,6 +16,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#include "hal_hw_headers.h" #include "dp_types.h" #include "dp_rx.h" #include "dp_peer.h" @@ -508,7 +509,7 @@ void dp_rx_fill_mesh_stats(struct dp_vdev *vdev, qdf_nbuf_t nbuf, pkt_type = hal_rx_msdu_start_get_pkt_type(rx_tlv_hdr); rate_mcs = hal_rx_msdu_start_rate_mcs_get(rx_tlv_hdr); bw = hal_rx_msdu_start_bw_get(rx_tlv_hdr); - nss = hal_rx_msdu_start_nss_get(rx_tlv_hdr); + nss = hal_rx_msdu_start_nss_get(vdev->pdev->soc->hal_soc, rx_tlv_hdr); rx_info->rs_ratephy1 = rate_mcs | (nss << 0x8) | (pkt_type << 16) | (bw << 24); @@ -1136,10 +1137,11 @@ static void dp_rx_msdu_stats_update(struct dp_soc *soc, sgi = hal_rx_msdu_start_sgi_get(rx_tlv_hdr); mcs = hal_rx_msdu_start_rate_mcs_get(rx_tlv_hdr); - tid = hal_rx_mpdu_start_tid_get(rx_tlv_hdr); + tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, rx_tlv_hdr); bw = hal_rx_msdu_start_bw_get(rx_tlv_hdr); - reception_type = hal_rx_msdu_start_reception_type_get(rx_tlv_hdr); - nss = hal_rx_msdu_start_nss_get(rx_tlv_hdr); + reception_type = hal_rx_msdu_start_reception_type_get(soc->hal_soc, + rx_tlv_hdr); + nss = hal_rx_msdu_start_nss_get(soc->hal_soc, rx_tlv_hdr); pkt_type = hal_rx_msdu_start_get_pkt_type(rx_tlv_hdr); /* Save tid to skb->priority */ @@ -1492,7 +1494,8 @@ done: if (qdf_unlikely(!hal_rx_attn_msdu_done_get(rx_tlv_hdr))) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("MSDU DONE failure")); - hal_rx_dump_pkt_tlvs(rx_tlv_hdr, QDF_TRACE_LEVEL_INFO); + hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr, + QDF_TRACE_LEVEL_INFO); qdf_assert(0); } diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c index e62e97000447..322654271076 100644 --- a/dp/wifi3.0/dp_rx_defrag.c +++ b/dp/wifi3.0/dp_rx_defrag.c @@ -16,6 +16,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#include "hal_hw_headers.h" #include "dp_types.h" #include "dp_rx.h" #include "dp_peer.h" @@ -1650,7 +1651,8 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc, qdf_nbuf_set_pktlen(msdu, (msdu_len + RX_PKT_TLVS_LEN)); - tid = hal_rx_mpdu_start_tid_get(rx_desc->rx_buf_start); + tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, + rx_desc->rx_buf_start); /* Process fragment-by-fragment */ status = dp_rx_defrag_store_fragment(soc, ring_desc, diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 83429313b884..f005950ebc2f 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -16,6 +16,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#include "hal_hw_headers.h" #include "dp_types.h" #include "dp_rx.h" #include "dp_peer.h" @@ -288,7 +289,8 @@ static uint32_t dp_rx_msdus_drop(struct dp_soc *soc, void *ring_desc, } rx_bufs_used++; - tid = hal_rx_mpdu_start_tid_get(rx_desc->rx_buf_start); + tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, + rx_desc->rx_buf_start); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "Packet received with PN error for tid :%d", tid); @@ -446,8 +448,7 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, dp_pdev->invalid_peer_head_msdu = NULL; dp_pdev->invalid_peer_tail_msdu = NULL; - - hal_rx_mon_hw_desc_get_mpdu_status(rx_tlv_hdr, + hal_rx_mon_hw_desc_get_mpdu_status(soc->hal_soc, rx_tlv_hdr, &(dp_pdev->ppdu_info.rx_status)); } @@ -525,7 +526,8 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("MSDU DONE failure")); - hal_rx_dump_pkt_tlvs(rx_tlv_hdr, QDF_TRACE_LEVEL_INFO); + hal_rx_dump_pkt_tlvs(soc->hal_soc, rx_tlv_hdr, + QDF_TRACE_LEVEL_INFO); qdf_assert(0); } @@ -614,7 +616,7 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, /* TODO: Assuming that qos_control_valid also indicates * unicast. Should we check this? */ - tid = hal_rx_mpdu_start_tid_get(rx_tlv_hdr); + tid = hal_rx_mpdu_start_tid_get(soc->hal_soc, rx_tlv_hdr); if (peer && peer->rx_tid[tid].hw_qdesc_vaddr_unaligned == NULL) { /* IEEE80211_SEQ_MAX indicates invalid start_seq */ @@ -696,7 +698,8 @@ dp_rx_err_deliver(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("MSDU DONE failure")); - hal_rx_dump_pkt_tlvs(rx_tlv_hdr, QDF_TRACE_LEVEL_INFO); + hal_rx_dump_pkt_tlvs(soc->hal_soc, rx_tlv_hdr, + QDF_TRACE_LEVEL_INFO); qdf_assert(0); } @@ -1246,7 +1249,8 @@ done: qdf_assert(0); } - hal_rx_dump_pkt_tlvs(rx_tlv_hdr, QDF_TRACE_LEVEL_DEBUG); + hal_rx_dump_pkt_tlvs(hal_soc, rx_tlv_hdr, + QDF_TRACE_LEVEL_DEBUG); qdf_nbuf_free(nbuf); nbuf = next; } diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index d6d7dd75190b..fe198c57c6b3 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -16,6 +16,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#include "hal_hw_headers.h" #include "dp_types.h" #include "dp_rx.h" #include "dp_peer.h" @@ -238,7 +239,8 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, } if (hal_rx_desc_is_first_msdu(rx_desc_tlv)) - hal_rx_mon_hw_desc_get_mpdu_status(rx_desc_tlv, + hal_rx_mon_hw_desc_get_mpdu_status(soc->hal_soc, + rx_desc_tlv, &(dp_pdev->ppdu_info.rx_status)); diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index ac2c9680a4ad..5c0e25b106e2 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -15,6 +15,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ +#include "hal_hw_headers.h" #include "dp_types.h" #include "dp_rx.h" #include "dp_peer.h" @@ -361,7 +362,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, do { tlv_status = hal_rx_status_get_tlv_info(rx_tlv, - ppdu_info); + ppdu_info, pdev->soc->hal_soc); dp_rx_mon_update_dbg_ppdu_stats(ppdu_info, rx_mon_stats); diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index fa60ba0a0b76..904463cfa574 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -17,6 +17,7 @@ */ #include "htt.h" +#include "hal_hw_headers.h" #include "dp_tx.h" #include "dp_tx_desc.h" #include "dp_peer.h" @@ -913,10 +914,10 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, hal_tx_desc_set_buf_length(hal_tx_desc_cached, length); hal_tx_desc_set_buf_offset(hal_tx_desc_cached, tx_desc->pkt_offset); hal_tx_desc_set_encap_type(hal_tx_desc_cached, tx_desc->tx_encap_type); - hal_tx_desc_set_lmac_id(hal_tx_desc_cached, - HAL_TX_DESC_DEFAULT_LMAC_ID); - hal_tx_desc_set_dscp_tid_table_id(hal_tx_desc_cached, - vdev->dscp_tid_map_id); + hal_tx_desc_set_lmac_id(soc->hal_soc, hal_tx_desc_cached, + HAL_TX_DESC_DEFAULT_LMAC_ID); + hal_tx_desc_set_dscp_tid_table_id(soc->hal_soc, hal_tx_desc_cached, + vdev->dscp_tid_map_id); hal_tx_desc_set_encrypt_type(hal_tx_desc_cached, sec_type_map[sec_type]); diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index bc4bebc24b20..ccbde50a7112 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/dp/wifi3.0/hal_rx.h @@ -1179,31 +1179,6 @@ hal_rx_msdu_start_bw_get(uint8_t *buf) return bw; } -#define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ - RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ - RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ - RX_MSDU_START_5_RECEPTION_TYPE_LSB)) - -/* - * hal_rx_msdu_start_reception_type_get(): API to get the reception type - * Interval from rx_msdu_start - * - * @buf: pointer to the start of RX PKT TLV header - * Return: uint32_t(reception_type) - */ -static inline uint32_t -hal_rx_msdu_start_reception_type_get(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_start *msdu_start = - &pkt_tlvs->msdu_start_tlv.rx_msdu_start; - uint32_t reception_type; - - reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); - - return reception_type; -} #define HAL_RX_MSDU_START_FLOWID_TOEPLITZ_GET(_rx_msdu_start) \ (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_start, \ @@ -1251,28 +1226,6 @@ hal_rx_mpdu_start_mpdu_qos_control_valid_get(uint8_t *buf) return qos_control_valid; } -/* - * Get tid from RX_MPDU_START - */ -#define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ - RX_MPDU_INFO_3_TID_OFFSET)), \ - RX_MPDU_INFO_3_TID_MASK, \ - RX_MPDU_INFO_3_TID_LSB)) - -static inline uint32_t -hal_rx_mpdu_start_tid_get(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - uint32_t tid; - - tid = HAL_RX_MPDU_INFO_TID_GET( - &(mpdu_start->rx_mpdu_info_details)); - - return tid; -} /* * Get SW peer id from RX_MPDU_START @@ -1505,53 +1458,6 @@ hal_rx_msdu_start_get_pkt_type(uint8_t *buf) return pkt_type; } -#define HAL_RX_MSDU_START_NSS_GET(_rx_msdu_start) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ - RX_MSDU_START_5_NSS_OFFSET)), \ - RX_MSDU_START_5_NSS_MASK, \ - RX_MSDU_START_5_NSS_LSB)) - -/* - * hal_rx_msdu_start_nss_get(): API to get the NSS - * Interval from rx_msdu_start - * - * @buf: pointer to the start of RX PKT TLV header - * Return: uint32_t(nss) - */ - -#if !defined(QCA_WIFI_QCA6290_11AX) -static inline uint32_t -hal_rx_msdu_start_nss_get(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_start *msdu_start = - &pkt_tlvs->msdu_start_tlv.rx_msdu_start; - uint32_t nss; - - nss = HAL_RX_MSDU_START_NSS_GET(msdu_start); - return nss; -} -#else -#define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start) \ - (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ - RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ - RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ - RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) - -static inline uint32_t -hal_rx_msdu_start_nss_get(uint8_t *buf) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; - struct rx_msdu_start *msdu_start = - &pkt_tlvs->msdu_start_tlv.rx_msdu_start; - uint8_t mimo_ss_bitmap; - - mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start); - - return qdf_get_hweight8(mimo_ss_bitmap); -} -#endif - #define HAL_RX_MPDU_GET_TODS(_rx_mpdu_info) \ (_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_mpdu_info, \ RX_MPDU_INFO_2_TO_DS_OFFSET)), \ @@ -2797,87 +2703,6 @@ uint8_t dbg_level) mpdu_info->mpdu_ht_control_field); } -/** - * hal_rx_dump_msdu_start_tlv: dump RX msdu_start TLV in structured - * human readable format. - * @ msdu_start: pointer the msdu_start TLV in pkt. - * @ dbg_level: log level. - * - * Return: void - */ -static void hal_rx_dump_msdu_start_tlv(struct rx_msdu_start *msdu_start, - uint8_t dbg_level) -{ - QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, - "rx_msdu_start tlv - " - "rxpcu_mpdu_filter_in_category: %d " - "sw_frame_group_id: %d " - "phy_ppdu_id: %d " - "msdu_length: %d " - "ipsec_esp: %d " - "l3_offset: %d " - "ipsec_ah: %d " - "l4_offset: %d " - "msdu_number: %d " - "decap_format: %d " - "ipv4_proto: %d " - "ipv6_proto: %d " - "tcp_proto: %d " - "udp_proto: %d " - "ip_frag: %d " - "tcp_only_ack: %d " - "da_is_bcast_mcast: %d " - "ip4_protocol_ip6_next_header: %d " - "toeplitz_hash_2_or_4: %d " - "flow_id_toeplitz: %d " - "user_rssi: %d " - "pkt_type: %d " - "stbc: %d " - "sgi: %d " - "rate_mcs: %d " - "receive_bandwidth: %d " - "reception_type: %d " -#if !defined(QCA_WIFI_QCA6290_11AX) - "toeplitz_hash: %d " - "nss: %d " -#endif - "ppdu_start_timestamp: %d " - "sw_phy_meta_data: %d ", - msdu_start->rxpcu_mpdu_filter_in_category, - msdu_start->sw_frame_group_id, - msdu_start->phy_ppdu_id, - msdu_start->msdu_length, - msdu_start->ipsec_esp, - msdu_start->l3_offset, - msdu_start->ipsec_ah, - msdu_start->l4_offset, - msdu_start->msdu_number, - msdu_start->decap_format, - msdu_start->ipv4_proto, - msdu_start->ipv6_proto, - msdu_start->tcp_proto, - msdu_start->udp_proto, - msdu_start->ip_frag, - msdu_start->tcp_only_ack, - msdu_start->da_is_bcast_mcast, - msdu_start->ip4_protocol_ip6_next_header, - msdu_start->toeplitz_hash_2_or_4, - msdu_start->flow_id_toeplitz, - msdu_start->user_rssi, - msdu_start->pkt_type, - msdu_start->stbc, - msdu_start->sgi, - msdu_start->rate_mcs, - msdu_start->receive_bandwidth, - msdu_start->reception_type, -#if !defined(QCA_WIFI_QCA6290_11AX) - msdu_start->toeplitz_hash, - msdu_start->nss, -#endif - msdu_start->ppdu_start_timestamp, - msdu_start->sw_phy_meta_data); -} - /** * hal_rx_dump_msdu_end_tlv: dump RX msdu_end TLV in structured * human readable format. @@ -3055,34 +2880,6 @@ static inline void hal_rx_dump_pkt_hdr_tlv(struct rx_pkt_hdr_tlv *pkt_hdr_tlv, pkt_hdr_tlv->rx_pkt_hdr, 128); } -/** - * hal_rx_dump_pkt_tlvs: API to print all member elements of - * RX TLVs - * @ buf: pointer the pkt buffer. - * @ dbg_level: log level. - * - * Return: void - */ -static inline void hal_rx_dump_pkt_tlvs(uint8_t *buf, uint8_t dbg_level) -{ - struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *) buf; - struct rx_attention *rx_attn = &pkt_tlvs->attn_tlv.rx_attn; - struct rx_mpdu_start *mpdu_start = - &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; - struct rx_msdu_start *msdu_start = - &pkt_tlvs->msdu_start_tlv.rx_msdu_start; - struct rx_mpdu_end *mpdu_end = &pkt_tlvs->mpdu_end_tlv.rx_mpdu_end; - struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; - struct rx_pkt_hdr_tlv *pkt_hdr_tlv = &pkt_tlvs->pkt_hdr_tlv; - - hal_rx_dump_rx_attention_tlv(rx_attn, dbg_level); - hal_rx_dump_mpdu_start_tlv(mpdu_start, dbg_level); - hal_rx_dump_msdu_start_tlv(msdu_start, dbg_level); - hal_rx_dump_mpdu_end_tlv(mpdu_end, dbg_level); - hal_rx_dump_msdu_end_tlv(msdu_end, dbg_level); - hal_rx_dump_pkt_hdr_tlv(pkt_hdr_tlv, dbg_level); -} - /** * hal_srng_ring_id_get: API to retrieve ring id from hal ring * structure @@ -3583,4 +3380,124 @@ static inline void hal_rx_wbm_err_info_get_from_tlv(uint8_t *buf, sizeof(struct hal_wbm_err_desc_info)); } +#define HAL_RX_MSDU_START_NSS_GET(_rx_msdu_start) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ + RX_MSDU_START_5_NSS_OFFSET)), \ + RX_MSDU_START_5_NSS_MASK, \ + RX_MSDU_START_5_NSS_LSB)) + +/** + * hal_rx_mon_hw_desc_get_mpdu_status: Retrieve MPDU status + * + * @ hal_soc: HAL version of the SOC pointer + * @ hw_desc_addr: Start address of Rx HW TLVs + * @ rs: Status for monitor mode + * + * Return: void + */ +static inline void hal_rx_mon_hw_desc_get_mpdu_status(struct hal_soc *hal_soc, + void *hw_desc_addr, + struct mon_rx_status *rs) +{ + hal_soc->ops->hal_rx_mon_hw_desc_get_mpdu_status(hw_desc_addr, rs); +} + +/* + * hal_rx_get_tlv(): API to get the tlv + * + * @hal_soc: HAL version of the SOC pointer + * @rx_tlv: TLV data extracted from the rx packet + * Return: uint8_t + */ +static inline uint8_t hal_rx_get_tlv(struct hal_soc *hal_soc, void *rx_tlv) +{ + return hal_soc->ops->hal_rx_get_tlv(rx_tlv); +} + +/* + * hal_rx_msdu_start_nss_get(): API to get the NSS + * Interval from rx_msdu_start + * + * @hal_soc: HAL version of the SOC pointer + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(nss) + */ +static inline uint32_t hal_rx_msdu_start_nss_get(struct hal_soc *hal_soc, + uint8_t *buf) +{ + return hal_soc->ops->hal_rx_msdu_start_nss_get(buf); +} + +/** + * hal_rx_dump_msdu_start_tlv: dump RX msdu_start TLV in structured + * human readable format. + * @ msdu_start: pointer the msdu_start TLV in pkt. + * @ dbg_level: log level. + * + * Return: void + */ +static inline void hal_rx_dump_msdu_start_tlv(struct hal_soc *hal_soc, + struct rx_msdu_start *msdu_start, + uint8_t dbg_level) +{ + hal_soc->ops->hal_rx_dump_msdu_start_tlv(msdu_start, dbg_level); +} + +/** + * hal_rx_mpdu_start_tid_get - Return tid info from the rx mpdu start + * info details + * + * @ buf - Pointer to buffer containing rx pkt tlvs. + * + * + */ +static inline uint32_t hal_rx_mpdu_start_tid_get(struct hal_soc *hal_soc, + uint8_t *buf) +{ + return hal_soc->ops->hal_rx_mpdu_start_tid_get(buf); +} + +/* + * hal_rx_msdu_start_reception_type_get(): API to get the reception type + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(reception_type) + */ +static inline +uint32_t hal_rx_msdu_start_reception_type_get(struct hal_soc *hal_soc, + uint8_t *buf) +{ + return hal_soc->ops->hal_rx_msdu_start_reception_type_get(buf); +} + +/** + * hal_rx_dump_pkt_tlvs: API to print all member elements of + * RX TLVs + * @ buf: pointer the pkt buffer. + * @ dbg_level: log level. + * + * Return: void + */ +static inline void hal_rx_dump_pkt_tlvs(struct hal_soc *hal_soc, + uint8_t *buf, uint8_t dbg_level) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_attention *rx_attn = &pkt_tlvs->attn_tlv.rx_attn; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + struct rx_mpdu_end *mpdu_end = &pkt_tlvs->mpdu_end_tlv.rx_mpdu_end; + struct rx_msdu_end *msdu_end = &pkt_tlvs->msdu_end_tlv.rx_msdu_end; + struct rx_pkt_hdr_tlv *pkt_hdr_tlv = &pkt_tlvs->pkt_hdr_tlv; + + hal_rx_dump_rx_attention_tlv(rx_attn, dbg_level); + hal_rx_dump_mpdu_start_tlv(mpdu_start, dbg_level); + hal_rx_dump_msdu_start_tlv(hal_soc, msdu_start, dbg_level); + hal_rx_dump_mpdu_end_tlv(mpdu_end, dbg_level); + hal_rx_dump_msdu_end_tlv(msdu_end, dbg_level); + hal_rx_dump_pkt_hdr_tlv(pkt_hdr_tlv, dbg_level); +} + #endif /* _HAL_RX_H */ diff --git a/hal/wifi3.0/README b/hal/wifi3.0/README new file mode 100644 index 000000000000..e966035035f7 --- /dev/null +++ b/hal/wifi3.0/README @@ -0,0 +1,17 @@ +The below qca6290 and qca8074 folder has c files defining functions +and structures to hold target specific definitions to handle differences between +chips with respect to hal. + +Please ensure changes get applied to all platform specific files if the fixes +are generic and applicable to all the folders. + +qca6290 + hal_6290_rx.c - rx related target specific function + hal_6290_srng_table.c - holds hw srng table and hal hw reg offsets array + hal_6290_tx.c - tx related target specific function +qca8074 + hal_8074_rx.c - rx related target specific function + hal_8074_srng_table.c - holds hw srng table and hal hw reg offsets array + hal_8074_tx.c - tx related target specific function + + diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 3bb4a3a3876c..18b8b0a864b3 100644 --- a/hal/wifi3.0/hal_api.h +++ b/hal/wifi3.0/hal_api.h @@ -33,9 +33,6 @@ #include "qdf_types.h" #include "qdf_util.h" #include "hal_internal.h" -#include "rx_msdu_link.h" -#include "rx_reo_queue.h" -#include "rx_reo_queue_ext.h" #define MAX_UNWINDOWED_ADDRESS 0x80000 #ifdef TARGET_TYPE_QCA6390 @@ -168,6 +165,7 @@ enum hal_ring_type { MAX_RING_TYPES }; +#define HAL_SRNG_LMAC_RING 0x80000000 /* SRNG flags passed in hal_srng_params.flags */ #define HAL_SRNG_MSI_SWAP 0x00000008 #define HAL_SRNG_RING_PTR_SWAP 0x00000010 @@ -512,8 +510,8 @@ static inline uint32_t hal_srng_dst_num_valid(void *hal_soc, void *hal_ring, int sync_hw_ptr) { struct hal_srng *srng = (struct hal_srng *)hal_ring; - uint32 hp; - uint32 tp = srng->u.dst_ring.tp; + uint32_t hp; + uint32_t tp = srng->u.dst_ring.tp; if (sync_hw_ptr) { hp = *(srng->u.dst_ring.hp_addr); @@ -747,8 +745,8 @@ static inline uint32_t hal_srng_src_num_avail(void *hal_soc, void *hal_ring, int sync_hw_ptr) { struct hal_srng *srng = (struct hal_srng *)hal_ring; - uint32 tp; - uint32 hp = srng->u.src_ring.hp; + uint32_t tp; + uint32_t hp = srng->u.src_ring.hp; if (sync_hw_ptr) { tp = *(srng->u.src_ring.tp_addr); @@ -836,13 +834,11 @@ static inline void hal_srng_access_end_reap(void *hal_soc, void *hal_ring) } /* TODO: Check if the following definitions is available in HW headers */ -#define WBM_IDLE_DESC_LIST 1 #define WBM_IDLE_SCATTER_BUF_SIZE 32704 #define NUM_MPDUS_PER_LINK_DESC 6 #define NUM_MSDUS_PER_LINK_DESC 7 #define REO_QUEUE_DESC_ALIGN 128 -#define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) #define LINK_DESC_ALIGN 128 #define ADDRESS_MATCH_TAG_VAL 0x5 @@ -858,28 +854,6 @@ static inline void hal_srng_access_end_reap(void *hal_soc, void *hal_ring) */ #define WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE 8 -/** - * hal_set_link_desc_addr - Setup link descriptor in a buffer_addr_info - * HW structure - * - * @desc: Descriptor entry (from WBM_IDLE_LINK ring) - * @cookie: SW cookie for the buffer/descriptor - * @link_desc_paddr: Physical address of link descriptor entry - * - */ -static inline void hal_set_link_desc_addr(void *desc, uint32_t cookie, - qdf_dma_addr_t link_desc_paddr) -{ - uint32_t *buf_addr = (uint32_t *)desc; - HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_0, BUFFER_ADDR_31_0, - link_desc_paddr & 0xffffffff); - HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_1, BUFFER_ADDR_39_32, - (uint64_t)link_desc_paddr >> 32); - HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_1, RETURN_BUFFER_MANAGER, - WBM_IDLE_DESC_LIST); - HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_1, SW_BUFFER_COOKIE, - cookie); -} /** * hal_idle_list_scatter_buf_size - Get the size of each scatter buffer @@ -899,9 +873,19 @@ static inline uint32_t hal_idle_list_scatter_buf_size(void *hal_soc) * @hal_soc: Opaque HAL SOC handle * */ -static inline uint32_t hal_get_link_desc_size(void *hal_soc) +static inline uint32_t hal_get_link_desc_size(struct hal_soc *hal_soc) { - return LINK_DESC_SIZE; + if (!hal_soc || !hal_soc->ops) { + qdf_print("Error: Invalid ops\n"); + QDF_BUG(0); + return -EINVAL; + } + if (!hal_soc->ops->hal_get_link_desc_size) { + qdf_print("Error: Invalid function pointer\n"); + QDF_BUG(0); + return -EINVAL; + } + return hal_soc->ops->hal_get_link_desc_size(); } /** @@ -1036,30 +1020,6 @@ enum hal_pn_type { }; #define HAL_RX_MAX_BA_WINDOW 256 -/** - * hal_get_reo_qdesc_size - Get size of reo queue descriptor - * - * @hal_soc: Opaque HAL SOC handle - * @ba_window_size: BlockAck window size - * - */ -static inline uint32_t hal_get_reo_qdesc_size(void *hal_soc, - uint32_t ba_window_size) -{ - if (ba_window_size <= 1) - return sizeof(struct rx_reo_queue); - - if (ba_window_size <= 105) - return sizeof(struct rx_reo_queue) + - sizeof(struct rx_reo_queue_ext); - - if (ba_window_size <= 210) - return sizeof(struct rx_reo_queue) + - (2 * sizeof(struct rx_reo_queue_ext)); - - return sizeof(struct rx_reo_queue) + - (3 * sizeof(struct rx_reo_queue_ext)); -} /** * hal_get_reo_qdesc_align - Get start address alignment for reo @@ -1151,4 +1111,11 @@ extern void hal_get_srng_params(void *hal_soc, void *hal_ring, * @mem: pointer to structure to be updated with hal mem info */ extern void hal_get_meminfo(void *hal_soc,struct hal_mem_info *mem ); + +/** + * hal_get_target_type - Return target type + * + * @hal_soc: Opaque HAL SOC handle + */ +uint32_t hal_get_target_type(struct hal_soc *hal); #endif /* _HAL_APIH_ */ diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h index c309204c0a57..45ab3a4c9094 100644 --- a/hal/wifi3.0/hal_api_mon.h +++ b/hal/wifi3.0/hal_api_mon.h @@ -21,6 +21,7 @@ #include "qdf_types.h" #include "hal_internal.h" +#include #define HAL_RX_OFFSET(block, field) block##_##field##_OFFSET #define HAL_RX_LSB(block, field) block##_##field##_LSB @@ -398,47 +399,6 @@ enum { HAL_RX_MON_PPDU_END, }; -/** - * hal_rx_mon_hw_desc_get_mpdu_status: Retrieve MPDU status - * - * @ hw_desc_addr: Start address of Rx HW TLVs - * @ rs: Status for monitor mode - * - * Return: void - */ -static inline -void hal_rx_mon_hw_desc_get_mpdu_status(void *hw_desc_addr, - struct mon_rx_status *rs) -{ - struct rx_msdu_start *rx_msdu_start; - struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; - uint32_t reg_value; - static uint32_t sgi_hw_to_cdp[] = { - CDP_SGI_0_8_US, - CDP_SGI_0_4_US, - CDP_SGI_1_6_US, - CDP_SGI_3_2_US, - }; - - rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; - HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); - - rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, - RX_MSDU_START_5, USER_RSSI); - rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); - - reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); - rs->sgi = sgi_hw_to_cdp[reg_value]; -#if !defined(QCA_WIFI_QCA6290_11AX) - rs->nr_ant = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS); -#endif - - reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); - rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; - /* TODO: rs->beamformed should be set for SU beamforming also */ - hal_rx_dump_pkt_tlvs((uint8_t *)rx_desc, QDF_TRACE_LEVEL_DEBUG); -} - struct hal_rx_ppdu_user_info { }; @@ -490,77 +450,14 @@ hal_rx_status_get_next_tlv(uint8_t *rx_tlv) { HAL_RX_TLV32_HDR_SIZE + 3)) & (~((unsigned long)3))); } -#ifdef QCA_WIFI_QCA6290_11AX -/** - * hal_rx_proc_phyrx_other_receive_info_tlv() - process other receive info TLV - * @rx_tlv_hdr: pointer to TLV header - * @ppdu_info: pointer to ppdu_info - * - * Return: None - */ -static void hal_rx_proc_phyrx_other_receive_info_tlv(void *rx_tlv_hdr, - struct hal_rx_ppdu_info *ppdu_info) +static void hal_rx_proc_phyrx_other_receive_info_tlv(struct hal_soc *hal_soc, + void *rx_tlv_hdr, + struct hal_rx_ppdu_info + *ppdu_info) { - uint32_t tlv_tag, tlv_len; - uint32_t temp_len, other_tlv_len, other_tlv_tag; - void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; - void *other_tlv_hdr = NULL; - void *other_tlv = NULL; - uint32_t ru_details_channel_0; - - tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); - tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); - temp_len = 0; - - other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE; - - other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr); - other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr); - temp_len += other_tlv_len; - other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; - - switch (other_tlv_tag) { - case WIFIPHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_E: - ru_details_channel_0 = - HAL_RX_GET(other_tlv, - PHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_0, - RU_DETAILS_CHANNEL_0); - - qdf_mem_copy(ppdu_info->rx_status.he_RU, - &ru_details_channel_0, - sizeof(ppdu_info->rx_status.he_RU)); - - if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_20) - ppdu_info->rx_status.he_sig_b_common_known |= - QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0; - - if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_40) - ppdu_info->rx_status.he_sig_b_common_known |= - QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU1; - - if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_80) - ppdu_info->rx_status.he_sig_b_common_known |= - QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU2; - - if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_160) - ppdu_info->rx_status.he_sig_b_common_known |= - QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU3; - break; - default: - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s unhandled TLV type: %d, TLV len:%d", - __func__, other_tlv_tag, other_tlv_len); - break; - } - + hal_soc->ops->hal_rx_proc_phyrx_other_receive_info_tlv(rx_tlv_hdr, + (void *)ppdu_info); } -#else -static inline void -hal_rx_proc_phyrx_other_receive_info_tlv(void *rx_tlv_hdr, - struct hal_rx_ppdu_info *ppdu_info) -{ -} -#endif /* QCA_WIFI_QCA6290_11AX */ /** * hal_rx_status_get_tlv_info() - process receive info TLV @@ -570,7 +467,8 @@ hal_rx_proc_phyrx_other_receive_info_tlv(void *rx_tlv_hdr, * Return: HAL_TLV_STATUS_PPDU_NOT_DONE or HAL_TLV_STATUS_PPDU_DONE from tlv */ static inline uint32_t -hal_rx_status_get_tlv_info(void *rx_tlv_hdr, struct hal_rx_ppdu_info *ppdu_info) +hal_rx_status_get_tlv_info(void *rx_tlv_hdr, struct hal_rx_ppdu_info *ppdu_info, + struct hal_soc *hal) { uint32_t tlv_tag, user_id, tlv_len, value; uint8_t group_id = 0; @@ -814,17 +712,31 @@ hal_rx_status_get_tlv_info(void *rx_tlv_hdr, struct hal_rx_ppdu_info *ppdu_info) VHT_SIG_A_INFO_1, MCS); ppdu_info->rx_status.sgi = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1, GI_SETTING); -#if !defined(QCA_WIFI_QCA6290_11AX) - ppdu_info->rx_status.is_stbc = HAL_RX_GET(vht_sig_a_info, - VHT_SIG_A_INFO_0, STBC); - value = HAL_RX_GET(vht_sig_a_info, - VHT_SIG_A_INFO_0, N_STS); - if (ppdu_info->rx_status.is_stbc && (value > 0)) - value = ((value + 1) >> 1) - 1; - ppdu_info->rx_status.nss = ((value & VHT_SIG_SU_NSS_MASK) + 1); -#else - ppdu_info->rx_status.nss = 0; + + switch (hal->target_type) { + case TARGET_TYPE_QCA8074: + ppdu_info->rx_status.is_stbc = + HAL_RX_GET(vht_sig_a_info, + VHT_SIG_A_INFO_0, STBC); + value = HAL_RX_GET(vht_sig_a_info, + VHT_SIG_A_INFO_0, N_STS); + if (ppdu_info->rx_status.is_stbc && (value > 0)) + value = ((value + 1) >> 1) - 1; + ppdu_info->rx_status.nss = + ((value & VHT_SIG_SU_NSS_MASK) + 1); + + break; + case TARGET_TYPE_QCA6290: + ppdu_info->rx_status.nss = 0; + break; +#ifdef QCA_WIFI_QCA6390 + case TARGET_TYPE_QCA6390: + ppdu_info->rx_status.nss = 0; + break; #endif + default: + break; + } ppdu_info->rx_status.vht_flag_values3[0] = (((ppdu_info->rx_status.mcs) << 4) | ppdu_info->rx_status.nss); @@ -1287,12 +1199,7 @@ hal_rx_status_get_tlv_info(void *rx_tlv_hdr, struct hal_rx_ppdu_info *ppdu_info) ppdu_info->rx_status.rssi_comb = HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_35, RSSI_COMB); - ppdu_info->rx_status.bw = HAL_RX_GET(rx_tlv, -#if !defined(QCA_WIFI_QCA6290_11AX) - PHYRX_RSSI_LEGACY_35, RECEIVE_BANDWIDTH); -#else - PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); -#endif + ppdu_info->rx_status.bw = hal->ops->hal_rx_get_tlv(rx_tlv); ppdu_info->rx_status.he_re = 0; ppdu_info->rx_status.reception_type = HAL_RX_GET(rx_tlv, @@ -1334,13 +1241,15 @@ hal_rx_status_get_tlv_info(void *rx_tlv_hdr, struct hal_rx_ppdu_info *ppdu_info) "RSSI_EXT80_HIGH_LOW20_CHAIN0: %d\n", value); value = HAL_RX_GET(rssi_info_tlv, - RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH20_CHAIN0); + RECEIVE_RSSI_INFO_1, + RSSI_EXT80_HIGH20_CHAIN0); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "RSSI_EXT80_HIGH20_CHAIN0: %d\n", value); break; } case WIFIPHYRX_OTHER_RECEIVE_INFO_E: - hal_rx_proc_phyrx_other_receive_info_tlv(rx_tlv_hdr, ppdu_info); + hal_rx_proc_phyrx_other_receive_info_tlv(hal, rx_tlv_hdr, + ppdu_info); break; case WIFIRX_HEADER_E: ppdu_info->msdu_info.first_msdu_payload = rx_tlv; diff --git a/hal/wifi3.0/hal_hw_headers.h b/hal/wifi3.0/hal_hw_headers.h new file mode 100644 index 000000000000..cac457f20c57 --- /dev/null +++ b/hal/wifi3.0/hal_hw_headers.h @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HAL_HW_INTERNAL_H_ +#define _HAL_HW_INTERNAL_H_ +#include "qdf_types.h" +#include "qdf_lock.h" +#include "qdf_mem.h" +#include "rx_msdu_link.h" +#include "rx_reo_queue.h" +#include "rx_reo_queue_ext.h" +#include "wcss_seq_hwiobase.h" +#include "tlv_hdr.h" +#include "tlv_tag_def.h" +#include "reo_destination_ring.h" +#include "reo_reg_seq_hwioreg.h" +#include "reo_entrance_ring.h" +#include "reo_get_queue_stats.h" +#include "reo_get_queue_stats_status.h" +#include "tcl_data_cmd.h" +#include "tcl_gse_cmd.h" +#include "tcl_status_ring.h" +#include "mac_tcl_reg_seq_hwioreg.h" +#include "ce_src_desc.h" +#include "ce_stat_desc.h" +#include "wfss_ce_reg_seq_hwioreg.h" +#include "wbm_link_descriptor_ring.h" +#include "wbm_reg_seq_hwioreg.h" +#include "wbm_buffer_ring.h" +#include "wbm_release_ring.h" +#include "rx_msdu_desc_info.h" +#include "rx_mpdu_start.h" +#include "rx_mpdu_end.h" +#include "rx_msdu_start.h" +#include "rx_msdu_end.h" +#include "rx_attention.h" +#include "rx_ppdu_start.h" +#include "rx_ppdu_start_user_info.h" +#include "rx_ppdu_end_user_stats.h" +#include "rx_ppdu_end_user_stats_ext.h" +#include "rx_mpdu_desc_info.h" +#include "rxpcu_ppdu_end_info.h" +#include "phyrx_he_sig_a_su.h" +#include "phyrx_he_sig_a_mu_dl.h" +#include "phyrx_he_sig_b1_mu.h" +#include "phyrx_he_sig_b2_mu.h" +#include "phyrx_he_sig_b2_ofdma.h" +#include "phyrx_l_sig_a.h" +#include "phyrx_l_sig_b.h" +#include "phyrx_vht_sig_a.h" +#include "phyrx_ht_sig.h" +#include "tx_msdu_extension.h" +#include "receive_rssi_info.h" +#include "phyrx_pkt_end.h" +#include "phyrx_rssi_legacy.h" +#include "wcss_version.h" +#include "rx_msdu_link.h" + +#define HAL_SRNG_REO_EXCEPTION HAL_SRNG_REO2SW1 +#define HAL_SRNG_REO_ALTERNATE_SELECT 0x7 + +/* calculate the register address offset from bar0 of shadow register x */ +#define SHADOW_REGISTER(x) (0x00003024 + (4 * (x))) + +/* TODO: Check if the following can be provided directly by HW headers */ +#define SRNG_LOOP_CNT_MASK REO_DESTINATION_RING_15_LOOPING_COUNT_MASK +#define SRNG_LOOP_CNT_LSB REO_DESTINATION_RING_15_LOOPING_COUNT_LSB + +#define HAL_DEFAULT_REO_TIMEOUT_MS 40 /* milliseconds */ + +#define HAL_DESC_SET_FIELD(_desc, _word, _fld, _value) do { \ + ((uint32_t *)(_desc))[(_word ## _ ## _fld ## _OFFSET) >> 2] &= \ + ~(_word ## _ ## _fld ## _MASK); \ + ((uint32_t *)(_desc))[(_word ## _ ## _fld ## _OFFSET) >> 2] |= \ + ((_value) << _word ## _ ## _fld ## _LSB); \ +} while (0) + +#define HAL_SM(_reg, _fld, _val) \ + (((_val) << (_reg ## _ ## _fld ## _SHFT)) & \ + (_reg ## _ ## _fld ## _BMSK)) + +#define HAL_MS(_reg, _fld, _val) \ + (((_val) & (_reg ## _ ## _fld ## _BMSK)) >> \ + (_reg ## _ ## _fld ## _SHFT)) + +#define HAL_REG_WRITE(_soc, _reg, _value) \ + hal_write32_mb(_soc, (_reg), (_value)) + +#define HAL_REG_READ(_soc, _offset) \ + hal_read32_mb(_soc, (_offset)) + +#define WBM_IDLE_DESC_LIST 1 + +/** + * Common SRNG register access macros: + * The SRNG registers are distributed across various UMAC and LMAC HW blocks, + * but the register group and format is exactly same for all rings, with some + * difference between producer rings (these are 'producer rings' with respect + * to HW and referred as 'destination rings' in SW) and consumer rings (these + * are 'consumer rings' with respect to HW and + * referred as 'source rings' in SW). + * The following macros provide uniform access to all SRNG rings. + */ + +/* SRNG registers are split among two groups R0 and R2 and following + * definitions identify the group to which each register belongs to + */ +#define R0_INDEX 0 +#define R2_INDEX 1 + +#define HWREG_INDEX(_reg_group) _reg_group ## _ ## INDEX + +/* Registers in R0 group */ +#define BASE_LSB_GROUP R0 +#define BASE_MSB_GROUP R0 +#define ID_GROUP R0 +#define STATUS_GROUP R0 +#define MISC_GROUP R0 +#define HP_ADDR_LSB_GROUP R0 +#define HP_ADDR_MSB_GROUP R0 +#define PRODUCER_INT_SETUP_GROUP R0 +#define PRODUCER_INT_STATUS_GROUP R0 +#define PRODUCER_FULL_COUNTER_GROUP R0 +#define MSI1_BASE_LSB_GROUP R0 +#define MSI1_BASE_MSB_GROUP R0 +#define MSI1_DATA_GROUP R0 +#define HP_TP_SW_OFFSET_GROUP R0 +#define TP_ADDR_LSB_GROUP R0 +#define TP_ADDR_MSB_GROUP R0 +#define CONSUMER_INT_SETUP_IX0_GROUP R0 +#define CONSUMER_INT_SETUP_IX1_GROUP R0 +#define CONSUMER_INT_STATUS_GROUP R0 +#define CONSUMER_EMPTY_COUNTER_GROUP R0 +#define CONSUMER_PREFETCH_TIMER_GROUP R0 +#define CONSUMER_PREFETCH_STATUS_GROUP R0 + +/* Registers in R2 group */ +#define HP_GROUP R2 +#define TP_GROUP R2 + +/** + * Register definitions for all SRNG based rings are same, except few + * differences between source (HW consumer) and destination (HW producer) + * registers. Following macros definitions provide generic access to all + * SRNG based rings. + * For source rings, we will use the register/field definitions of SW2TCL1 + * ring defined in the HW header file mac_tcl_reg_seq_hwioreg.h. To setup + * individual fields, SRNG_SM macros should be used with fields specified + * using SRNG_SRC_FLD(, ), Register writes should be done + * using SRNG_SRC_REG_WRITE(, , ). + * Similarly for destination rings we will use definitions of REO2SW1 ring + * defined in the register reo_destination_ring.h. To setup individual + * fields SRNG_SM macros should be used with fields specified using + * SRNG_DST_FLD(, ). Register writes should be done using + * SRNG_DST_REG_WRITE(, , ). + */ + +#define SRNG_DST_REG_OFFSET(_reg, _reg_group) \ + HWIO_REO_ ## _reg_group ## _REO2SW1_RING_ ## _reg##_ADDR(0) + +#define SRNG_SRC_REG_OFFSET(_reg, _reg_group) \ + HWIO_TCL_ ## _reg_group ## _SW2TCL1_RING_ ## _reg ## _ADDR(0) + +#define _SRNG_DST_FLD(_reg_group, _reg_fld) \ + HWIO_REO_ ## _reg_group ## _REO2SW1_RING_ ## _reg_fld +#define _SRNG_SRC_FLD(_reg_group, _reg_fld) \ + HWIO_TCL_ ## _reg_group ## _SW2TCL1_RING_ ## _reg_fld + +#define _SRNG_FLD(_reg_group, _reg_fld, _dir) \ + _SRNG_ ## _dir ## _FLD(_reg_group, _reg_fld) + +#define SRNG_DST_FLD(_reg, _f) _SRNG_FLD(_reg ## _GROUP, _reg ## _ ## _f, DST) +#define SRNG_SRC_FLD(_reg, _f) _SRNG_FLD(_reg ## _GROUP, _reg ## _ ## _f, SRC) + +#define SRNG_SRC_R0_START_OFFSET SRNG_SRC_REG_OFFSET(BASE_LSB, R0) +#define SRNG_DST_R0_START_OFFSET SRNG_DST_REG_OFFSET(BASE_LSB, R0) + +#define SRNG_SRC_R2_START_OFFSET SRNG_SRC_REG_OFFSET(HP, R2) +#define SRNG_DST_R2_START_OFFSET SRNG_DST_REG_OFFSET(HP, R2) + +#define SRNG_SRC_START_OFFSET(_reg_group) \ + SRNG_SRC_ ## _reg_group ## _START_OFFSET +#define SRNG_DST_START_OFFSET(_reg_group) \ + SRNG_DST_ ## _reg_group ## _START_OFFSET +#define SRNG_REG_ADDR(_srng, _reg, _reg_group, _dir) \ + ((_srng)->hwreg_base[HWREG_INDEX(_reg_group)] + \ + ((_srng)->hal_soc->hal_hw_reg_offset[_dir ## _ ##_reg])) + +#define CALCULATE_REG_OFFSET(_dir, _reg, _reg_group) \ + (SRNG_ ## _dir ## _REG_OFFSET(_reg, _reg_group) - \ + SRNG_ ## _dir ## _START_OFFSET(_reg_group)) + +#define REG_OFFSET(_dir, _reg) \ + CALCULATE_REG_OFFSET(_dir, _reg, _reg ## _GROUP) + +#define SRNG_DST_ADDR(_srng, _reg) \ + SRNG_REG_ADDR(_srng, _reg, _reg ## _GROUP, DST) + +#define SRNG_SRC_ADDR(_srng, _reg) \ + SRNG_REG_ADDR(_srng, _reg, _reg ## _GROUP, SRC) + +#define SRNG_REG_WRITE(_srng, _reg, _value, _dir) \ + hal_write_address_32_mb(_srng->hal_soc, \ + SRNG_ ## _dir ## _ADDR(_srng, _reg), (_value)) + +#define SRNG_REG_READ(_srng, _reg, _dir) \ + hal_read_address_32_mb(_srng->hal_soc, \ + SRNG_ ## _dir ## _ADDR(_srng, _reg)) + +#define SRNG_SRC_REG_WRITE(_srng, _reg, _value) \ + SRNG_REG_WRITE(_srng, _reg, _value, SRC) + +#define SRNG_DST_REG_WRITE(_srng, _reg, _value) \ + SRNG_REG_WRITE(_srng, _reg, _value, DST) + +#define SRNG_SRC_REG_READ(_srng, _reg) \ + SRNG_REG_READ(_srng, _reg, SRC) + +#define _SRNG_FM(_reg_fld) _reg_fld ## _BMSK +#define _SRNG_FS(_reg_fld) _reg_fld ## _SHFT + +#define SRNG_SM(_reg_fld, _val) \ + (((_val) << _SRNG_FS(_reg_fld)) & _SRNG_FM(_reg_fld)) + +#define SRNG_MS(_reg_fld, _val) \ + (((_val) & _SRNG_FM(_reg_fld)) >> _SRNG_FS(_reg_fld)) + +#define SRNG_MAX_SIZE_DWORDS \ + (SRNG_MS(SRNG_SRC_FLD(BASE_MSB, RING_SIZE), 0xffffffff)) + +/** + * HW ring configuration table to identify hardware ring attributes like + * register addresses, number of rings, ring entry size etc., for each type + * of SRNG ring. + * + * Currently there is just one HW ring table, but there could be multiple + * configurations in future based on HW variants from the same wifi3.0 family + * and hence need to be attached with hal_soc based on HW type + */ +#define HAL_SRNG_CONFIG(_hal_soc, _ring_type) \ + (&_hal_soc->hw_srng_table[_ring_type]) + +enum SRNG_REGISTERS { +DST_HP = 0, +DST_TP, +DST_ID, +DST_MISC, +DST_HP_ADDR_LSB, +DST_HP_ADDR_MSB, +DST_MSI1_BASE_LSB, +DST_MSI1_BASE_MSB, +DST_MSI1_DATA, +DST_BASE_LSB, +DST_BASE_MSB, +DST_PRODUCER_INT_SETUP, + +SRC_HP, +SRC_TP, +SRC_ID, +SRC_MISC, +SRC_TP_ADDR_LSB, +SRC_TP_ADDR_MSB, +SRC_MSI1_BASE_LSB, +SRC_MSI1_BASE_MSB, +SRC_MSI1_DATA, +SRC_BASE_LSB, +SRC_BASE_MSB, +SRC_CONSUMER_INT_SETUP_IX0, +SRC_CONSUMER_INT_SETUP_IX1, +}; + +/** + * hal_set_link_desc_addr - Setup link descriptor in a buffer_addr_info + * HW structure + * + * @desc: Descriptor entry (from WBM_IDLE_LINK ring) + * @cookie: SW cookie for the buffer/descriptor + * @link_desc_paddr: Physical address of link descriptor entry + * + */ +static inline void hal_set_link_desc_addr(void *desc, uint32_t cookie, + qdf_dma_addr_t link_desc_paddr) +{ + uint32_t *buf_addr = (uint32_t *)desc; + + HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_0, BUFFER_ADDR_31_0, + link_desc_paddr & 0xffffffff); + HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_1, BUFFER_ADDR_39_32, + (uint64_t)link_desc_paddr >> 32); + HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_1, RETURN_BUFFER_MANAGER, + WBM_IDLE_DESC_LIST); + HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_1, SW_BUFFER_COOKIE, + cookie); +} + +/** + * hal_get_reo_qdesc_size - Get size of reo queue descriptor + * + * @hal_soc: Opaque HAL SOC handle + * @ba_window_size: BlockAck window size + * + */ +static inline uint32_t hal_get_reo_qdesc_size(void *hal_soc, + uint32_t ba_window_size) +{ + if (ba_window_size <= 1) + return sizeof(struct rx_reo_queue); + + if (ba_window_size <= 105) + return sizeof(struct rx_reo_queue) + + sizeof(struct rx_reo_queue_ext); + + if (ba_window_size <= 210) + return sizeof(struct rx_reo_queue) + + (2 * sizeof(struct rx_reo_queue_ext)); + + return sizeof(struct rx_reo_queue) + + (3 * sizeof(struct rx_reo_queue_ext)); +} + +#endif /* _HAL_HW_INTERNAL_H_ */ diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index c446fd8d0dfb..c8ae3efdbca3 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -34,57 +34,8 @@ #include "qdf_lock.h" #include "qdf_mem.h" #include "qdf_nbuf.h" -#include "wcss_seq_hwiobase.h" -#include "tlv_hdr.h" -#include "tlv_tag_def.h" -#include "reo_destination_ring.h" -#include "reo_reg_seq_hwioreg.h" -#include "reo_entrance_ring.h" -#include "reo_get_queue_stats.h" -#include "reo_get_queue_stats_status.h" -#include "tcl_data_cmd.h" -#include "tcl_gse_cmd.h" -#include "tcl_status_ring.h" -#include "mac_tcl_reg_seq_hwioreg.h" -#include "ce_src_desc.h" -#include "ce_stat_desc.h" -#include "wfss_ce_reg_seq_hwioreg.h" -#include "wbm_link_descriptor_ring.h" -#include "wbm_reg_seq_hwioreg.h" -#include "wbm_buffer_ring.h" -#include "wbm_release_ring.h" -#include "rx_msdu_desc_info.h" -#include "rx_mpdu_start.h" -#include "rx_mpdu_end.h" -#include "rx_msdu_start.h" -#include "rx_msdu_end.h" -#include "rx_attention.h" -#include "rx_ppdu_start.h" -#include "rx_ppdu_start_user_info.h" -#include "rx_ppdu_end_user_stats.h" -#include "rx_ppdu_end_user_stats_ext.h" -#include "rx_mpdu_desc_info.h" -#include "rxpcu_ppdu_end_info.h" -#include "phyrx_he_sig_a_su.h" -#include "phyrx_he_sig_a_mu_dl.h" -#include "phyrx_he_sig_b1_mu.h" -#include "phyrx_he_sig_b2_mu.h" -#include "phyrx_he_sig_b2_ofdma.h" -#include "phyrx_l_sig_a.h" -#include "phyrx_l_sig_b.h" -#include "phyrx_vht_sig_a.h" -#include "phyrx_ht_sig.h" -#include "tx_msdu_extension.h" -#include "receive_rssi_info.h" -#include "phyrx_pkt_end.h" -#include "phyrx_rssi_legacy.h" -#include "wcss_version.h" #include "pld_common.h" -#include "rx_msdu_link.h" -#ifdef QCA_WIFI_QCA6290_11AX -#include "phyrx_other_receive_info_ru_details.h" -#endif /* QCA_WIFI_QCA6290_11AX */ /* TBD: This should be movded to shared HW header file */ enum hal_srng_ring_id { @@ -181,9 +132,7 @@ enum hal_srng_ring_id { HAL_SRNG_LMAC1_ID_END = 143 }; -#define HAL_SRNG_REO_EXCEPTION HAL_SRNG_REO2SW1 -#define HAL_SRNG_REO_ALTERNATE_SELECT 0x7 - +#define HAL_RXDMA_MAX_RING_SIZE 0xFFFF #define HAL_MAX_LMACS 3 #define HAL_MAX_RINGS_PER_LMAC (HAL_SRNG_LMAC1_ID_END - HAL_SRNG_LMAC1_ID_START) #define HAL_MAX_LMAC_RINGS (HAL_MAX_LMACS * HAL_MAX_RINGS_PER_LMAC) @@ -202,6 +151,7 @@ enum hal_srng_dir { #define SRNG_UNLOCK(_lock) qdf_spin_unlock_bh(_lock) #define SRNG_LOCK_DESTROY(_lock) qdf_spinlock_destroy(_lock) +struct hal_soc; #define MAX_SRNG_REG_GROUPS 2 /* Common SRNG ring structure for source and destination rings */ @@ -321,10 +271,30 @@ struct hal_hw_srng_config { uint32_t max_size; }; -/* calculate the register address offset from bar0 of shadow register x */ -#define SHADOW_REGISTER(x) (0x00003024 + (4*x)) #define MAX_SHADOW_REGISTERS 36 +struct hal_hw_txrx_ops { + /* tx */ + void (*hal_tx_desc_set_dscp_tid_table_id)(void *desc, uint8_t id); + void (*hal_tx_set_dscp_tid_map)(void *hal_soc, uint8_t *map, + uint8_t id); + void (*hal_tx_update_dscp_tid)(void *hal_soc, uint8_t tid, uint8_t id, + uint8_t dscp); + void (*hal_tx_desc_set_lmac_id)(void *desc, uint8_t lmac_id); + + /* rx */ + uint32_t (*hal_rx_msdu_start_nss_get)(uint8_t *); + void (*hal_rx_mon_hw_desc_get_mpdu_status)(void *hw_desc_addr, + struct mon_rx_status *rs); + uint8_t (*hal_rx_get_tlv)(void *rx_tlv); + void (*hal_rx_proc_phyrx_other_receive_info_tlv)(void *rx_tlv_hdr, + void *ppdu_info_handle); + void (*hal_rx_dump_msdu_start_tlv)(void *msdu_start, uint8_t dbg_level); + uint32_t (*hal_get_link_desc_size)(void); + uint32_t (*hal_rx_mpdu_start_tid_get)(uint8_t *buf); + uint32_t (*hal_rx_msdu_start_reception_type_get)(uint8_t *buf); +}; + /** * HAL context to be used to access SRNG APIs (currently used by data path * and transport (CE) modules) @@ -355,6 +325,7 @@ struct hal_soc { /* REO blocking resource index */ uint8_t reo_res_bitmap; uint8_t index; + uint32_t target_type; /* shadow register configuration */ struct pld_shadow_reg_v2_cfg shadow_config[MAX_SHADOW_REGISTERS]; @@ -362,35 +333,10 @@ struct hal_soc { bool use_register_windowing; uint32_t register_window; qdf_spinlock_t register_access_lock; + + /* srng table */ + struct hal_hw_srng_config *hw_srng_table; + int32_t *hal_hw_reg_offset; + struct hal_hw_txrx_ops *ops; }; - -/* TODO: Check if the following can be provided directly by HW headers */ -#define SRNG_LOOP_CNT_MASK REO_DESTINATION_RING_15_LOOPING_COUNT_MASK -#define SRNG_LOOP_CNT_LSB REO_DESTINATION_RING_15_LOOPING_COUNT_LSB - -#define HAL_SRNG_LMAC_RING 0x80000000 - -#define HAL_DEFAULT_REO_TIMEOUT_MS 40 /* milliseconds */ - -#define HAL_DESC_SET_FIELD(_desc, _word, _fld, _value) do { \ - ((uint32_t *)(_desc))[(_word ## _ ## _fld ## _OFFSET) >> 2] &= \ - ~(_word ## _ ## _fld ## _MASK); \ - ((uint32_t *)(_desc))[(_word ## _ ## _fld ## _OFFSET) >> 2] |= \ - ((_value) << _word ## _ ## _fld ## _LSB); \ -} while (0) - -#define HAL_SM(_reg, _fld, _val) \ - (((_val) << (_reg ## _ ## _fld ## _SHFT)) & \ - (_reg ## _ ## _fld ## _BMSK)) - -#define HAL_MS(_reg, _fld, _val) \ - (((_val) & (_reg ## _ ## _fld ## _BMSK)) >> \ - (_reg ## _ ## _fld ## _SHFT)) - -#define HAL_REG_WRITE(_soc, _reg, _value) \ - hal_write32_mb(_soc, (_reg), (_value)) - -#define HAL_REG_READ(_soc, _offset) \ - hal_read32_mb(_soc, (_offset)) - #endif /* _HAL_INTERNAL_H_ */ diff --git a/hal/wifi3.0/hal_srng.c b/hal/wifi3.0/hal_srng.c index ff35b81d3dca..708b78df9e1f 100644 --- a/hal/wifi3.0/hal_srng.c +++ b/hal/wifi3.0/hal_srng.c @@ -26,547 +26,17 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - +#include "hal_hw_headers.h" #include "hal_api.h" #include "target_type.h" #include "wcss_version.h" #include "qdf_module.h" - -/** - * Common SRNG register access macros: - * The SRNG registers are distributed across various UMAC and LMAC HW blocks, - * but the register group and format is exactly same for all rings, with some - * difference between producer rings (these are 'producer rings' with respect - * to HW and referred as 'destination rings' in SW) and consumer rings (these - * are 'consumer rings' with respect to HW and referred as 'source rings' in SW). - * The following macros provide uniform access to all SRNG rings. - */ - -/* SRNG registers are split among two groups R0 and R2 and following - * definitions identify the group to which each register belongs to - */ -#define R0_INDEX 0 -#define R2_INDEX 1 - -#define HWREG_INDEX(_reg_group) _reg_group ## _ ## INDEX - -/* Registers in R0 group */ -#define BASE_LSB_GROUP R0 -#define BASE_MSB_GROUP R0 -#define ID_GROUP R0 -#define STATUS_GROUP R0 -#define MISC_GROUP R0 -#define HP_ADDR_LSB_GROUP R0 -#define HP_ADDR_MSB_GROUP R0 -#define PRODUCER_INT_SETUP_GROUP R0 -#define PRODUCER_INT_STATUS_GROUP R0 -#define PRODUCER_FULL_COUNTER_GROUP R0 -#define MSI1_BASE_LSB_GROUP R0 -#define MSI1_BASE_MSB_GROUP R0 -#define MSI1_DATA_GROUP R0 -#define HP_TP_SW_OFFSET_GROUP R0 -#define TP_ADDR_LSB_GROUP R0 -#define TP_ADDR_MSB_GROUP R0 -#define CONSUMER_INT_SETUP_IX0_GROUP R0 -#define CONSUMER_INT_SETUP_IX1_GROUP R0 -#define CONSUMER_INT_STATUS_GROUP R0 -#define CONSUMER_EMPTY_COUNTER_GROUP R0 -#define CONSUMER_PREFETCH_TIMER_GROUP R0 -#define CONSUMER_PREFETCH_STATUS_GROUP R0 - -/* Registers in R2 group */ -#define HP_GROUP R2 -#define TP_GROUP R2 - -/** - * Register definitions for all SRNG based rings are same, except few - * differences between source (HW consumer) and destination (HW producer) - * registers. Following macros definitions provide generic access to all - * SRNG based rings. - * For source rings, we will use the register/field definitions of SW2TCL1 - * ring defined in the HW header file mac_tcl_reg_seq_hwioreg.h. To setup - * individual fields, SRNG_SM macros should be used with fields specified - * using SRNG_SRC_FLD(, ), Register writes should be done - * using SRNG_SRC_REG_WRITE(, , ). - * Similarly for destination rings we will use definitions of REO2SW1 ring - * defined in the register reo_destination_ring.h. To setup individual - * fields SRNG_SM macros should be used with fields specified using - * SRNG_DST_FLD(, ). Register writes should be done using - * SRNG_DST_REG_WRITE(, , ). - */ - -#define SRNG_DST_REG_OFFSET(_reg, _reg_group) \ - HWIO_REO_ ## _reg_group ## _REO2SW1_RING_ ## _reg##_ADDR(0) - -#define SRNG_SRC_REG_OFFSET(_reg, _reg_group) \ - HWIO_TCL_ ## _reg_group ## _SW2TCL1_RING_ ## _reg ## _ADDR(0) - -#define _SRNG_DST_FLD(_reg_group, _reg_fld) \ - HWIO_REO_ ## _reg_group ## _REO2SW1_RING_ ## _reg_fld -#define _SRNG_SRC_FLD(_reg_group, _reg_fld) \ - HWIO_TCL_ ## _reg_group ## _SW2TCL1_RING_ ## _reg_fld - -#define _SRNG_FLD(_reg_group, _reg_fld, _dir) \ - _SRNG_ ## _dir ## _FLD(_reg_group, _reg_fld) - -#define SRNG_DST_FLD(_reg, _f) _SRNG_FLD(_reg ## _GROUP, _reg ## _ ## _f, DST) -#define SRNG_SRC_FLD(_reg, _f) _SRNG_FLD(_reg ## _GROUP, _reg ## _ ## _f, SRC) - -#define SRNG_SRC_R0_START_OFFSET SRNG_SRC_REG_OFFSET(BASE_LSB, R0) -#define SRNG_DST_R0_START_OFFSET SRNG_DST_REG_OFFSET(BASE_LSB, R0) - -#define SRNG_SRC_R2_START_OFFSET SRNG_SRC_REG_OFFSET(HP, R2) -#define SRNG_DST_R2_START_OFFSET SRNG_DST_REG_OFFSET(HP, R2) - -#define SRNG_SRC_START_OFFSET(_reg_group) \ - SRNG_SRC_ ## _reg_group ## _START_OFFSET -#define SRNG_DST_START_OFFSET(_reg_group) \ - SRNG_DST_ ## _reg_group ## _START_OFFSET - -#define SRNG_REG_ADDR(_srng, _reg, _reg_group, _dir) \ - ((_srng)->hwreg_base[HWREG_INDEX(_reg_group)] + \ - SRNG_ ## _dir ## _REG_OFFSET(_reg, _reg_group) - \ - SRNG_ ## _dir ## _START_OFFSET(_reg_group)) - -#define SRNG_DST_ADDR(_srng, _reg) \ - SRNG_REG_ADDR(_srng, _reg, _reg ## _GROUP, DST) - -#define SRNG_SRC_ADDR(_srng, _reg) \ - SRNG_REG_ADDR(_srng, _reg, _reg ## _GROUP, SRC) - -#define SRNG_REG_WRITE(_srng, _reg, _value, _dir) \ - hal_write_address_32_mb(_srng->hal_soc, SRNG_ ## _dir ## _ADDR(_srng, _reg), (_value)) - -#define SRNG_REG_READ(_srng, _reg, _dir) \ - hal_read_address_32_mb(_srng->hal_soc, SRNG_ ## _dir ## _ADDR(_srng, _reg)) - -#define SRNG_SRC_REG_WRITE(_srng, _reg, _value) \ - SRNG_REG_WRITE(_srng, _reg, _value, SRC) - -#define SRNG_DST_REG_WRITE(_srng, _reg, _value) \ - SRNG_REG_WRITE(_srng, _reg, _value, DST) - -#define SRNG_SRC_REG_READ(_srng, _reg) \ - SRNG_REG_READ(_srng, _reg, SRC) - -#define _SRNG_FM(_reg_fld) _reg_fld ## _BMSK -#define _SRNG_FS(_reg_fld) _reg_fld ## _SHFT - -#define SRNG_SM(_reg_fld, _val) \ - (((_val) << _SRNG_FS(_reg_fld)) & _SRNG_FM(_reg_fld)) - -#define SRNG_MS(_reg_fld, _val) \ - (((_val) & _SRNG_FM(_reg_fld)) >> _SRNG_FS(_reg_fld)) - -#define SRNG_MAX_SIZE_DWORDS \ - (SRNG_MS(SRNG_SRC_FLD(BASE_MSB, RING_SIZE), 0xffffffff)) - -#define HAL_RXDMA_MAX_RING_SIZE 0xFFFF -/** - * HW ring configuration table to identify hardware ring attributes like - * register addresses, number of rings, ring entry size etc., for each type - * of SRNG ring. - * - * Currently there is just one HW ring table, but there could be multiple - * configurations in future based on HW variants from the same wifi3.0 family - * and hence need to be attached with hal_soc based on HW type - */ -#define HAL_SRNG_CONFIG(_hal_soc, _ring_type) (&hw_srng_table[_ring_type]) -static struct hal_hw_srng_config hw_srng_table[] = { - /* TODO: max_rings can populated by querying HW capabilities */ - { /* REO_DST */ - .start_ring_id = HAL_SRNG_REO2SW1, - .max_rings = 4, - .entry_size = sizeof(struct reo_destination_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_REO2SW1_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET) - }, - .reg_size = { - HWIO_REO_R0_REO2SW2_RING_BASE_LSB_ADDR(0) - - HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR(0), - HWIO_REO_R2_REO2SW2_RING_HP_ADDR(0) - - HWIO_REO_R2_REO2SW1_RING_HP_ADDR(0), - }, - .max_size = HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* REO_EXCEPTION */ - /* Designating REO2TCL ring as exception ring. This ring is - * similar to other REO2SW rings though it is named as REO2TCL. - * Any of theREO2SW rings can be used as exception ring. - */ - .start_ring_id = HAL_SRNG_REO2TCL, - .max_rings = 1, - .entry_size = sizeof(struct reo_destination_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_REO_R0_REO2TCL_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_REO2TCL_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET) - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported */ - .reg_size = {}, - .max_size = HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* REO_REINJECT */ - .start_ring_id = HAL_SRNG_SW2REO, - .max_rings = 1, - .entry_size = sizeof(struct reo_entrance_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_REO_R0_SW2REO_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_SW2REO_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET) - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported */ - .reg_size = {}, - .max_size = HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* REO_CMD */ - .start_ring_id = HAL_SRNG_REO_CMD, - .max_rings = 1, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct reo_get_queue_stats)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_REO_R0_REO_CMD_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_REO_CMD_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported */ - .reg_size = {}, - .max_size = HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* REO_STATUS */ - .start_ring_id = HAL_SRNG_REO_STATUS, - .max_rings = 1, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct reo_get_queue_stats_status)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_REO_R0_REO_STATUS_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - HWIO_REO_R2_REO_STATUS_RING_HP_ADDR( - SEQ_WCSS_UMAC_REO_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported */ - .reg_size = {}, - .max_size = HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* TCL_DATA */ - .start_ring_id = HAL_SRNG_SW2TCL1, - .max_rings = 3, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct tcl_data_cmd)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - }, - .reg_size = { - HWIO_TCL_R0_SW2TCL2_RING_BASE_LSB_ADDR(0) - - HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR(0), - HWIO_TCL_R2_SW2TCL2_RING_HP_ADDR(0) - - HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR(0), - }, - .max_size = HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* TCL_CMD */ - .start_ring_id = HAL_SRNG_SW2TCL_CMD, - .max_rings = 1, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct tcl_gse_cmd)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - HWIO_TCL_R2_SW2TCL_CMD_RING_HP_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported */ - .reg_size = {}, - .max_size = HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* TCL_STATUS */ - .start_ring_id = HAL_SRNG_TCL_STATUS, - .max_rings = 1, - .entry_size = (sizeof(struct tlv_32_hdr) + - sizeof(struct tcl_status_ring)) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_TCL_R0_TCL_STATUS1_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - HWIO_TCL_R2_TCL_STATUS1_RING_HP_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported */ - .reg_size = {}, - .max_size = HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* CE_SRC */ - .start_ring_id = HAL_SRNG_CE_0_SRC, - .max_rings = 12, - .entry_size = sizeof(struct ce_src_desc) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), - HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), - }, - .reg_size = { - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, - }, - .max_size = HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* CE_DST */ - .start_ring_id = HAL_SRNG_CE_0_DST, - .max_rings = 12, - .entry_size = 8 >> 2, - /*TODO: entry_size above should actually be - * sizeof(struct ce_dst_desc) >> 2, but couldn't find definition - * of struct ce_dst_desc in HW header files - */ - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), - HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), - }, - .reg_size = { - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, - }, - .max_size = HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* CE_DST_STATUS */ - .start_ring_id = HAL_SRNG_CE_0_DST_STATUS, - .max_rings = 12, - .entry_size = sizeof(struct ce_stat_desc) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_LSB_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), - HWIO_WFSS_CE_CHANNEL_DST_R2_STATUS_RING_HP_ADDR( - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), - }, - /* TODO: check destination status ring registers */ - .reg_size = { - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - - SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, - }, - .max_size = - HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* WBM_IDLE_LINK */ - .start_ring_id = HAL_SRNG_WBM_IDLE_LINK, - .max_rings = 1, - .entry_size = sizeof(struct wbm_link_descriptor_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - HWIO_WBM_R2_WBM_IDLE_LINK_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported */ - .reg_size = {}, - .max_size = - HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* SW2WBM_RELEASE */ - .start_ring_id = HAL_SRNG_WBM_SW_RELEASE, - .max_rings = 1, - .entry_size = sizeof(struct wbm_release_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_SRC_RING, - .reg_start = { - HWIO_WBM_R0_SW_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - HWIO_WBM_R2_SW_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - }, - /* Single ring - provide ring size if multiple rings of this - * type are supported */ - .reg_size = {}, - .max_size = - HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* WBM2SW_RELEASE */ - .start_ring_id = HAL_SRNG_WBM2SW0_RELEASE, - .max_rings = 4, - .entry_size = sizeof(struct wbm_release_ring) >> 2, - .lmac_ring = FALSE, - .ring_dir = HAL_SRNG_DST_RING, - .reg_start = { - HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - }, - .reg_size = { - HWIO_WBM_R0_WBM2SW1_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - - HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - HWIO_WBM_R2_WBM2SW1_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - - HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), - }, - .max_size = - HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> - HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, - }, - { /* RXDMA_BUF */ - .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA0_BUF0, -#ifdef IPA_OFFLOAD - .max_rings = 3, -#else - .max_rings = 2, +#ifdef QCA_WIFI_QCA8074 +void hal_qca6290_attach(struct hal_soc *hal); #endif - .entry_size = sizeof(struct wbm_buffer_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_DST */ - .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW0, - .max_rings = 1, - .entry_size = sizeof(struct reo_entrance_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_DST_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_MONITOR_BUF */ - .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA2_BUF, - .max_rings = 1, - .entry_size = sizeof(struct wbm_buffer_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_MONITOR_STATUS */ - .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_STATBUF, - .max_rings = 1, - .entry_size = sizeof(struct wbm_buffer_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_MONITOR_DST */ - .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW1, - .max_rings = 1, - .entry_size = sizeof(struct reo_entrance_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_DST_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* RXDMA_MONITOR_DESC */ - .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_DESC, - .max_rings = 1, - .entry_size = sizeof(struct wbm_buffer_ring) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, - { /* DIR_BUF_RX_DMA_SRC */ - .start_ring_id = HAL_SRNG_DIR_BUF_RX_SRC_DMA_RING, - .max_rings = 1, - .entry_size = 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, -#ifdef WLAN_FEATURE_CIF_CFR - { /* WIFI_POS_SRC */ - .start_ring_id = HAL_SRNG_WIFI_POS_SRC_DMA_RING, - .max_rings = 1, - .entry_size = sizeof(wmi_oem_dma_buf_release_entry) >> 2, - .lmac_ring = TRUE, - .ring_dir = HAL_SRNG_SRC_RING, - /* reg_start is not set because LMAC rings are not accessed - * from host - */ - .reg_start = {}, - .reg_size = {}, - .max_size = HAL_RXDMA_MAX_RING_SIZE, - }, +#ifdef QCA_WIFI_QCA8074 +void hal_qca8074_attach(struct hal_soc *hal); #endif -}; /** * hal_get_srng_ring_id() - get the ring id of a descriped ring @@ -639,7 +109,7 @@ QDF_STATUS hal_set_one_shadow_config(void *hal_soc, { uint32_t target_register; struct hal_soc *hal = (struct hal_soc *)hal_soc; - struct hal_hw_srng_config *srng_config = &hw_srng_table[ring_type]; + struct hal_hw_srng_config *srng_config = &hal->hw_srng_table[ring_type]; int shadow_config_index = hal->num_shadow_registers_configured; if (shadow_config_index >= MAX_SHADOW_REGISTERS) { @@ -674,10 +144,11 @@ QDF_STATUS hal_set_one_shadow_config(void *hal_soc, QDF_STATUS hal_construct_shadow_config(void *hal_soc) { int ring_type, ring_num; + struct hal_soc *hal = (struct hal_soc *)hal_soc; for (ring_type = 0; ring_type < MAX_RING_TYPES; ring_type++) { struct hal_hw_srng_config *srng_config = - &hw_srng_table[ring_type]; + &hal->hw_srng_table[ring_type]; if (ring_type == CE_SRC || ring_type == CE_DST || @@ -743,18 +214,33 @@ error: static void hal_target_based_configure(struct hal_soc *hal) { - struct hif_target_info *tgt_info = - hif_get_target_info_handle(hal->hif_handle); - - switch (tgt_info->target_type) { + switch (hal->target_type) { +#ifdef QCA_WIFI_QCA6290 case TARGET_TYPE_QCA6290: hal->use_register_windowing = true; + hal_qca6290_attach(hal); break; +#endif +#ifdef QCA_WIFI_QCA8074 + case TARGET_TYPE_QCA8074: + hal_qca8074_attach(hal); + break; +#endif default: break; } } +uint32_t hal_get_target_type(struct hal_soc *hal) +{ + struct hif_target_info *tgt_info = + hif_get_target_info_handle(hal->hif_handle); + + return tgt_info->target_type; +} + +qdf_export_symbol(hal_get_target_type); + /** * hal_attach - Initialize HAL layer * @hif_handle: Opaque HIF handle @@ -810,6 +296,7 @@ void *hal_attach(void *hif_handle, qdf_device_t qdf_dev) qdf_spinlock_create(&hal->register_access_lock); hal->register_window = 0; + hal->target_type = hal_get_target_type(hal); hal_target_based_configure(hal); @@ -1351,6 +838,7 @@ qdf_export_symbol(hal_srng_cleanup); */ uint32_t hal_srng_get_entrysize(void *hal_soc, int ring_type) { + struct hal_soc *hal = (struct hal_soc *)hal_soc; struct hal_hw_srng_config *ring_config = HAL_SRNG_CONFIG(hal, ring_type); return ring_config->entry_size << 2; @@ -1366,6 +854,7 @@ qdf_export_symbol(hal_srng_get_entrysize); */ uint32_t hal_srng_max_entries(void *hal_soc, int ring_type) { + struct hal_soc *hal = (struct hal_soc *)hal_soc; struct hal_hw_srng_config *ring_config = HAL_SRNG_CONFIG(hal, ring_type); @@ -1375,6 +864,7 @@ qdf_export_symbol(hal_srng_max_entries); enum hal_srng_dir hal_srng_get_dir(void *hal_soc, int ring_type) { + struct hal_soc *hal = (struct hal_soc *)hal_soc; struct hal_hw_srng_config *ring_config = HAL_SRNG_CONFIG(hal, ring_type); diff --git a/hal/wifi3.0/hal_tx.h b/hal/wifi3.0/hal_tx.h index 6097509b7a52..53cb476416cd 100644 --- a/hal/wifi3.0/hal_tx.h +++ b/hal/wifi3.0/hal_tx.h @@ -454,33 +454,6 @@ static inline void hal_tx_desc_set_to_fw(void *desc, uint8_t to_fw) HAL_TX_SM(TCL_DATA_CMD_3, TO_FW, to_fw); } -/** - * hal_tx_desc_set_dscp_tid_table_id - Sets DSCP to TID conversion table ID - * @desc: Handle to Tx Descriptor - * @id: DSCP to tid conversion table to be used for this frame - * - * Return: void - */ -#if !defined(QCA_WIFI_QCA6290_11AX) -static inline void hal_tx_desc_set_dscp_tid_table_id(void *desc, - uint8_t id) -{ - HAL_SET_FLD(desc, TCL_DATA_CMD_3, - DSCP_TO_TID_PRIORITY_TABLE_ID) |= - HAL_TX_SM(TCL_DATA_CMD_3, - DSCP_TO_TID_PRIORITY_TABLE_ID, id); -} -#else -static inline void hal_tx_desc_set_dscp_tid_table_id(void *desc, - uint8_t id) -{ - HAL_SET_FLD(desc, TCL_DATA_CMD_5, - DSCP_TID_TABLE_NUM) |= - HAL_TX_SM(TCL_DATA_CMD_5, - DSCP_TID_TABLE_NUM, id); -} -#endif - /** * hal_tx_desc_set_mesh_en - Set mesh_enable flag in Tx descriptor * @desc: Handle to Tx Descriptor @@ -515,31 +488,6 @@ static inline void hal_tx_desc_set_hlos_tid(void *desc, HAL_SET_FLD(desc, TCL_DATA_CMD_4, HLOS_TID_OVERWRITE) |= HAL_TX_SM(TCL_DATA_CMD_4, HLOS_TID_OVERWRITE, 1); } - -#ifdef QCA_WIFI_QCA6290_11AX -/** - * hal_tx_desc_set_lmac_id - Set the lmac_id value - * @desc: Handle to Tx Descriptor - * @lmac_id: mac Id to ast matching - * b00 – mac 0 - * b01 – mac 1 - * b10 – mac 2 - * b11 – all macs (legacy HK way) - * - * Return: void - */ -static inline void hal_tx_desc_set_lmac_id(void *desc, - uint8_t lmac_id) -{ - HAL_SET_FLD(desc, TCL_DATA_CMD_4, LMAC_ID) |= - HAL_TX_SM(TCL_DATA_CMD_4, LMAC_ID, lmac_id); -} -#else -static inline void hal_tx_desc_set_lmac_id(void *desc, - uint8_t lmac_id) -{ -} -#endif /** * hal_tx_desc_sync - Commit the descriptor to Hardware * @hal_tx_des_cached: Cached descriptor that software maintains @@ -1005,199 +953,6 @@ static inline void hal_tx_comp_get_htt_desc(void *hw_desc, uint8_t *htt_desc) qdf_mem_copy(htt_desc, desc, HAL_TX_COMP_HTT_STATUS_LEN); } -#if !defined(QCA_WIFI_QCA6290_11AX) -/** - * hal_tx_set_dscp_tid_map_default() - Configure default DSCP to TID map table - * @soc: HAL SoC context - * @map: DSCP-TID mapping table - * @id: mapping table ID - 0,1 - * - * DSCP are mapped to 8 TID values using TID values programmed - * in two set of mapping registers DSCP_TID1_MAP_<0 to 6> (id = 0) - * and DSCP_TID2_MAP_<0 to 6> (id = 1) - * Each mapping register has TID mapping for 10 DSCP values - * - * Return: none - */ -static inline void hal_tx_set_dscp_tid_map(void *hal_soc, uint8_t *map, - uint8_t id) -{ - int i; - uint32_t addr; - uint32_t value; - - struct hal_soc *soc = (struct hal_soc *)hal_soc; - - if (id == HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT) { - addr = - HWIO_TCL_R0_DSCP_TID1_MAP_0_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); - } else { - addr = - HWIO_TCL_R0_DSCP_TID2_MAP_0_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); - } - - for (i = 0; i < 64; i += 10) { - value = (map[i] | - (map[i+1] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_1_SHFT) | - (map[i+2] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_2_SHFT) | - (map[i+3] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_3_SHFT) | - (map[i+4] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_4_SHFT) | - (map[i+5] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_5_SHFT) | - (map[i+6] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_6_SHFT) | - (map[i+7] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_7_SHFT) | - (map[i+8] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_8_SHFT) | - (map[i+9] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_9_SHFT)); - - HAL_REG_WRITE(soc, addr, - (value & HWIO_TCL_R0_DSCP_TID1_MAP_1_RMSK)); - - addr += 4; - } -} - -/** - * hal_tx_update_dscp_tid() - Update the dscp tid map table as updated by user - * @soc: HAL SoC context - * @map: DSCP-TID mapping table - * @id : MAP ID - * @dscp: DSCP_TID map index - * - * Return: void - */ -static inline void hal_tx_update_dscp_tid(void *hal_soc, uint8_t tid, - uint8_t id, uint8_t dscp) -{ - int index; - uint32_t addr; - uint32_t value; - uint32_t regval; - - struct hal_soc *soc = (struct hal_soc *)hal_soc; - - if (id == HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT) - addr = - HWIO_TCL_R0_DSCP_TID1_MAP_0_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); - else - addr = - HWIO_TCL_R0_DSCP_TID2_MAP_0_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); - - index = dscp % HAL_TX_NUM_DSCP_PER_REGISTER; - addr += 4 * (dscp/HAL_TX_NUM_DSCP_PER_REGISTER); - value = tid << (HAL_TX_BITS_PER_TID * index); - - /* Read back previous DSCP TID config and update - * with new config. - */ - regval = HAL_REG_READ(soc, addr); - regval &= ~(HAL_TX_TID_BITS_MASK << (HAL_TX_BITS_PER_TID * index)); - regval |= value; - - HAL_REG_WRITE(soc, addr, - (regval & HWIO_TCL_R0_DSCP_TID1_MAP_1_RMSK)); -} -#else - -#define DSCP_TID_TABLE_SIZE 24 -#define NUM_WORDS_PER_DSCP_TID_TABLE (DSCP_TID_TABLE_SIZE/4) - -/** - * hal_tx_set_dscp_tid_map_default() - Configure default DSCP to TID map table - * @soc: HAL SoC context - * @map: DSCP-TID mapping table - * @id: mapping table ID - 0-31 - * - * DSCP are mapped to 8 TID values using TID values programmed - * in any of the 32 DSCP_TID_MAPS (id = 0-31). - * - * Return: none - */ -static inline void hal_tx_set_dscp_tid_map(void *hal_soc, uint8_t *map, - uint8_t id) -{ - int i; - uint32_t addr, cmn_reg_addr; - uint32_t value = 0, regval; - uint8_t val[DSCP_TID_TABLE_SIZE], cnt = 0; - - struct hal_soc *soc = (struct hal_soc *)hal_soc; - - if (id >= HAL_MAX_HW_DSCP_TID_MAPS_11AX) { - return; - } - - cmn_reg_addr = HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); - - addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, - id * NUM_WORDS_PER_DSCP_TID_TABLE); - - /* Enable read/write access */ - regval = HAL_REG_READ(soc, cmn_reg_addr); - regval |= - (1 << HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT); - - HAL_REG_WRITE(soc, cmn_reg_addr, regval); - - /* Write 8 (24 bits) DSCP-TID mappings in each interation */ - for (i = 0; i < 64; i += 8) { - value = (map[i] | - (map[i+1] << 0x3) | - (map[i+2] << 0x6) | - (map[i+3] << 0x9) | - (map[i+4] << 0xc) | - (map[i+5] << 0xf) | - (map[i+6] << 0x12) | - (map[i+7] << 0x15)); - - qdf_mem_copy(&val[cnt], (void *)&value, 3); - cnt += 3; - } - - for (i = 0; i < DSCP_TID_TABLE_SIZE; i += 4) { - regval = *(uint32_t *)(val + i); - HAL_REG_WRITE(soc, addr, - (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); - addr += 4; - } - - /* Diasble read/write access */ - regval = HAL_REG_READ(soc, cmn_reg_addr); - regval &= - ~(HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_BMSK); - - HAL_REG_WRITE(soc, cmn_reg_addr, regval); -} - -static inline void hal_tx_update_dscp_tid(void *hal_soc, uint8_t tid, - uint8_t id, uint8_t dscp) -{ - int index; - uint32_t addr; - uint32_t value; - uint32_t regval; - - struct hal_soc *soc = (struct hal_soc *)hal_soc; - addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( - SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, id); - - index = dscp % HAL_TX_NUM_DSCP_PER_REGISTER; - addr += 4 * (dscp/HAL_TX_NUM_DSCP_PER_REGISTER); - value = tid << (HAL_TX_BITS_PER_TID * index); - - regval = HAL_REG_READ(soc, addr); - regval &= ~(HAL_TX_TID_BITS_MASK << (HAL_TX_BITS_PER_TID * index)); - regval |= value; - - HAL_REG_WRITE(soc, addr, - (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); -} -#endif - /** * hal_tx_init_data_ring() - Initialize all the TCL Descriptors in SRNG * @hal_soc: Handle to HAL SoC structure @@ -1214,15 +969,77 @@ static inline void hal_tx_init_data_ring(void *hal_soc, void *hal_srng) hal_get_srng_params(hal_soc, hal_srng, &srng_params); - desc_addr = (uint8_t *) srng_params.ring_base_vaddr; + desc_addr = (uint8_t *)srng_params.ring_base_vaddr; desc_size = sizeof(struct tcl_data_cmd); num_desc = srng_params.num_entries; while (num_desc) { HAL_TX_DESC_SET_TLV_HDR(desc_addr, HAL_TX_TCL_DATA_TAG, - desc_size); + desc_size); desc_addr += (desc_size + sizeof(struct tlv_32_hdr)); num_desc--; } } + +/** + * hal_tx_desc_set_dscp_tid_table_id() - Sets DSCP to TID conversion table ID + * @hal_soc: Handle to HAL SoC structure + * @desc: Handle to Tx Descriptor + * @id: DSCP to tid conversion table to be used for this frame + * + * Return: void + */ +static inline void hal_tx_desc_set_dscp_tid_table_id(struct hal_soc *hal_soc, + void *desc, uint8_t id) +{ + hal_soc->ops->hal_tx_desc_set_dscp_tid_table_id(desc, id); +} + +/** + * hal_tx_set_dscp_tid_map_default() - Configure default DSCP to TID map table + * + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id: mapping table ID - 0,1 + * + * Return: void + */ +static inline void hal_tx_set_dscp_tid_map(struct hal_soc *hal_soc, + uint8_t *map, uint8_t id) +{ + hal_soc->ops->hal_tx_set_dscp_tid_map(hal_soc, map, id); +} + +/** + * hal_tx_update_dscp_tid() - Update the dscp tid map table as updated by user + * + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id : MAP ID + * @dscp: DSCP_TID map index + * + * Return: void + */ +static inline void hal_tx_update_dscp_tid(struct hal_soc *hal_soc, uint8_t tid, + uint8_t id, uint8_t dscp) +{ + hal_soc->ops->hal_tx_update_dscp_tid(hal_soc, tid, id, dscp); +} + +/** + * hal_tx_desc_set_lmac_id - Set the lmac_id value + * @desc: Handle to Tx Descriptor + * @lmac_id: mac Id to ast matching + * b00 – mac 0 + * b01 – mac 1 + * b10 – mac 2 + * b11 – all macs (legacy HK way) + * + * Return: void + */ +static inline void hal_tx_desc_set_lmac_id(struct hal_soc *hal_soc, + void *desc, uint8_t lmac_id) +{ + hal_soc->ops->hal_tx_desc_set_lmac_id(desc, lmac_id); +} #endif /* HAL_TX_H */ diff --git a/hal/wifi3.0/qca6290/hal_6290_rx.h b/hal/wifi3.0/qca6290/hal_6290_rx.h new file mode 100644 index 000000000000..1628c66cb241 --- /dev/null +++ b/hal/wifi3.0/qca6290/hal_6290_rx.h @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "qdf_util.h" +#include "qdf_types.h" +#include "qdf_lock.h" +#include "qdf_mem.h" +#include "qdf_nbuf.h" +#include "tcl_data_cmd.h" +#include "mac_tcl_reg_seq_hwioreg.h" +#include "phyrx_rssi_legacy.h" +#include "rx_msdu_start.h" +#include "tlv_tag_def.h" +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "cdp_txrx_mon_struct.h" +#include "qdf_trace.h" +#include "hal_rx.h" +#include "hal_tx.h" +#include "dp_types.h" +#include "hal_api_mon.h" +#include "phyrx_other_receive_info_ru_details.h" + +#define HAL_RX_MSDU_START_MIMO_SS_BITMAP(_rx_msdu_start)\ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start),\ + RX_MSDU_START_5_MIMO_SS_BITMAP_OFFSET)), \ + RX_MSDU_START_5_MIMO_SS_BITMAP_MASK, \ + RX_MSDU_START_5_MIMO_SS_BITMAP_LSB)) + +/* + * hal_rx_msdu_start_nss_get_6290(): API to get the NSS + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(nss) + */ +uint32_t +hal_rx_msdu_start_nss_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint8_t mimo_ss_bitmap; + + mimo_ss_bitmap = HAL_RX_MSDU_START_MIMO_SS_BITMAP(msdu_start); + + return qdf_get_hweight8(mimo_ss_bitmap); +} + +qdf_export_symbol(hal_rx_msdu_start_nss_get_6290); + +/** + * hal_rx_mon_hw_desc_get_mpdu_status_6290(): Retrieve MPDU status + * + * @ hw_desc_addr: Start address of Rx HW TLVs + * @ rs: Status for monitor mode + * + * Return: void + */ +void hal_rx_mon_hw_desc_get_mpdu_status_6290(void *hw_desc_addr, + struct mon_rx_status *rs) +{ + struct rx_msdu_start *rx_msdu_start; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + uint32_t reg_value; + const uint32_t sgi_hw_to_cdp[] = { + CDP_SGI_0_8_US, + CDP_SGI_0_4_US, + CDP_SGI_1_6_US, + CDP_SGI_3_2_US, + }; + + rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; + + HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); + + rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, + RX_MSDU_START_5, USER_RSSI); + rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); + + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); + rs->sgi = sgi_hw_to_cdp[reg_value]; + + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); + switch (reg_value) { + case HAL_RX_PKT_TYPE_11N: + rs->ht_flags = 1; + break; + case HAL_RX_PKT_TYPE_11AC: + rs->vht_flags = 1; + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, + RECEIVE_BANDWIDTH); + rs->vht_flag_values2 = reg_value; + break; + case HAL_RX_PKT_TYPE_11AX: + rs->he_flags = 1; + break; + default: + break; + } + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); + rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; + /* TODO: rs->beamformed should be set for SU beamforming also */ +} + +qdf_export_symbol(hal_rx_mon_hw_desc_get_mpdu_status_6290); + +#define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) + +uint32_t hal_get_link_desc_size_6290(void) +{ + return LINK_DESC_SIZE; +} + +qdf_export_symbol(hal_get_link_desc_size_6290); + +/* + * hal_rx_get_tlv_6290(): API to get the tlv + * + * @rx_tlv: TLV data extracted from the rx packet + * Return: uint8_t + */ +uint8_t hal_rx_get_tlv_6290(void *rx_tlv) +{ + return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_0, RECEIVE_BANDWIDTH); +} + +qdf_export_symbol(hal_rx_get_tlv_6290); + +/** + * hal_rx_proc_phyrx_other_receive_info_tlv_6290() + * - process other receive info TLV + * @rx_tlv_hdr: pointer to TLV header + * @ppdu_info: pointer to ppdu_info + * + * Return: None + */ +void hal_rx_proc_phyrx_other_receive_info_tlv_6290(void *rx_tlv_hdr, + void *ppdu_info_handle) +{ + uint32_t tlv_tag, tlv_len; + uint32_t temp_len, other_tlv_len, other_tlv_tag; + void *rx_tlv = (uint8_t *)rx_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; + void *other_tlv_hdr = NULL; + void *other_tlv = NULL; + uint32_t ru_details_channel_0; + struct hal_rx_ppdu_info *ppdu_info = + (struct hal_rx_ppdu_info *)ppdu_info_handle; + + tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv_hdr); + tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv_hdr); + temp_len = 0; + + other_tlv_hdr = rx_tlv + HAL_RX_TLV32_HDR_SIZE; + + other_tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(other_tlv_hdr); + other_tlv_len = HAL_RX_GET_USER_TLV32_LEN(other_tlv_hdr); + temp_len += other_tlv_len; + other_tlv = other_tlv_hdr + HAL_RX_TLV32_HDR_SIZE; + + switch (other_tlv_tag) { + case WIFIPHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_E: + ru_details_channel_0 = + HAL_RX_GET(other_tlv, + PHYRX_OTHER_RECEIVE_INFO_RU_DETAILS_0, + RU_DETAILS_CHANNEL_0); + + qdf_mem_copy(ppdu_info->rx_status.he_RU, + &ru_details_channel_0, + sizeof(ppdu_info->rx_status.he_RU)); + + if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_20) + ppdu_info->rx_status.he_sig_b_common_known |= + QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0; + + if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_40) + ppdu_info->rx_status.he_sig_b_common_known |= + QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU1; + + if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_80) + ppdu_info->rx_status.he_sig_b_common_known |= + QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU2; + + if (ppdu_info->rx_status.bw >= HAL_FULL_RX_BW_160) + ppdu_info->rx_status.he_sig_b_common_known |= + QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU3; + break; + default: + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "%s unhandled TLV type: %d, TLV len:%d", + __func__, other_tlv_tag, other_tlv_len); + break; + } +} + +qdf_export_symbol(hal_rx_proc_phyrx_other_receive_info_tlv_6290); + +/** + * hal_rx_dump_msdu_start_tlv_6290() : dump RX msdu_start TLV in structured + * human readable format. + * @ msdu_start: pointer the msdu_start TLV in pkt. + * @ dbg_level: log level. + * + * Return: void + */ +void hal_rx_dump_msdu_start_tlv_6290(void *msdustart, uint8_t dbg_level) +{ + struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; + + QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, + "rx_msdu_start tlv - " + "rxpcu_mpdu_filter_in_category: %d " + "sw_frame_group_id: %d " + "phy_ppdu_id: %d " + "msdu_length: %d " + "ipsec_esp: %d " + "l3_offset: %d " + "ipsec_ah: %d " + "l4_offset: %d " + "msdu_number: %d " + "decap_format: %d " + "ipv4_proto: %d " + "ipv6_proto: %d " + "tcp_proto: %d " + "udp_proto: %d " + "ip_frag: %d " + "tcp_only_ack: %d " + "da_is_bcast_mcast: %d " + "ip4_protocol_ip6_next_header: %d " + "toeplitz_hash_2_or_4: %d " + "flow_id_toeplitz: %d " + "user_rssi: %d " + "pkt_type: %d " + "stbc: %d " + "sgi: %d " + "rate_mcs: %d " + "receive_bandwidth: %d " + "reception_type: %d " + "ppdu_start_timestamp: %d " + "sw_phy_meta_data: %d ", + msdu_start->rxpcu_mpdu_filter_in_category, + msdu_start->sw_frame_group_id, + msdu_start->phy_ppdu_id, + msdu_start->msdu_length, + msdu_start->ipsec_esp, + msdu_start->l3_offset, + msdu_start->ipsec_ah, + msdu_start->l4_offset, + msdu_start->msdu_number, + msdu_start->decap_format, + msdu_start->ipv4_proto, + msdu_start->ipv6_proto, + msdu_start->tcp_proto, + msdu_start->udp_proto, + msdu_start->ip_frag, + msdu_start->tcp_only_ack, + msdu_start->da_is_bcast_mcast, + msdu_start->ip4_protocol_ip6_next_header, + msdu_start->toeplitz_hash_2_or_4, + msdu_start->flow_id_toeplitz, + msdu_start->user_rssi, + msdu_start->pkt_type, + msdu_start->stbc, + msdu_start->sgi, + msdu_start->rate_mcs, + msdu_start->receive_bandwidth, + msdu_start->reception_type, + msdu_start->ppdu_start_timestamp, + msdu_start->sw_phy_meta_data); +} + +qdf_export_symbol(hal_rx_dump_msdu_start_tlv_6290); + +/* + * Get tid from RX_MPDU_START + */ +#define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_3_TID_OFFSET)), \ + RX_MPDU_INFO_3_TID_MASK, \ + RX_MPDU_INFO_3_TID_LSB)) + +uint32_t hal_rx_mpdu_start_tid_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t tid; + + tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); + + return tid; +} + +qdf_export_symbol(hal_rx_mpdu_start_tid_get_6290); + +#define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ + RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ + RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ + RX_MSDU_START_5_RECEPTION_TYPE_LSB)) + +/* + * hal_rx_msdu_start_reception_type_get(): API to get the reception type + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(reception_type) + */ +uint32_t hal_rx_msdu_start_reception_type_get_6290(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint32_t reception_type; + + reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); + + return reception_type; +} + +qdf_export_symbol(hal_rx_msdu_start_reception_type_get_6290); + diff --git a/hal/wifi3.0/qca6290/hal_6290_srng.c b/hal/wifi3.0/qca6290/hal_6290_srng.c new file mode 100644 index 000000000000..eee73f50dd48 --- /dev/null +++ b/hal/wifi3.0/qca6290/hal_6290_srng.c @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "qdf_types.h" +#include "qdf_util.h" +#include "qdf_types.h" +#include "qdf_lock.h" +#include "qdf_mem.h" +#include "qdf_nbuf.h" +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "hal_api.h" +#include "target_type.h" +#include "wcss_version.h" +#include "qdf_module.h" +#include "hal_6290_tx.h" +#include "hal_6290_rx.h" + +struct hal_hw_txrx_ops qca6290_hal_hw_txrx_ops = { + /* tx */ + hal_tx_desc_set_dscp_tid_table_id_6290, + hal_tx_set_dscp_tid_map_6290, + hal_tx_update_dscp_tid_6290, + hal_tx_desc_set_lmac_id_6290, + + /* rx */ + hal_rx_msdu_start_nss_get_6290, + hal_rx_mon_hw_desc_get_mpdu_status_6290, + hal_rx_get_tlv_6290, + hal_rx_proc_phyrx_other_receive_info_tlv_6290, + hal_rx_dump_msdu_start_tlv_6290, + hal_get_link_desc_size_6290, + hal_rx_mpdu_start_tid_get_6290, + hal_rx_msdu_start_reception_type_get_6290, +}; + +struct hal_hw_srng_config hw_srng_table_6290[] = { + /* TODO: max_rings can populated by querying HW capabilities */ + { /* REO_DST */ + .start_ring_id = HAL_SRNG_REO2SW1, + .max_rings = 4, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2SW1_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + .reg_size = { + HWIO_REO_R0_REO2SW2_RING_BASE_LSB_ADDR(0) - + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR(0), + HWIO_REO_R2_REO2SW2_RING_HP_ADDR(0) - + HWIO_REO_R2_REO2SW1_RING_HP_ADDR(0), + }, + .max_size = HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_EXCEPTION */ + /* Designating REO2TCL ring as exception ring. This ring is + * similar to other REO2SW rings though it is named as REO2TCL. + * Any of theREO2SW rings can be used as exception ring. + */ + .start_ring_id = HAL_SRNG_REO2TCL, + .max_rings = 1, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2TCL_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2TCL_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_REINJECT */ + .start_ring_id = HAL_SRNG_SW2REO, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_SW2REO_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_SW2REO_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_CMD */ + .start_ring_id = HAL_SRNG_REO_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_REO_CMD_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_CMD_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_STATUS */ + .start_ring_id = HAL_SRNG_REO_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats_status)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO_STATUS_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_STATUS_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_DATA */ + .start_ring_id = HAL_SRNG_SW2TCL1, + .max_rings = 3, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_data_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + .reg_size = { + HWIO_TCL_R0_SW2TCL2_RING_BASE_LSB_ADDR(0) - + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR(0), + HWIO_TCL_R2_SW2TCL2_RING_HP_ADDR(0) - + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR(0), + }, + .max_size = HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_CMD */ + .start_ring_id = HAL_SRNG_SW2TCL_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_gse_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL_CMD_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_STATUS */ + .start_ring_id = HAL_SRNG_TCL_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_status_ring)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_TCL_STATUS1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_SRC */ + .start_ring_id = HAL_SRNG_CE_0_SRC, + .max_rings = 12, + .entry_size = sizeof(struct ce_src_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), + }, + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_DST */ + .start_ring_id = HAL_SRNG_CE_0_DST, + .max_rings = 12, + .entry_size = 8 >> 2, + /*TODO: entry_size above should actually be + * sizeof(struct ce_dst_desc) >> 2, but couldn't find definition + * of struct ce_dst_desc in HW header files + */ + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + }, + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_DST_STATUS */ + .start_ring_id = HAL_SRNG_CE_0_DST_STATUS, + .max_rings = 12, + .entry_size = sizeof(struct ce_stat_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_STATUS_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + }, + /* TODO: check destination status ring registers */ + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM_IDLE_LINK */ + .start_ring_id = HAL_SRNG_WBM_IDLE_LINK, + .max_rings = 1, + .entry_size = sizeof(struct wbm_link_descriptor_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM_IDLE_LINK_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* SW2WBM_RELEASE */ + .start_ring_id = HAL_SRNG_WBM_SW_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_SW_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_SW_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM2SW_RELEASE */ + .start_ring_id = HAL_SRNG_WBM2SW0_RELEASE, + .max_rings = 4, + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .reg_size = { + HWIO_WBM_R0_WBM2SW1_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW1_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .max_size = + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* RXDMA_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA0_BUF0, +#ifdef IPA_OFFLOAD + .max_rings = 3, +#else + .max_rings = 2, +#endif + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW0, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA2_BUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_STATUS */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_STATBUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW1, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DESC */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_DESC, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* DIR_BUF_RX_DMA_SRC */ + .start_ring_id = HAL_SRNG_DIR_BUF_RX_SRC_DMA_RING, + .max_rings = 1, + .entry_size = 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#ifdef WLAN_FEATURE_CIF_CFR + { /* WIFI_POS_SRC */ + .start_ring_id = HAL_SRNG_WIFI_POS_SRC_DMA_RING, + .max_rings = 1, + .entry_size = sizeof(wmi_oem_dma_buf_release_entry) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#endif +}; + +int32_t hal_hw_reg_offset_qca6290[] = { + /* dst */ + REG_OFFSET(DST, HP), + REG_OFFSET(DST, TP), + REG_OFFSET(DST, ID), + REG_OFFSET(DST, MISC), + REG_OFFSET(DST, HP_ADDR_LSB), + REG_OFFSET(DST, HP_ADDR_MSB), + REG_OFFSET(DST, MSI1_BASE_LSB), + REG_OFFSET(DST, MSI1_BASE_MSB), + REG_OFFSET(DST, MSI1_DATA), + REG_OFFSET(DST, BASE_LSB), + REG_OFFSET(DST, BASE_MSB), + REG_OFFSET(DST, PRODUCER_INT_SETUP), + /* src */ + REG_OFFSET(SRC, HP), + REG_OFFSET(SRC, TP), + REG_OFFSET(SRC, ID), + REG_OFFSET(SRC, MISC), + REG_OFFSET(SRC, TP_ADDR_LSB), + REG_OFFSET(SRC, TP_ADDR_MSB), + REG_OFFSET(SRC, MSI1_BASE_LSB), + REG_OFFSET(SRC, MSI1_BASE_MSB), + REG_OFFSET(SRC, MSI1_DATA), + REG_OFFSET(SRC, BASE_LSB), + REG_OFFSET(SRC, BASE_MSB), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX0), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1), +}; + +void hal_qca6290_attach(struct hal_soc *hal_soc) +{ + hal_soc->hw_srng_table = hw_srng_table_6290; + hal_soc->hal_hw_reg_offset = hal_hw_reg_offset_qca6290; + hal_soc->ops = &qca6290_hal_hw_txrx_ops; +} diff --git a/hal/wifi3.0/qca6290/hal_6290_tx.h b/hal/wifi3.0/qca6290/hal_6290_tx.h new file mode 100644 index 000000000000..5f4f388d807c --- /dev/null +++ b/hal/wifi3.0/qca6290/hal_6290_tx.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tcl_data_cmd.h" +#include "mac_tcl_reg_seq_hwioreg.h" +#include "phyrx_rssi_legacy.h" +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "cdp_txrx_mon_struct.h" +#include "qdf_trace.h" +#include "hal_rx.h" +#include "hal_tx.h" +#include "dp_types.h" +#include "hal_api_mon.h" + +/** + * hal_tx_desc_set_dscp_tid_table_id_6290() - Sets DSCP to TID conversion + * table ID + * @desc: Handle to Tx Descriptor + * @id: DSCP to tid conversion table to be used for this frame + * + * Return: void + */ +void hal_tx_desc_set_dscp_tid_table_id_6290(void *desc, + uint8_t id) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_5, + DSCP_TID_TABLE_NUM) |= + HAL_TX_SM(TCL_DATA_CMD_5, + DSCP_TID_TABLE_NUM, id); +} + +qdf_export_symbol(hal_tx_desc_set_dscp_tid_table_id_6290); + +#define DSCP_TID_TABLE_SIZE 24 +#define NUM_WORDS_PER_DSCP_TID_TABLE (DSCP_TID_TABLE_SIZE / 4) + +/** + * hal_tx_set_dscp_tid_map_6290() - Configure default DSCP to TID map table + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id: mapping table ID - 0-31 + * + * DSCP are mapped to 8 TID values using TID values programmed + * in any of the 32 DSCP_TID_MAPS (id = 0-31). + * + * Return: none + */ +void hal_tx_set_dscp_tid_map_6290(void *hal_soc, uint8_t *map, + uint8_t id) +{ + int i; + uint32_t addr, cmn_reg_addr; + uint32_t value = 0, regval; + uint8_t val[DSCP_TID_TABLE_SIZE], cnt = 0; + + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + if (id >= HAL_MAX_HW_DSCP_TID_MAPS_11AX) + return; + + cmn_reg_addr = HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + + addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, + id * NUM_WORDS_PER_DSCP_TID_TABLE); + + /* Enable read/write access */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval |= + (1 << HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_SHFT); + + HAL_REG_WRITE(soc, cmn_reg_addr, regval); + + /* Write 8 (24 bits) DSCP-TID mappings in each interation */ + for (i = 0; i < 64; i += 8) { + value = (map[i] | + (map[i + 1] << 0x3) | + (map[i + 2] << 0x6) | + (map[i + 3] << 0x9) | + (map[i + 4] << 0xc) | + (map[i + 5] << 0xf) | + (map[i + 6] << 0x12) | + (map[i + 7] << 0x15)); + + qdf_mem_copy(&val[cnt], (void *)&value, 3); + cnt += 3; + } + + for (i = 0; i < DSCP_TID_TABLE_SIZE; i += 4) { + regval = *(uint32_t *)(val + i); + HAL_REG_WRITE(soc, addr, + (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); + addr += 4; + } + + /* Diasble read/write access */ + regval = HAL_REG_READ(soc, cmn_reg_addr); + regval &= + ~(HWIO_TCL_R0_CONS_RING_CMN_CTRL_REG_DSCP_TID_MAP_PROGRAM_EN_BMSK); + + HAL_REG_WRITE(soc, cmn_reg_addr, regval); +} + +qdf_export_symbol(hal_tx_set_dscp_tid_map_6290); + +/** + * hal_tx_update_dscp_tid_6290() - Update the dscp tid map table as updated + * by the user + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id : MAP ID + * @dscp: DSCP_TID map index + * + * Return: void + */ +void hal_tx_update_dscp_tid_6290(void *hal_soc, uint8_t tid, + uint8_t id, uint8_t dscp) +{ + int index; + uint32_t addr; + uint32_t value; + uint32_t regval; + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + addr = HWIO_TCL_R0_DSCP_TID_MAP_n_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET, id); + + index = dscp % HAL_TX_NUM_DSCP_PER_REGISTER; + addr += 4 * (dscp / HAL_TX_NUM_DSCP_PER_REGISTER); + value = tid << (HAL_TX_BITS_PER_TID * index); + + regval = HAL_REG_READ(soc, addr); + regval &= ~(HAL_TX_TID_BITS_MASK << (HAL_TX_BITS_PER_TID * index)); + regval |= value; + + HAL_REG_WRITE(soc, addr, (regval & HWIO_TCL_R0_DSCP_TID_MAP_n_RMSK)); +} + +qdf_export_symbol(hal_tx_update_dscp_tid_6290); + +/** + * hal_tx_desc_set_lmac_id - Set the lmac_id value + * @desc: Handle to Tx Descriptor + * @lmac_id: mac Id to ast matching + * b00 – mac 0 + * b01 – mac 1 + * b10 – mac 2 + * b11 – all macs (legacy HK way) + * + * Return: void + */ +void hal_tx_desc_set_lmac_id_6290(void *desc, + uint8_t lmac_id) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_4, LMAC_ID) |= + HAL_TX_SM(TCL_DATA_CMD_4, LMAC_ID, lmac_id); +} + +qdf_export_symbol(hal_tx_desc_set_lmac_id_6290); + diff --git a/hal/wifi3.0/qca8074/hal_8074_rx.h b/hal/wifi3.0/qca8074/hal_8074_rx.h new file mode 100644 index 000000000000..e244411f0783 --- /dev/null +++ b/hal/wifi3.0/qca8074/hal_8074_rx.h @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "cdp_txrx_mon_struct.h" +#include "qdf_trace.h" +#include "hal_rx.h" +#include "hal_tx.h" +#include "dp_types.h" +#include "hal_api_mon.h" + +/* + * hal_rx_msdu_start_nss_get_8074(): API to get the NSS + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(nss) + */ +uint32_t +hal_rx_msdu_start_nss_get_8074(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint32_t nss; + + nss = HAL_RX_MSDU_START_NSS_GET(msdu_start); + return nss; +} + +qdf_export_symbol(hal_rx_msdu_start_nss_get_8074); +/** + * hal_rx_mon_hw_desc_get_mpdu_status_8074(): Retrieve MPDU status + * + * @ hw_desc_addr: Start address of Rx HW TLVs + * @ rs: Status for monitor mode + * + * Return: void + */ +void hal_rx_mon_hw_desc_get_mpdu_status_8074(void *hw_desc_addr, + struct mon_rx_status *rs) +{ + struct rx_msdu_start *rx_msdu_start; + struct rx_pkt_tlvs *rx_desc = (struct rx_pkt_tlvs *)hw_desc_addr; + uint32_t reg_value; + const uint32_t sgi_hw_to_cdp[] = { + CDP_SGI_0_8_US, + CDP_SGI_0_4_US, + CDP_SGI_1_6_US, + CDP_SGI_3_2_US, + }; + + rx_msdu_start = &rx_desc->msdu_start_tlv.rx_msdu_start; + + HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs); + + rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, + RX_MSDU_START_5, USER_RSSI); + rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); + + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); + rs->sgi = sgi_hw_to_cdp[reg_value]; + rs->nr_ant = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, NSS); + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); + switch (reg_value) { + case HAL_RX_PKT_TYPE_11N: + rs->ht_flags = 1; + break; + case HAL_RX_PKT_TYPE_11AC: + rs->vht_flags = 1; + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, + RECEIVE_BANDWIDTH); + rs->vht_flag_values2 = reg_value; + break; + case HAL_RX_PKT_TYPE_11AX: + rs->he_flags = 1; + break; + default: + break; + } + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); + rs->beamformed = (reg_value == HAL_RX_RECEPTION_TYPE_MU_MIMO) ? 1 : 0; + /* TODO: rs->beamformed should be set for SU beamforming also */ +} + +qdf_export_symbol(hal_rx_mon_hw_desc_get_mpdu_status_8074); + + +#define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) +uint32_t hal_get_link_desc_size_8074(void) +{ + return LINK_DESC_SIZE; +} + +qdf_export_symbol(hal_get_link_desc_size_8074); + +/* + * hal_rx_get_tlv_8074(): API to get the tlv + * + * @rx_tlv: TLV data extracted from the rx packet + * Return: uint8_t + */ +uint8_t hal_rx_get_tlv_8074(void *rx_tlv) +{ + return HAL_RX_GET(rx_tlv, PHYRX_RSSI_LEGACY_35, RECEIVE_BANDWIDTH); +} + +qdf_export_symbol(hal_rx_get_tlv_8074); + +/** + * hal_rx_proc_phyrx_other_receive_info_tlv_8074() + * -process other receive info TLV + * @rx_tlv_hdr: pointer to TLV header + * @ppdu_info: pointer to ppdu_info + * + * Return: None + */ +void hal_rx_proc_phyrx_other_receive_info_tlv_8074(void *rx_tlv_hdr, + void *ppdu_info) +{ +} + +qdf_export_symbol(hal_rx_proc_phyrx_other_receive_info_tlv_8074); + +/** + * hal_rx_dump_msdu_start_tlv_8074() : dump RX msdu_start TLV in structured + * human readable format. + * @ msdu_start: pointer the msdu_start TLV in pkt. + * @ dbg_level: log level. + * + * Return: void + */ +void hal_rx_dump_msdu_start_tlv_8074(void *msdustart, + uint8_t dbg_level) +{ + struct rx_msdu_start *msdu_start = (struct rx_msdu_start *)msdustart; + + QDF_TRACE(QDF_MODULE_ID_DP, dbg_level, + "rx_msdu_start tlv - " + "rxpcu_mpdu_filter_in_category: %d " + "sw_frame_group_id: %d " + "phy_ppdu_id: %d " + "msdu_length: %d " + "ipsec_esp: %d " + "l3_offset: %d " + "ipsec_ah: %d " + "l4_offset: %d " + "msdu_number: %d " + "decap_format: %d " + "ipv4_proto: %d " + "ipv6_proto: %d " + "tcp_proto: %d " + "udp_proto: %d " + "ip_frag: %d " + "tcp_only_ack: %d " + "da_is_bcast_mcast: %d " + "ip4_protocol_ip6_next_header: %d " + "toeplitz_hash_2_or_4: %d " + "flow_id_toeplitz: %d " + "user_rssi: %d " + "pkt_type: %d " + "stbc: %d " + "sgi: %d " + "rate_mcs: %d " + "receive_bandwidth: %d " + "reception_type: %d " + "toeplitz_hash: %d " + "nss: %d " + "ppdu_start_timestamp: %d " + "sw_phy_meta_data: %d ", + msdu_start->rxpcu_mpdu_filter_in_category, + msdu_start->sw_frame_group_id, + msdu_start->phy_ppdu_id, + msdu_start->msdu_length, + msdu_start->ipsec_esp, + msdu_start->l3_offset, + msdu_start->ipsec_ah, + msdu_start->l4_offset, + msdu_start->msdu_number, + msdu_start->decap_format, + msdu_start->ipv4_proto, + msdu_start->ipv6_proto, + msdu_start->tcp_proto, + msdu_start->udp_proto, + msdu_start->ip_frag, + msdu_start->tcp_only_ack, + msdu_start->da_is_bcast_mcast, + msdu_start->ip4_protocol_ip6_next_header, + msdu_start->toeplitz_hash_2_or_4, + msdu_start->flow_id_toeplitz, + msdu_start->user_rssi, + msdu_start->pkt_type, + msdu_start->stbc, + msdu_start->sgi, + msdu_start->rate_mcs, + msdu_start->receive_bandwidth, + msdu_start->reception_type, + msdu_start->toeplitz_hash, + msdu_start->nss, + msdu_start->ppdu_start_timestamp, + msdu_start->sw_phy_meta_data); +} + +qdf_export_symbol(hal_rx_dump_msdu_start_tlv_8074); + +/* + * Get tid from RX_MPDU_START + */ +#define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \ + RX_MPDU_INFO_3_TID_OFFSET)), \ + RX_MPDU_INFO_3_TID_MASK, \ + RX_MPDU_INFO_3_TID_LSB)) + +uint32_t hal_rx_mpdu_start_tid_get_8074(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_mpdu_start *mpdu_start = + &pkt_tlvs->mpdu_start_tlv.rx_mpdu_start; + uint32_t tid; + + tid = HAL_RX_MPDU_INFO_TID_GET(&mpdu_start->rx_mpdu_info_details); + + return tid; +} + +qdf_export_symbol(hal_rx_mpdu_start_tid_get_8074); + +#define HAL_RX_MSDU_START_RECEPTION_TYPE_GET(_rx_msdu_start) \ + (_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_msdu_start), \ + RX_MSDU_START_5_RECEPTION_TYPE_OFFSET)), \ + RX_MSDU_START_5_RECEPTION_TYPE_MASK, \ + RX_MSDU_START_5_RECEPTION_TYPE_LSB)) + +/* + * hal_rx_msdu_start_reception_type_get(): API to get the reception type + * Interval from rx_msdu_start + * + * @buf: pointer to the start of RX PKT TLV header + * Return: uint32_t(reception_type) + */ +uint32_t hal_rx_msdu_start_reception_type_get_8074(uint8_t *buf) +{ + struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf; + struct rx_msdu_start *msdu_start = + &pkt_tlvs->msdu_start_tlv.rx_msdu_start; + uint32_t reception_type; + + reception_type = HAL_RX_MSDU_START_RECEPTION_TYPE_GET(msdu_start); + + return reception_type; +} + +qdf_export_symbol(hal_rx_msdu_start_reception_type_get_8074); + diff --git a/hal/wifi3.0/qca8074/hal_8074_srng.c b/hal/wifi3.0/qca8074/hal_8074_srng.c new file mode 100644 index 000000000000..d42f76d833b1 --- /dev/null +++ b/hal/wifi3.0/qca8074/hal_8074_srng.c @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "hal_api.h" +#include "target_type.h" +#include "wcss_version.h" +#include "qdf_module.h" +#include "hal_8074_tx.h" +#include "hal_8074_rx.h" + +struct hal_hw_txrx_ops qca8074_hal_hw_txrx_ops = { + /* tx */ + hal_tx_desc_set_dscp_tid_table_id_8074, + hal_tx_set_dscp_tid_map_8074, + hal_tx_update_dscp_tid_8074, + hal_tx_desc_set_lmac_id_8074, + + /* rx */ + hal_rx_msdu_start_nss_get_8074, + hal_rx_mon_hw_desc_get_mpdu_status_8074, + hal_rx_get_tlv_8074, + hal_rx_proc_phyrx_other_receive_info_tlv_8074, + hal_rx_dump_msdu_start_tlv_8074, + hal_get_link_desc_size_8074, + hal_rx_mpdu_start_tid_get_8074, + hal_rx_msdu_start_reception_type_get_8074, +}; + +struct hal_hw_srng_config hw_srng_table_8074[] = { + /* TODO: max_rings can populated by querying HW capabilities */ + { /* REO_DST */ + .start_ring_id = HAL_SRNG_REO2SW1, + .max_rings = 4, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2SW1_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + .reg_size = { + HWIO_REO_R0_REO2SW2_RING_BASE_LSB_ADDR(0) - + HWIO_REO_R0_REO2SW1_RING_BASE_LSB_ADDR(0), + HWIO_REO_R2_REO2SW2_RING_HP_ADDR(0) - + HWIO_REO_R2_REO2SW1_RING_HP_ADDR(0), + }, + .max_size = + HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2SW1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_EXCEPTION */ + /* Designating REO2TCL ring as exception ring. This ring is + * similar to other REO2SW rings though it is named as REO2TCL. + * Any of theREO2SW rings can be used as exception ring. + */ + .start_ring_id = HAL_SRNG_REO2TCL, + .max_rings = 1, + .entry_size = sizeof(struct reo_destination_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO2TCL_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO2TCL_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO2TCL_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_REINJECT */ + .start_ring_id = HAL_SRNG_SW2REO, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_SW2REO_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_SW2REO_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET) + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_SW2REO_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_CMD */ + .start_ring_id = HAL_SRNG_REO_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_REO_R0_REO_CMD_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_CMD_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_CMD_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* REO_STATUS */ + .start_ring_id = HAL_SRNG_REO_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct reo_get_queue_stats_status)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_REO_R0_REO_STATUS_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + HWIO_REO_R2_REO_STATUS_RING_HP_ADDR( + SEQ_WCSS_UMAC_REO_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_REO_R0_REO_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_DATA */ + .start_ring_id = HAL_SRNG_SW2TCL1, + .max_rings = 3, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_data_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + .reg_size = { + HWIO_TCL_R0_SW2TCL2_RING_BASE_LSB_ADDR(0) - + HWIO_TCL_R0_SW2TCL1_RING_BASE_LSB_ADDR(0), + HWIO_TCL_R2_SW2TCL2_RING_HP_ADDR(0) - + HWIO_TCL_R2_SW2TCL1_RING_HP_ADDR(0), + }, + .max_size = + HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_CMD */ + .start_ring_id = HAL_SRNG_SW2TCL_CMD, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_gse_cmd)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_SW2TCL_CMD_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_SW2TCL_CMD_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* TCL_STATUS */ + .start_ring_id = HAL_SRNG_TCL_STATUS, + .max_rings = 1, + .entry_size = (sizeof(struct tlv_32_hdr) + + sizeof(struct tcl_status_ring)) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + HWIO_TCL_R2_TCL_STATUS1_RING_HP_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_TCL_R0_TCL_STATUS1_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_SRC */ + .start_ring_id = HAL_SRNG_CE_0_SRC, + .max_rings = 12, + .entry_size = sizeof(struct ce_src_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET), + }, + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_SRC_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_SRC_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_DST */ + .start_ring_id = HAL_SRNG_CE_0_DST, + .max_rings = 12, + .entry_size = 8 >> 2, + /*TODO: entry_size above should actually be + * sizeof(struct ce_dst_desc) >> 2, but couldn't find definition + * of struct ce_dst_desc in HW header files + */ + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_DEST_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + }, + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_DEST_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* CE_DST_STATUS */ + .start_ring_id = HAL_SRNG_CE_0_DST_STATUS, + .max_rings = 12, + .entry_size = sizeof(struct ce_stat_desc) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_LSB_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + HWIO_WFSS_CE_CHANNEL_DST_R2_STATUS_RING_HP_ADDR( + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET), + }, + /* TODO: check destination status ring registers */ + .reg_size = { + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_1_CHANNEL_DST_REG_OFFSET - + SEQ_WCSS_UMAC_WFSS_CE_0_REG_WFSS_CE_0_CHANNEL_DST_REG_OFFSET, + }, + .max_size = + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WFSS_CE_CHANNEL_DST_R0_STATUS_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM_IDLE_LINK */ + .start_ring_id = HAL_SRNG_WBM_IDLE_LINK, + .max_rings = 1, + .entry_size = sizeof(struct wbm_link_descriptor_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM_IDLE_LINK_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* SW2WBM_RELEASE */ + .start_ring_id = HAL_SRNG_WBM_SW_RELEASE, + .max_rings = 1, + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_SRC_RING, + .reg_start = { + HWIO_WBM_R0_SW_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_SW_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + /* Single ring - provide ring size if multiple rings of this + * type are supported + */ + .reg_size = {}, + .max_size = + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_SW_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* WBM2SW_RELEASE */ + .start_ring_id = HAL_SRNG_WBM2SW0_RELEASE, + .max_rings = 4, + .entry_size = sizeof(struct wbm_release_ring) >> 2, + .lmac_ring = FALSE, + .ring_dir = HAL_SRNG_DST_RING, + .reg_start = { + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .reg_size = { + HWIO_WBM_R0_WBM2SW1_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_LSB_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + HWIO_WBM_R2_WBM2SW1_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET) - + HWIO_WBM_R2_WBM2SW0_RELEASE_RING_HP_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET), + }, + .max_size = + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_BMSK >> + HWIO_WBM_R0_WBM2SW0_RELEASE_RING_BASE_MSB_RING_SIZE_SHFT, + }, + { /* RXDMA_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA0_BUF0, +#ifdef IPA_OFFLOAD + .max_rings = 3, +#else + .max_rings = 2, +#endif + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW0, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_BUF */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA2_BUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_STATUS */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_STATBUF, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DST */ + .start_ring_id = HAL_SRNG_WMAC1_RXDMA2SW1, + .max_rings = 1, + .entry_size = sizeof(struct reo_entrance_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_DST_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* RXDMA_MONITOR_DESC */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA1_DESC, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + { /* DIR_BUF_RX_DMA_SRC */ + .start_ring_id = HAL_SRNG_DIR_BUF_RX_SRC_DMA_RING, + .max_rings = 1, + .entry_size = 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#ifdef WLAN_FEATURE_CIF_CFR + { /* WIFI_POS_SRC */ + .start_ring_id = HAL_SRNG_WIFI_POS_SRC_DMA_RING, + .max_rings = 1, + .entry_size = sizeof(wmi_oem_dma_buf_release_entry) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, +#endif +}; + +int32_t hal_hw_reg_offset_qca8074[] = { + /* dst */ + REG_OFFSET(DST, HP), + REG_OFFSET(DST, TP), + REG_OFFSET(DST, ID), + REG_OFFSET(DST, MISC), + REG_OFFSET(DST, HP_ADDR_LSB), + REG_OFFSET(DST, HP_ADDR_MSB), + REG_OFFSET(DST, MSI1_BASE_LSB), + REG_OFFSET(DST, MSI1_BASE_MSB), + REG_OFFSET(DST, MSI1_DATA), + REG_OFFSET(DST, BASE_LSB), + REG_OFFSET(DST, BASE_MSB), + REG_OFFSET(DST, PRODUCER_INT_SETUP), + /* src */ + REG_OFFSET(SRC, HP), + REG_OFFSET(SRC, TP), + REG_OFFSET(SRC, ID), + REG_OFFSET(SRC, MISC), + REG_OFFSET(SRC, TP_ADDR_LSB), + REG_OFFSET(SRC, TP_ADDR_MSB), + REG_OFFSET(SRC, MSI1_BASE_LSB), + REG_OFFSET(SRC, MSI1_BASE_MSB), + REG_OFFSET(SRC, MSI1_DATA), + REG_OFFSET(SRC, BASE_LSB), + REG_OFFSET(SRC, BASE_MSB), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX0), + REG_OFFSET(SRC, CONSUMER_INT_SETUP_IX1), +}; + +void hal_qca8074_attach(struct hal_soc *hal_soc) +{ + hal_soc->hw_srng_table = hw_srng_table_8074; + hal_soc->hal_hw_reg_offset = hal_hw_reg_offset_qca8074; + hal_soc->ops = &qca8074_hal_hw_txrx_ops; +} diff --git a/hal/wifi3.0/qca8074/hal_8074_tx.h b/hal/wifi3.0/qca8074/hal_8074_tx.h new file mode 100644 index 000000000000..83ae0fa7fc88 --- /dev/null +++ b/hal/wifi3.0/qca8074/hal_8074_tx.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "hal_hw_headers.h" +#include "hal_internal.h" +#include "cdp_txrx_mon_struct.h" +#include "qdf_trace.h" +#include "hal_rx.h" +#include "hal_tx.h" +#include "dp_types.h" +#include "hal_api_mon.h" + +/** + * hal_tx_desc_set_dscp_tid_table_id_8074() - Sets DSCP to TID conversion + * table ID + * @desc: Handle to Tx Descriptor + * @id: DSCP to tid conversion table to be used for this frame + * + * Return: void + */ + +void hal_tx_desc_set_dscp_tid_table_id_8074(void *desc, + uint8_t id) +{ + HAL_SET_FLD(desc, TCL_DATA_CMD_3, + DSCP_TO_TID_PRIORITY_TABLE_ID) |= + HAL_TX_SM(TCL_DATA_CMD_3, + DSCP_TO_TID_PRIORITY_TABLE_ID, id); +} + +qdf_export_symbol(hal_tx_desc_set_dscp_tid_table_id_8074); + +/** + * hal_tx_set_dscp_tid_map_8074() - Configure default DSCP to TID map table + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id: mapping table ID - 0,1 + * + * DSCP are mapped to 8 TID values using TID values programmed + * in two set of mapping registers DSCP_TID1_MAP_<0 to 6> (id = 0) + * and DSCP_TID2_MAP_<0 to 6> (id = 1) + * Each mapping register has TID mapping for 10 DSCP values + * + * Return: none + */ +void hal_tx_set_dscp_tid_map_8074(void *hal_soc, uint8_t *map, + uint8_t id) +{ + int i; + uint32_t addr; + uint32_t value; + + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + if (id == HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT) { + addr = HWIO_TCL_R0_DSCP_TID1_MAP_0_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + } else { + addr = HWIO_TCL_R0_DSCP_TID2_MAP_0_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + } + + for (i = 0; i < 64; i += 10) { + value = + (map[i] | + (map[i + 1] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_1_SHFT) | + (map[i + 2] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_2_SHFT) | + (map[i + 3] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_3_SHFT) | + (map[i + 4] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_4_SHFT) | + (map[i + 5] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_5_SHFT) | + (map[i + 6] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_6_SHFT) | + (map[i + 7] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_7_SHFT) | + (map[i + 8] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_8_SHFT) | + (map[i + 9] << HWIO_TCL_R0_DSCP_TID1_MAP_0_DSCP_9_SHFT)); + + HAL_REG_WRITE(soc, addr, + (value & HWIO_TCL_R0_DSCP_TID1_MAP_1_RMSK)); + + addr += 4; + } +} + +qdf_export_symbol(hal_tx_set_dscp_tid_map_8074); + +/** + * hal_tx_update_dscp_tid_8074() - Update the dscp tid map table as + updated by user + * @soc: HAL SoC context + * @map: DSCP-TID mapping table + * @id : MAP ID + * @dscp: DSCP_TID map index + * + * Return: void + */ +void hal_tx_update_dscp_tid_8074(void *hal_soc, uint8_t tid, + uint8_t id, uint8_t dscp) +{ + int index; + uint32_t addr; + uint32_t value; + uint32_t regval; + + struct hal_soc *soc = (struct hal_soc *)hal_soc; + + if (id == HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT) + addr = HWIO_TCL_R0_DSCP_TID1_MAP_0_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + else + addr = HWIO_TCL_R0_DSCP_TID2_MAP_0_ADDR( + SEQ_WCSS_UMAC_MAC_TCL_REG_OFFSET); + + index = dscp % HAL_TX_NUM_DSCP_PER_REGISTER; + addr += 4 * (dscp / HAL_TX_NUM_DSCP_PER_REGISTER); + value = tid << (HAL_TX_BITS_PER_TID * index); + + /* Read back previous DSCP TID config and update + * with new config. + */ + regval = HAL_REG_READ(soc, addr); + regval &= ~(HAL_TX_TID_BITS_MASK << (HAL_TX_BITS_PER_TID * index)); + regval |= value; + + HAL_REG_WRITE(soc, addr, + (regval & HWIO_TCL_R0_DSCP_TID1_MAP_1_RMSK)); +} + +qdf_export_symbol(hal_tx_update_dscp_tid_8074); +/** + * hal_tx_desc_set_lmac_id - Set the lmac_id value + * @desc: Handle to Tx Descriptor + * @lmac_id: mac Id to ast matching + * b00 – mac 0 + * b01 – mac 1 + * b10 – mac 2 + * b11 – all macs (legacy HK way) + * + * Return: void + */ +void hal_tx_desc_set_lmac_id_8074(void *desc, + uint8_t lmac_id) +{ +} + +qdf_export_symbol(hal_tx_desc_set_lmac_id_8074); +