diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index f0c2aabbec0a..97a8cd47cc54 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -815,7 +815,7 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng, htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PACKET_HEADER, htt_tlv_filter->packet_header); htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, ATTENTION, - htt_tlv_filter->ppdu_end_status_done); + htt_tlv_filter->attention); htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_START, htt_tlv_filter->ppdu_start); htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_END, diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 59b36d585eb6..5caf47e2b075 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -2389,8 +2389,8 @@ static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle, htt_tlv_filter.enable_mo = 1; htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id, - pdev->rxdma_mon_dst_ring.hal_srng, - RXDMA_MONITOR_BUF, RX_BUFFER_SIZE, &htt_tlv_filter); + pdev->rxdma_mon_buf_ring.hal_srng, + RXDMA_MONITOR_BUF, RX_BUFFER_SIZE, &htt_tlv_filter); htt_tlv_filter.mpdu_start = 1; htt_tlv_filter.msdu_start = 1; @@ -2405,13 +2405,12 @@ static int dp_vdev_set_monitor_mode(struct cdp_vdev *vdev_handle, htt_tlv_filter.ppdu_end_user_stats_ext = 1; htt_tlv_filter.ppdu_end_status_done = 1; htt_tlv_filter.enable_fp = 1; - htt_tlv_filter.enable_md = 1; + htt_tlv_filter.enable_md = 0; htt_tlv_filter.enable_mo = 1; - /* - * htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id, - * pdev->rxdma_mon_status_ring.hal_srng, - * RXDMA_MONITOR_STATUS, RX_BUFFER_SIZE, &htt_tlv_filter); - */ + + htt_h2t_rx_ring_cfg(soc->htt_handle, pdev_id, + pdev->rxdma_mon_status_ring.hal_srng, RXDMA_MONITOR_STATUS, + RX_BUFFER_SIZE, &htt_tlv_filter); return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 1ffa37b83425..003ea4fc050a 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -99,8 +99,7 @@ done: * @tail: tail of decs list to be freed * Return: number of msdu in MPDU to be popped */ -static inline -uint32_t +static inline uint32_t dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, void *rxdma_dst_ring_desc, qdf_nbuf_t *head_msdu, qdf_nbuf_t *tail_msdu, uint32_t *npackets, uint32_t *ppdu_id, @@ -161,6 +160,23 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, "[%s][%d] msdu_nbuf=%p, data=%p\n", __func__, __LINE__, msdu, data); + rx_desc_tlv = HAL_RX_MON_DEST_GET_DESC(data); + msdu_ppdu_id = + HAL_RX_MON_HW_DESC_GET_PPDUID_GET(rx_desc_tlv); + + QDF_TRACE(QDF_MODULE_ID_DP, + QDF_TRACE_LEVEL_DEBUG, + "[%s][%d] i=%d, ppdu_id=%x, msdu_ppdu_id=%x\n", + __func__, __LINE__, i, *ppdu_id, msdu_ppdu_id); + if (*ppdu_id != msdu_ppdu_id) { + *ppdu_id = msdu_ppdu_id; + return rx_bufs_used; + } + + if (hal_rx_desc_is_first_msdu(rx_desc_tlv)) + hal_rx_mon_hw_desc_get_mpdu_status(rx_desc_tlv, + &(dp_pdev->ppdu_info.rx_status)); + rx_pkt_offset = HAL_RX_MON_HW_RX_DESC_SIZE(); /* * HW structures call this L3 header padding @@ -176,7 +192,6 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, qdf_nbuf_set_pktlen(msdu, rx_buf_size); - rx_desc_tlv = HAL_RX_MON_DEST_GET_DESC(data); #if 0 /* Disble it.see packet on msdu done set to 0 */ @@ -200,17 +215,6 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, } #endif - msdu_ppdu_id = - HAL_RX_MON_HW_DESC_GET_PPDUID_GET(rx_desc_tlv); - -#if 0 - /* Temporary only handle destination ring */ - if (*ppdu_id != msdu_ppdu_id) { - *ppdu_id = msdu_ppdu_id; - return rx_bufs_used; - } -#endif - rx_bufs_used++; QDF_TRACE(QDF_MODULE_ID_DP, @@ -306,8 +310,6 @@ qdf_nbuf_t dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, rx_desc = qdf_nbuf_data(head_msdu); - HAL_RX_MON_HW_DESC_GET_PPDU_START_STATUS(rx_desc, rx_status); - decap_format = HAL_RX_DESC_GET_DECAP_FORMAT(rx_desc); /* Easy case - The MSDU status indicates that this is a non-decapped @@ -616,7 +618,6 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, struct cdp_mon_status *rs = &pdev->rx_mon_recv_status; qdf_nbuf_t mon_skb, skb_next; qdf_nbuf_t mon_mpdu = NULL; - struct mon_rx_status rx_mon_status; if ((pdev->monitor_vdev == NULL) || (pdev->monitor_vdev->osif_rx_mon == NULL)) { @@ -628,13 +629,10 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, tail_msdu, rs); if (mon_mpdu) { - /* Push radiotap header */ - dp_rx_extract_radiotap_info(rs, &rx_mon_status); - - qdf_nbuf_update_radiotap(&rx_mon_status, mon_mpdu, - sizeof(struct rx_pkt_tlvs)); + qdf_nbuf_update_radiotap(&(pdev->ppdu_info.rx_status), + mon_mpdu, sizeof(struct rx_pkt_tlvs)); pdev->monitor_vdev->osif_rx_mon( - pdev->monitor_vdev->osif_vdev, mon_mpdu, rs); + pdev->monitor_vdev->osif_vdev, mon_mpdu, NULL); } else { goto mon_deliver_fail; } @@ -676,8 +674,8 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) void *mon_dst_srng = pdev->rxdma_mon_dst_ring.hal_srng; union dp_rx_desc_list_elem_t *head = NULL; union dp_rx_desc_list_elem_t *tail = NULL; - struct dp_srng *dp_rxdma_srng; - struct rx_desc_pool *rx_desc_pool; + uint32_t ppdu_id; + uint32_t rx_bufs_used; #ifdef DP_INTR_POLL_BASED if (!pdev) @@ -687,12 +685,6 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) pdev_id = pdev->pdev_id; mon_dst_srng = pdev->rxdma_mon_dst_ring.hal_srng; -#if 0 - /* Temporary only handle destination ring */ - if (pdev->mon_ppdu_status != DP_PPDU_STATUS_DONE) - return; -#endif - if (!mon_dst_srng) { QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, "%s %d : HAL Monitor Destination Ring Init \ @@ -713,44 +705,40 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) return; } + ppdu_id = pdev->ppdu_info.com_info.ppdu_id; + rx_bufs_used = 0; while (qdf_likely((rxdma_dst_ring_desc = - hal_srng_dst_peek(hal_soc, mon_dst_srng)))) { - qdf_nbuf_t head_msdu, tail_msdu; - uint32_t rx_bufs_used = 0; - uint32_t npackets, ppdu_id; - head_msdu = (qdf_nbuf_t) NULL; - tail_msdu = (qdf_nbuf_t) NULL; + hal_srng_dst_peek(hal_soc, mon_dst_srng)) && quota--)) { + qdf_nbuf_t head_msdu, tail_msdu; + uint32_t npackets; + head_msdu = (qdf_nbuf_t) NULL; + tail_msdu = (qdf_nbuf_t) NULL; - ppdu_id = pdev->mon_ppdu_id; - rx_bufs_used += dp_rx_mon_mpdu_pop(soc, mac_id, - rxdma_dst_ring_desc, - &head_msdu, &tail_msdu, - &npackets, &ppdu_id, - &head, &tail); -#if 0 - /* Temporary only handle destination ring */ - if (ppdu_id != pdev->mon_ppdu_id) { - pdev->mon_ppdu_status = DP_PPDU_STATUS_START; - break; - } -#endif + rx_bufs_used += dp_rx_mon_mpdu_pop(soc, mac_id, + rxdma_dst_ring_desc, + &head_msdu, &tail_msdu, + &npackets, &ppdu_id, + &head, &tail); - dp_rx_mon_deliver(soc, mac_id, head_msdu, tail_msdu); + if (ppdu_id != pdev->ppdu_info.com_info.ppdu_id) { + pdev->mon_ppdu_status = DP_PPDU_STATUS_START; + qdf_mem_zero(&(pdev->ppdu_info.rx_status), + sizeof(pdev->ppdu_info.rx_status)); + break; + } - /* replenish function should be changed to include - * ring pointer */ - dp_rxdma_srng = &pdev->rxdma_mon_buf_ring; - rx_desc_pool = &soc->rx_desc_mon[pdev_id]; + dp_rx_mon_deliver(soc, mac_id, head_msdu, tail_msdu); - dp_rx_buffers_replenish(soc, pdev_id, dp_rxdma_srng, - rx_desc_pool, rx_bufs_used, &head, &tail, - HAL_RX_BUF_RBM_SW3_BM); - - rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc, - mon_dst_srng); + rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc, + mon_dst_srng); } - hal_srng_access_end(hal_soc, mon_dst_srng); + + if (rx_bufs_used) { + dp_rx_buffers_replenish(soc, pdev_id, + &pdev->rxdma_mon_buf_ring, &soc->rx_desc_mon[pdev_id], + rx_bufs_used, &head, &tail, HAL_RX_BUF_RBM_SW3_BM); + } } static QDF_STATUS @@ -940,12 +928,6 @@ static int dp_mon_link_desc_pool_setup(struct dp_soc *soc, uint32_t mac_id) hal_srng_src_get_next(soc->hal_soc, mon_desc_srng))) { - QDF_TRACE(QDF_MODULE_ID_TXRX, - QDF_TRACE_LEVEL_DEBUG, - "[%s][%d] desc=%p, i=%d, vaddr=%lx, paddr=%lx", - __func__, __LINE__, desc, i, - (unsigned long)vaddr, (unsigned long)paddr); - hal_set_link_desc_addr(desc, i, paddr); num_entries--; num_replenish_buf++; diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index 5e87fd654f04..2e3d1a6a9ddf 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -36,7 +36,9 @@ * Return: none */ static inline void -dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id) { +dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, + uint32_t quota) +{ struct dp_pdev *pdev = soc->pdev_list[mac_id]; struct hal_rx_ppdu_info *ppdu_info; qdf_nbuf_t status_nbuf; @@ -73,12 +75,8 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id) { qdf_nbuf_free(status_nbuf); if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { - pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE; - /* Temperary */ - pdev->mon_ppdu_status = - DP_PPDU_STATUS_START; - break; + dp_rx_mon_dest_process(soc, mac_id, quota); } } return; @@ -237,8 +235,8 @@ dp_rx_mon_status_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { uint32_t work_done; work_done = dp_rx_mon_status_srng_process(soc, mac_id, quota); - - dp_rx_mon_status_process_tlv(soc, mac_id); + quota -= work_done; + dp_rx_mon_status_process_tlv(soc, mac_id, quota); return work_done; } @@ -255,14 +253,9 @@ dp_rx_mon_status_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { */ uint32_t dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) { - uint32_t work_done; - - work_done = dp_rx_mon_status_process(soc, mac_id, quota); - - dp_rx_mon_dest_process(soc, mac_id, quota); - - return work_done; + return dp_rx_mon_status_process(soc, mac_id, quota); } + /** * dp_rx_pdev_mon_detach() - detach dp rx for status ring * @pdev: core txrx pdev context @@ -397,7 +390,7 @@ QDF_STATUS dp_rx_mon_status_buffers_replenish(struct dp_soc *dp_soc, hal_rxdma_buff_addr_info_set(rxdma_ring_entry, paddr, (*desc_list)->rx_desc.cookie, owner); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "[%s][%d] rx_desc=%p, cookie=%d, nbuf=%p, \ status_buf=%p paddr=%p\n", __func__, __LINE__, &(*desc_list)->rx_desc, @@ -474,6 +467,8 @@ dp_rx_pdev_mon_status_attach(struct dp_pdev *pdev) { qdf_nbuf_queue_init(&pdev->rx_status_q); pdev->mon_ppdu_status = DP_PPDU_STATUS_START; + qdf_mem_zero(&(pdev->ppdu_info.rx_status), + sizeof(pdev->ppdu_info.rx_status)); return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 27255c187b29..0d60efcd3711 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -791,7 +791,6 @@ struct dp_pdev { uint8_t operating_channel; qdf_nbuf_queue_t rx_status_q; - uint32_t mon_ppdu_id; uint32_t mon_ppdu_status; struct cdp_mon_status rx_mon_recv_status; diff --git a/hal/wifi3.0/hal_api_mon.h b/hal/wifi3.0/hal_api_mon.h index 14eb550e140f..b78854563fc8 100644 --- a/hal/wifi3.0/hal_api_mon.h +++ b/hal/wifi3.0/hal_api_mon.h @@ -32,6 +32,7 @@ HAL_RX_LSB(block, field)) #define HAL_RX_PHY_DATA_RADAR 0x01 +#define HAL_SU_MU_CODING_LDPC 0x01 #define HAL_RX_FCS_LEN (4) #define KEY_EXTIV 0x20 @@ -74,6 +75,17 @@ #define HAL_MAX_UL_MU_USERS 8 +#define HAL_RX_PKT_TYPE_11A 0 +#define HAL_RX_PKT_TYPE_11B 1 +#define HAL_RX_PKT_TYPE_11N 2 +#define HAL_RX_PKT_TYPE_11AC 3 +#define HAL_RX_PKT_TYPE_11AX 4 + +#define HAL_RX_RECEPTION_TYPE_SU 0 +#define HAL_RX_RECEPTION_TYPE_MU_MIMO 1 +#define HAL_RX_RECEPTION_TYPE_OFDMA 2 +#define HAL_RX_RECEPTION_TYPE_MU_OFDMA 3 + enum { HAL_HW_RX_DECAP_FORMAT_RAW = 0, HAL_HW_RX_DECAP_FORMAT_NWIFI, @@ -154,6 +166,16 @@ uint32_t HAL_RX_MON_HW_DESC_GET_PPDUID_GET(void *hw_desc_addr) return HAL_RX_GET(rx_attn, RX_ATTENTION_0, PHY_PPDU_ID); } +/* TODO: Move all Rx descriptor functions to hal_rx.h to avoid duplication */ +static inline +uint32_t hal_rx_desc_is_first_msdu(void *hw_desc_addr) +{ + struct rx_pkt_tlvs *rx_tlvs = (struct rx_pkt_tlvs *)hw_desc_addr; + struct rx_msdu_end *msdu_end = &rx_tlvs->msdu_end_tlv.rx_msdu_end; + + return HAL_RX_GET(msdu_end, RX_MSDU_END_5, FIRST_MSDU); +} + #define HAL_RX_BUFFER_ADDR_31_0_GET(buff_addr_info) \ (_HAL_MS((*_OFFSET_TO_WORD_PTR(buff_addr_info, \ BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_OFFSET)), \ @@ -286,7 +308,7 @@ uint32 hal_get_rx_msdu_link_desc_size(void) enum { HAL_PKT_TYPE_OFDM = 0, - HAL_CDP_PKT_TYPE_CCK, + HAL_PKT_TYPE_CCK, HAL_PKT_TYPE_HT, HAL_PKT_TYPE_VHT, HAL_PKT_TYPE_HE, @@ -313,73 +335,60 @@ enum { HAL_RX_TYPE_MU_OFDMA_MIMO, }; +/** + * 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_PPDU_START_STATUS(void *hw_desc_addr, - struct cdp_mon_status *rs) +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 rx_pream_type; - uint32_t rx_sgi; - uint32_t rx_type; - uint32_t rx_bw; -static uint32_t pkt_type_hw_to_cdp[] = { - CDP_PKT_TYPE_OFDM, - CDP_PKT_TYPE_CCK, - CDP_PKT_TYPE_HT, - CDP_PKT_TYPE_VHT, - CDP_PKT_TYPE_HE, - }; + 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, - }; - -static uint32_t rx_type_hw_to_cdp[] = { - CDP_RX_TYPE_SU, - CDP_RX_TYPE_MU_MIMO, - CDP_RX_TYPE_MU_OFDMA, - CDP_RX_TYPE_MU_OFDMA_MIMO, - }; - -static uint32_t rx_bw_hw_to_cdp[] = { - CDP_FULL_RX_BW_20, - CDP_FULL_RX_BW_40, - CDP_FULL_RX_BW_80, - CDP_FULL_RX_BW_160, - }; + 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; - rs->cdp_rs_tstamp.cdp_tsf = rx_msdu_start->ppdu_start_timestamp; - - rx_pream_type = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, PKT_TYPE); - rs->cdp_rs_pream_type = pkt_type_hw_to_cdp[rx_pream_type]; - - rs->cdp_rs_user_rssi = HAL_RX_GET(rx_msdu_start, + rs->ant_signal_db = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, USER_RSSI); - - rs->cdp_rs_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); - - rx_sgi = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, SGI); - rs->cdp_rs_sgi = sgi_hw_to_cdp[rx_sgi]; - - rs->cdf_rs_rate_mcs = HAL_RX_GET(rx_msdu_start, + rs->mcs = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RATE_MCS); + rs->is_stbc = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, STBC); - rx_type = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEPTION_TYPE); + 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); - rs->cdp_rs_reception_type = rx_type_hw_to_cdp[rx_type]; - - rx_bw = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, RECEIVE_BANDWIDTH); - - rs->cdp_rs_bw = rx_bw_hw_to_cdp[rx_bw]; - - rs->cdp_rs_nss = 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_11AC: + rs->vht_flags = 1; + reg_value = HAL_RX_GET(rx_msdu_start, RX_MSDU_START_5, + RECEIVE_BANDWIDTH); + rs->vht_flag_values2 = 0x01 << reg_value; + rs->vht_flag_values3[0] = rs->mcs << 4; + 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 */ } struct hal_rx_ppdu_user_info { @@ -394,6 +403,7 @@ struct hal_rx_ppdu_common_info { struct hal_rx_ppdu_info { struct hal_rx_ppdu_common_info com_info; struct hal_rx_ppdu_user_info user_info[HAL_MAX_UL_MU_USERS]; + struct mon_rx_status rx_status; }; static inline uint32_t @@ -404,9 +414,18 @@ hal_get_rx_status_buf_size(void) { static inline uint8_t* hal_rx_status_get_next_tlv(uint8_t *rx_tlv) { - uint32_t tlv_len; + uint32_t tlv_len, tlv_tag; tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv); + tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); + + /* The actual length of PPDU_END is the combined lenght of many PHY + * TLVs that follow. Skip the TLV header and + * rx_rxpcu_classification_overview that follows the header to get to + * next TLV. + */ + if (tlv_tag == WIFIRX_PPDU_END_E) + tlv_len = sizeof(struct rx_rxpcu_classification_overview); return (uint8_t *)(((unsigned long)(rx_tlv + tlv_len + HAL_RX_TLV32_HDR_SIZE + 3)) & (~((unsigned long)3))); @@ -415,7 +434,7 @@ hal_rx_status_get_next_tlv(uint8_t *rx_tlv) { static inline uint32_t hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) { - uint32_t tlv_tag, user_id, tlv_len; + uint32_t tlv_tag, user_id, tlv_len, value; tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv); user_id = HAL_RX_GET_USER_TLV32_USERID(rx_tlv); @@ -432,6 +451,10 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) ppdu_info->com_info.ppdu_id = HAL_RX_GET(rx_tlv, RX_PPDU_START_0, PHY_PPDU_ID); + /* TODO: Ensure channel number is set in PHY meta data */ + ppdu_info->rx_status.chan_freq = + HAL_RX_GET(rx_tlv, RX_PPDU_START_1, + SW_PHY_META_DATA); ppdu_info->com_info.ppdu_timestamp = HAL_RX_GET(rx_tlv, RX_PPDU_START_2, PPDU_START_TIMESTAMP); @@ -444,9 +467,16 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, "[%s][%d] ppdu_end_e len=%d\n", __func__, __LINE__, tlv_len); + /* This is followed by sub-TLVs of PPDU_END */ break; case WIFIRXPCU_PPDU_END_INFO_E: + ppdu_info->rx_status.tsft = + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_1, + WB_TIMESTAMP_UPPER_32); + ppdu_info->rx_status.tsft = (ppdu_info->rx_status.tsft << 32) | + HAL_RX_GET(rx_tlv, RXPCU_PPDU_END_INFO_0, + WB_TIMESTAMP_LOWER_32); break; case WIFIRX_PPDU_END_USER_STATS_E: @@ -459,8 +489,147 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) return HAL_TLV_STATUS_PPDU_DONE; case WIFIDUMMY_E: - return HAL_TLV_STATUS_DUMMY; + return HAL_TLV_STATUS_PPDU_DONE; + case WIFIPHYRX_HT_SIG_E: + { + uint8_t *ht_sig_info = (uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HT_SIG_0, + HT_SIG_INFO_PHYRX_HT_SIG_INFO_DETAILS); + value = HAL_RX_GET(ht_sig_info, HT_SIG_INFO_1, + FEC_CODING); + ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? + 1 : 0; + break; + } + case WIFIPHYRX_VHT_SIG_A_E: + { + uint8_t *vht_sig_a_info = (uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_VHT_SIG_A_0, + VHT_SIG_A_INFO_PHYRX_VHT_SIG_A_INFO_DETAILS); + value = HAL_RX_GET(vht_sig_a_info, VHT_SIG_A_INFO_1, + SU_MU_CODING); + ppdu_info->rx_status.ldpc = (value == HAL_SU_MU_CODING_LDPC) ? + 1 : 0; + break; + } + case WIFIPHYRX_HE_SIG_A_SU_E: + ppdu_info->rx_status.he_sig_A1 = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_0, + HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_A1 |= + QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_SU; + /* TODO: Enabling all known bits. Check if this should be + * enabled selectively + */ + ppdu_info->rx_status.he_sig_A1_known = + QDF_MON_STATUS_HE_SIG_A1_SU_KNOWN_ALL; + ppdu_info->rx_status.he_sig_A2 = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_A_SU_1, + HE_SIG_A_SU_INFO_PHYRX_HE_SIG_A_SU_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_A2_known = + QDF_MON_STATUS_HE_SIG_A2_SU_KNOWN_ALL; + break; + case WIFIPHYRX_HE_SIG_A_MU_DL_E: + ppdu_info->rx_status.he_sig_A1 = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_0, + HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_A1 |= + QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_MU; + ppdu_info->rx_status.he_sig_A1_known = + QDF_MON_STATUS_HE_SIG_A1_MU_KNOWN_ALL; + + ppdu_info->rx_status.he_sig_A2 = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_A_MU_DL_1, + HE_SIG_A_MU_DL_INFO_PHYRX_HE_SIG_A_MU_DL_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_A2_known = + QDF_MON_STATUS_HE_SIG_A2_MU_KNOWN_ALL; + break; + case WIFIPHYRX_HE_SIG_B1_MU_E: + { + uint8_t *he_sig_b1_mu_info = (uint8_t *)rx_tlv + + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_B1_MU_0, + HE_SIG_B1_MU_INFO_PHYRX_HE_SIG_B1_MU_INFO_DETAILS))); + + ppdu_info->rx_status.he_sig_b_common_RU[0] = + HAL_RX_GET(he_sig_b1_mu_info, HE_SIG_B1_MU_INFO_0, + RU_ALLOCATION); + + ppdu_info->rx_status.he_sig_b_common_known = + QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0; + /* TODO: Check on the availability of other fields in + * sig_b_common + */ + break; + } + case WIFIPHYRX_HE_SIG_B2_MU_E: + ppdu_info->rx_status.he_sig_b_user = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_B2_MU_0, + HE_SIG_B2_MU_INFO_PHYRX_HE_SIG_B2_MU_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_b_user_known = + QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL; + break; + case WIFIPHYRX_HE_SIG_B2_OFDMA_E: + ppdu_info->rx_status.he_sig_b_user = + *((uint32_t *)((uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_HE_SIG_B2_OFDMA_0, + HE_SIG_B2_OFDMA_INFO_PHYRX_HE_SIG_B2_OFDMA_INFO_DETAILS))); + ppdu_info->rx_status.he_sig_b_user_known = + QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL; + break; + case WIFIPHYRX_RSSI_LEGACY_E: + { + uint8_t *rssi_info_tlv = (uint8_t *)rx_tlv + + HAL_RX_OFFSET(PHYRX_RSSI_LEGACY_3, + RECEIVE_RSSI_INFO_PRE_RSSI_INFO_DETAILS); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_0, RSSI_PRI20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_PRI20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_0, RSSI_EXT20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_0, RSSI_EXT40_LOW20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT40_LOW20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_0, RSSI_EXT40_HIGH20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT40_HIGH20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT80_LOW20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_1, RSSI_EXT80_LOW_HIGH20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT80_LOW_HIGH20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + RECEIVE_RSSI_INFO_1, RSSI_EXT80_HIGH_LOW20_CHAIN0); + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, + "RSSI_EXT80_HIGH_LOW20_CHAIN0: %d\n", value); + + value = HAL_RX_GET(rssi_info_tlv, + 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 0: return HAL_TLV_STATUS_PPDU_DONE; @@ -468,6 +637,10 @@ hal_rx_status_get_tlv_info(void *rx_tlv, struct hal_rx_ppdu_info *ppdu_info) break; } + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + "%s TLV type: %d, TLV len:%d\n", + __func__, tlv_tag, tlv_len); + return HAL_TLV_STATUS_PPDU_NOT_DONE; } diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 3df6f3e3746f..3fe719800e8f 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -64,7 +64,18 @@ #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_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" diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index d78b30a6b436..cef0e0f14b8b 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -178,6 +178,18 @@ struct mon_rx_status { uint8_t he_sig_b_common_RU[4]; }; +/* Masks for HE SIG known fields in mon_rx_status structure */ +#define QDF_MON_STATUS_HE_SIG_A1_SU_KNOWN_ALL 0x000007ff +#define QDF_MON_STATUS_HE_SIG_A1_MU_KNOWN_ALL 0x000003ff +#define QDF_MON_STATUS_HE_SIG_A2_SU_KNOWN_ALL 0x00000ffd +#define QDF_MON_STATUS_HE_SIG_A2_MU_KNOWN_ALL 0x00000ffd +#define QDF_MON_STATUS_HE_SIG_B_COMMON_KNOWN_RU0 0x00000001 +#define QDF_MON_STATUS_HE_SIG_B_USER_KNOWN_SIG_B_ALL 0x00fe0000 +#define QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_SU 0x00000000 +#define QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_EXT_SU 0x40000000 +#define QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_MU 0x80000000 +#define QDF_MON_STATUS_HE_SIG_A1_HE_FORMAT_TRIG 0xc0000000 + /* DHCP Related Mask */ #define QDF_DHCP_OPTION53 (0x35) #define QDF_DHCP_OPTION53_LENGTH (1) diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 88665521dc74..99141596ddb7 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -2752,7 +2752,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, qdf_print("ERROR: not enough space to update radiotap\n"); return 0; } - qdf_nbuf_pull_head(nbuf, headroom_sz - rtap_len); + qdf_nbuf_push_head(nbuf, rtap_len); qdf_mem_copy(qdf_nbuf_data(nbuf), rtap_buf, rtap_len); return rtap_len; }