Pārlūkot izejas kodu

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
Aditya Kodukula 3 gadi atpakaļ
vecāks
revīzija
6a5c5db59d

+ 15 - 0
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_ */

+ 5 - 0
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,

+ 11 - 0
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

+ 154 - 1
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);
 }