wlan: Add Dhcp server offload feature

Add support to set the dhcp server offload.
dhcp info such as DHCP enable, server ip address,
number of clients, and start address of dhcp pool
will be sent to firmware.

Change-Id: Id24c355820287d77b0e4200b86b42fe80e6cd4f8
CRs-Fixed: 1091422
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index 6cb743b..da7c8c2 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -2491,6 +2491,74 @@
    vos_mem_free(configParam);
    return VOS_STATUS_E_FAILURE;
 }
+
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wda_dhcp_server_offload_rsp_callback() - response to the dhcp server offload
+ * @wdi_rsp: pointer to the dhcp server offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_dhcp_server_offload_rsp_callback(wdi_dhcp_server_offload_rsp_param_t*
+					  wdi_rsp,
+					  void* user_data)
+{
+	tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+	sir_dhcp_srv_offload_info_t *dhcp_srv_offload_info;
+	VOS_STATUS status;
+
+	VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+		   "<------ %s " ,__func__);
+
+	if(NULL == wda_params)
+	{
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: pWdaParams received NULL", __func__);
+		VOS_ASSERT(0);
+		return;
+	}
+
+	if(NULL == wda_params->wdaMsgParam)
+	{
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: pWdaParams->wdaMsgParam is NULL", __func__);
+		VOS_ASSERT(0);
+		vos_mem_free(wda_params->wdaWdiApiMsgParam);
+		vos_mem_free(wda_params);
+		return;
+	}
+
+	dhcp_srv_offload_info = (sir_dhcp_srv_offload_info_t *)
+		wda_params->wdaMsgParam;
+
+	if(dhcp_srv_offload_info->dhcp_offload_callback)
+	{
+	   dhcp_srv_offload_info->dhcp_offload_callback(
+				    dhcp_srv_offload_info->dhcp_server_offload_cb_context,
+				    CONVERT_WDI2VOS_STATUS(wdi_rsp->status));
+	}
+	else
+	{
+	   VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+		   "%s: pFWLoggingInitParams callback is NULL", __func__);
+	}
+
+	status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+	if (status)
+	{
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: DHCP server offload failed with status=%d", __func__, status);
+		VOS_ASSERT(0);
+	}
+
+	vos_mem_free(wda_params->wdaWdiApiMsgParam);
+	vos_mem_free(wda_params->wdaMsgParam);
+	vos_mem_free(wda_params);
+	return;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
 /*
  * FUNCTION: WDA_wdiCompleteCB
  * call the voss call back function
@@ -15506,6 +15574,90 @@
     return WLANTL_SuspendDataTx(pWDA->pVosContext, &staId, NULL);
 }
 
+#ifdef DHCP_SERVER_OFFLOAD
+/**
+ * wda_process_dhcpserver_offload_req() - wda api to set dhcp server offload
+ * @wda_handle: pointer to wda handle
+ * @dhcp_server_offload_info: dhcp server offload info
+ *
+ * Return: status
+ *	0 - success or else failure
+ */
+static int wda_process_dhcpserver_offload_req(tWDA_CbContext *wda_handle,
+					  sir_dhcp_srv_offload_info_t
+					  *dhcp_server_offload_info)
+{
+	wdi_set_dhcp_server_offload_t *dhcp_info;
+	tWDA_ReqParams *wda_params;
+	WDI_Status wstatus;
+	VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+	VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+		  FL("---> %s"), __func__);
+
+	if(NULL == dhcp_server_offload_info)
+	{
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: dhcp_server_offload_info received NULL",
+			  __func__);
+		VOS_ASSERT(0) ;
+		return VOS_STATUS_E_FAULT;
+	}
+
+	dhcp_info = (wdi_set_dhcp_server_offload_t *)
+		vos_mem_malloc(sizeof(*dhcp_info));
+	if (!dhcp_info) {
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "Failed to allocate buffer to send "
+			  "set_dhcp_server_offload cmd");
+		vos_mem_free(dhcp_server_offload_info);
+		return VOS_STATUS_E_NOMEM;
+	}
+
+	vos_mem_zero(dhcp_info, sizeof(*dhcp_info));
+
+	wda_params = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+	if(NULL == wda_params)
+	{
+		VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			  "%s: VOS MEM Alloc Failure", __func__);
+		VOS_ASSERT(0);
+		vos_mem_free(dhcp_info);
+		vos_mem_free(dhcp_server_offload_info);
+		return VOS_STATUS_E_NOMEM;
+	}
+
+	dhcp_info->bssidx = dhcp_server_offload_info->bssidx;
+	dhcp_info->enable = dhcp_server_offload_info->dhcp_srv_offload_enabled;
+	dhcp_info->num_client = dhcp_server_offload_info->dhcp_client_num;
+	dhcp_info->srv_ipv4 = dhcp_server_offload_info->dhcp_srv_ip;
+	dhcp_info->start_lsb = dhcp_server_offload_info->start_lsb;
+
+	wda_params->pWdaContext = wda_handle;
+	wda_params->wdaMsgParam = dhcp_server_offload_info;
+	wda_params->wdaWdiApiMsgParam = (void *)dhcp_info;
+
+	wstatus = wdi_process_dhcpserver_offload_req(dhcp_info,
+					(wdi_dhcp_srv_offload_rsp_cb)
+					 wda_dhcp_server_offload_rsp_callback,
+					 wda_params);
+	if(IS_WDI_STATUS_FAILURE(wstatus))
+	{
+		VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+			   "Failed to send set_dhcp_server_offload cmd" );
+		status = CONVERT_WDI2VOS_STATUS(wstatus);
+		vos_mem_free(wda_params->wdaWdiApiMsgParam) ;
+		vos_mem_free(wda_params->wdaMsgParam);
+		vos_mem_free(wda_params);
+	}
+
+	VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+		  "Set dhcp server offload");
+	return status;
+}
+#endif /* DHCP_SERVER_OFFLOAD */
+
+
 /*
  * FUNCTION: WDA_McProcessMsg
  * Trigger DAL-AL to start CFG download 
@@ -16431,6 +16583,15 @@
          WDA_ProcessEncryptMsgReq(pWDA, (u8 *)pMsg->bodyptr);
          break;
       }
+#ifdef DHCP_SERVER_OFFLOAD
+      case WDA_SET_DHCP_SERVER_OFFLOAD_REQ:
+      {
+         wda_process_dhcpserver_offload_req(pWDA,
+              (sir_dhcp_srv_offload_info_t *)pMsg->bodyptr);
+         break;
+      }
+#endif /* DHCP_SERVER_OFFLOAD */
+
 
       case WDA_NAN_REQUEST:
       {