diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index e973f348af..f4ca38746d 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -79,6 +79,7 @@ #define CDP_BUNDLE_STATS 23 #define CDP_CREDIT_STATS 24 #define CDP_DISCONNECT_STATS 25 +#define CDP_DP_RX_FISA_STATS 26 #define WME_AC_TO_TID(_ac) ( \ ((_ac) == WME_AC_VO) ? 6 : \ @@ -284,6 +285,7 @@ enum cdp_host_txrx_stats { TXRX_PDEV_CFG_PARAMS = 10, TXRX_NAPI_STATS = 11, TXRX_SOC_INTERRUPT_STATS = 12, + TXRX_SOC_FSE_STATS = 13, TXRX_HOST_STATS_MAX, }; @@ -729,6 +731,11 @@ typedef bool (*ol_txrx_tx_flow_control_is_pause_fp)(void *osif_dev); */ typedef QDF_STATUS(*ol_txrx_rx_fp)(void *osif_dev, qdf_nbuf_t msdu_list); +typedef QDF_STATUS(*ol_txrx_fisa_rx_fp)(void *soc, + void *dp_vdev, + qdf_nbuf_t msdu_list); + +typedef QDF_STATUS(*ol_txrx_fisa_flush_fp)(void *soc, int ring_num); /** * ol_txrx_rx_flush_fp - receive function to hand batches of data * frames from txrx to OS shim @@ -905,6 +912,8 @@ struct ol_txrx_ops { ol_txrx_rx_mon_fp mon; ol_txrx_stats_rx_fp stats_rx; ol_txrx_rsim_rx_decap_fp rsim_rx_decap; + ol_txrx_fisa_rx_fp osif_fisa_rx; + ol_txrx_fisa_flush_fp osif_fisa_flush; } rx; /* proxy arp function pointer - specified by OS shim, stored by txrx */ ol_txrx_proxy_arp_fp proxy_arp; @@ -2234,6 +2243,14 @@ struct cdp_peer_cookie { uint8_t cookie; }; +#ifdef WLAN_SUPPORT_RX_FISA +struct cdp_flow_stats { + uint32_t aggr_count; + uint32_t curr_aggr_count; + uint32_t flush_count; + uint32_t bytes_aggregated; +}; +#else /** * cdp_flow_stats - Per-Flow (5-tuple) statistics * @msdu_count: number of rx msdus matching this flow @@ -2244,6 +2261,7 @@ struct cdp_peer_cookie { struct cdp_flow_stats { uint32_t msdu_count; }; +#endif /** * cdp_flow_fst_operation - RX FST operations allowed @@ -2278,6 +2296,9 @@ enum cdp_flow_protocol_type { * @l4_protocol: protocol type in flow (TCP/UDP) */ struct cdp_rx_flow_tuple_info { +#ifdef WLAN_SUPPORT_RX_FISA + uint8_t tuple_populated; +#endif uint32_t dest_ip_127_96; uint32_t dest_ip_95_64; uint32_t dest_ip_63_32; diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 14cfe65099..c165a15566 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -4686,8 +4686,8 @@ dp_htt_rx_flow_fst_setup(struct dp_pdev *pdev, DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_RX_FSE_SETUP_CFG, htt_logger_bufp); - qdf_info("HTT_H2T RX_FSE_SETUP sent to FW for pdev = %u", - fse_setup_info->pdev_id); + dp_info("HTT_H2T RX_FSE_SETUP sent to FW for pdev = %u", + fse_setup_info->pdev_id); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG, (void *)fse_setup_info->hash_key, fse_setup_info->hash_key_len); @@ -4731,6 +4731,7 @@ dp_htt_rx_flow_fse_operation(struct dp_pdev *pdev, if (!qdf_nbuf_put_tail(msg, sizeof(struct htt_h2t_msg_rx_fse_operation_t))) { qdf_err("Failed to expand head for HTT_RX_FSE_OPERATION msg"); + qdf_nbuf_free(msg); return QDF_STATUS_E_FAILURE; } @@ -4829,8 +4830,114 @@ dp_htt_rx_flow_fse_operation(struct dp_pdev *pdev, DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_RX_FSE_OPERATION_CFG, htt_logger_bufp); - qdf_info("HTT_H2T RX_FSE_OPERATION_CFG sent to FW for pdev = %u", - fse_op_info->pdev_id); + dp_info("HTT_H2T RX_FSE_OPERATION_CFG sent to FW for pdev = %u", + fse_op_info->pdev_id); + + return QDF_STATUS_SUCCESS; +} + +/** + * dp_htt_rx_fisa_config(): Send HTT msg to configure FISA + * @pdev: DP pdev handle + * @fse_op_info: Flow entry parameters + * + * Return: Success when HTT message is sent, error on failure + */ +QDF_STATUS +dp_htt_rx_fisa_config(struct dp_pdev *pdev, + struct dp_htt_rx_fisa_cfg *fisa_config) +{ + struct htt_soc *soc = pdev->soc->htt_handle; + struct dp_htt_htc_pkt *pkt; + qdf_nbuf_t msg; + u_int32_t *msg_word; + struct htt_h2t_msg_type_fisa_config_t *htt_fisa_config; + uint8_t *htt_logger_bufp; + uint32_t len; + + len = HTT_MSG_BUF_SIZE(sizeof(struct htt_h2t_msg_type_fisa_config_t)); + + msg = qdf_nbuf_alloc(soc->osdev, + len, + /* reserve room for the HTC header */ + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, + 4, + TRUE); + if (!msg) + return QDF_STATUS_E_NOMEM; + + /* + * Set the length of the message. + * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added + * separately during the below call to qdf_nbuf_push_head. + * The contribution from the HTC header is added separately inside HTC. + */ + if (!qdf_nbuf_put_tail(msg, + sizeof(struct htt_h2t_msg_type_fisa_config_t))) { + qdf_err("Failed to expand head for HTT_RX_FSE_OPERATION msg"); + qdf_nbuf_free(msg); + return QDF_STATUS_E_FAILURE; + } + + /* fill in the message contents */ + msg_word = (u_int32_t *)qdf_nbuf_data(msg); + + memset(msg_word, 0, sizeof(struct htt_h2t_msg_type_fisa_config_t)); + /* rewind beyond alignment pad to get to the HTC header reserved area */ + qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING); + htt_logger_bufp = (uint8_t *)msg_word; + + *msg_word = 0; + HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_FISA_CFG); + + htt_fisa_config = (struct htt_h2t_msg_type_fisa_config_t *)msg_word; + + HTT_RX_FSE_OPERATION_PDEV_ID_SET(*msg_word, htt_fisa_config->pdev_id); + + msg_word++; + HTT_RX_FISA_CONFIG_FISA_ENABLE_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_IPSEC_SKIP_SEARCH_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_NON_TCP_SKIP_SEARCH_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_ADD_IPV4_FIXED_HDR_LEN_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_ADD_IPV6_FIXED_HDR_LEN_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_ADD_TCP_FIXED_HDR_LEN_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_ADD_UDP_HDR_LEN_SET(*msg_word, 0); + HTT_RX_FISA_CONFIG_CHKSUM_CUM_IP_LEN_EN_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_TID_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_TA_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_QOS_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_RAW_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_DECRYPT_ERR_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_DISABLE_MSDU_DROP_CHECK_SET(*msg_word, 1); + HTT_RX_FISA_CONFIG_FISA_AGGR_LIMIT_SET(*msg_word, 0xf); + + msg_word++; + htt_fisa_config->fisa_timeout_threshold = fisa_config->fisa_timeout; + + pkt = htt_htc_pkt_alloc(soc); + if (!pkt) { + qdf_err("Fail to allocate dp_htt_htc_pkt buffer"); + qdf_assert(0); + qdf_nbuf_free(msg); + return QDF_STATUS_E_RESOURCES; /* failure */ + } + + pkt->soc_ctxt = NULL; /* not used during send-done callback */ + + SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt, + dp_htt_h2t_send_complete_free_netbuf, + qdf_nbuf_data(msg), + qdf_nbuf_len(msg), + soc->htc_endpoint, + 1); /* tag - not relevant here */ + + SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); + + DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_RX_FISA_CFG, + htt_logger_bufp); + + dp_info("HTT_H2T_MSG_TYPE_RX_FISA_CFG sent to FW for pdev = %u", + fisa_config->pdev_id); return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_htt.h b/dp/wifi3.0/dp_htt.h index 364506d66d..56853b071c 100644 --- a/dp/wifi3.0/dp_htt.h +++ b/dp/wifi3.0/dp_htt.h @@ -289,6 +289,19 @@ struct dp_htt_rx_flow_fst_operation { struct cdp_rx_flow_info *rx_flow; }; +/** + * struct dp_htt_rx_fisa_config - Rx fisa config + * @pdev_id: DP Pdev identifier + * @fisa_timeout: fisa aggregation timeout + */ +struct dp_htt_rx_fisa_cfg { + uint8_t pdev_id; + uint32_t fisa_timeout; +}; + +QDF_STATUS dp_htt_rx_fisa_config(struct dp_pdev *pdev, + struct dp_htt_rx_fisa_cfg *fisa_config); + /* * htt_soc_initialize() - SOC level HTT initialization * @htt_soc: Opaque htt SOC handle diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 19696e9c28..7e2b7a0e9d 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -2031,4 +2031,7 @@ void dp_is_hw_dbs_enable(struct dp_soc *soc, int *max_mac_rings); +#if defined(WLAN_SUPPORT_RX_FISA) +void dp_rx_dump_fisa_table(struct dp_soc *soc); +#endif /* WLAN_SUPPORT_RX_FISA */ #endif /* #ifndef _DP_INTERNAL_H_ */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 59a1466780..1113c3315a 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -46,6 +46,9 @@ #include "dp_rx_mon.h" #include "htt_stats.h" #include "dp_htt.h" +#ifdef WLAN_SUPPORT_RX_FISA +#include +#endif #include "htt_ppdu_stats.h" #include "qdf_mem.h" /* qdf_mem_malloc,free */ #include "cfg_ucfg_api.h" @@ -314,6 +317,7 @@ const int dp_stats_mapping_table[][STATS_TYPE_MAX] = { {TXRX_FW_STATS_INVALID, TXRX_SOC_CFG_PARAMS}, {TXRX_FW_STATS_INVALID, TXRX_PDEV_CFG_PARAMS}, {TXRX_FW_STATS_INVALID, TXRX_SOC_INTERRUPT_STATS}, + {TXRX_FW_STATS_INVALID, TXRX_SOC_FSE_STATS}, }; /* MCL specific functions */ @@ -4885,25 +4889,57 @@ dp_rx_target_fst_config(struct dp_soc *soc) } return status; } -#elif WLAN_SUPPORT_RX_FISA +#elif defined(WLAN_SUPPORT_RX_FISA) /** * dp_rx_target_fst_config() - Configure RX OLE FSE engine in HW * @soc: SoC handle * * Return: Success */ -static inline QDF_STATUS -dp_rx_target_fst_config(struct dp_soc *soc) +static inline QDF_STATUS dp_rx_target_fst_config(struct dp_soc *soc) { + /* Check if it is enabled in the INI */ + if (!soc->fisa_enable) { + dp_err("RX FISA feature is disabled"); + return QDF_STATUS_E_NOSUPPORT; + } + return dp_rx_flow_send_fst_fw_setup(soc, soc->pdev_list[0]); } -#else /* WLAN_SUPPORT_RX_FISA */ -static inline QDF_STATUS -dp_rx_target_fst_config(struct dp_soc *soc) + +#define FISA_MAX_TIMEOUT 0xffffffff +#define FISA_DISABLE_TIMEOUT 0 +static QDF_STATUS dp_rx_fisa_config(struct dp_soc *soc) +{ + struct dp_htt_rx_fisa_cfg fisa_config; + + fisa_config.pdev_id = 0; + fisa_config.fisa_timeout = FISA_MAX_TIMEOUT; + + return dp_htt_rx_fisa_config(soc->pdev_list[0], &fisa_config); +} +#else /* !WLAN_SUPPORT_RX_FISA */ +static inline QDF_STATUS dp_rx_target_fst_config(struct dp_soc *soc) { return QDF_STATUS_SUCCESS; } -#endif +#endif /* !WLAN_SUPPORT_RX_FISA */ + +#ifndef WLAN_SUPPORT_RX_FISA +static QDF_STATUS dp_rx_fisa_config(struct dp_soc *soc) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc) +{ + return QDF_STATUS_SUCCESS; +} + +static void dp_rx_dump_fisa_table(struct dp_soc *soc) +{ +} +#endif /* !WLAN_SUPPORT_RX_FISA */ /* * dp_soc_attach_target_wifi3() - SOC initialization in the target @@ -4932,11 +4968,20 @@ dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc) } status = dp_rx_target_fst_config(soc); - if (status != QDF_STATUS_SUCCESS) { + if (status != QDF_STATUS_SUCCESS && + status != QDF_STATUS_E_NOSUPPORT) { dp_err("Failed to send htt fst setup config message to target"); return status; } + if (status == QDF_STATUS_SUCCESS) { + status = dp_rx_fisa_config(soc); + if (status != QDF_STATUS_SUCCESS) { + dp_err("Failed to send htt FISA config message to target"); + return status; + } + } + DP_STATS_INIT(soc); /* initialize work queue for stats processing */ @@ -5096,6 +5141,8 @@ static QDF_STATUS dp_vdev_register_wifi3(struct cdp_soc_t *soc, vdev->osif_rx_flush = txrx_ops->rx.rx_flush; vdev->osif_gro_flush = txrx_ops->rx.rx_gro_flush; vdev->osif_rsim_rx_decap = txrx_ops->rx.rsim_rx_decap; + vdev->osif_fisa_rx = txrx_ops->rx.osif_fisa_rx; + vdev->osif_fisa_flush = txrx_ops->rx.osif_fisa_flush; vdev->osif_get_key = txrx_ops->get_key; vdev->osif_rx_mon = txrx_ops->rx.mon; vdev->osif_tx_free_ext = txrx_ops->tx.tx_free_ext; @@ -7440,6 +7487,7 @@ static void dp_txrx_stats_help(void) dp_info(" 28 -- Host REO Queue Statistics"); dp_info(" 29 -- Host Soc cfg param Statistics"); dp_info(" 30 -- Host pdev cfg param Statistics"); + dp_info(" 31 -- Host FISA stats"); } /** @@ -7502,6 +7550,8 @@ dp_print_host_stats(struct dp_vdev *vdev, case TXRX_SOC_INTERRUPT_STATS: dp_print_soc_interrupt_stats(pdev->soc); break; + case TXRX_SOC_FSE_STATS: + dp_rx_dump_fisa_table(pdev->soc); default: dp_info("Wrong Input For TxRx Host Stats"); dp_txrx_stats_help(); @@ -8952,6 +9002,10 @@ static QDF_STATUS dp_txrx_dump_stats(struct cdp_soc_t *psoc, uint16_t value, /* TODO: NOT IMPLEMENTED */ break; + case CDP_DP_RX_FISA_STATS: + dp_rx_dump_fisa_stats(soc); + break; + default: status = QDF_STATUS_E_INVAL; break; diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 6526c48c6a..a0b66a7716 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -1348,7 +1348,13 @@ void dp_rx_deliver_to_stack(struct dp_soc *soc, vdev->osif_rsim_rx_decap(vdev->osif_vdev, &nbuf_head, &nbuf_tail, peer->mac_addr.raw); } - vdev->osif_rx(vdev->osif_vdev, nbuf_head); + + /* Function pointer initialized only when FISA is enabled */ + if (vdev->osif_fisa_rx) + /* on failure send it via regular path */ + vdev->osif_fisa_rx(soc, vdev, nbuf_head); + else + vdev->osif_rx(vdev->osif_vdev, nbuf_head); } /** @@ -1739,6 +1745,28 @@ uint32_t dp_rx_srng_get_num_pending(hal_soc_handle_t hal_soc, return num_pending; } +#ifdef WLAN_SUPPORT_RX_FISA +/* + * dp_rx_skip_tlvs() - Skip TLVs only if FISA is not enabled + * @vdev: DP vdev context + * @nbuf: nbuf whose data pointer is adjusted + * @size: size to be adjusted + * + * Return: None + */ +static void dp_rx_skip_tlvs(struct dp_vdev *vdev, qdf_nbuf_t nbuf, int size) +{ + /* TLVs include FISA info do not skip them yet */ + if (!vdev->osif_fisa_rx) + qdf_nbuf_pull_head(nbuf, size); +} +#else /* !WLAN_SUPPORT_RX_FISA */ +static void dp_rx_skip_tlvs(struct dp_vdev *vdev, qdf_nbuf_t nbuf, int size) +{ + qdf_nbuf_pull_head(nbuf, size); +} +#endif /* !WLAN_SUPPORT_RX_FISA */ + /** * dp_rx_process() - Brain of the Rx processing functionality * Called from the bottom half (tasklet/NET_RX_SOFTIRQ) @@ -2185,9 +2213,8 @@ done: RX_PKT_TLVS_LEN; qdf_nbuf_set_pktlen(nbuf, pkt_len); - qdf_nbuf_pull_head(nbuf, - RX_PKT_TLVS_LEN + - msdu_metadata.l3_hdr_pad); + dp_rx_skip_tlvs(vdev, nbuf, RX_PKT_TLVS_LEN + + msdu_metadata.l3_hdr_pad); } /* @@ -2355,6 +2382,9 @@ done: } } + if (vdev->osif_fisa_flush) + vdev->osif_fisa_flush(soc, reo_ring_num); + if (vdev && vdev->osif_gro_flush && rx_ol_pkt_cnt) { vdev->osif_gro_flush(vdev->osif_vdev, reo_ring_num); diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 8ccc2f6fbb..ac4500b67f 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1252,6 +1252,9 @@ struct dp_soc { * TBD: rx_fst[num_macs] if we decide to have per mac FST */ struct dp_rx_fst *rx_fst; +#ifdef WLAN_SUPPORT_RX_FISA + uint8_t fisa_enable; +#endif #endif /* WLAN_SUPPORT_RX_FLOW_TAG || WLAN_SUPPORT_RX_FISA */ }; @@ -1810,6 +1813,10 @@ struct dp_vdev { ol_txrx_rx_fp osif_rx; /* callback to deliver rx frames to the OS */ ol_txrx_rx_fp osif_rx_stack; + /* Callback to handle rx fisa frames */ + ol_txrx_fisa_rx_fp osif_fisa_rx; + ol_txrx_fisa_flush_fp osif_fisa_flush; + /* call back function to flush out queued rx packets*/ ol_txrx_rx_flush_fp osif_rx_flush; ol_txrx_rsim_rx_decap_fp osif_rsim_rx_decap; @@ -2241,9 +2248,16 @@ struct dp_rx_fst { #define DP_RX_GET_SW_FT_ENTRY_SIZE sizeof(struct dp_rx_fse) #elif WLAN_SUPPORT_RX_FISA + +enum fisa_aggr_ret { + FISA_AGGR_DONE, + FISA_AGGR_NOT_ELIGIBLE, + FISA_FLUSH_FLOW +}; + struct dp_fisa_rx_sw_ft { /* HAL Rx Flow Search Entry which matches HW definition */ - void *hal_rx_fse; + void *hw_fse; /* Toeplitz hash value */ uint32_t flow_hash; /* Flow index, equivalent to hash value truncated to FST size */ @@ -2254,7 +2268,26 @@ struct dp_fisa_rx_sw_ft { uint8_t is_ipv4_addr_entry; /* Flag indicating whether flow is valid */ uint8_t is_valid; - qdf_nbuf_t *head_skb; + uint8_t is_populated; + uint8_t is_flow_udp; + uint8_t is_flow_tcp; + qdf_nbuf_t head_skb; + uint16_t cumulative_l4_checksum; + uint16_t adjusted_cumulative_ip_length; + uint16_t cur_aggr; + uint16_t napi_flush_cumulative_l4_checksum; + uint16_t napi_flush_cumulative_ip_length; + qdf_nbuf_t last_skb; + uint32_t head_skb_ip_hdr_offset; + uint32_t head_skb_l4_hdr_offset; + struct cdp_rx_flow_tuple_info rx_flow_tuple_info; + uint8_t napi_id; + struct dp_vdev *vdev; + uint64_t bytes_aggregated; + uint32_t flush_count; + uint32_t aggr_count; + uint8_t do_not_aggregate; + uint16_t hal_cumultive_ip_len; }; #define DP_RX_GET_SW_FT_ENTRY_SIZE sizeof(struct dp_fisa_rx_sw_ft) @@ -2276,6 +2309,10 @@ struct dp_rx_fst { uint32_t hash_mask; /* Lock for adding/deleting entries of FST */ qdf_spinlock_t dp_rx_fst_lock; + uint32_t add_flow_count; + uint32_t del_flow_count; + uint32_t hash_collision_cnt; + struct dp_soc *soc_hdl; }; #endif /* WLAN_SUPPORT_RX_FISA */