From 16816ae8d0a11e700a2694e2d773a1d44b2294e1 Mon Sep 17 00:00:00 2001 From: Mohit Khanna Date: Tue, 30 Oct 2018 14:12:03 -0700 Subject: [PATCH] qcacmn: Enable GRO for TCP packets Add support for GRO functionality for TCP packets. - Pass GRO config to DP layer as a part of dp_update_config_parameters - Add API to read the number of active RX contexts from DP layer cdp_get_num_rx_contexts - Fill GRO info into skb->cb from rx_tlv during dp_rx_process CRs-Fixed: 2346995 Change-Id: I1c143d8ce2c7522ba2c76142fb6cc82193df5608 --- dp/inc/cdp_txrx_cmn_struct.h | 4 +- dp/inc/cdp_txrx_misc.h | 20 ++++++++ dp/inc/cdp_txrx_ops.h | 3 +- dp/wifi3.0/dp_main.c | 95 +++++++++++++++++++++++------------- dp/wifi3.0/dp_rx.c | 85 ++++++++++++++------------------ dp/wifi3.0/dp_types.h | 1 - wlan_cfg/wlan_cfg.c | 5 ++ wlan_cfg/wlan_cfg.h | 8 +++ 8 files changed, 135 insertions(+), 86 deletions(-) diff --git a/dp/inc/cdp_txrx_cmn_struct.h b/dp/inc/cdp_txrx_cmn_struct.h index 1e85ae7c99..4ebbf260a1 100644 --- a/dp/inc/cdp_txrx_cmn_struct.h +++ b/dp/inc/cdp_txrx_cmn_struct.h @@ -1342,7 +1342,8 @@ struct cdp_rx_indication_msdu { * struct cdp_config_params - Propagate configuration parameters to datapath * @tso_enable: Enable/Disable TSO * @lro_enable: Enable/Disable LRO - * @flow_steering_enable: Enable/Disable Rx Hash + * @gro_enable: Enable/Disable GRO + * @flow_steering_enable: Enable/Disable Rx Hash based flow steering * @tcp_Udp_ChecksumOffload: Enable/Disable tcp-Udp checksum Offload * @napi_enable: Enable/Disable Napi * @ipa_enable: Flag indicating if IPA is enabled or not @@ -1353,6 +1354,7 @@ struct cdp_rx_indication_msdu { struct cdp_config_params { unsigned int tso_enable:1; unsigned int lro_enable:1; + unsigned int gro_enable:1; unsigned int flow_steering_enable:1; unsigned int tcp_udp_checksumoffload:1; unsigned int napi_enable:1; diff --git a/dp/inc/cdp_txrx_misc.h b/dp/inc/cdp_txrx_misc.h index 446d341ae0..52eca14eb0 100644 --- a/dp/inc/cdp_txrx_misc.h +++ b/dp/inc/cdp_txrx_misc.h @@ -550,4 +550,24 @@ static inline void cdp_pkt_log_con_service(ol_txrx_soc_handle soc, return; } + +/** + * cdp_get_num_rx_contexts() - API to get the number of RX contexts + * @soc: soc handle + * + * Return: number of RX contexts + */ +static inline int cdp_get_num_rx_contexts(ol_txrx_soc_handle soc) +{ + if (!soc || !soc->ops || !soc->ops->misc_ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return 0; + } + + if (soc->ops->misc_ops->get_num_rx_contexts) + return soc->ops->misc_ops->get_num_rx_contexts(soc); + + return 0; +} #endif /* _CDP_TXRX_MISC_H_ */ diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 7da20eadc6..875605ca5e 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -989,6 +989,7 @@ struct cdp_misc_ops { uint64_t *fwd_tx_packets, uint64_t *fwd_rx_packets); void (*pkt_log_init)(struct cdp_pdev *handle, void *scn); void (*pkt_log_con_service)(struct cdp_pdev *pdev, void *scn); + int (*get_num_rx_contexts)(struct cdp_soc_t *soc); }; /** @@ -1282,7 +1283,7 @@ struct cdp_mob_stats_ops { #ifdef RECEIVE_OFFLOAD /** - * struct cdp_rx_offld_ops - mcl receive offload ops + * struct cdp_rx_offld_ops - mcl host receive offload ops * @register_rx_offld_flush_cb: * @deregister_rx_offld_flush_cb: */ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 13e5860d03..81fd990547 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -434,6 +434,26 @@ static void dp_pkt_log_con_service(struct cdp_pdev *ppdev, void *scn) pktlog_htc_attach(); } +/** + * dp_get_num_rx_contexts() - get number of RX contexts + * @soc_hdl: cdp opaque soc handle + * + * Return: number of RX contexts + */ +static int dp_get_num_rx_contexts(struct cdp_soc_t *soc_hdl) +{ + int i; + int num_rx_contexts = 0; + + struct dp_soc *soc = (struct dp_soc *)soc_hdl; + + for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) + if (wlan_cfg_get_rx_ring_mask(soc->wlan_cfg_ctx, i)) + num_rx_contexts++; + + return num_rx_contexts; +} + /** * dp_pktlogmod_exit() - API to cleanup pktlog info * @handle: Pdev handle @@ -2711,20 +2731,22 @@ fail1: static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force); -static void dp_lro_hash_setup(struct dp_soc *soc, struct dp_pdev *pdev) +static QDF_STATUS dp_lro_hash_setup(struct dp_soc *soc, struct dp_pdev *pdev) { struct cdp_lro_hash_config lro_hash; + QDF_STATUS status; if (!wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx) && - !wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("LRO disabled RX hash disabled")); - return; + !wlan_cfg_is_gro_enabled(soc->wlan_cfg_ctx) && + !wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) { + dp_err("LRO, GRO and RX hash disabled"); + return QDF_STATUS_E_FAILURE; } qdf_mem_zero(&lro_hash, sizeof(lro_hash)); - if (wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx)) { + if (wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx) || + wlan_cfg_is_gro_enabled(soc->wlan_cfg_ctx)) { lro_hash.lro_enable = 1; lro_hash.tcp_flag = QDF_TCPHDR_ACK; lro_hash.tcp_flag_mask = QDF_TCPHDR_FIN | QDF_TCPHDR_SYN | @@ -2732,7 +2754,6 @@ static void dp_lro_hash_setup(struct dp_soc *soc, struct dp_pdev *pdev) QDF_TCPHDR_ECE | QDF_TCPHDR_CWR; } - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW, FL("enabled")); qdf_get_random_bytes(lro_hash.toeplitz_hash_ipv4, (sizeof(lro_hash.toeplitz_hash_ipv4[0]) * LRO_IPV4_SEED_ARR_SZ)); @@ -2740,28 +2761,38 @@ static void dp_lro_hash_setup(struct dp_soc *soc, struct dp_pdev *pdev) (sizeof(lro_hash.toeplitz_hash_ipv6[0]) * LRO_IPV6_SEED_ARR_SZ)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW, - "lro_hash: lro_enable: 0x%x tcp_flag 0x%x tcp_flag_mask 0x%x", - lro_hash.lro_enable, lro_hash.tcp_flag, - lro_hash.tcp_flag_mask); - - qdf_trace_hex_dump(QDF_MODULE_ID_DP, - QDF_TRACE_LEVEL_ERROR, - (void *)lro_hash.toeplitz_hash_ipv4, - (sizeof(lro_hash.toeplitz_hash_ipv4[0]) * - LRO_IPV4_SEED_ARR_SZ)); - - qdf_trace_hex_dump(QDF_MODULE_ID_DP, - QDF_TRACE_LEVEL_ERROR, - (void *)lro_hash.toeplitz_hash_ipv6, - (sizeof(lro_hash.toeplitz_hash_ipv6[0]) * - LRO_IPV6_SEED_ARR_SZ)); - qdf_assert(soc->cdp_soc.ol_ops->lro_hash_config); - if (soc->cdp_soc.ol_ops->lro_hash_config) - (void)soc->cdp_soc.ol_ops->lro_hash_config - (pdev->ctrl_pdev, &lro_hash); + if (!soc->cdp_soc.ol_ops->lro_hash_config) { + QDF_BUG(0); + dp_err("lro_hash_config not configured"); + return QDF_STATUS_E_FAILURE; + } + + status = soc->cdp_soc.ol_ops->lro_hash_config(pdev->ctrl_pdev, + &lro_hash); + if (!QDF_IS_STATUS_SUCCESS(status)) { + dp_err("failed to send lro_hash_config to FW %u", status); + return status; + } + + dp_info("LRO CMD config: lro_enable: 0x%x tcp_flag 0x%x tcp_flag_mask 0x%x", + lro_hash.lro_enable, lro_hash.tcp_flag, + lro_hash.tcp_flag_mask); + + dp_info("toeplitz_hash_ipv4:"); + qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + (void *)lro_hash.toeplitz_hash_ipv4, + (sizeof(lro_hash.toeplitz_hash_ipv4[0]) * + LRO_IPV4_SEED_ARR_SZ)); + + dp_info("toeplitz_hash_ipv6:"); + qdf_trace_hex_dump(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + (void *)lro_hash.toeplitz_hash_ipv6, + (sizeof(lro_hash.toeplitz_hash_ipv6[0]) * + LRO_IPV6_SEED_ARR_SZ)); + + return status; } /* @@ -4176,14 +4207,6 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev, if (pdev->vdev_count == 1) dp_lro_hash_setup(soc, pdev); - /* LRO */ - if (wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx) && - wlan_op_mode_sta == vdev->opmode) - vdev->lro_enable = true; - - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, - "LRO: vdev_id %d lro_enable %d", vdev_id, vdev->lro_enable); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "Created vdev %pK (%pM)", vdev, vdev->mac_addr.raw); DP_STATS_INIT(vdev); @@ -8506,6 +8529,7 @@ QDF_STATUS dp_update_config_parameters(struct cdp_soc *psoc, params->tcp_udp_checksumoffload; soc->wlan_cfg_ctx->napi_enabled = params->napi_enable; soc->wlan_cfg_ctx->ipa_enabled = params->ipa_enable; + soc->wlan_cfg_ctx->gro_enabled = params->gro_enable; dp_update_flow_control_parameters(soc, params); @@ -9138,6 +9162,7 @@ static struct cdp_misc_ops dp_ops_misc = { #endif /* FEATURE_RUNTIME_PM */ .pkt_log_init = dp_pkt_log_init, .pkt_log_con_service = dp_pkt_log_con_service, + .get_num_rx_contexts = dp_get_num_rx_contexts, }; static struct cdp_flowctl_ops dp_ops_flowctl = { diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 1d22ca155b..ed88552be0 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -887,62 +887,51 @@ void dp_rx_process_invalid_peer_wrapper(struct dp_soc *soc, } #endif -#if defined(FEATURE_LRO) -static void dp_rx_print_lro_info(uint8_t *rx_tlv) +#ifdef RECEIVE_OFFLOAD +/** + * dp_rx_print_offload_info() - Print offload info from RX TLV + * @rx_tlv: RX TLV for which offload information is to be printed + * + * Return: None + */ +static void dp_rx_print_offload_info(uint8_t *rx_tlv) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("----------------------RX DESC LRO----------------------")); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("lro_eligible 0x%x"), HAL_RX_TLV_GET_LRO_ELIGIBLE(rx_tlv)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("pure_ack 0x%x"), HAL_RX_TLV_GET_TCP_PURE_ACK(rx_tlv)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("chksum 0x%x"), HAL_RX_TLV_GET_TCP_CHKSUM(rx_tlv)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("TCP seq num 0x%x"), HAL_RX_TLV_GET_TCP_SEQ(rx_tlv)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("TCP ack num 0x%x"), HAL_RX_TLV_GET_TCP_ACK(rx_tlv)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("TCP window 0x%x"), HAL_RX_TLV_GET_TCP_WIN(rx_tlv)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("TCP protocol 0x%x"), HAL_RX_TLV_GET_TCP_PROTO(rx_tlv)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("TCP offset 0x%x"), HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("toeplitz 0x%x"), HAL_RX_TLV_GET_FLOW_ID_TOEPLITZ(rx_tlv)); - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, - FL("---------------------------------------------------------")); + dp_debug("----------------------RX DESC LRO/GRO----------------------"); + dp_debug("lro_eligible 0x%x", HAL_RX_TLV_GET_LRO_ELIGIBLE(rx_tlv)); + dp_debug("pure_ack 0x%x", HAL_RX_TLV_GET_TCP_PURE_ACK(rx_tlv)); + dp_debug("chksum 0x%x", HAL_RX_TLV_GET_TCP_CHKSUM(rx_tlv)); + dp_debug("TCP seq num 0x%x", HAL_RX_TLV_GET_TCP_SEQ(rx_tlv)); + dp_debug("TCP ack num 0x%x", HAL_RX_TLV_GET_TCP_ACK(rx_tlv)); + dp_debug("TCP window 0x%x", HAL_RX_TLV_GET_TCP_WIN(rx_tlv)); + dp_debug("TCP protocol 0x%x", HAL_RX_TLV_GET_TCP_PROTO(rx_tlv)); + dp_debug("TCP offset 0x%x", HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv)); + dp_debug("toeplitz 0x%x", HAL_RX_TLV_GET_FLOW_ID_TOEPLITZ(rx_tlv)); + dp_debug("---------------------------------------------------------"); } /** - * dp_rx_lro() - LRO related processing - * @rx_tlv: TLV data extracted from the rx packet - * @peer: destination peer of the msdu - * @msdu: network buffer - * @ctx: LRO context + * dp_rx_fill_gro_info() - Fill GRO info from RX TLV into skb->cb + * @soc: DP SOC handle + * @rx_tlv: RX TLV received for the msdu + * @msdu: msdu for which GRO info needs to be filled * - * This function performs the LRO related processing of the msdu - * - * Return: true: LRO enabled false: LRO is not enabled + * Return: None */ -static void dp_rx_lro(uint8_t *rx_tlv, struct dp_peer *peer, - qdf_nbuf_t msdu, qdf_lro_ctx_t ctx) +static +void dp_rx_fill_gro_info(struct dp_soc *soc, uint8_t *rx_tlv, + qdf_nbuf_t msdu) { - if (!peer || !peer->vdev || !peer->vdev->lro_enable) { - QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, - FL("no peer, no vdev or LRO disabled")); - QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu) = 0; + if (!wlan_cfg_is_gro_enabled(soc->wlan_cfg_ctx)) + return; + + /* Filling up RX offload info only for TCP packets */ + if (!HAL_RX_TLV_GET_TCP_PROTO(rx_tlv)) return; - } - qdf_assert(rx_tlv); - dp_rx_print_lro_info(rx_tlv); QDF_NBUF_CB_RX_LRO_ELIGIBLE(msdu) = HAL_RX_TLV_GET_LRO_ELIGIBLE(rx_tlv); - QDF_NBUF_CB_RX_TCP_PURE_ACK(msdu) = HAL_RX_TLV_GET_TCP_PURE_ACK(rx_tlv); - QDF_NBUF_CB_RX_TCP_CHKSUM(msdu) = HAL_RX_TLV_GET_TCP_CHKSUM(rx_tlv); QDF_NBUF_CB_RX_TCP_SEQ_NUM(msdu) = @@ -959,15 +948,15 @@ static void dp_rx_lro(uint8_t *rx_tlv, struct dp_peer *peer, HAL_RX_TLV_GET_TCP_OFFSET(rx_tlv); QDF_NBUF_CB_RX_FLOW_ID(msdu) = HAL_RX_TLV_GET_FLOW_ID_TOEPLITZ(rx_tlv); - QDF_NBUF_CB_RX_LRO_CTX(msdu) = (unsigned char *)ctx; + dp_rx_print_offload_info(rx_tlv); } #else -static void dp_rx_lro(uint8_t *rx_tlv, struct dp_peer *peer, - qdf_nbuf_t msdu, qdf_lro_ctx_t ctx) +static void dp_rx_fill_gro_info(struct dp_soc *soc, uint8_t *rx_tlv, + qdf_nbuf_t msdu) { } -#endif +#endif /* RECEIVE_OFFLOAD */ /** * dp_rx_adjust_nbuf_len() - set appropriate msdu length in nbuf. @@ -1756,7 +1745,7 @@ done: } } - dp_rx_lro(rx_tlv_hdr, peer, nbuf, int_ctx->lro_ctx); + dp_rx_fill_gro_info(soc, rx_tlv_hdr, nbuf); qdf_nbuf_cb_update_peer_local_id(nbuf, peer->local_id); DP_RX_LIST_APPEND(deliver_list_head, deliver_list_tail, diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 8980efa4e5..aed9e5ace1 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1482,7 +1482,6 @@ struct dp_vdev { /* VDEV Stats */ struct cdp_vdev_stats stats; - bool lro_enable; /* Is this a proxySTA VAP */ bool proxysta_vdev; diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index f0242caeb2..4fb3487f59 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -721,6 +721,11 @@ int wlan_cfg_get_num_mac_rings(struct wlan_cfg_dp_pdev_ctxt *cfg) return cfg->num_mac_rings; } +bool wlan_cfg_is_gro_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->gro_enabled; +} + bool wlan_cfg_is_lro_enabled(struct wlan_cfg_dp_soc_ctxt *cfg) { return cfg->lro_enabled; diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index ea9c489946..ac7bfdc44e 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -740,6 +740,14 @@ int wlan_cfg_get_num_mac_rings(struct wlan_cfg_dp_pdev_ctxt *cfg); */ bool wlan_cfg_is_lro_enabled(struct wlan_cfg_dp_soc_ctxt *cfg); +/* + * wlan_cfg_is_gro_enabled - Return GRO enabled/disabled + * @wlan_cfg_dp_soc_ctxt + * + * Return: true - GRO enabled false - GRO disabled + */ +bool wlan_cfg_is_gro_enabled(struct wlan_cfg_dp_soc_ctxt *cfg); + /* * wlan_cfg_is_rx_hash_enabled - Return RX hash enabled/disabled * @wlan_cfg_dp_soc_ctxt