From 6a5c5db59d60d3591e1c1aeaf15fa77f388ee01e Mon Sep 17 00:00:00 2001 From: Aditya Kodukula Date: Tue, 7 Sep 2021 23:37:34 -0700 Subject: [PATCH] qcacmn: Add Support to offload icmp feature to fw Send command with required parameters to offload icmp feature to fw. Change-Id: Iefac64a34e274830f0c1c82589b2f35817306a64 CRs-Fixed: 3042454 --- wmi/inc/wmi_unified_pmo_api.h | 15 ++++ wmi/inc/wmi_unified_priv.h | 5 ++ wmi/src/wmi_unified_pmo_api.c | 11 +++ wmi/src/wmi_unified_pmo_tlv.c | 155 +++++++++++++++++++++++++++++++++- 4 files changed, 185 insertions(+), 1 deletion(-) diff --git a/wmi/inc/wmi_unified_pmo_api.h b/wmi/inc/wmi_unified_pmo_api.h index 769caa034f..e32e6935ec 100644 --- a/wmi/inc/wmi_unified_pmo_api.h +++ b/wmi/inc/wmi_unified_pmo_api.h @@ -399,4 +399,19 @@ QDF_STATUS wmi_unified_send_igmp_offload_cmd(wmi_unified_t wmi_handle, struct pmo_igmp_offload_req *pmo_igmp_req); #endif + +#ifdef WLAN_FEATURE_ICMP_OFFLOAD +/** + * wmi_unified_config_icmp_offload_cmd() - enable ICMP offload + * @wmi_hdl: wmi handle + * @pmo_icmp_req: icmp offload request + * + * To configure ICMP offload data to firmware + * when target goes to wow mode. + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_config_icmp_offload_cmd(wmi_unified_t wmi_handle, + struct pmo_icmp_offload *pmo_icmp_req); +#endif #endif /* _WMI_UNIFIED_PMO_API_H_ */ diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 1de890fd60..98f8b4b3bc 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -988,6 +988,11 @@ QDF_STATUS (*send_config_packet_filter_cmd)(wmi_unified_t wmi_handle, uint8_t vdev_id, struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param, uint8_t filter_id, bool enable); #endif + +#ifdef WLAN_FEATURE_ICMP_OFFLOAD +QDF_STATUS (*send_icmp_offload_config_cmd)(wmi_unified_t wmi_handle, + struct pmo_icmp_offload *pmo_icmp_req); +#endif #endif /* end of WLAN_POWER_MANAGEMENT_OFFLOAD */ #ifdef WLAN_WMI_BCN QDF_STATUS (*send_bcn_buf_ll_cmd)(wmi_unified_t wmi_handle, diff --git a/wmi/src/wmi_unified_pmo_api.c b/wmi/src/wmi_unified_pmo_api.c index 85a28dea43..b7ba6660aa 100644 --- a/wmi/src/wmi_unified_pmo_api.c +++ b/wmi/src/wmi_unified_pmo_api.c @@ -361,3 +361,14 @@ QDF_STATUS wmi_unified_app_type1_params_in_fw_cmd( } #endif /* WLAN_FEATURE_EXTWOW_SUPPORT */ +#ifdef WLAN_FEATURE_ICMP_OFFLOAD +QDF_STATUS wmi_unified_config_icmp_offload_cmd(wmi_unified_t wmi_handle, + struct pmo_icmp_offload *pmo_icmp_req) +{ + if (wmi_handle->ops->send_icmp_offload_config_cmd) + return wmi_handle->ops->send_icmp_offload_config_cmd( + wmi_handle, pmo_icmp_req); + + return QDF_STATUS_E_FAILURE; +} +#endif diff --git a/wmi/src/wmi_unified_pmo_tlv.c b/wmi/src/wmi_unified_pmo_tlv.c index 3766e5d74c..9ffe773248 100644 --- a/wmi/src/wmi_unified_pmo_tlv.c +++ b/wmi/src/wmi_unified_pmo_tlv.c @@ -768,7 +768,7 @@ fill_fils_tlv_params(WMI_GTK_OFFLOAD_CMD_fixed_param *cmd, * @wmi_handle: wmi handle * @params: IGMP offload parameters * - * Return: CDF status + * Return: QDF status */ static QDF_STATUS send_igmp_offload_cmd_tlv(wmi_unified_t wmi_handle, @@ -2010,6 +2010,158 @@ void wmi_extwow_attach_tlv(struct wmi_unified *wmi_handle) } #endif /* WLAN_FEATURE_EXTWOW_SUPPORT */ +#ifdef WLAN_FEATURE_ICMP_OFFLOAD +/** + * send_icmp_ipv4_config_cmd_tlv() - send ICMP IPV4 offload command to fw + * @wmi_handle: wmi handle + * @pmo_icmp_req: ICMP offload parameters + * + * Return: QDF status + */ +static QDF_STATUS +send_icmp_ipv4_config_cmd_tlv(wmi_unified_t wmi_handle, + struct pmo_icmp_offload *pmo_icmp_req) +{ + wmi_buf_t buf; + wmi_icmp_offload_fixed_param *cmd; + uint16_t len = sizeof(*cmd); + QDF_STATUS status; + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + wmi_err_rl("Failed to allocate wmi buffer"); + status = QDF_STATUS_E_NOMEM; + return status; + } + cmd = (wmi_icmp_offload_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_icmp_offload_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_icmp_offload_fixed_param)); + + cmd->vdev_id = pmo_icmp_req->vdev_id; + cmd->enable = pmo_icmp_req->enable; + cmd->valid_bitmask = 0; + + WMI_SET_ICMP_OFFLOAD_IPV4_ENABLED_BIT(cmd->valid_bitmask); + qdf_mem_copy(&cmd->ipv4_addr, pmo_icmp_req->ipv4_addr, + QDF_IPV4_ADDR_SIZE); + wmi_debug("ipv4:%pI4", &cmd->ipv4_addr); + + wmi_mtrace(WMI_VDEV_ICMP_OFFLOAD_CMDID, cmd->vdev_id, 0); + status = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_VDEV_ICMP_OFFLOAD_CMDID); + + if (QDF_IS_STATUS_ERROR(status)) + wmi_buf_free(buf); + + return status; +} + +/** + * send_icmp_ipv6_config_cmd_tlv() - send ICMP IPV6 offload command to fw + * @wmi_handle: wmi handle + * @pmo_icmp_req: ICMP offload parameters + * + * Return: QDF status + */ +static QDF_STATUS +send_icmp_ipv6_config_cmd_tlv(wmi_unified_t wmi_handle, + struct pmo_icmp_offload *pmo_icmp_req) +{ + wmi_buf_t buf; + uint8_t *buf_ptr; + uint16_t len; + int i; + WMI_IPV6_ADDR *ipv6_list; + wmi_icmp_offload_fixed_param *cmd; + QDF_STATUS status; + + len = sizeof(wmi_icmp_offload_fixed_param) + WMI_TLV_HDR_SIZE + + (pmo_icmp_req->ipv6_count) * sizeof(WMI_IPV6_ADDR); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) { + wmi_err_rl("Failed to allocate wmi buffer"); + status = QDF_STATUS_E_NOMEM; + return status; + } + + buf_ptr = (uint8_t *)wmi_buf_data(buf); + cmd = (wmi_icmp_offload_fixed_param *)wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_icmp_offload_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_icmp_offload_fixed_param)); + + cmd->vdev_id = pmo_icmp_req->vdev_id; + cmd->enable = pmo_icmp_req->enable; + cmd->valid_bitmask = 0; + + WMI_SET_ICMP_OFFLOAD_IPV6_ENABLED_BIT(cmd->valid_bitmask); + buf_ptr += sizeof(*cmd); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_FIXED_STRUC, + sizeof(WMI_IPV6_ADDR) * pmo_icmp_req->ipv6_count); + ipv6_list = (WMI_IPV6_ADDR *)(buf_ptr + WMI_TLV_HDR_SIZE); + + for (i = 0; i < pmo_icmp_req->ipv6_count; i++) { + qdf_mem_copy(((*(ipv6_list + i)).address), + &pmo_icmp_req->ipv6_addr[i], + sizeof(WMI_IPV6_ADDR)); + wmi_debug("ipv6_list[%d]:%pI6", i, (ipv6_list + i)); + } + + /* send the wmi command */ + wmi_mtrace(WMI_VDEV_ICMP_OFFLOAD_CMDID, cmd->vdev_id, 0); + status = wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_VDEV_ICMP_OFFLOAD_CMDID); + + if (QDF_IS_STATUS_ERROR(status)) + wmi_buf_free(buf); + + return status; +} + +/** + * send_icmp_offload_config_cmd_tlv() - send ICMP offload command to fw + * @wmi_handle: wmi handle + * @pmo_icmp_req: ICMP offload parameters + * + * Return: QDF status + */ +static QDF_STATUS +send_icmp_offload_config_cmd_tlv(wmi_unified_t wmi_handle, + struct pmo_icmp_offload *pmo_icmp_req) +{ + QDF_STATUS status; + + switch (pmo_icmp_req->trigger) { + case pmo_ipv4_change_notify: + status = send_icmp_ipv4_config_cmd_tlv(wmi_handle, + pmo_icmp_req); + break; + case pmo_ipv6_change_notify: + status = send_icmp_ipv6_config_cmd_tlv(wmi_handle, + pmo_icmp_req); + break; + default: + QDF_DEBUG_PANIC("Invalid ICMP trigger %d", + pmo_icmp_req->trigger); + status = QDF_STATUS_E_FAILURE; + } + + return status; +} + +static void wmi_icmp_offload_config_tlv(struct wmi_unified *wmi_handle) +{ + struct wmi_ops *ops = wmi_handle->ops; + + ops->send_icmp_offload_config_cmd = send_icmp_offload_config_cmd_tlv; +} +#else +static inline void wmi_icmp_offload_config_tlv(struct wmi_unified *wmi_handle) +{} +#endif /* WLAN_FEATURE_ICMP_OFFLOAD */ + void wmi_pmo_attach_tlv(wmi_unified_t wmi_handle) { struct wmi_ops *ops = wmi_handle->ops; @@ -2045,4 +2197,5 @@ void wmi_pmo_attach_tlv(wmi_unified_t wmi_handle) wmi_lphb_attach_tlv(wmi_handle); wmi_packet_filtering_attach_tlv(wmi_handle); wmi_extwow_attach_tlv(wmi_handle); + wmi_icmp_offload_config_tlv(wmi_handle); }