diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 1ac232a3e4..a57c4db02a 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -43,6 +43,8 @@ #include "dp_ratetable.h" #endif +#ifndef WLAN_SOFTUMAC_SUPPORT /* WLAN_SOFTUMAC_SUPPORT */ + #ifdef DUP_RX_DESC_WAR void dp_rx_dump_info_and_assert(struct dp_soc *soc, hal_ring_handle_t hal_ring, @@ -106,7 +108,115 @@ fail: } #endif + +uint32_t dp_rx_srng_get_num_pending(hal_soc_handle_t hal_soc, + hal_ring_handle_t hal_ring_hdl, + uint32_t num_entries, + bool *near_full) +{ + uint32_t num_pending = 0; + + num_pending = hal_srng_dst_num_valid_locked(hal_soc, + hal_ring_hdl, + true); + + if (num_entries && (num_pending >= num_entries >> 1)) + *near_full = true; + else + *near_full = false; + + return num_pending; +} + +#ifdef RX_DESC_DEBUG_CHECK +QDF_STATUS dp_rx_desc_nbuf_sanity_check(struct dp_soc *soc, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc) +{ + struct hal_buf_info hbi; + + hal_rx_reo_buf_paddr_get(soc->hal_soc, ring_desc, &hbi); + /* Sanity check for possible buffer paddr corruption */ + if (dp_rx_desc_paddr_sanity_check(rx_desc, (&hbi)->paddr)) + return QDF_STATUS_SUCCESS; + + return QDF_STATUS_E_FAILURE; +} + +/** + * dp_rx_desc_nbuf_len_sanity_check - Add sanity check to catch Rx buffer + * out of bound access from H.W + * + * @soc: DP soc + * @pkt_len: Packet length received from H.W + * + * Return: NONE + */ +static inline void +dp_rx_desc_nbuf_len_sanity_check(struct dp_soc *soc, + uint32_t pkt_len) +{ + struct rx_desc_pool *rx_desc_pool; + + rx_desc_pool = &soc->rx_desc_buf[0]; + qdf_assert_always(pkt_len <= rx_desc_pool->buf_size); +} +#else +static inline void +dp_rx_desc_nbuf_len_sanity_check(struct dp_soc *soc, uint32_t pkt_len) { } +#endif + +#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY +void +dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, + hal_ring_desc_t ring_desc) +{ + struct dp_buf_info_record *record; + struct hal_buf_info hbi; + uint32_t idx; + + if (qdf_unlikely(!soc->rx_ring_history[ring_num])) + return; + + hal_rx_reo_buf_paddr_get(soc->hal_soc, ring_desc, &hbi); + + /* buffer_addr_info is the first element of ring_desc */ + hal_rx_buf_cookie_rbm_get(soc->hal_soc, (uint32_t *)ring_desc, + &hbi); + + idx = dp_history_get_next_index(&soc->rx_ring_history[ring_num]->index, + DP_RX_HIST_MAX); + + /* No NULL check needed for record since its an array */ + record = &soc->rx_ring_history[ring_num]->entry[idx]; + + record->timestamp = qdf_get_log_timestamp(); + record->hbi.paddr = hbi.paddr; + record->hbi.sw_cookie = hbi.sw_cookie; + record->hbi.rbm = hbi.rbm; +} +#endif + +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +void dp_rx_mark_first_packet_after_wow_wakeup(struct dp_pdev *pdev, + uint8_t *rx_tlv, + qdf_nbuf_t nbuf) +{ + struct dp_soc *soc; + + if (!pdev->is_first_wakeup_packet) + return; + + soc = pdev->soc; + if (hal_get_first_wow_wakeup_packet(soc->hal_soc, rx_tlv)) { + qdf_nbuf_mark_wakeup_frame(nbuf); + dp_info("First packet after WOW Wakeup rcvd"); + } +} +#endif + #endif /* QCA_HOST_MODE_WIFI_DISABLED */ +#endif /* WLAN_SOFTUMAC_SUPPORT */ /** * dp_pdev_frag_alloc_and_map() - Allocate frag for desc buffer and map @@ -2408,44 +2518,6 @@ int dp_wds_rx_policy_check(uint8_t *rx_tlv_hdr, } #endif -#ifdef RX_DESC_DEBUG_CHECK -QDF_STATUS dp_rx_desc_nbuf_sanity_check(struct dp_soc *soc, - hal_ring_desc_t ring_desc, - struct dp_rx_desc *rx_desc) -{ - struct hal_buf_info hbi; - - hal_rx_reo_buf_paddr_get(soc->hal_soc, ring_desc, &hbi); - /* Sanity check for possible buffer paddr corruption */ - if (dp_rx_desc_paddr_sanity_check(rx_desc, (&hbi)->paddr)) - return QDF_STATUS_SUCCESS; - - return QDF_STATUS_E_FAILURE; -} - -/** - * dp_rx_desc_nbuf_len_sanity_check - Add sanity check to catch Rx buffer - * out of bound access from H.W - * - * @soc: DP soc - * @pkt_len: Packet length received from H.W - * - * Return: NONE - */ -static inline void -dp_rx_desc_nbuf_len_sanity_check(struct dp_soc *soc, - uint32_t pkt_len) -{ - struct rx_desc_pool *rx_desc_pool; - - rx_desc_pool = &soc->rx_desc_buf[0]; - qdf_assert_always(pkt_len <= rx_desc_pool->buf_size); -} -#else -static inline void -dp_rx_desc_nbuf_len_sanity_check(struct dp_soc *soc, uint32_t pkt_len) { } -#endif - #ifdef DP_RX_PKT_NO_PEER_DELIVER #ifdef DP_RX_UDP_OVER_PEER_ROAM /** @@ -2593,25 +2665,6 @@ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf) } #endif -uint32_t dp_rx_srng_get_num_pending(hal_soc_handle_t hal_soc, - hal_ring_handle_t hal_ring_hdl, - uint32_t num_entries, - bool *near_full) -{ - uint32_t num_pending = 0; - - num_pending = hal_srng_dst_num_valid_locked(hal_soc, - hal_ring_hdl, - true); - - if (num_entries && (num_pending >= num_entries >> 1)) - *near_full = true; - else - *near_full = false; - - return num_pending; -} - #endif /* QCA_HOST_MODE_WIFI_DISABLED */ #ifdef WLAN_SUPPORT_RX_FISA @@ -2641,37 +2694,6 @@ bool dp_rx_is_raw_frame_dropped(qdf_nbuf_t nbuf) } #endif -#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY -void -dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, - hal_ring_desc_t ring_desc) -{ - struct dp_buf_info_record *record; - struct hal_buf_info hbi; - uint32_t idx; - - if (qdf_unlikely(!soc->rx_ring_history[ring_num])) - return; - - hal_rx_reo_buf_paddr_get(soc->hal_soc, ring_desc, &hbi); - - /* buffer_addr_info is the first element of ring_desc */ - hal_rx_buf_cookie_rbm_get(soc->hal_soc, (uint32_t *)ring_desc, - &hbi); - - idx = dp_history_get_next_index(&soc->rx_ring_history[ring_num]->index, - DP_RX_HIST_MAX); - - /* No NULL check needed for record since its an array */ - record = &soc->rx_ring_history[ring_num]->entry[idx]; - - record->timestamp = qdf_get_log_timestamp(); - record->hbi.paddr = hbi.paddr; - record->hbi.sw_cookie = hbi.sw_cookie; - record->hbi.rbm = hbi.rbm; -} -#endif - #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR void dp_rx_update_stats(struct dp_soc *soc, qdf_nbuf_t nbuf) { @@ -3140,21 +3162,3 @@ bool dp_rx_deliver_special_frame(struct dp_soc *soc, return false; } #endif - -#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET -void dp_rx_mark_first_packet_after_wow_wakeup(struct dp_pdev *pdev, - uint8_t *rx_tlv, - qdf_nbuf_t nbuf) -{ - struct dp_soc *soc; - - if (!pdev->is_first_wakeup_packet) - return; - - soc = pdev->soc; - if (hal_get_first_wow_wakeup_packet(soc->hal_soc, rx_tlv)) { - qdf_nbuf_mark_wakeup_frame(nbuf); - dp_info("First packet after WOW Wakeup rcvd"); - } -} -#endif diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 2797ea25ef..c8c038396f 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -955,38 +955,6 @@ dp_rx_process(struct dp_intr *int_ctx, hal_ring_handle_t hal_ring_hdl, uint8_t reo_ring_num, uint32_t quota); -/** - * dp_rx_err_process() - Processes error frames routed to REO error ring - * @int_ctx: pointer to DP interrupt context - * @soc: core txrx main context - * @hal_ring_hdl: opaque pointer to the HAL Rx Error Ring, which will be serviced - * @quota: No. of units (packets) that can be serviced in one shot. - * - * This function implements error processing and top level demultiplexer - * for all the frames routed to REO error ring. - * - * Return: uint32_t: No. of elements processed - */ -uint32_t dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, - hal_ring_handle_t hal_ring_hdl, uint32_t quota); - -/** - * dp_rx_wbm_err_process() - Processes error frames routed to WBM release ring - * @int_ctx: pointer to DP interrupt context - * @soc: core txrx main context - * @hal_ring_hdl: opaque pointer to the HAL Rx Error Ring, which will be - * serviced - * @quota: No. of units (packets) that can be serviced in one shot. - * - * This function implements error processing and top level demultiplexer - * for all the frames routed to WBM2HOST sw release ring. - * - * Return: uint32_t: No. of elements processed - */ -uint32_t -dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, - hal_ring_handle_t hal_ring_hdl, uint32_t quota); - /** * dp_rx_sg_create() - create a frag_list for MSDUs which are spread across * multiple nbufs. @@ -1211,38 +1179,6 @@ uint8_t dp_rx_process_invalid_peer(struct dp_soc *soc, qdf_nbuf_t nbuf, void dp_rx_process_invalid_peer_wrapper(struct dp_soc *soc, qdf_nbuf_t mpdu, bool mpdu_done, uint8_t mac_id); -/** - * dp_rx_process_mic_error(): Function to pass mic error indication to umac - * @soc: core DP main context - * @nbuf: buffer pointer - * @rx_tlv_hdr: start of rx tlv header - * @txrx_peer: txrx peer handle - * - * Return: void - */ -void dp_rx_process_mic_error(struct dp_soc *soc, qdf_nbuf_t nbuf, - uint8_t *rx_tlv_hdr, - struct dp_txrx_peer *txrx_peer); - -/** - * dp_2k_jump_handle() - Function to handle 2k jump exception - * on WBM ring - * @soc: core DP main context - * @nbuf: buffer pointer - * @rx_tlv_hdr: start of rx tlv header - * @peer_id: peer id of first msdu - * @tid: Tid for which exception occurred - * - * This function handles 2k jump violations arising out - * of receiving aggregates in non BA case. This typically - * may happen if aggregates are received on a QOS enabled TID - * while Rx window size is still initialized to value of 2. Or - * it may also happen if negotiated window size is 1 but peer - * sends aggregates. - */ -void dp_2k_jump_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, - uint16_t peer_id, uint8_t tid); - #define DP_RX_HEAD_APPEND(head, elem) \ do { \ qdf_nbuf_set_next((elem), (head)); \ @@ -1826,48 +1762,6 @@ dp_pdev_rx_buffers_attach(struct dp_soc *dp_soc, uint32_t mac_id, struct rx_desc_pool *rx_desc_pool, uint32_t num_req_buffers); -/** - * dp_rx_link_desc_return() - Return a MPDU link descriptor to HW - * (WBM), following error handling - * - * @soc: core DP main context - * @ring_desc: opaque pointer to the REO error ring descriptor - * @bm_action: put to idle_list or release to msdu_list - * - * Return: QDF_STATUS_E_FAILURE for failure else QDF_STATUS_SUCCESS - */ -QDF_STATUS -dp_rx_link_desc_return(struct dp_soc *soc, hal_ring_desc_t ring_desc, - uint8_t bm_action); - -/** - * dp_rx_link_desc_return_by_addr - Return a MPDU link descriptor to - * (WBM) by address - * - * @soc: core DP main context - * @link_desc_addr: link descriptor addr - * @bm_action: put to idle_list or release to msdu_list - * - * Return: QDF_STATUS_E_FAILURE for failure else QDF_STATUS_SUCCESS - */ -QDF_STATUS -dp_rx_link_desc_return_by_addr(struct dp_soc *soc, - hal_buff_addrinfo_t link_desc_addr, - uint8_t bm_action); - -/** - * dp_rxdma_err_process() - RxDMA error processing functionality - * @int_ctx: pointer to DP interrupt context - * @soc: core txrx main context - * @mac_id: mac id which is one of 3 mac_ids - * @quota: No. of units (packets) that can be serviced in one shot. - * - * Return: num of buffers processed - */ -uint32_t -dp_rxdma_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, - uint32_t mac_id, uint32_t quota); - /** * dp_rx_fill_mesh_stats() - Fills the mesh per packet receive stats * @vdev: DP Virtual device handle @@ -1902,21 +1796,6 @@ QDF_STATUS dp_rx_filter_mesh_packets(struct dp_vdev *vdev, qdf_nbuf_t nbuf, int dp_wds_rx_policy_check(uint8_t *rx_tlv_hdr, struct dp_vdev *vdev, struct dp_txrx_peer *peer); -/** - * dp_rx_dump_info_and_assert() - dump RX Ring info and Rx Desc info - * - * @soc: core txrx main context - * @hal_ring_hdl: opaque pointer to the HAL Rx Ring, which will be serviced - * @ring_desc: opaque pointer to the RX ring descriptor - * @rx_desc: host rx descriptor - * - * Return: void - */ -void dp_rx_dump_info_and_assert(struct dp_soc *soc, - hal_ring_handle_t hal_ring_hdl, - hal_ring_desc_t ring_desc, - struct dp_rx_desc *rx_desc); - /** * dp_rx_compute_delay() - Compute and fill in all timestamps * to pass in correct fields @@ -2074,24 +1953,6 @@ bool dp_rx_desc_paddr_sanity_check(struct dp_rx_desc *rx_desc, void dp_rx_enable_mon_dest_frag(struct rx_desc_pool *rx_desc_pool, bool is_mon_dest_desc); -/** - * dp_rx_process_rxdma_err() - Function to deliver rxdma unencrypted_err - * frames to OS or wifi parse errors. - * @soc: core DP main context - * @nbuf: buffer pointer - * @rx_tlv_hdr: start of rx tlv header - * @txrx_peer: peer reference - * @err_code: rxdma err code - * @mac_id: mac_id which is one of 3 mac_ids(Assuming mac_id and - * pool_id has same mapping) - * - * Return: None - */ -void -dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf, - uint8_t *rx_tlv_hdr, struct dp_txrx_peer *txrx_peer, - uint8_t err_code, uint8_t mac_id); - #ifndef QCA_MULTIPASS_SUPPORT static inline bool dp_rx_multipass_process(struct dp_txrx_peer *peer, qdf_nbuf_t nbuf, @@ -2170,88 +2031,6 @@ QDF_STATUS dp_rx_eapol_deliver_to_stack(struct dp_soc *soc, #ifndef QCA_HOST_MODE_WIFI_DISABLED -#ifdef QCA_OL_RX_LOCK_LESS_ACCESS -/** - * dp_rx_srng_access_start()- Wrapper function to log access start of a hal ring - * @int_ctx: pointer to DP interrupt context - * @soc: DP soc structure pointer - * @hal_ring_hdl: HAL ring handle - * - * Return: 0 on success; error on failure - */ -static inline int -dp_rx_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *soc, - hal_ring_handle_t hal_ring_hdl) -{ - return hal_srng_access_start_unlocked(soc->hal_soc, hal_ring_hdl); -} - -/** - * dp_rx_srng_access_end()- Wrapper function to log access end of a hal ring - * @int_ctx: pointer to DP interrupt context - * @soc: DP soc structure pointer - * @hal_ring_hdl: HAL ring handle - * - * Return: None - */ -static inline void -dp_rx_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *soc, - hal_ring_handle_t hal_ring_hdl) -{ - hal_srng_access_end_unlocked(soc->hal_soc, hal_ring_hdl); -} -#else -static inline int -dp_rx_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *soc, - hal_ring_handle_t hal_ring_hdl) -{ - return dp_srng_access_start(int_ctx, soc, hal_ring_hdl); -} - -static inline void -dp_rx_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *soc, - hal_ring_handle_t hal_ring_hdl) -{ - dp_srng_access_end(int_ctx, soc, hal_ring_hdl); -} -#endif - -#endif /* QCA_HOST_MODE_WIFI_DISABLED */ - -/** - * dp_rx_wbm_sg_list_reset() - Initialize sg list - * - * This api should be called at soc init and afterevery sg processing. - *@soc: DP SOC handle - */ -static inline void dp_rx_wbm_sg_list_reset(struct dp_soc *soc) -{ - if (soc) { - soc->wbm_sg_param.wbm_is_first_msdu_in_sg = false; - soc->wbm_sg_param.wbm_sg_nbuf_head = NULL; - soc->wbm_sg_param.wbm_sg_nbuf_tail = NULL; - soc->wbm_sg_param.wbm_sg_desc_msdu_len = 0; - } -} - -/** - * dp_rx_wbm_sg_list_deinit() - De-initialize sg list - * - * This api should be called in down path, to avoid any leak. - *@soc: DP SOC handle - */ -static inline void dp_rx_wbm_sg_list_deinit(struct dp_soc *soc) -{ - if (soc) { - if (soc->wbm_sg_param.wbm_sg_nbuf_head) - qdf_nbuf_list_free(soc->wbm_sg_param.wbm_sg_nbuf_head); - - dp_rx_wbm_sg_list_reset(soc); - } -} - -#ifndef QCA_HOST_MODE_WIFI_DISABLED - #ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL #define DP_RX_PROCESS_NBUF(soc, head, tail, ebuf_head, ebuf_tail, rx_desc) \ do { \ @@ -2276,20 +2055,6 @@ static inline void dp_rx_wbm_sg_list_deinit(struct dp_soc *soc) #endif /* QCA_HOST_MODE_WIFI_DISABLED */ -/** - * dp_rx_link_desc_refill_duplicate_check() - check if link desc duplicate - * to refill - * @soc: DP SOC handle - * @buf_info: the last link desc buf info - * @ring_buf_info: current buf address pointor including link desc - * - * Return: none. - */ -void dp_rx_link_desc_refill_duplicate_check( - struct dp_soc *soc, - struct hal_buf_info *buf_info, - hal_buff_addrinfo_t ring_buf_info); - #ifdef WLAN_FEATURE_PKT_CAPTURE_V2 /** * dp_rx_deliver_to_pkt_capture() - deliver rx packet to packet capture @@ -2402,64 +2167,7 @@ void dp_rx_msdu_stats_update(struct dp_soc *soc, qdf_nbuf_t nbuf, */ void dp_rx_deliver_to_stack_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf); -/** - * dp_rx_srng_get_num_pending() - get number of pending entries - * @hal_soc: hal soc opaque pointer - * @hal_ring_hdl: opaque pointer to the HAL Rx Ring - * @num_entries: number of entries in the hal_ring. - * @near_full: pointer to a boolean. This is set if ring is near full. - * - * The function returns the number of entries in a destination ring which are - * yet to be reaped. The function also checks if the ring is near full. - * If more than half of the ring needs to be reaped, the ring is considered - * approaching full. - * The function uses hal_srng_dst_num_valid_locked to get the number of valid - * entries. It should not be called within a SRNG lock. HW pointer value is - * synced into cached_hp. - * - * Return: Number of pending entries if any - */ -uint32_t dp_rx_srng_get_num_pending(hal_soc_handle_t hal_soc, - hal_ring_handle_t hal_ring_hdl, - uint32_t num_entries, - bool *near_full); - -#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY -/** - * dp_rx_ring_record_entry() - Record an entry into the rx ring history. - * @soc: Datapath soc structure - * @ring_num: REO ring number - * @ring_desc: REO ring descriptor - * - * Return: None - */ -void dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, - hal_ring_desc_t ring_desc); -#else -static inline void -dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, - hal_ring_desc_t ring_desc) -{ -} -#endif - #ifndef QCA_HOST_MODE_WIFI_DISABLED -#ifdef RX_DESC_SANITY_WAR -QDF_STATUS dp_rx_desc_sanity(struct dp_soc *soc, hal_soc_handle_t hal_soc, - hal_ring_handle_t hal_ring_hdl, - hal_ring_desc_t ring_desc, - struct dp_rx_desc *rx_desc); -#else -static inline -QDF_STATUS dp_rx_desc_sanity(struct dp_soc *soc, hal_soc_handle_t hal_soc, - hal_ring_handle_t hal_ring_hdl, - hal_ring_desc_t ring_desc, - struct dp_rx_desc *rx_desc) -{ - return QDF_STATUS_SUCCESS; -} -#endif - #ifdef DP_RX_DROP_RAW_FRM /** * dp_rx_is_raw_frame_dropped() - if raw frame nbuf, free and drop @@ -2477,29 +2185,6 @@ bool dp_rx_is_raw_frame_dropped(qdf_nbuf_t nbuf) } #endif -#ifdef RX_DESC_DEBUG_CHECK -/** - * dp_rx_desc_nbuf_sanity_check - Add sanity check to catch REO rx_desc paddr - * corruption - * @soc: DP SoC context - * @ring_desc: REO ring descriptor - * @rx_desc: Rx descriptor - * - * Return: NONE - */ -QDF_STATUS dp_rx_desc_nbuf_sanity_check(struct dp_soc *soc, - hal_ring_desc_t ring_desc, - struct dp_rx_desc *rx_desc); -#else -static inline -QDF_STATUS dp_rx_desc_nbuf_sanity_check(struct dp_soc *soc, - hal_ring_desc_t ring_desc, - struct dp_rx_desc *rx_desc) -{ - return QDF_STATUS_SUCCESS; -} -#endif - #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR /** * dp_rx_update_stats() - Update soc level rx packet count @@ -2630,98 +2315,6 @@ static inline int dp_rx_get_loop_pkt_limit(struct dp_soc *soc) void dp_rx_update_stats(struct dp_soc *soc, qdf_nbuf_t nbuf); -#ifdef QCA_SUPPORT_WDS_EXTENDED -/** - * dp_rx_is_list_ready() - Make different lists for 4-address - * and 3-address frames - * @nbuf_head: skb list head - * @vdev: vdev - * @txrx_peer : txrx_peer - * @peer_id: peer id of new received frame - * @vdev_id: vdev_id of new received frame - * - * Return: true if peer_ids are different. - */ -static inline bool -dp_rx_is_list_ready(qdf_nbuf_t nbuf_head, - struct dp_vdev *vdev, - struct dp_txrx_peer *txrx_peer, - uint16_t peer_id, - uint8_t vdev_id) -{ - if (nbuf_head && txrx_peer && txrx_peer->peer_id != peer_id) - return true; - - return false; -} -#else -static inline bool -dp_rx_is_list_ready(qdf_nbuf_t nbuf_head, - struct dp_vdev *vdev, - struct dp_txrx_peer *txrx_peer, - uint16_t peer_id, - uint8_t vdev_id) -{ - if (nbuf_head && vdev && (vdev->vdev_id != vdev_id)) - return true; - - return false; -} -#endif - -#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET -/** - * dp_rx_mark_first_packet_after_wow_wakeup - get first packet after wow wakeup - * @pdev: pointer to dp_pdev structure - * @rx_tlv: pointer to rx_pkt_tlvs structure - * @nbuf: pointer to skb buffer - * - * Return: None - */ -void dp_rx_mark_first_packet_after_wow_wakeup(struct dp_pdev *pdev, - uint8_t *rx_tlv, - qdf_nbuf_t nbuf); -#else -static inline void -dp_rx_mark_first_packet_after_wow_wakeup(struct dp_pdev *pdev, - uint8_t *rx_tlv, - qdf_nbuf_t nbuf) -{ -} -#endif - -#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) -static inline uint8_t -dp_rx_get_defrag_bm_id(struct dp_soc *soc) -{ - return DP_DEFRAG_RBM(soc->wbm_sw0_bm_id); -} - -static inline uint8_t -dp_rx_get_rx_bm_id(struct dp_soc *soc) -{ - return DP_WBM2SW_RBM(soc->wbm_sw0_bm_id); -} -#else -static inline uint8_t -dp_rx_get_rx_bm_id(struct dp_soc *soc) -{ - struct wlan_cfg_dp_soc_ctxt *cfg_ctx = soc->wlan_cfg_ctx; - uint8_t wbm2_sw_rx_rel_ring_id; - - wbm2_sw_rx_rel_ring_id = wlan_cfg_get_rx_rel_ring_id(cfg_ctx); - - return HAL_RX_BUF_RBM_SW_BM(soc->wbm_sw0_bm_id, - wbm2_sw_rx_rel_ring_id); -} - -static inline uint8_t -dp_rx_get_defrag_bm_id(struct dp_soc *soc) -{ - return dp_rx_get_rx_bm_id(soc); -} -#endif - static inline uint16_t dp_rx_peer_metadata_peer_id_get(struct dp_soc *soc, uint32_t peer_metadata) { @@ -3356,4 +2949,441 @@ dp_rx_deliver_to_osif_stack(struct dp_soc *soc, qdf_nbuf_t nbuf, qdf_nbuf_t tail, bool is_eapol); + +#ifndef WLAN_SOFTUMAC_SUPPORT /* WLAN_SOFTUMAC_SUPPORT */ +/** + * dp_rx_dump_info_and_assert() - dump RX Ring info and Rx Desc info + * + * @soc: core txrx main context + * @hal_ring_hdl: opaque pointer to the HAL Rx Ring, which will be serviced + * @ring_desc: opaque pointer to the RX ring descriptor + * @rx_desc: host rx descriptor + * + * Return: void + */ +void dp_rx_dump_info_and_assert(struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc); + +/** + * dp_rx_link_desc_return() - Return a MPDU link descriptor to HW + * (WBM), following error handling + * + * @soc: core DP main context + * @ring_desc: opaque pointer to the REO error ring descriptor + * @bm_action: put to idle_list or release to msdu_list + * + * Return: QDF_STATUS_E_FAILURE for failure else QDF_STATUS_SUCCESS + */ +QDF_STATUS +dp_rx_link_desc_return(struct dp_soc *soc, hal_ring_desc_t ring_desc, + uint8_t bm_action); + +/** + * dp_rx_link_desc_return_by_addr - Return a MPDU link descriptor to + * (WBM) by address + * + * @soc: core DP main context + * @link_desc_addr: link descriptor addr + * @bm_action: put to idle_list or release to msdu_list + * + * Return: QDF_STATUS_E_FAILURE for failure else QDF_STATUS_SUCCESS + */ +QDF_STATUS +dp_rx_link_desc_return_by_addr(struct dp_soc *soc, + hal_buff_addrinfo_t link_desc_addr, + uint8_t bm_action); + +/** + * dp_rxdma_err_process() - RxDMA error processing functionality + * @int_ctx: pointer to DP interrupt context + * @soc: core txrx main context + * @mac_id: mac id which is one of 3 mac_ids + * @quota: No. of units (packets) that can be serviced in one shot. + * + * Return: num of buffers processed + */ +uint32_t +dp_rxdma_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, + uint32_t mac_id, uint32_t quota); + +/** + * dp_rx_process_rxdma_err() - Function to deliver rxdma unencrypted_err + * frames to OS or wifi parse errors. + * @soc: core DP main context + * @nbuf: buffer pointer + * @rx_tlv_hdr: start of rx tlv header + * @txrx_peer: peer reference + * @err_code: rxdma err code + * @mac_id: mac_id which is one of 3 mac_ids(Assuming mac_id and + * pool_id has same mapping) + * + * Return: None + */ +void +dp_rx_process_rxdma_err(struct dp_soc *soc, qdf_nbuf_t nbuf, + uint8_t *rx_tlv_hdr, struct dp_txrx_peer *txrx_peer, + uint8_t err_code, uint8_t mac_id); + +/** + * dp_rx_process_mic_error(): Function to pass mic error indication to umac + * @soc: core DP main context + * @nbuf: buffer pointer + * @rx_tlv_hdr: start of rx tlv header + * @txrx_peer: txrx peer handle + * + * Return: void + */ +void dp_rx_process_mic_error(struct dp_soc *soc, qdf_nbuf_t nbuf, + uint8_t *rx_tlv_hdr, + struct dp_txrx_peer *txrx_peer); + +/** + * dp_2k_jump_handle() - Function to handle 2k jump exception + * on WBM ring + * @soc: core DP main context + * @nbuf: buffer pointer + * @rx_tlv_hdr: start of rx tlv header + * @peer_id: peer id of first msdu + * @tid: Tid for which exception occurred + * + * This function handles 2k jump violations arising out + * of receiving aggregates in non BA case. This typically + * may happen if aggregates are received on a QOS enabled TID + * while Rx window size is still initialized to value of 2. Or + * it may also happen if negotiated window size is 1 but peer + * sends aggregates. + */ +void dp_2k_jump_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr, + uint16_t peer_id, uint8_t tid); + +#ifndef QCA_HOST_MODE_WIFI_DISABLED + +/** + * dp_rx_err_process() - Processes error frames routed to REO error ring + * @int_ctx: pointer to DP interrupt context + * @soc: core txrx main context + * @hal_ring_hdl: opaque pointer to the HAL Rx Error Ring, which will be serviced + * @quota: No. of units (packets) that can be serviced in one shot. + * + * This function implements error processing and top level demultiplexer + * for all the frames routed to REO error ring. + * + * Return: uint32_t: No. of elements processed + */ +uint32_t dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl, uint32_t quota); + +/** + * dp_rx_wbm_err_process() - Processes error frames routed to WBM release ring + * @int_ctx: pointer to DP interrupt context + * @soc: core txrx main context + * @hal_ring_hdl: opaque pointer to the HAL Rx Error Ring, which will be + * serviced + * @quota: No. of units (packets) that can be serviced in one shot. + * + * This function implements error processing and top level demultiplexer + * for all the frames routed to WBM2HOST sw release ring. + * + * Return: uint32_t: No. of elements processed + */ +uint32_t +dp_rx_wbm_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl, uint32_t quota); + +#ifdef QCA_OL_RX_LOCK_LESS_ACCESS +/** + * dp_rx_srng_access_start()- Wrapper function to log access start of a hal ring + * @int_ctx: pointer to DP interrupt context + * @soc: DP soc structure pointer + * @hal_ring_hdl: HAL ring handle + * + * Return: 0 on success; error on failure + */ +static inline int +dp_rx_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl) +{ + return hal_srng_access_start_unlocked(soc->hal_soc, hal_ring_hdl); +} + +/** + * dp_rx_srng_access_end()- Wrapper function to log access end of a hal ring + * @int_ctx: pointer to DP interrupt context + * @soc: DP soc structure pointer + * @hal_ring_hdl: HAL ring handle + * + * Return: None + */ +static inline void +dp_rx_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl) +{ + hal_srng_access_end_unlocked(soc->hal_soc, hal_ring_hdl); +} +#else +static inline int +dp_rx_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl) +{ + return dp_srng_access_start(int_ctx, soc, hal_ring_hdl); +} + +static inline void +dp_rx_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *soc, + hal_ring_handle_t hal_ring_hdl) +{ + dp_srng_access_end(int_ctx, soc, hal_ring_hdl); +} +#endif + +#ifdef RX_DESC_SANITY_WAR +QDF_STATUS dp_rx_desc_sanity(struct dp_soc *soc, hal_soc_handle_t hal_soc, + hal_ring_handle_t hal_ring_hdl, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc); +#else +static inline +QDF_STATUS dp_rx_desc_sanity(struct dp_soc *soc, hal_soc_handle_t hal_soc, + hal_ring_handle_t hal_ring_hdl, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +#ifdef RX_DESC_DEBUG_CHECK +/** + * dp_rx_desc_nbuf_sanity_check - Add sanity check to catch REO rx_desc paddr + * corruption + * @soc: DP SoC context + * @ring_desc: REO ring descriptor + * @rx_desc: Rx descriptor + * + * Return: NONE + */ +QDF_STATUS dp_rx_desc_nbuf_sanity_check(struct dp_soc *soc, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc); +#else +static inline +QDF_STATUS dp_rx_desc_nbuf_sanity_check(struct dp_soc *soc, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc) +{ + return QDF_STATUS_SUCCESS; +} +#endif +#endif /* QCA_HOST_MODE_WIFI_DISABLED */ + +/** + * dp_rx_wbm_sg_list_reset() - Initialize sg list + * + * This api should be called at soc init and afterevery sg processing. + *@soc: DP SOC handle + */ +static inline void dp_rx_wbm_sg_list_reset(struct dp_soc *soc) +{ + if (soc) { + soc->wbm_sg_param.wbm_is_first_msdu_in_sg = false; + soc->wbm_sg_param.wbm_sg_nbuf_head = NULL; + soc->wbm_sg_param.wbm_sg_nbuf_tail = NULL; + soc->wbm_sg_param.wbm_sg_desc_msdu_len = 0; + } +} + +/** + * dp_rx_wbm_sg_list_deinit() - De-initialize sg list + * + * This api should be called in down path, to avoid any leak. + *@soc: DP SOC handle + */ +static inline void dp_rx_wbm_sg_list_deinit(struct dp_soc *soc) +{ + if (soc) { + if (soc->wbm_sg_param.wbm_sg_nbuf_head) + qdf_nbuf_list_free(soc->wbm_sg_param.wbm_sg_nbuf_head); + + dp_rx_wbm_sg_list_reset(soc); + } +} + +/** + * dp_rx_link_desc_refill_duplicate_check() - check if link desc duplicate + * to refill + * @soc: DP SOC handle + * @buf_info: the last link desc buf info + * @ring_buf_info: current buf address pointor including link desc + * + * Return: none. + */ +void dp_rx_link_desc_refill_duplicate_check( + struct dp_soc *soc, + struct hal_buf_info *buf_info, + hal_buff_addrinfo_t ring_buf_info); +/** + * dp_rx_srng_get_num_pending() - get number of pending entries + * @hal_soc: hal soc opaque pointer + * @hal_ring_hdl: opaque pointer to the HAL Rx Ring + * @num_entries: number of entries in the hal_ring. + * @near_full: pointer to a boolean. This is set if ring is near full. + * + * The function returns the number of entries in a destination ring which are + * yet to be reaped. The function also checks if the ring is near full. + * If more than half of the ring needs to be reaped, the ring is considered + * approaching full. + * The function uses hal_srng_dst_num_valid_locked to get the number of valid + * entries. It should not be called within a SRNG lock. HW pointer value is + * synced into cached_hp. + * + * Return: Number of pending entries if any + */ +uint32_t dp_rx_srng_get_num_pending(hal_soc_handle_t hal_soc, + hal_ring_handle_t hal_ring_hdl, + uint32_t num_entries, + bool *near_full); + +#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY +/** + * dp_rx_ring_record_entry() - Record an entry into the rx ring history. + * @soc: Datapath soc structure + * @ring_num: REO ring number + * @ring_desc: REO ring descriptor + * + * Return: None + */ +void dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, + hal_ring_desc_t ring_desc); +#else +static inline void +dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, + hal_ring_desc_t ring_desc) +{ +} +#endif + +#ifdef QCA_SUPPORT_WDS_EXTENDED +/** + * dp_rx_is_list_ready() - Make different lists for 4-address + * and 3-address frames + * @nbuf_head: skb list head + * @vdev: vdev + * @txrx_peer : txrx_peer + * @peer_id: peer id of new received frame + * @vdev_id: vdev_id of new received frame + * + * Return: true if peer_ids are different. + */ +static inline bool +dp_rx_is_list_ready(qdf_nbuf_t nbuf_head, + struct dp_vdev *vdev, + struct dp_txrx_peer *txrx_peer, + uint16_t peer_id, + uint8_t vdev_id) +{ + if (nbuf_head && txrx_peer && txrx_peer->peer_id != peer_id) + return true; + + return false; +} +#else +static inline bool +dp_rx_is_list_ready(qdf_nbuf_t nbuf_head, + struct dp_vdev *vdev, + struct dp_txrx_peer *txrx_peer, + uint16_t peer_id, + uint8_t vdev_id) +{ + if (nbuf_head && vdev && (vdev->vdev_id != vdev_id)) + return true; + + return false; +} +#endif + +#ifdef WLAN_FEATURE_MARK_FIRST_WAKEUP_PACKET +/** + * dp_rx_mark_first_packet_after_wow_wakeup - get first packet after wow wakeup + * @pdev: pointer to dp_pdev structure + * @rx_tlv: pointer to rx_pkt_tlvs structure + * @nbuf: pointer to skb buffer + * + * Return: None + */ +void dp_rx_mark_first_packet_after_wow_wakeup(struct dp_pdev *pdev, + uint8_t *rx_tlv, + qdf_nbuf_t nbuf); +#else +static inline void +dp_rx_mark_first_packet_after_wow_wakeup(struct dp_pdev *pdev, + uint8_t *rx_tlv, + qdf_nbuf_t nbuf) +{ +} +#endif + +#if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) +static inline uint8_t +dp_rx_get_defrag_bm_id(struct dp_soc *soc) +{ + return DP_DEFRAG_RBM(soc->wbm_sw0_bm_id); +} + +static inline uint8_t +dp_rx_get_rx_bm_id(struct dp_soc *soc) +{ + return DP_WBM2SW_RBM(soc->wbm_sw0_bm_id); +} +#else +static inline uint8_t +dp_rx_get_rx_bm_id(struct dp_soc *soc) +{ + struct wlan_cfg_dp_soc_ctxt *cfg_ctx = soc->wlan_cfg_ctx; + uint8_t wbm2_sw_rx_rel_ring_id; + + wbm2_sw_rx_rel_ring_id = wlan_cfg_get_rx_rel_ring_id(cfg_ctx); + + return HAL_RX_BUF_RBM_SW_BM(soc->wbm_sw0_bm_id, + wbm2_sw_rx_rel_ring_id); +} + +static inline uint8_t +dp_rx_get_defrag_bm_id(struct dp_soc *soc) +{ + return dp_rx_get_rx_bm_id(soc); +} +#endif + +#else +static inline QDF_STATUS +dp_rx_link_desc_return_by_addr(struct dp_soc *soc, + hal_buff_addrinfo_t link_desc_addr, + uint8_t bm_action) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void dp_rx_wbm_sg_list_reset(struct dp_soc *soc) +{ +} + +static inline void dp_rx_wbm_sg_list_deinit(struct dp_soc *soc) +{ +} + +static inline uint8_t +dp_rx_get_defrag_bm_id(struct dp_soc *soc) +{ + return 0; +} + +static inline uint8_t +dp_rx_get_rx_bm_id(struct dp_soc *soc) +{ + return 0; +} +#endif /* WLAN_SOFTUMAC_SUPPORT */ + #endif /* _DP_RX_H */ diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c index 3e8b02d57a..b30fff8238 100644 --- a/dp/wifi3.0/dp_rx_defrag.c +++ b/dp/wifi3.0/dp_rx_defrag.c @@ -86,6 +86,7 @@ static void dp_rx_defrag_frames_free(qdf_nbuf_t frames) } } +#ifndef WLAN_SOFTUMAC_SUPPORT /* WLAN_SOFTUMAC_SUPPORT */ /** * dp_rx_clear_saved_desc_info() - Clears descriptor info * @txrx_peer: Pointer to the peer data structure @@ -140,6 +141,18 @@ static void dp_rx_return_head_frag_desc(struct dp_txrx_peer *txrx_peer, "%s: Failed to return link desc", __func__); } } +#else + +static void dp_rx_clear_saved_desc_info(struct dp_txrx_peer *txrx_peer, + unsigned int tid) +{ +} + +static void dp_rx_return_head_frag_desc(struct dp_txrx_peer *txrx_peer, + unsigned int tid) +{ +} +#endif /* WLAN_SOFTUMAC_SUPPORT */ void dp_rx_reorder_flush_frag(struct dp_txrx_peer *txrx_peer, unsigned int tid) @@ -1584,44 +1597,6 @@ void dp_rx_defrag_cleanup(struct dp_txrx_peer *txrx_peer, unsigned int tid) txrx_peer->rx_tid[tid].curr_seq_num = 0; } -/** - * dp_rx_defrag_save_info_from_ring_desc() - Save info from REO ring descriptor - * @soc: Pointer to the SOC data structure - * @ring_desc: Pointer to the dst ring descriptor - * @rx_desc: Pointer to rx descriptor - * @txrx_peer: Pointer to the peer - * @tid: Transmit Identifier - * - * Return: None - */ -static QDF_STATUS -dp_rx_defrag_save_info_from_ring_desc(struct dp_soc *soc, - hal_ring_desc_t ring_desc, - struct dp_rx_desc *rx_desc, - struct dp_txrx_peer *txrx_peer, - unsigned int tid) -{ - void *dst_ring_desc; - - dst_ring_desc = qdf_mem_malloc(hal_srng_get_entrysize(soc->hal_soc, - REO_DST)); - - if (!dst_ring_desc) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: Memory alloc failed !", __func__); - QDF_ASSERT(0); - return QDF_STATUS_E_NOMEM; - } - - qdf_mem_copy(dst_ring_desc, ring_desc, - hal_srng_get_entrysize(soc->hal_soc, REO_DST)); - - txrx_peer->rx_tid[tid].dst_ring_desc = dst_ring_desc; - txrx_peer->rx_tid[tid].head_frag_desc = rx_desc; - - return QDF_STATUS_SUCCESS; -} - #ifdef DP_RX_DEFRAG_ADDR1_CHECK_WAR #ifdef WLAN_FEATURE_11BE_MLO /** @@ -1689,6 +1664,154 @@ static inline bool dp_rx_defrag_addr1_check(struct dp_soc *soc, } #endif +QDF_STATUS dp_rx_defrag_add_last_frag(struct dp_soc *soc, + struct dp_txrx_peer *txrx_peer, + uint16_t tid, + uint16_t rxseq, qdf_nbuf_t nbuf) +{ + struct dp_rx_tid_defrag *rx_tid = &txrx_peer->rx_tid[tid]; + struct dp_rx_reorder_array_elem *rx_reorder_array_elem; + uint8_t all_frag_present; + uint32_t msdu_len; + QDF_STATUS status; + + rx_reorder_array_elem = txrx_peer->rx_tid[tid].array; + + /* + * HW may fill in unexpected peer_id in RX PKT TLV, + * if this peer_id related peer is valid by coincidence, + * but actually this peer won't do dp_peer_rx_init(like SAP vdev + * self peer), then invalid access to rx_reorder_array_elem happened. + */ + if (!rx_reorder_array_elem) { + dp_verbose_debug( + "peer id:%d drop rx frame!", + txrx_peer->peer_id); + DP_STATS_INC(soc, rx.err.defrag_peer_uninit, 1); + dp_rx_nbuf_free(nbuf); + goto fail; + } + + if (rx_reorder_array_elem->head && + rxseq != rx_tid->curr_seq_num) { + /* Drop stored fragments if out of sequence + * fragment is received + */ + dp_rx_reorder_flush_frag(txrx_peer, tid); + + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "%s: No list found for TID %d Seq# %d", + __func__, tid, rxseq); + dp_rx_nbuf_free(nbuf); + goto fail; + } + + msdu_len = hal_rx_msdu_start_msdu_len_get(soc->hal_soc, + qdf_nbuf_data(nbuf)); + + qdf_nbuf_set_pktlen(nbuf, (msdu_len + soc->rx_pkt_tlv_size)); + + status = dp_rx_defrag_fraglist_insert(txrx_peer, tid, + &rx_reorder_array_elem->head, + &rx_reorder_array_elem->tail, nbuf, + &all_frag_present); + + if (QDF_IS_STATUS_ERROR(status)) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "%s Fragment insert failed", __func__); + + goto fail; + } + + if (soc->rx.flags.defrag_timeout_check) + dp_rx_defrag_waitlist_remove(txrx_peer, tid); + + if (!all_frag_present) { + uint32_t now_ms = + qdf_system_ticks_to_msecs(qdf_system_ticks()); + + txrx_peer->rx_tid[tid].defrag_timeout_ms = + now_ms + soc->rx.defrag.timeout_ms; + + dp_rx_defrag_waitlist_add(txrx_peer, tid); + + return QDF_STATUS_SUCCESS; + } + + status = dp_rx_defrag(txrx_peer, tid, rx_reorder_array_elem->head, + rx_reorder_array_elem->tail); + + if (QDF_IS_STATUS_ERROR(status)) { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "%s Fragment processing failed", __func__); + + dp_rx_return_head_frag_desc(txrx_peer, tid); + dp_rx_defrag_cleanup(txrx_peer, tid); + + goto fail; + } + + /* Re-inject the fragments back to REO for further processing */ + status = dp_rx_defrag_reo_reinject(txrx_peer, tid, + rx_reorder_array_elem->head); + if (QDF_IS_STATUS_SUCCESS(status)) { + rx_reorder_array_elem->head = NULL; + rx_reorder_array_elem->tail = NULL; + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, + "%s: Frag seq successfully reinjected", + __func__); + } else { + QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, + "%s: Frag seq reinjection failed", __func__); + dp_rx_return_head_frag_desc(txrx_peer, tid); + } + + dp_rx_defrag_cleanup(txrx_peer, tid); + return QDF_STATUS_SUCCESS; + +fail: + return QDF_STATUS_E_DEFRAG_ERROR; +} + +#ifndef WLAN_SOFTUMAC_SUPPORT /* WLAN_SOFTUMAC_SUPPORT */ +/** + * dp_rx_defrag_save_info_from_ring_desc() - Save info from REO ring descriptor + * @soc: Pointer to the SOC data structure + * @ring_desc: Pointer to the dst ring descriptor + * @rx_desc: Pointer to rx descriptor + * @txrx_peer: Pointer to the peer + * @tid: Transmit Identifier + * + * Return: None + */ +static QDF_STATUS +dp_rx_defrag_save_info_from_ring_desc(struct dp_soc *soc, + hal_ring_desc_t ring_desc, + struct dp_rx_desc *rx_desc, + struct dp_txrx_peer *txrx_peer, + unsigned int tid) +{ + void *dst_ring_desc; + + dst_ring_desc = qdf_mem_malloc(hal_srng_get_entrysize(soc->hal_soc, + REO_DST)); + + if (!dst_ring_desc) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + "%s: Memory alloc failed !", __func__); + QDF_ASSERT(0); + return QDF_STATUS_E_NOMEM; + } + + qdf_mem_copy(dst_ring_desc, ring_desc, + hal_srng_get_entrysize(soc->hal_soc, REO_DST)); + + txrx_peer->rx_tid[tid].dst_ring_desc = dst_ring_desc; + txrx_peer->rx_tid[tid].head_frag_desc = rx_desc; + + return QDF_STATUS_SUCCESS; +} + /** * dp_rx_defrag_store_fragment() - Store incoming fragments * @soc: Pointer to the SOC data structure @@ -2078,111 +2201,4 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc, return rx_bufs_used; } -QDF_STATUS dp_rx_defrag_add_last_frag(struct dp_soc *soc, - struct dp_txrx_peer *txrx_peer, - uint16_t tid, - uint16_t rxseq, qdf_nbuf_t nbuf) -{ - struct dp_rx_tid_defrag *rx_tid = &txrx_peer->rx_tid[tid]; - struct dp_rx_reorder_array_elem *rx_reorder_array_elem; - uint8_t all_frag_present; - uint32_t msdu_len; - QDF_STATUS status; - - rx_reorder_array_elem = txrx_peer->rx_tid[tid].array; - - /* - * HW may fill in unexpected peer_id in RX PKT TLV, - * if this peer_id related peer is valid by coincidence, - * but actually this peer won't do dp_peer_rx_init(like SAP vdev - * self peer), then invalid access to rx_reorder_array_elem happened. - */ - if (!rx_reorder_array_elem) { - dp_verbose_debug( - "peer id:%d drop rx frame!", - txrx_peer->peer_id); - DP_STATS_INC(soc, rx.err.defrag_peer_uninit, 1); - dp_rx_nbuf_free(nbuf); - goto fail; - } - - if (rx_reorder_array_elem->head && - rxseq != rx_tid->curr_seq_num) { - /* Drop stored fragments if out of sequence - * fragment is received - */ - dp_rx_reorder_flush_frag(txrx_peer, tid); - - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - "%s: No list found for TID %d Seq# %d", - __func__, tid, rxseq); - dp_rx_nbuf_free(nbuf); - goto fail; - } - - msdu_len = hal_rx_msdu_start_msdu_len_get(soc->hal_soc, - qdf_nbuf_data(nbuf)); - - qdf_nbuf_set_pktlen(nbuf, (msdu_len + soc->rx_pkt_tlv_size)); - - status = dp_rx_defrag_fraglist_insert(txrx_peer, tid, - &rx_reorder_array_elem->head, - &rx_reorder_array_elem->tail, nbuf, - &all_frag_present); - - if (QDF_IS_STATUS_ERROR(status)) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "%s Fragment insert failed", __func__); - - goto fail; - } - - if (soc->rx.flags.defrag_timeout_check) - dp_rx_defrag_waitlist_remove(txrx_peer, tid); - - if (!all_frag_present) { - uint32_t now_ms = - qdf_system_ticks_to_msecs(qdf_system_ticks()); - - txrx_peer->rx_tid[tid].defrag_timeout_ms = - now_ms + soc->rx.defrag.timeout_ms; - - dp_rx_defrag_waitlist_add(txrx_peer, tid); - - return QDF_STATUS_SUCCESS; - } - - status = dp_rx_defrag(txrx_peer, tid, rx_reorder_array_elem->head, - rx_reorder_array_elem->tail); - - if (QDF_IS_STATUS_ERROR(status)) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "%s Fragment processing failed", __func__); - - dp_rx_return_head_frag_desc(txrx_peer, tid); - dp_rx_defrag_cleanup(txrx_peer, tid); - - goto fail; - } - - /* Re-inject the fragments back to REO for further processing */ - status = dp_rx_defrag_reo_reinject(txrx_peer, tid, - rx_reorder_array_elem->head); - if (QDF_IS_STATUS_SUCCESS(status)) { - rx_reorder_array_elem->head = NULL; - rx_reorder_array_elem->tail = NULL; - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO, - "%s: Frag seq successfully reinjected", - __func__); - } else { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "%s: Frag seq reinjection failed", __func__); - dp_rx_return_head_frag_desc(txrx_peer, tid); - } - - dp_rx_defrag_cleanup(txrx_peer, tid); - return QDF_STATUS_SUCCESS; - -fail: - return QDF_STATUS_E_DEFRAG_ERROR; -} +#endif /* WLAN_SOFTUMAC_SUPPORT */ diff --git a/dp/wifi3.0/dp_rx_defrag.h b/dp/wifi3.0/dp_rx_defrag.h index 3b9a3ee129..47f86f6edc 100644 --- a/dp/wifi3.0/dp_rx_defrag.h +++ b/dp/wifi3.0/dp_rx_defrag.h @@ -49,6 +49,7 @@ struct dp_rx_defrag_cipher { uint8_t ic_miclen; }; +#ifndef WLAN_SOFTUMAC_SUPPORT /* WLAN_SOFTUMAC_SUPPORT */ /** * dp_rx_frag_handle() - Handles fragmented Rx frames * @@ -73,6 +74,7 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc, struct dp_rx_desc *rx_desc, uint8_t *mac_id, uint32_t quota); +#endif /* WLAN_SOFTUMAC_SUPPORT */ /** * dp_rx_frag_get_mac_hdr() - Return pointer to the mac hdr