wlan: Add mDNS server offload feature

Add support to set the mDNS server offload.
mDNS info such as mDNS enable, FQDN query,
UFQDN Query, Responses for TXT, PTR, A, Ipv4 address type
of queries firmware.

Change-Id: I9036e54ff7902309018cc131fd3bb60147381969
CRs-Fixed: 1099420
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index ea652f4..5b0c047 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -2776,6 +2776,76 @@
 #define CFG_DHCP_SERVER_IP_DEFAULT  "192.168.1.2"
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+/*
+ * Enable/Disable multicast DNS Offload
+ * 0x0 - Disable mDNS (Default)
+ * 0x1 - Enable mDNS
+ */
+#define CFG_MDNS_OFFLOAD_SUPPORT_NAME         "gMDNSOffloadEnable"
+#define CFG_MDNS_OFFLOAD_SUPPORT_MIN          ( 0 )
+#define CFG_MDNS_OFFLOAD_SUPPORT_MAX          ( 1 )
+#define CFG_MDNS_OFFLOAD_SUPPORT_ENABLE       ( 1 )
+#define CFG_MDNS_OFFLOAD_SUPPORT_DEFAULT      ( 1 )
+
+/* Set FQDN string for mDNS */
+#define CFG_MDNS_FQDN_NAME                    "gMDNSFqdn"
+#define CFG_MDNS_FQDN_DEFAULT                 "_GoProRemote._tcp.local"
+
+/* Set UFQDN string for mDNS */
+#define CFG_MDNS_UNIQUE_FQDN_NAME             "gMDNSUniqueFqdn"
+#define CFG_MDNS_UNIQUE_FQDN_DEFAULT          "service._GoProRemote._tcp.local"
+
+/* Set the response Type A to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_A_NAME         "gMDNSResponseTypeA"
+#define CFG_MDNS_RESPONSE_TYPE_A_DEFAULT      "goprobp-D89685121212.local"
+
+#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_NAME    "gMDNSResponseTypeAIpv4Addr"
+#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_MIN     ( 1 )
+#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_MAX     ( 0xffffffff )
+#define CFG_MDNS_RESPONSE_TYPE_A_IPV4_DEFAULT ( 0xc0a80102 )
+
+/* Set the response Type TXT to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_TXT_NAME       "gMDNSResponseTypeTXT"
+#define CFG_MDNS_RESPONSE_TYPE_TXT_DEFAULT    "GoProBP-D89685121212._GoProRemote._tcp.local"
+
+#define CFG_MDNS_RESPONSE_TYPE_TXT_CNT_NAME    "gMDNSResponseTypeTXTContent"
+#define CFG_MDNS_RESPONSE_TYPE_TXT_CNT_DEFAULT "Device=HERO 3+-BAWA Model=BAWA Version=HD3.11.02.00 Wifi Version=4.0.36.0 Protocol Version=2"
+
+/* Set the response Type PTR to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_PTR_NAME       "gMDNSResponseTypePTR"
+#define CFG_MDNS_RESPONSE_TYPE_PTR_DEFAULT    "_GoProRemote._tcp.local"
+
+#define CFG_MDNS_RESPONSE_TYPE_PTR_DN_NAME    "gMDNSResponseTypePTRDomainName"
+#define CFG_MDNS_RESPONSE_TYPE_PTR_DN_DEFAULT "GoProBP-D89685121212._GoProRemote._tcp.local"
+
+/* Set the response Type SRV to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_NAME       "gMDNSResponseTypeSRV"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_DEFAULT    "GoProBP-D89685121212._GoProRemote._tcp.local"
+
+/* Set the response Type SRV Priority to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_NAME    "gMDNSResponseTypeSRVPriority"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MIN     ( 0 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MAX     ( 65535 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_DEFAULT ( 0 )
+
+/* Set the response Type SRV Weight to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_NAME    "gMDNSResponseTypeSRVWeight"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MIN     ( 0 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MAX     ( 65525 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_DEFAULT ( 0 )
+
+/* Set the response Type SRV Port to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_NAME    "gMDNSResponseTypeSRVPort"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MIN     ( 0 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MAX     ( 65525 )
+#define CFG_MDNS_RESPONSE_TYPE_SRV_PORT_DEFAULT ( 80 )
+
+/* Set the response Type SRV Target to mDNS queries */
+#define CFG_MDNS_RESPONSE_TYPE_SRV_TGT_NAME    "gMDNSResponseTypeSRVTarget"
+#define CFG_MDNS_RESPONSE_TYPE_SRV_TGT_DEFAULT "goprobp-D89685121212.local"
+#endif /* MDNS_OFFLOAD */
+
 /*
  * gExtScanConcMode is used to manage EXT Scan during concurrency
  * This can be useful during WFD session. To avoid glitches during WFD
@@ -3522,6 +3592,22 @@
    v_U8_t                      dhcp_srv_ip[IPADDR_STRING_LENGTH];
    v_U8_t                      dhcp_start_lsb;
 #endif  /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+   uint32_t                    enable_mdns_offload;
+   uint8_t                     mdns_fqdn[MAX_MDNS_FQDN_LEN];
+   uint8_t                     mdns_uniquefqdn[MAX_MDNS_FQDN_LEN];
+   uint8_t                     mdns_resp_type_a[MAX_MDNS_RESP_LEN];
+   uint32_t                    mdns_resp_type_a_ipv4;
+   uint8_t                     mdns_resp_type_txt[MAX_MDNS_RESP_LEN];
+   uint8_t                     mdns_resp_type_txt_content[MAX_MDNS_RESP_LEN];
+   uint8_t                     mdns_resp_type_ptr[MAX_MDNS_RESP_LEN];
+   uint8_t                     mdns_resp_type_ptr_dname[MAX_MDNS_RESP_LEN];
+   uint8_t                     mdns_resp_type_srv[MAX_MDNS_RESP_LEN];
+   uint16_t                    mdns_resp_type_srv_priority;
+   uint16_t                    mdns_resp_type_srv_weight;
+   uint16_t                    mdns_resp_type_srv_port;
+   uint8_t                     mdns_resp_type_srv_target[MAX_MDNS_RESP_LEN];
+#endif  /* MDNS_OFFLOAD */
    uint32_t                    enable_edca_params;
    uint32_t                    edca_vo_cwmin;
    uint32_t                    edca_vi_cwmin;
@@ -3561,6 +3647,13 @@
 VOS_STATUS hdd_string_to_u8_array(char *str, tANI_U8 *intArray, tANI_U8 *len,
 				  tANI_U8 intArrayMaxLen, char *seperator);
 
+#ifdef MDNS_OFFLOAD
+int hdd_string_to_string_array(char *data, uint8_t *datalist,
+                                      char separator, uint8_t *num_entries,
+                                      uint8_t max_entries,
+                                      uint8_t max_len_entry);
+#endif /* MDNS_OFFLOAD */
+
 #define VAR_OFFSET( _Struct, _Var ) (offsetof(_Struct, _Var))
 #define VAR_SIZE( _Struct, _Var ) (sizeof(((_Struct *)0)->_Var))
 
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index da10694..223ba13 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -245,6 +245,23 @@
 
 #define HDD_MAX_STA_COUNT (HAL_NUM_STA)
 
+#ifdef MDNS_OFFLOAD
+#define MDNS_HEADER_LEN                           12
+#define MDNS_FQDN_TYPE_GENERAL                    0
+#define MDNS_FQDN_TYPE_UNIQUE                     1
+#define MAX_NUM_FIELD_DOMAINNAME                  6
+#define MAX_LEN_DOMAINNAME_FIELD                  64
+#define MAX_MDNS_RESP_TYPE                        6
+#define MDNS_TYPE_A                               1
+#define MDNS_TYPE_TXT                             16
+#define MDNS_TYPE_PTR                             12
+#define MDNS_TYPE_PTR_DNAME                       13
+#define MDNS_TYPE_SRV                             33
+#define MDNS_TYPE_SRV_TARGET                      34
+#define MDNS_CLASS                                1
+#define MDNS_TTL                                  5
+#endif /* MDNS_OFFLOAD */
+
 /*
  * Generic asynchronous request/response support
  *
@@ -784,6 +801,15 @@
 } hdd_dhcp_state_t;
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+typedef struct hdd_mdns_state_s
+{
+    VOS_STATUS mdns_enable_status;
+    VOS_STATUS mdns_fqdn_status;
+    VOS_STATUS mdns_resp_status;
+    vos_event_t vos_event;
+} hdd_mdns_state_t;
+#endif /* MDNS_OFFLOAD */
 
 /*
  * Per station structure kept in HDD for multiple station support for SoftAP
@@ -1223,6 +1249,9 @@
 #ifdef DHCP_SERVER_OFFLOAD
    hdd_dhcp_state_t dhcp_status;
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+    hdd_mdns_state_t mdns_status;
+#endif /* MDNS_OFFLOAD */
 };
 
 #define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station)
@@ -1709,6 +1738,20 @@
    WLAN_FW_MEM_DUMP_EN = 1<<6,
 } WLAN_ENABLE_HW_FW_LOG_TYPE;
 
+#ifdef MDNS_OFFLOAD
+/* Offload struct */
+struct hdd_mdns_resp_info {
+    uint8_t num_entries;
+    uint8_t *data;
+    uint16_t *offset;
+};
+
+struct hdd_mdns_resp_matched {
+    uint8_t num_matched;
+    uint8_t type;
+};
+#endif /* MDNS_OFFLOAD */
+
 /*--------------------------------------------------------------------------- 
   Function declarations and documenation
   -------------------------------------------------------------------------*/
@@ -1979,4 +2022,12 @@
                                 unsigned long delay);
 int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid,
 			const tANI_U8 channel, const handoff_src src);
+#ifdef MDNS_OFFLOAD
+bool wlan_hdd_set_mdns_offload(hdd_adapter_t *adapter);
+#else
+static inline bool wlan_hdd_set_mdns_offload(hdd_adapter_t *adapter)
+{
+    return FALSE;
+}
+#endif /* MDNS_OFFLOAD */
 #endif    // end #if !defined( WLAN_HDD_MAIN_H )
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 307c467..8f26b7e 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -3816,6 +3816,88 @@
                 CFG_MAX_SCHED_SCAN_PLAN_ITRNS_DEFAULT,
                 CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MIN,
                 CFG_MAX_SCHED_SCAN_PLAN_ITRNS_MAX),
+
+#ifdef MDNS_OFFLOAD
+  REG_VARIABLE( CFG_MDNS_OFFLOAD_SUPPORT_NAME, WLAN_PARAM_Integer,
+               hdd_config_t, enable_mdns_offload,
+               VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+               CFG_MDNS_OFFLOAD_SUPPORT_DEFAULT,
+               CFG_MDNS_OFFLOAD_SUPPORT_MIN,
+               CFG_MDNS_OFFLOAD_SUPPORT_MAX ),
+
+  REG_VARIABLE_STRING( CFG_MDNS_FQDN_NAME, WLAN_PARAM_String,
+               hdd_config_t, mdns_fqdn,
+               VAR_FLAGS_OPTIONAL,
+               (void *) CFG_MDNS_FQDN_DEFAULT ),
+
+  REG_VARIABLE_STRING( CFG_MDNS_UNIQUE_FQDN_NAME, WLAN_PARAM_String,
+               hdd_config_t, mdns_uniquefqdn,
+               VAR_FLAGS_OPTIONAL,
+               (void *) CFG_MDNS_UNIQUE_FQDN_DEFAULT ),
+
+  REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_A_NAME, WLAN_PARAM_String,
+               hdd_config_t, mdns_resp_type_a,
+               VAR_FLAGS_OPTIONAL,
+               (void *) CFG_MDNS_RESPONSE_TYPE_A_DEFAULT ),
+
+  REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_A_IPV4_NAME, WLAN_PARAM_HexInteger,
+               hdd_config_t, mdns_resp_type_a_ipv4,
+               VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+               CFG_MDNS_RESPONSE_TYPE_A_IPV4_DEFAULT,
+               CFG_MDNS_RESPONSE_TYPE_A_IPV4_MIN,
+               CFG_MDNS_RESPONSE_TYPE_A_IPV4_MAX ),
+
+  REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_TXT_NAME, WLAN_PARAM_String,
+               hdd_config_t, mdns_resp_type_txt,
+               VAR_FLAGS_OPTIONAL,
+               (void *) CFG_MDNS_RESPONSE_TYPE_TXT_DEFAULT ),
+
+  REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_TXT_CNT_NAME, WLAN_PARAM_String,
+               hdd_config_t, mdns_resp_type_txt_content,
+               VAR_FLAGS_OPTIONAL,
+               (void *) CFG_MDNS_RESPONSE_TYPE_TXT_CNT_DEFAULT ),
+
+  REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_PTR_NAME, WLAN_PARAM_String,
+               hdd_config_t, mdns_resp_type_ptr,
+               VAR_FLAGS_OPTIONAL,
+               (void *) CFG_MDNS_RESPONSE_TYPE_PTR_DEFAULT ),
+
+  REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_PTR_DN_NAME, WLAN_PARAM_String,
+               hdd_config_t, mdns_resp_type_ptr_dname,
+               VAR_FLAGS_OPTIONAL,
+               (void *) CFG_MDNS_RESPONSE_TYPE_PTR_DN_DEFAULT ),
+
+  REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_SRV_NAME, WLAN_PARAM_String,
+               hdd_config_t, mdns_resp_type_srv,
+               VAR_FLAGS_OPTIONAL,
+               (void *) CFG_MDNS_RESPONSE_TYPE_SRV_DEFAULT ),
+
+  REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_NAME, WLAN_PARAM_Integer,
+               hdd_config_t, mdns_resp_type_srv_priority,
+               VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+               CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_DEFAULT,
+               CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MIN,
+               CFG_MDNS_RESPONSE_TYPE_SRV_PRIORITY_MAX ),
+
+  REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_NAME, WLAN_PARAM_Integer,
+               hdd_config_t, mdns_resp_type_srv_weight,
+               VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+               CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_DEFAULT,
+               CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MIN,
+               CFG_MDNS_RESPONSE_TYPE_SRV_WEIGHT_MAX ),
+
+  REG_VARIABLE( CFG_MDNS_RESPONSE_TYPE_SRV_PORT_NAME, WLAN_PARAM_Integer,
+               hdd_config_t, mdns_resp_type_srv_port,
+               VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+               CFG_MDNS_RESPONSE_TYPE_SRV_PORT_DEFAULT,
+               CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MIN,
+               CFG_MDNS_RESPONSE_TYPE_SRV_PORT_MAX ),
+
+  REG_VARIABLE_STRING( CFG_MDNS_RESPONSE_TYPE_SRV_TGT_NAME, WLAN_PARAM_String,
+               hdd_config_t, mdns_resp_type_srv_target,
+               VAR_FLAGS_OPTIONAL,
+               (void *) CFG_MDNS_RESPONSE_TYPE_SRV_TGT_DEFAULT ),
+#endif /* MDNS_OFFLOAD */
 };
 
 /*
@@ -4367,6 +4449,51 @@
            "Name = [gDHCPStartLsb] Value = [%u]",
                    pHddCtx->cfg_ini->dhcp_start_lsb);
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSOffloadEnable] Value = [%u]",
+                   pHddCtx->cfg_ini->enable_mdns_offload);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSFqdn] Value = [%s]",
+                   pHddCtx->cfg_ini->mdns_fqdn);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSUniqueFqdn] Value = [%s]",
+                   pHddCtx->cfg_ini->mdns_uniquefqdn);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypeA] Value = [%s]",
+                   pHddCtx->cfg_ini->mdns_resp_type_a);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypeAIpv4Addr] Value = [%u]",
+                   pHddCtx->cfg_ini->mdns_resp_type_a_ipv4);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypeTXT] Value = [%s]",
+                   pHddCtx->cfg_ini->mdns_resp_type_txt);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypeTXTContent] Value = [%s]",
+                   pHddCtx->cfg_ini->mdns_resp_type_txt_content);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypePTR] Value = [%s]",
+                   pHddCtx->cfg_ini->mdns_resp_type_ptr);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypePTRDomainName] Value = [%s]",
+                   pHddCtx->cfg_ini->mdns_resp_type_ptr_dname);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypeSRV] Value = [%s]",
+                   pHddCtx->cfg_ini->mdns_resp_type_srv);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypeSRVPriority] Value = [%u]",
+                   pHddCtx->cfg_ini->mdns_resp_type_srv_priority);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypeSRVWeight] Value = [%u]",
+                   pHddCtx->cfg_ini->mdns_resp_type_srv_weight);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypeSRVPort] Value = [%u]",
+                   pHddCtx->cfg_ini->mdns_resp_type_srv_port);
+  VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+           "Name = [gMDNSResponseTypeSRVTarget] Value = [%s]",
+                   pHddCtx->cfg_ini->mdns_resp_type_srv_target);
+#endif /* MDNS_OFFLOAD */
+
 
   VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
           "Name = [gPERRoamFullScanThreshold] Value = [%u] ",
@@ -4954,6 +5081,47 @@
 
 }
 
+#ifdef MDNS_OFFLOAD
+int hdd_string_to_string_array(char *data, uint8_t *datalist,
+                      char separator, uint8_t *num_entries,
+                      uint8_t max_entries,
+                      uint8_t max_len_entry)
+{
+    uint8_t num = 0;
+    char *str = data;
+    char *field;
+    uint16_t len = 0;
+
+    if ((data == NULL) || ( datalist == NULL) || (num_entries == NULL))
+        return VOS_STATUS_E_INVAL;
+
+    /* parse the string */
+    while (str && ('\0' != *str) && (num < max_entries)) {
+        field = str;
+        while (str && ('\0' != *str) && (separator != *str))
+            str++;
+        if ('\0' == *str) {
+            /* reach the end of string */
+            if ('\0' != *field) {
+                strlcpy((char *)(datalist +
+                         (num * max_len_entry)),
+                    field, max_len_entry);
+                num++;
+            }
+            break;
+        }
+        /* replace separator with NULL to terminate the data */
+        *str++ = '\0';
+        len = (char *)str - (char *)field;
+        strlcpy((char *)(datalist + (num * max_len_entry)),
+            field, len);
+        num++;
+    }
+    *num_entries = num;
+
+    return 0;
+}
+#endif /* MDNS_OFFLOAD */
 
 v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
 {
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index dbcd369..c94c37d 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -9820,6 +9820,37 @@
                      pHostapdAdapter->dhcp_status.dhcp_offload_status);
             return -EINVAL;
         }
+#ifdef MDNS_OFFLOAD
+        if (iniConfig->enable_mdns_offload) {
+            status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
+            if (VOS_IS_STATUS_SUCCESS(status))
+            {
+                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                          ("HDD MDNS Server Offload Failed!!"));
+                return -EINVAL;
+            }
+            vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
+            status = vos_wait_single_event(&pHostapdAdapter->
+                                           mdns_status.vos_event, 2000);
+            if (!VOS_IS_STATUS_SUCCESS(status) ||
+                pHostapdAdapter->mdns_status.mdns_enable_status ||
+                pHostapdAdapter->mdns_status.mdns_fqdn_status ||
+                pHostapdAdapter->mdns_status.mdns_resp_status)
+            {
+                VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                          ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
+                          pHostapdAdapter->mdns_status.mdns_enable_status,
+                          pHostapdAdapter->mdns_status.mdns_fqdn_status,
+                          pHostapdAdapter->mdns_status.mdns_resp_status);
+                return -EINVAL;
+            }
+        }
+#endif /* MDNS_OFFLOAD */
+    } else {
+        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                  ("DHCP Disabled ini %d, FW %d"),
+                  iniConfig->enable_dhcp_srv_offload,
+                  sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
     }
 #endif /* DHCP_SERVER_OFFLOAD */
 
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 7fffff6..b4fd06f 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -4828,6 +4828,9 @@
 #ifdef DHCP_SERVER_OFFLOAD
     hdd_dhcp_state_t *dhcp_status;
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+    hdd_mdns_state_t *mdns_status;
+#endif /* MDNS_OFFLOAD */
     struct net_device *dev = pAdapter->dev;
     hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
     VOS_STATUS status;
@@ -4854,6 +4857,9 @@
 #ifdef DHCP_SERVER_OFFLOAD
     dhcp_status = &pAdapter->dhcp_status;
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+    mdns_status = &pAdapter->mdns_status;
+#endif /* MDNS_OFFLOAD */
 
     spin_lock_init(&pAdapter->sta_hash_lock);
     pAdapter->is_sta_id_hash_initialized = VOS_FALSE;
@@ -4878,6 +4884,9 @@
 #ifdef DHCP_SERVER_OFFLOAD
     memset(dhcp_status, 0,sizeof(*dhcp_status));
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+    memset(mdns_status, 0,sizeof(*mdns_status));
+#endif /* MDNS_OFFLOAD */
 
     // Set up the pointer to the Wireless Extensions state structure
     // NOP
@@ -4900,6 +4909,15 @@
          return status;
     }
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+    status = vos_event_init(&mdns_status->vos_event);
+    if (!VOS_IS_STATUS_SUCCESS(status)) {
+         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                   ("Hostapd HDD vos event init failed!!"));
+         return status;
+    }
+#endif /* MDNS_OFFLOAD */
+
     sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
  
      // Register as a wireless device
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index f3c6f66..7536f9a 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -8969,6 +8969,9 @@
 #ifdef DHCP_SERVER_OFFLOAD
     vos_event_destroy(&adapter->dhcp_status.vos_event);
 #endif
+#ifdef MDNS_OFFLOAD
+    vos_event_destroy(&adapter->mdns_status.vos_event);
+#endif
     return VOS_STATUS_SUCCESS;
 }
 
@@ -14708,6 +14711,1457 @@
         return;
 }
 
+#ifdef MDNS_OFFLOAD
+
+/**
+ * hdd_mdns_enable_offload_done() - mdns enable offload response api
+ * @padapter: holds adapter
+ * @status: response status
+ *
+ * Return - None
+ */
+void hdd_mdns_enable_offload_done(void *padapter, VOS_STATUS status)
+{
+    hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
+
+    ENTER();
+
+    if (NULL == adapter)
+    {
+        hddLog(VOS_TRACE_LEVEL_ERROR,
+               "%s: adapter is NULL",__func__);
+        return;
+    }
+
+    adapter->mdns_status.mdns_enable_status = status;
+    vos_event_set(&adapter->mdns_status.vos_event);
+    return;
+}
+
+/**
+ * hdd_mdns_fqdn_offload_done() - mdns fqdn offload response api
+ * @padapter: holds adapter
+ * @status: responce status
+ *
+ * Return - None
+ */
+void hdd_mdns_fqdn_offload_done(void *padapter, VOS_STATUS status)
+{
+    hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
+
+    ENTER();
+
+    if (NULL == adapter)
+    {
+        hddLog(VOS_TRACE_LEVEL_ERROR,
+               "%s: adapter is NULL",__func__);
+        return;
+    }
+
+    adapter->mdns_status.mdns_fqdn_status = status;
+    return;
+}
+
+/**
+ * hdd_mdns_resp_offload_done() - mdns resp offload response api
+ * @padapter: holds adapter
+ * @status: responce status
+ *
+ * Return - None
+ */
+void hdd_mdns_resp_offload_done(void *padapter, VOS_STATUS status)
+{
+    hdd_adapter_t* adapter = (hdd_adapter_t*) padapter;
+
+    ENTER();
+
+    if (NULL == adapter)
+    {
+        hddLog(VOS_TRACE_LEVEL_ERROR,
+               "%s: adapter is NULL",__func__);
+        return;
+    }
+
+    adapter->mdns_status.mdns_resp_status = status;
+    return;
+}
+
+/**
+ * wlan_hdd_mdns_process_response_dname() - Process mDNS domain name
+ * @response: Pointer to a struct hdd_mdns_resp_info
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ *
+ * This function will pack the whole domain name without compression. It will
+ * add the leading len for each field and add zero length octet to terminate
+ * the domain name.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_process_response_dname(struct hdd_mdns_resp_info *response,
+                     sir_mdns_resp_info resp_info)
+{
+    uint8_t  num;
+    uint16_t idx;
+    uint8_t len = 0;
+
+    if ((response == NULL) || (response->data == NULL) ||
+        (response->offset == NULL)) {
+        hddLog(LOGE, FL("Either data or offset in response is NULL!"));
+        return FALSE;
+    }
+
+    if ((resp_info == NULL) ||
+        (resp_info->resp_len >= MAX_MDNS_RESP_LEN)) {
+        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+        return FALSE;
+    }
+
+    for (num = 0; num < response->num_entries; num++) {
+        response->offset[num] =
+                    resp_info->resp_len + MDNS_HEADER_LEN;
+        idx = num * MAX_LEN_DOMAINNAME_FIELD;
+        len = strlen((char *)&response->data[idx]);
+        if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
+            hddLog(LOGE, FL("resp_len exceeds %d!"),
+                MAX_MDNS_RESP_LEN);
+            return FALSE;
+                }
+        resp_info->resp_data[resp_info->resp_len] = len;
+        resp_info->resp_len++;
+        vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
+                &response->data[idx], len);
+        resp_info->resp_len += len;
+    }
+
+    /* The domain name terminates with the zero length octet */
+    if (num == response->num_entries) {
+        if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
+            hddLog(LOGE, FL("resp_len exceeds %d!"),
+                MAX_MDNS_RESP_LEN);
+            return FALSE;
+        }
+        resp_info->resp_data[resp_info->resp_len] = 0;
+        resp_info->resp_len++;
+    }
+
+    return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_format_response_u16() - Form uint16_t response data
+ * @value: The uint16_t value is formed to the struct tSirMDNSResponseInfo
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_format_response_u16(uint16_t value,
+                          sir_mdns_resp_info resp_info)
+{
+    uint8_t val_u8;
+
+    if ((resp_info == NULL) || (resp_info->resp_data == NULL))
+        return;
+    val_u8 = (value & 0xff00) >> 8;
+    resp_info->resp_data[resp_info->resp_len++] = val_u8;
+    val_u8 = value & 0xff;
+    resp_info->resp_data[resp_info->resp_len++] = val_u8;
+}
+
+/**
+ * wlan_hdd_mdns_format_response_u32() - Form uint32_t response data
+ * @value: The uint32_t value is formed to the struct tSirMDNSResponseInfo
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_format_response_u32(uint32_t value,
+                          sir_mdns_resp_info resp_info)
+{
+    uint8_t val_u8;
+
+    if ((resp_info == NULL) || (resp_info->resp_data == NULL))
+        return;
+    val_u8 = (value & 0xff000000) >> 24;
+    resp_info->resp_data[resp_info->resp_len++] = val_u8;
+    val_u8 = (value & 0xff0000) >> 16;
+    resp_info->resp_data[resp_info->resp_len++] = val_u8;
+    val_u8 = (value & 0xff00) >> 8;
+    resp_info->resp_data[resp_info->resp_len++] = val_u8;
+    val_u8 = value & 0xff;
+    resp_info->resp_data[resp_info->resp_len++] = val_u8;
+}
+
+/**
+ * wlan_hdd_mdns_process_response_misc() - Process misc info in mDNS response
+ * @resp_type: Response type for mDNS
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ *
+ * This function will pack the response type, class and TTL (Time To Live).
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool wlan_hdd_mdns_process_response_misc(uint16_t resp_type,
+                        sir_mdns_resp_info resp_info)
+{
+    uint16_t len;
+
+    if (resp_info == NULL) {
+        hddLog(LOGE, FL("resp_info is NULL!"));
+        return FALSE;
+    }
+
+    len = resp_info->resp_len + (2 * sizeof(uint16_t) + sizeof(uint32_t));
+    if (len >= MAX_MDNS_RESP_LEN) {
+        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+        return FALSE;
+    }
+
+    /* Fill Type, Class, TTL */
+    wlan_hdd_mdns_format_response_u16(resp_type, resp_info);
+    wlan_hdd_mdns_format_response_u16(MDNS_CLASS, resp_info);
+    wlan_hdd_mdns_format_response_u32(MDNS_TTL, resp_info);
+
+    return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_compress_data() - Compress the domain name in mDNS response
+ * @resp_info: Pointer to a struct tSirMDNSResponseInfo
+ * @response_dst: The response which domain name is compressed.
+ * @response_src: The response which domain name is matched with response_dst.
+ *                Its offset is used for data compression.
+ * @num_matched: The number of matched entries between response_dst and
+ *               response_src
+ *
+ * This function will form the different fields of domain name in response_dst
+ * if any. Then use the offset of the matched domain name in response_src to
+ * compress the matched domain name.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_compress_data(sir_mdns_resp_info resp_info,
+                struct hdd_mdns_resp_info *response_dst,
+                struct hdd_mdns_resp_info *response_src,
+                uint8_t num_matched)
+{
+    uint8_t  num, num_diff;
+    uint16_t value, idx;
+    uint8_t len = 0;
+
+    if ((response_src == NULL) || (response_dst == NULL) ||
+        (resp_info == NULL)) {
+        hddLog(LOGE, FL("response info is NULL!"));
+        return FALSE;
+    }
+
+    if (response_dst->num_entries < num_matched) {
+        hddLog(LOGE, FL("num_entries is less than num_matched!"));
+        return FALSE;
+    }
+
+    if (resp_info->resp_len >= MAX_MDNS_RESP_LEN) {
+        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+        return FALSE;
+    }
+
+    num_diff = response_dst->num_entries - num_matched;
+    if ((num_diff > 0) && (response_dst->data == NULL)) {
+        hddLog(LOGE, FL("response_dst->data is NULL!"));
+        return FALSE;
+    }
+
+    /*
+    * Handle the unmatched string at the beginning
+    * Store the length of octets and the octets
+    */
+    for (num = 0; num < num_diff; num++) {
+        response_dst->offset[num] =
+            resp_info->resp_len + MDNS_HEADER_LEN;
+        idx = num * MAX_LEN_DOMAINNAME_FIELD;
+        len = strlen((char *)&response_dst->data[idx]);
+        if ((resp_info->resp_len + len + 1) >= MAX_MDNS_RESP_LEN) {
+            hddLog(LOGE, FL("resp_len exceeds %d!"),
+                MAX_MDNS_RESP_LEN);
+            return FALSE;
+        }
+        resp_info->resp_data[resp_info->resp_len] = len;
+        resp_info->resp_len++;
+        vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
+            &response_dst->data[idx], len);
+        resp_info->resp_len += len;
+    }
+    /*
+    * Handle the matched string from the end
+    * Just keep the offset and mask the leading two bit
+    */
+    if (response_src->num_entries >= num_matched) {
+        num_diff = response_src->num_entries - num_matched;
+        value = response_src->offset[num_diff];
+        if (value > 0) {
+            value |= 0xc000;
+            if ((resp_info->resp_len + sizeof(uint16_t)) >=
+                MAX_MDNS_RESP_LEN) {
+                hddLog(LOGE, FL("resp_len exceeds %d!"),
+                    MAX_MDNS_RESP_LEN);
+                return FALSE;
+            }
+            wlan_hdd_mdns_format_response_u16(value, resp_info);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+/**
+ * wlan_hdd_mdns_reset_response() - Reset the response info
+ * @response: The response which info is reset.
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_reset_response(struct hdd_mdns_resp_info *response)
+{
+    if (response == NULL)
+        return;
+    response->num_entries = 0;
+    response->data = NULL;
+    response->offset = NULL;
+}
+
+/**
+ * wlan_hdd_mdns_init_response() - Initialize the response info
+ * @response: The response which info is initiatized.
+ * @resp_dname: The domain name string which might be tokenized.
+ *
+ * This function will allocate the memory for both response->data and
+ * response->offset. Besides, it will also tokenize the domain name to some
+ * entries and fill response->num_entries with the num of entries.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool wlan_hdd_mdns_init_response(struct hdd_mdns_resp_info *response,
+                    uint8_t *resp_dname, char separator)
+{
+    uint16_t size;
+
+    if ((resp_dname == NULL) || (response == NULL)) {
+        hddLog(LOGE, FL("resp_dname or response is NULL!"));
+        return FALSE;
+    }
+
+    size = MAX_NUM_FIELD_DOMAINNAME * MAX_LEN_DOMAINNAME_FIELD;
+    response->data = vos_mem_malloc(size);
+    if (response->data) {
+        vos_mem_zero(response->data, size);
+        if (VOS_STATUS_SUCCESS !=
+            hdd_string_to_string_array((char *)resp_dname,
+                        response->data,
+                        separator,
+                        &response->num_entries,
+                        MAX_NUM_FIELD_DOMAINNAME,
+                        MAX_LEN_DOMAINNAME_FIELD)) {
+            hddLog(LOGE, FL("hdd_string_to_string_array fail!"));
+            goto err_init_resp;
+        }
+
+        if ((response->num_entries > 0) &&
+            (strlen((char *)&response->data[0]) > 0)) {
+            size = sizeof(uint16_t) * response->num_entries;
+            response->offset = vos_mem_malloc(size);
+            if (response->offset) {
+                vos_mem_zero(response->offset, size);
+                return TRUE;
+            }
+        }
+    }
+
+err_init_resp:
+    if (response->data)
+        vos_mem_free(response->data);
+    wlan_hdd_mdns_reset_response(response);
+    return FALSE;
+}
+
+/**
+ * wlan_hdd_mdns_find_entries_from_end() - Find the matched entries
+ * @response1: The response info is used to be compared.
+ * @response2: The response info is used to be compared.
+ *
+ * This function will find the matched entries from the end.
+ *
+ * Return: Return the number of the matched entries.
+ */
+static uint8_t
+wlan_hdd_mdns_find_entries_from_end(struct hdd_mdns_resp_info *response1,
+                    struct hdd_mdns_resp_info *response2)
+{
+    uint8_t  min, len1, i;
+    uint16_t  num1, num2;
+    uint8_t num_matched = 0;
+
+    min = VOS_MIN(response1->num_entries, response2->num_entries);
+
+    for (i = 1; i <= min; i++) {
+        num1 = (response1->num_entries - i);
+        num1 *= MAX_LEN_DOMAINNAME_FIELD;
+        num2 = (response2->num_entries - i);
+        num2 *= MAX_LEN_DOMAINNAME_FIELD;
+        len1 = strlen((char *)&response1->data[num1]);
+
+        if ((len1 == 0) ||
+            (len1 != strlen((char *)&response2->data[num2])))
+            break;
+        if (memcmp(&response1->data[num1],
+            &response2->data[num2], len1))
+            break;
+        else
+            num_matched++;
+    }
+
+    return num_matched;
+}
+
+/**
+ * wlan_hdd_mdns_find_max() - Find the maximum number of the matched entries
+ * @matchedlist: Pointer to the array of struct hdd_mdns_resp_matched
+ * @numlist: The number of the elements in the array matchedlist.
+ *
+ * Find the max number of the matched entries among the array matchedlist.
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_find_max(struct hdd_mdns_resp_matched *matchedlist,
+                   uint8_t numlist)
+{
+    int j;
+    struct hdd_mdns_resp_matched tmp;
+
+    /* At least two values are used for sorting */
+    if ((numlist < 2) || (matchedlist == NULL)) {
+        hddLog(LOGE, FL("At least two values are used for sorting!"));
+        return;
+    }
+
+    for (j = 0; j < numlist-1; j++) {
+        if (matchedlist[j].num_matched >
+            matchedlist[j+1].num_matched) {
+            vos_mem_copy(&tmp, &matchedlist[j],
+                    sizeof(struct hdd_mdns_resp_matched));
+            vos_mem_copy(&matchedlist[j], &matchedlist[j+1],
+                    sizeof(struct hdd_mdns_resp_matched));
+            vos_mem_copy(&matchedlist[j+1], &tmp,
+                    sizeof(struct hdd_mdns_resp_matched));
+        }
+    }
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_a() - Pack Type A response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * Type A response include QName, response type, class, TTL and Ipv4.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_a(hdd_config_t *ini_config,
+                   sir_mdns_resp_info resp_info,
+                   struct hdd_mdns_resp_info *resptype_a)
+{
+    uint16_t value;
+    uint32_t len;
+
+    ENTER();
+    if ((ini_config == NULL) || (resp_info == NULL) ||
+        (resptype_a == NULL)) {
+        hddLog(LOGE, FL("ini_config or response info is NULL!"));
+        return FALSE;
+    }
+
+    /* No Type A response */
+    if (strlen((char *)ini_config->mdns_resp_type_a) <= 0)
+        return TRUE;
+
+    /* Wrong response is assigned, just ignore this response */
+    if (!wlan_hdd_mdns_init_response(resptype_a,
+                    ini_config->mdns_resp_type_a, '.'))
+        return TRUE;
+
+    /* Process response domain name */
+    if (!wlan_hdd_mdns_process_response_dname(resptype_a, resp_info)) {
+        hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+            MDNS_TYPE_A);
+        return FALSE;
+    }
+
+    /* Process response Type, Class, TTL */
+    if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_A, resp_info)) {
+        hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
+            MDNS_TYPE_A);
+        return FALSE;
+    }
+
+    /* Process response RDLength, RData */
+    len = sizeof(uint16_t) + sizeof(uint32_t);
+    len += resp_info->resp_len;
+    if (len >= MAX_MDNS_RESP_LEN) {
+        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+        return FALSE;
+    }
+    value = sizeof(uint32_t);
+    wlan_hdd_mdns_format_response_u16(value, resp_info);
+    wlan_hdd_mdns_format_response_u32(ini_config->mdns_resp_type_a_ipv4,
+                    resp_info);
+
+    EXIT();
+    return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_txt() - Pack Type Txt response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * Type Txt response include QName, response type, class, TTL and text content.
+ * Also, it will find the matched QName from resptype_A and compress the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_txt(hdd_config_t *ini_config,
+                     sir_mdns_resp_info resp_info,
+                     struct hdd_mdns_resp_info *resptype_txt,
+                     struct hdd_mdns_resp_info *resptype_a)
+{
+    uint8_t num_matched;
+    uint8_t num;
+    uint16_t idx;
+    uint16_t value = 0;
+    uint32_t len;
+    uint32_t total_len;
+    bool status;
+    struct hdd_mdns_resp_info resptype_content;
+
+    ENTER();
+
+    if ((ini_config == NULL) || (resp_info == NULL) ||
+        (resptype_txt == NULL)) {
+        hddLog(LOGE, FL("ini_config or response info is NULL!"));
+        return FALSE;
+    }
+
+    /* No Type Txt response */
+    if (strlen((char *)ini_config->mdns_resp_type_txt) <= 0)
+        return TRUE;
+
+    /* Wrong response is assigned, just ignore this response */
+    if (!wlan_hdd_mdns_init_response(resptype_txt,
+                ini_config->mdns_resp_type_txt, '.'))
+        return TRUE;
+
+    /*
+    * For data compression
+    * Check if any strings are matched with Type A response
+    */
+    if (resptype_a && (resptype_a->num_entries > 0)) {
+        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_txt,
+                                resptype_a);
+        if (num_matched > 0) {
+            if (!wlan_hdd_mdns_compress_data(resp_info,
+                resptype_txt, resptype_a, num_matched)) {
+                hddLog(LOGE, FL("Fail to compress mDNS "
+                    "response (%d)!"), MDNS_TYPE_TXT);
+                return FALSE;
+            }
+        } else {
+            /*
+            * num_matched is zero. Error!
+            * At least ".local" is needed.
+            */
+            hddLog(LOGE, FL("No matched string! Fail to pack mDNS "
+                    "response (%d)!"), MDNS_TYPE_TXT);
+            return FALSE;
+        }
+    } else {
+        /* no TypeA response, so show the whole data */
+        if (!wlan_hdd_mdns_process_response_dname(resptype_txt,
+                            resp_info)) {
+            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+                MDNS_TYPE_TXT);
+            return FALSE;
+        }
+    }
+
+    /* Process response Type, Class, TTL */
+    if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_TXT, resp_info)) {
+        hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
+            MDNS_TYPE_TXT);
+        return FALSE;
+    }
+
+    /*
+    * Process response RDLength, RData.
+    * TypeTxt RData include len.
+    */
+    status = wlan_hdd_mdns_init_response(&resptype_content,
+                ini_config->mdns_resp_type_txt_content,
+                '/');
+    if (status == FALSE) {
+        hddLog(LOGE, FL("wlan_hdd_mdns_init_response FAIL"));
+        return FALSE;
+    }
+
+    for (num = 0; num < resptype_content.num_entries; num++) {
+        idx = num * MAX_LEN_DOMAINNAME_FIELD;
+        value += strlen((char *)&resptype_content.data[idx]);
+    }
+
+    /* content len is uint16_t */
+    total_len = sizeof(uint16_t);
+    total_len += resp_info->resp_len + value +
+        resptype_content.num_entries;
+
+    if (total_len >= MAX_MDNS_RESP_LEN) {
+        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+        return FALSE;
+    }
+    wlan_hdd_mdns_format_response_u16(value + resptype_content.num_entries,
+                        resp_info);
+
+    for (num = 0; num < resptype_content.num_entries; num++) {
+        idx = num * MAX_LEN_DOMAINNAME_FIELD;
+        len = strlen((char *)&resptype_content.data[idx]);
+        resp_info->resp_data[resp_info->resp_len] = len;
+        resp_info->resp_len++;
+
+        vos_mem_copy(&resp_info->resp_data[resp_info->resp_len],
+            &resptype_content.data[idx], len);
+
+        resp_info->resp_len += len;
+        hddLog(LOG1, FL("index = %d, len = %d, str = %s"),
+            num, len, &resptype_content.data[idx]);
+    }
+
+    EXIT();
+    return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_ptr_dname() - Pack Type PTR domain name
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ *                     domain name
+ * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * The Type Ptr response include Type PTR domain name in its data field.
+ * Also, it will find the matched QName from the existing resptype_ptr,
+ * resptype_txt, resptype_a and then compress the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_ptr_dname(hdd_config_t *ini_config,
+                   sir_mdns_resp_info resp_info,
+                   struct hdd_mdns_resp_info *resptype_ptr_dn,
+                   struct hdd_mdns_resp_info *resptype_ptr,
+                   struct hdd_mdns_resp_info *resptype_txt,
+                   struct hdd_mdns_resp_info *resptype_a)
+{
+    uint8_t  num_matched, numlist, size;
+    struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
+    struct hdd_mdns_resp_info *resp;
+
+    if ((ini_config == NULL) || (resp_info == NULL) ||
+        (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
+        hddLog(LOGE, FL("ini_config or response info is NULL!"));
+        return FALSE;
+    }
+
+    /* No Type Ptr domain name response */
+    if (strlen((char *)ini_config->mdns_resp_type_ptr_dname) <= 0)
+        return TRUE;
+
+    /* Wrong response is assigned, just ignore this response */
+    if (!wlan_hdd_mdns_init_response(resptype_ptr_dn,
+                ini_config->mdns_resp_type_ptr_dname, '.'))
+        return TRUE;
+
+    /*
+    * For data compression
+    * Check if any strings are matched with previous
+    * response.
+    */
+    numlist = 0;
+    size = (MAX_MDNS_RESP_TYPE-1);
+    size *= sizeof(struct hdd_mdns_resp_matched);
+    vos_mem_zero(matchedlist, size);
+    num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr_dn,
+                            resptype_ptr);
+    if (num_matched > 0) {
+        matchedlist[numlist].num_matched = num_matched;
+        matchedlist[numlist].type = MDNS_TYPE_PTR;
+        numlist++;
+    }
+    if (resptype_txt && (resptype_txt->num_entries > 0)) {
+        num_matched = wlan_hdd_mdns_find_entries_from_end(
+                    resptype_ptr_dn, resptype_txt);
+        if (num_matched > 0) {
+            matchedlist[numlist].num_matched = num_matched;
+            matchedlist[numlist].type = MDNS_TYPE_TXT;
+            numlist++;
+        }
+    }
+    if (resptype_a && (resptype_a->num_entries > 0)) {
+        num_matched = wlan_hdd_mdns_find_entries_from_end(
+                    resptype_ptr_dn,resptype_a);
+        if (num_matched > 0) {
+            matchedlist[numlist].num_matched = num_matched;
+            matchedlist[numlist].type = MDNS_TYPE_A;
+            numlist++;
+        }
+    }
+    if (numlist > 0) {
+        if (numlist > 1)
+            wlan_hdd_mdns_find_max(matchedlist, numlist);
+        resp = NULL;
+        switch (matchedlist[numlist-1].type) {
+        case MDNS_TYPE_A:
+            resp = resptype_a;
+            break;
+        case MDNS_TYPE_TXT:
+            resp = resptype_txt;
+            break;
+        case MDNS_TYPE_PTR:
+            resp = resptype_ptr;
+            break;
+        default:
+            hddLog(LOGE, FL("Fail to compress mDNS response "
+                    "(%d)!"), MDNS_TYPE_PTR_DNAME);
+            return FALSE;
+        }
+        num_matched = matchedlist[numlist-1].num_matched;
+        if (!wlan_hdd_mdns_compress_data(resp_info, resptype_ptr_dn,
+                        resp, num_matched)) {
+            hddLog(LOGE, FL("Fail to compress mDNS response "
+                    "(%d)!"), MDNS_TYPE_PTR_DNAME);
+            return FALSE;
+        }
+    } else {
+        /* num = 0 -> no matched string */
+        if (!wlan_hdd_mdns_process_response_dname(resptype_ptr_dn,
+                            resp_info)) {
+            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+                    MDNS_TYPE_PTR_DNAME);
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_ptr() - Pack Type PTR response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ *                     domain name
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * The Type Ptr response include QName, response type, class, TTL and
+ * Type PTR domain name. Also, it will find the matched QName from the
+ * existing resptype_txt, resptype_a and then compress the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_ptr(hdd_config_t *ini_config,
+                 sir_mdns_resp_info resp_info,
+                 struct hdd_mdns_resp_info *resptype_ptr,
+                 struct hdd_mdns_resp_info *resptype_ptr_dn,
+                 struct hdd_mdns_resp_info *resptype_txt,
+                 struct hdd_mdns_resp_info *resptype_a)
+{
+    uint8_t num_matched, num_matched1;
+    uint16_t value;
+    uint8_t val_u8;
+    uint32_t offset_data_len, len;
+
+    ENTER();
+    if ((ini_config == NULL) || (resp_info == NULL) ||
+        (resptype_ptr == NULL) || (resptype_ptr_dn == NULL)) {
+        hddLog(LOGE, FL("ini_config or response info is NULL!"));
+        return FALSE;
+    }
+
+    /* No Type Ptr response */
+    if (strlen((char *)ini_config->mdns_resp_type_ptr) <= 0)
+        return TRUE;
+
+    /* Wrong response is assigned, just ignore this response */
+    if (!wlan_hdd_mdns_init_response(resptype_ptr,
+                    ini_config->mdns_resp_type_ptr, '.'))
+        return TRUE;
+
+    /*
+    * For data compression
+    * Check if any strings are matched with Type A response
+    */
+    num_matched  = 0;
+    num_matched1 = 0;
+    if (resptype_a && (resptype_a->num_entries > 0)) {
+        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_ptr,
+                                resptype_a);
+    }
+    if (resptype_txt && (resptype_txt->num_entries > 0)) {
+        num_matched1 = wlan_hdd_mdns_find_entries_from_end(
+                        resptype_ptr, resptype_txt);
+    }
+    if ((num_matched != num_matched1) ||
+        ((num_matched > 0) && (num_matched1 > 0))) {
+        if (num_matched >= num_matched1) {
+            if (!wlan_hdd_mdns_compress_data(resp_info,
+                resptype_ptr, resptype_a, num_matched)) {
+                hddLog(LOGE, FL("Fail to compress mDNS "
+                    "response (%d)!"), MDNS_TYPE_PTR);
+                return FALSE;
+            }
+        } else {
+            /* num_matched is less than num_matched1 */
+            if (!wlan_hdd_mdns_compress_data(resp_info,
+                resptype_ptr, resptype_txt, num_matched1)) {
+                hddLog(LOGE, FL("Fail to compress mDNS "
+                    "response (%d)!"), MDNS_TYPE_PTR);
+                return FALSE;
+            }
+        }
+    } else {
+        /*
+        * Both num_matched and num_matched1 are zero.
+        * no TypeA & TypeTxt
+        */
+        if (!wlan_hdd_mdns_process_response_dname(resptype_ptr,
+                            resp_info)) {
+            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+                MDNS_TYPE_PTR);
+            return FALSE;
+        }
+    }
+
+    /* Process response Type, Class, TTL */
+    if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_PTR, resp_info)) {
+        hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
+            MDNS_TYPE_PTR);
+        return FALSE;
+    }
+
+    /*
+    * Process response RDLength, RData (Ptr domain name)
+    * Save the offset of RData length
+    */
+    offset_data_len = resp_info->resp_len;
+    resp_info->resp_len += sizeof(uint16_t);
+
+    if (!wlan_hdd_mdns_pack_response_type_ptr_dname(ini_config, resp_info,
+                        resptype_ptr_dn, resptype_ptr,
+                        resptype_txt, resptype_a)) {
+        return FALSE;
+    }
+    /* Set the RData length */
+    len = offset_data_len + sizeof(uint16_t);
+    if ((resptype_ptr_dn->num_entries > 0) &&
+        (resp_info->resp_len > len)) {
+        value = resp_info->resp_len - len;
+        val_u8 = (value & 0xff00) >> 8;
+        resp_info->resp_data[offset_data_len] = val_u8;
+        val_u8 = value & 0xff;
+        resp_info->resp_data[offset_data_len+1] = val_u8;
+    } else {
+        hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+            MDNS_TYPE_PTR);
+        return FALSE;
+    }
+
+    EXIT();
+    return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_srv_target()- Pack Type Service Target
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
+ *                      target
+ * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
+ * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ *                     domain name
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * The Type service target is one of the data field in the Type SRV response.
+ * Also, it will find the matched QName from the existing resptype_srv,
+ * resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and then compress
+ * the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_srv_target(hdd_config_t *ini_config,
+                sir_mdns_resp_info resp_info,
+                struct hdd_mdns_resp_info *resptype_srv_tgt,
+                struct hdd_mdns_resp_info *resptype_srv,
+                struct hdd_mdns_resp_info *resptype_ptr,
+                struct hdd_mdns_resp_info *resptype_ptr_dn,
+                struct hdd_mdns_resp_info *resptype_txt,
+                struct hdd_mdns_resp_info *resptype_a)
+{
+    uint8_t  num_matched, num, size;
+    struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
+    struct hdd_mdns_resp_info *resp;
+
+    if ((ini_config == NULL) || (resp_info == NULL) ||
+        (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
+        hddLog(LOGE, FL("ini_config or response info is NULL!"));
+        return FALSE;
+    }
+
+    /* No Type Srv Target response */
+    if (strlen((char *)ini_config->mdns_resp_type_srv_target) <= 0)
+        return TRUE;
+
+    /* Wrong response is assigned, just ignore this response */
+    if (!wlan_hdd_mdns_init_response(resptype_srv_tgt,
+                ini_config->mdns_resp_type_srv_target, '.'))
+        return TRUE;
+
+    /*
+    * For data compression
+    * Check if any strings are matched with previous response.
+    */
+    num = 0;
+    size = (MAX_MDNS_RESP_TYPE-1);
+    size *= sizeof(struct hdd_mdns_resp_matched);
+    vos_mem_zero(matchedlist, size);
+    num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv_tgt,
+                            resptype_srv);
+    if (num_matched > 0) {
+        matchedlist[num].num_matched = num_matched;
+        matchedlist[num].type = MDNS_TYPE_SRV;
+        num++;
+    }
+    if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
+        if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
+            num_matched = wlan_hdd_mdns_find_entries_from_end(
+                    resptype_srv_tgt, resptype_ptr_dn);
+            if (num_matched > 0) {
+                matchedlist[num].num_matched = num_matched;
+                matchedlist[num].type = MDNS_TYPE_PTR_DNAME;
+                num++;
+            }
+        }
+        num_matched = wlan_hdd_mdns_find_entries_from_end(
+                    resptype_srv_tgt, resptype_ptr);
+        if (num_matched > 0) {
+            matchedlist[num].num_matched = num_matched;
+            matchedlist[num].type = MDNS_TYPE_PTR;
+            num++;
+        }
+    }
+    if (resptype_txt && (resptype_txt->num_entries > 0)) {
+        num_matched = wlan_hdd_mdns_find_entries_from_end(
+                    resptype_srv_tgt, resptype_txt);
+        if (num_matched > 0) {
+            matchedlist[num].num_matched = num_matched;
+            matchedlist[num].type = MDNS_TYPE_TXT;
+            num++;
+        }
+    }
+    if (resptype_a && (resptype_a->num_entries > 0)) {
+        num_matched = wlan_hdd_mdns_find_entries_from_end(
+                    resptype_srv_tgt, resptype_a);
+        if (num_matched > 0) {
+            matchedlist[num].num_matched = num_matched;
+            matchedlist[num].type = MDNS_TYPE_A;
+            num++;
+        }
+    }
+    if (num > 0) {
+        if (num > 1)
+            wlan_hdd_mdns_find_max(matchedlist, num);
+        resp = NULL;
+        switch (matchedlist[num-1].type) {
+        case MDNS_TYPE_A:
+            resp = resptype_a;
+            break;
+        case MDNS_TYPE_TXT:
+            resp = resptype_txt;
+            break;
+        case MDNS_TYPE_PTR:
+            resp = resptype_ptr;
+            break;
+        case MDNS_TYPE_PTR_DNAME:
+            resp = resptype_ptr_dn;
+            break;
+        case MDNS_TYPE_SRV:
+            resp = resptype_srv;
+            break;
+        default:
+            hddLog(LOGE, FL("Fail to compress mDNS response "
+                    "(%d)!"), MDNS_TYPE_SRV_TARGET);
+            return FALSE;
+        }
+        num_matched = matchedlist[num-1].num_matched;
+        if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv_tgt,
+                        resp, num_matched)) {
+            hddLog(LOGE, FL("Fail to compress mDNS response "
+                    "(%d)!"), MDNS_TYPE_SRV_TARGET);
+            return FALSE;
+        }
+    } else {
+        /* num = 0 -> no matched string */
+        if (!wlan_hdd_mdns_process_response_dname(resptype_srv_tgt,
+                            resp_info)) {
+            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+                    MDNS_TYPE_SRV_TARGET);
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_pack_response_type_srv()- Pack Type Service response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ * @resptype_srv: Pointer to the struct hdd_mdns_resp_info of Type Srv
+ * @resptype_srv_tgt: Pointer to the struct hdd_mdns_resp_info of Type Srv
+ *                      target
+ * @resptype_ptr: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ * @resptype_ptr_dn: Pointer to the struct hdd_mdns_resp_info of Type Ptr
+ *                     domain name
+ * @resptype_txt: Pointer to the struct hdd_mdns_resp_info of Type Txt
+ * @resptype_a: Pointer to the struct hdd_mdns_resp_info of Type A
+ *
+ * The Type SRV (Service) response include QName, response type, class, TTL
+ * and four kinds of data fields. Also, it will find the matched QName from
+ * the existing resptype_ptr, resptype_ptr_dn, resptype_txt, resptype_a and
+ * then compress the data.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool
+wlan_hdd_mdns_pack_response_type_srv(hdd_config_t *ini_config,
+                 sir_mdns_resp_info resp_info,
+                 struct hdd_mdns_resp_info *resptype_srv,
+                 struct hdd_mdns_resp_info *resptype_srv_tgt,
+                 struct hdd_mdns_resp_info *resptype_ptr,
+                 struct hdd_mdns_resp_info *resptype_ptr_dn,
+                 struct hdd_mdns_resp_info *resptype_txt,
+                 struct hdd_mdns_resp_info *resptype_a)
+{
+    uint8_t num_matched, num, size;
+    uint16_t value;
+    uint8_t val_u8;
+    uint32_t offset_data_len, len;
+    struct hdd_mdns_resp_info *resp;
+    struct hdd_mdns_resp_matched matchedlist[MAX_MDNS_RESP_TYPE-1];
+
+    ENTER();
+
+    if ((ini_config == NULL) || (resp_info == NULL) ||
+        (resptype_srv == NULL) || (resptype_srv_tgt == NULL)) {
+        hddLog(LOGE, FL("ini_config or response info is NULL!"));
+        return FALSE;
+    }
+
+    /* No Type Srv response */
+    if (strlen((char *)ini_config->mdns_resp_type_srv) <= 0)
+        return TRUE;
+
+    /* Wrong response is assigned, just ignore this response */
+    if (!wlan_hdd_mdns_init_response(resptype_srv,
+                    ini_config->mdns_resp_type_srv, '.'))
+        return TRUE;
+
+    /*
+    * For data compression
+    * Check if any strings are matched with Type A response
+    */
+    num = 0;
+    size = (MAX_MDNS_RESP_TYPE-1);
+    size *= sizeof(struct hdd_mdns_resp_matched);
+    vos_mem_zero(matchedlist, size);
+    if (resptype_ptr && (resptype_ptr->num_entries > 0)) {
+        if (resptype_ptr_dn && (resptype_ptr_dn->num_entries > 0)) {
+            num_matched = wlan_hdd_mdns_find_entries_from_end(
+                            resptype_srv,
+                            resptype_ptr_dn);
+            if (num_matched > 0) {
+                matchedlist[num].num_matched = num_matched;
+                matchedlist[num].type =    MDNS_TYPE_PTR_DNAME;
+                num++;
+            }
+        }
+        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
+                                resptype_ptr);
+        if (num_matched > 0) {
+            matchedlist[num].num_matched = num_matched;
+            matchedlist[num].type = MDNS_TYPE_PTR;
+            num++;
+        }
+    }
+    if (resptype_txt && (resptype_txt->num_entries > 0)) {
+        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
+                                resptype_txt);
+        if (num_matched > 0) {
+            matchedlist[num].num_matched =num_matched;
+            matchedlist[num].type = MDNS_TYPE_TXT;
+            num++;
+        }
+    }
+    if (resptype_a && (resptype_a->num_entries > 0)) {
+        num_matched = wlan_hdd_mdns_find_entries_from_end(resptype_srv,
+                                resptype_a);
+        if (num_matched > 0) {
+            matchedlist[num].num_matched = num_matched;
+            matchedlist[num].type = MDNS_TYPE_A;
+            num++;
+        }
+    }
+    if (num > 0) {
+        if (num > 1)
+            wlan_hdd_mdns_find_max(matchedlist, num);
+        resp = NULL;
+        switch (matchedlist[num-1].type) {
+        case MDNS_TYPE_A:
+            resp = resptype_a;
+            break;
+        case MDNS_TYPE_TXT:
+            resp = resptype_txt;
+            break;
+        case MDNS_TYPE_PTR:
+            resp = resptype_ptr;
+            break;
+        case MDNS_TYPE_PTR_DNAME:
+            resp = resptype_ptr_dn;
+            break;
+        default:
+            hddLog(LOGE, FL("Fail to compress mDNS response "
+                    "(%d)!"), MDNS_TYPE_SRV);
+            return FALSE;
+        }
+        num_matched = matchedlist[num-1].num_matched;
+        if (!wlan_hdd_mdns_compress_data(resp_info, resptype_srv,
+                        resp, num_matched)) {
+            hddLog(LOGE, FL("Fail to compress mDNS response "
+                    "(%d)!"), MDNS_TYPE_SRV);
+            return FALSE;
+        }
+    } else {
+        /* num = 0 -> no matched string */
+        if (!wlan_hdd_mdns_process_response_dname(resptype_srv,
+                            resp_info)) {
+            hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+                    MDNS_TYPE_SRV);
+            return FALSE;
+        }
+    }
+
+    /* Process response Type, Class, TTL */
+    if (!wlan_hdd_mdns_process_response_misc(MDNS_TYPE_SRV, resp_info)) {
+        hddLog(LOGE, FL("Fail to process mDNS misc response (%d)!"),
+                    MDNS_TYPE_SRV);
+        return FALSE;
+    }
+
+    /*
+    * Process response RDLength, RData (Srv target name)
+    * Save the offset of RData length
+    */
+    offset_data_len = resp_info->resp_len;
+    resp_info->resp_len += sizeof(uint16_t);
+
+    len = resp_info->resp_len + (3 * sizeof(uint16_t));
+    if (len >= MAX_MDNS_RESP_LEN) {
+        hddLog(LOGE, FL("resp_len exceeds %d!"), MAX_MDNS_RESP_LEN);
+        return FALSE;
+    }
+
+    /* set Srv Priority */
+    value = ini_config->mdns_resp_type_srv_priority;
+    wlan_hdd_mdns_format_response_u16(value, resp_info);
+    /* set Srv Weight */
+    value = ini_config->mdns_resp_type_srv_weight;
+    wlan_hdd_mdns_format_response_u16(value, resp_info);
+    /* set Srv Port */
+    value = ini_config->mdns_resp_type_srv_port;
+    wlan_hdd_mdns_format_response_u16(value, resp_info);
+
+    if (!wlan_hdd_mdns_pack_response_type_srv_target(ini_config, resp_info,
+                        resptype_srv_tgt, resptype_srv,
+                        resptype_ptr, resptype_ptr_dn,
+                        resptype_txt, resptype_a)) {
+        return FALSE;
+    }
+    /* Set the RData length */
+    len = offset_data_len + sizeof(uint16_t);
+    if ((resptype_srv_tgt->num_entries > 0) &&
+        (resp_info->resp_len > len)) {
+        value = resp_info->resp_len - len;
+        val_u8 = (value & 0xff00) >> 8;
+        resp_info->resp_data[offset_data_len] = val_u8;
+        val_u8 = value & 0xff;
+        resp_info->resp_data[offset_data_len+1] = val_u8;
+    } else {
+        hddLog(LOGE, FL("Fail to process mDNS response (%d)!"),
+            MDNS_TYPE_SRV);
+        return FALSE;
+    }
+
+    EXIT();
+    return TRUE;
+}
+
+/**
+ * wlan_hdd_mdns_free_mem() - Free the allocated memory
+ * @response: Pointer to the struct hdd_mdns_resp_info
+ *
+ * Return: None
+ */
+static void wlan_hdd_mdns_free_mem(struct hdd_mdns_resp_info *response)
+{
+    if (response && response->data)
+        vos_mem_free(response->data);
+    if (response && response->offset)
+        vos_mem_free(response->offset);
+}
+
+/**
+ * wlan_hdd_mdns_pack_response() - Pack mDNS response
+ * @ini_config: Pointer to the struct hdd_config_t
+ * @resp_info: Pointer to the struct tSirMDNSResponseInfo
+ *
+ * This function will pack four types of responses (Type A, Type Txt, Type Ptr
+ * and Type Service). Each response contains QName, response type, class, TTL
+ * and data fields.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+static bool wlan_hdd_mdns_pack_response(hdd_config_t *ini_config,
+                    sir_mdns_resp_info resp_info)
+{
+    struct hdd_mdns_resp_info resptype_a, resptype_txt;
+    struct hdd_mdns_resp_info resptype_ptr, resptype_ptr_dn;
+    struct hdd_mdns_resp_info resptype_srv, resptype_srv_tgt;
+    uint32_t num_res_records = 0;
+    bool status = FALSE;
+
+    ENTER();
+
+    wlan_hdd_mdns_reset_response(&resptype_a);
+    wlan_hdd_mdns_reset_response(&resptype_txt);
+    wlan_hdd_mdns_reset_response(&resptype_ptr);
+    wlan_hdd_mdns_reset_response(&resptype_ptr_dn);
+    wlan_hdd_mdns_reset_response(&resptype_srv);
+    wlan_hdd_mdns_reset_response(&resptype_srv_tgt);
+
+    resp_info->resp_len = 0;
+
+    /* Process Type A response */
+    if (!wlan_hdd_mdns_pack_response_type_a(ini_config, resp_info,
+                        &resptype_a))
+        goto err_resptype_a;
+
+    if ((resptype_a.num_entries > 0) &&
+        (strlen((char *)&resptype_a.data[0]) > 0))
+        num_res_records++;
+
+    /* Process Type TXT response */
+    if (!wlan_hdd_mdns_pack_response_type_txt(ini_config, resp_info,
+                          &resptype_txt, &resptype_a))
+        goto err_resptype_txt;
+
+    if ((resptype_txt.num_entries > 0) &&
+        (strlen((char *)&resptype_txt.data[0]) > 0))
+        num_res_records++;
+
+    /* Process Type PTR response */
+    if (!wlan_hdd_mdns_pack_response_type_ptr(ini_config, resp_info,
+                      &resptype_ptr, &resptype_ptr_dn,
+                      &resptype_txt, &resptype_a))
+        goto err_resptype_ptr;
+
+    if ((resptype_ptr.num_entries > 0) &&
+        (strlen((char *)&resptype_ptr.data[0]) > 0))
+        num_res_records++;
+
+    /* Process Type SRV response */
+    if (!wlan_hdd_mdns_pack_response_type_srv(ini_config, resp_info,
+                      &resptype_srv, &resptype_srv_tgt,
+                      &resptype_ptr, &resptype_ptr_dn,
+                      &resptype_txt, &resptype_a))
+        goto err_resptype_srv;
+
+    if ((resptype_srv.num_entries > 0) &&
+        (strlen((char *)&resptype_srv.data[0]) > 0))
+        num_res_records++;
+
+    resp_info->resourceRecord_count = num_res_records;
+    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
+           "%s: Pack mDNS response data successfully!", __func__);
+    status = TRUE;
+
+err_resptype_srv:
+    wlan_hdd_mdns_free_mem(&resptype_srv);
+    wlan_hdd_mdns_free_mem(&resptype_srv_tgt);
+
+err_resptype_ptr:
+    wlan_hdd_mdns_free_mem(&resptype_ptr);
+    wlan_hdd_mdns_free_mem(&resptype_ptr_dn);
+
+err_resptype_txt:
+    wlan_hdd_mdns_free_mem(&resptype_txt);
+
+err_resptype_a:
+    wlan_hdd_mdns_free_mem(&resptype_a);
+
+    EXIT();
+    return status;
+}
+
+/**
+ * wlan_hdd_set_mdns_offload() - Enable mDNS offload
+ * @hostapd_adapter: Pointer to the struct hdd_adapter_t
+ *
+ * This function will set FQDN/unique FQDN (full qualified domain name)
+ * and the mDNS response. Then send them to SME.
+ *
+ * Return: Return boolean. TRUE for success, FALSE for fail.
+ */
+bool wlan_hdd_set_mdns_offload(hdd_adapter_t *hostapd_adapter)
+{
+    hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
+    sir_mdns_offload_info mdns_offload_info;
+    sir_mdns_fqdn_info mdns_fqdn_info;
+    sir_mdns_resp_info mdns_resp_info;
+    uint32_t fqdn_len, ufqdn_len;
+
+    ENTER();
+
+    /* 1. Prepare the MDNS fqdn request to send to SME */
+    fqdn_len = strlen(hdd_ctx->cfg_ini->mdns_fqdn);
+    ufqdn_len = strlen(hdd_ctx->cfg_ini->mdns_uniquefqdn);
+    if ((fqdn_len == 0) && (ufqdn_len == 0)) {
+        hddLog(LOGE, FL("No mDNS FQDN or UFQDN is assigned fqdn_len %d,"
+                        "ufqdn_len %d!"), fqdn_len, ufqdn_len);
+        return FALSE;
+    }
+
+    mdns_fqdn_info = vos_mem_malloc(sizeof(*mdns_fqdn_info));
+    if (NULL == mdns_fqdn_info) {
+        hddLog(LOGE, FL("could not allocate tSirMDNSFqdnInfo!"));
+        return FALSE;
+    }
+    /* MDNS fqdn request */
+    if (fqdn_len > 0) {
+           vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
+           mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
+           mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_GENERAL;
+           mdns_fqdn_info->fqdn_len = fqdn_len;
+           mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
+           mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
+           vos_mem_copy(mdns_fqdn_info->fqdn_data,
+                hdd_ctx->cfg_ini->mdns_fqdn,
+                mdns_fqdn_info->fqdn_len);
+
+        if (eHAL_STATUS_SUCCESS !=
+            sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
+            hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
+            vos_mem_free(mdns_fqdn_info);
+            return FALSE;
+        }
+    }
+    /* MDNS unique fqdn request */
+    if (ufqdn_len > 0) {
+           vos_mem_zero(mdns_fqdn_info, sizeof(*mdns_fqdn_info));
+           mdns_fqdn_info->bss_idx = hostapd_adapter->sessionId;
+           mdns_fqdn_info->fqdn_type = MDNS_FQDN_TYPE_UNIQUE;
+           mdns_fqdn_info->fqdn_len = ufqdn_len;
+           mdns_fqdn_info->mdns_fqdn_callback = hdd_mdns_fqdn_offload_done;
+           mdns_fqdn_info->mdns_fqdn_cb_context = hostapd_adapter;
+           vos_mem_copy(mdns_fqdn_info->fqdn_data,
+                hdd_ctx->cfg_ini->mdns_uniquefqdn,
+                mdns_fqdn_info->fqdn_len);
+        if (eHAL_STATUS_SUCCESS !=
+            sme_set_mdns_fqdn(hdd_ctx->hHal, mdns_fqdn_info)) {
+            hddLog(LOGE, FL("sme_set_mdns_fqdn fail!"));
+            vos_mem_free(mdns_fqdn_info);
+            return FALSE;
+        }
+    }
+    vos_mem_free(mdns_fqdn_info);
+
+    /* 2. Prepare the MDNS response request to send to SME */
+    mdns_resp_info = vos_mem_malloc(sizeof(*mdns_resp_info));
+    if (NULL == mdns_resp_info) {
+        hddLog(LOGE, FL("could not allocate tSirMDNSResponseInfo!"));
+        return FALSE;
+    }
+
+    vos_mem_zero(mdns_resp_info, sizeof(*mdns_resp_info));
+    mdns_resp_info->bss_idx = hostapd_adapter->sessionId;
+    mdns_resp_info->mdns_resp_callback = hdd_mdns_resp_offload_done;
+    mdns_resp_info->mdns_resp_cb_context = hostapd_adapter;
+    if (!wlan_hdd_mdns_pack_response(hdd_ctx->cfg_ini, mdns_resp_info)) {
+        hddLog(LOGE, FL("wlan_hdd_pack_mdns_response fail!"));
+        vos_mem_free(mdns_resp_info);
+        return FALSE;
+    }
+    if (eHAL_STATUS_SUCCESS !=
+        sme_set_mdns_resp(hdd_ctx->hHal, mdns_resp_info)) {
+        hddLog(LOGE, FL("sme_set_mdns_resp fail!"));
+        vos_mem_free(mdns_resp_info);
+        return FALSE;
+    }
+    vos_mem_free(mdns_resp_info);
+
+    /* 3. Prepare the MDNS Enable request to send to SME */
+    mdns_offload_info = vos_mem_malloc(sizeof(*mdns_offload_info));
+    if (NULL == mdns_offload_info) {
+        hddLog(LOGE, FL("could not allocate tSirMDNSOffloadInfo!"));
+        return FALSE;
+    }
+
+    vos_mem_zero(mdns_offload_info, sizeof(*mdns_offload_info));
+
+    mdns_offload_info->bss_idx = hostapd_adapter->sessionId;
+    mdns_offload_info->enable = hdd_ctx->cfg_ini->enable_mdns_offload;
+    mdns_offload_info->mdns_enable_callback = hdd_mdns_enable_offload_done;
+    mdns_offload_info->mdns_enable_cb_context = hostapd_adapter;
+    if (eHAL_STATUS_SUCCESS !=
+        sme_set_mdns_offload(hdd_ctx->hHal, mdns_offload_info)) {
+        hddLog(LOGE, FL("sme_set_mdns_offload fail!"));
+        vos_mem_free(mdns_offload_info);
+        return FALSE;
+    }
+
+    vos_mem_free(mdns_offload_info);
+    hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
+           "%s: enable mDNS offload successfully!", __func__);
+    return TRUE;
+}
+#endif /* MDNS_OFFLOAD */
 
 //Register the module init/exit functions
 module_init(hdd_module_init);
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index bc1427b..6ad300d 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -3794,8 +3794,11 @@
 typedef void(*RssiMonitorReqCb)(void *rssiMonitorCbContext, VOS_STATUS status);
 typedef void(*pktFilterReqCb)(void *data, tANI_U32 status);
 typedef void(*dhcp_offload_req_cb)(void *rssiMonitorCbContext,
-				   VOS_STATUS status);
-
+                                   VOS_STATUS status);
+typedef void(*mdns_enable_req_cb)(void *mdns_enable_cb_context,
+                                  VOS_STATUS status);
+typedef void(*mdns_fqdn_req_cb)(void *mdns_fqdn_cb_context, VOS_STATUS status);
+typedef void(*mdns_resp_req_cb)(void *mdns_resp_cb_context, VOS_STATUS status);
 
 typedef struct sAniGetFrameLogReq
 {
@@ -5590,6 +5593,45 @@
 } sir_dhcp_srv_offload_info_t, *sir_dhcp_srv_offload_info;
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+#define MAX_MDNS_FQDN_LEN                         64
+#define MAX_MDNS_RESP_LEN                         512
+
+typedef struct
+{
+    tANI_U8 bss_idx;
+    tANI_U32 enable;
+    mdns_enable_req_cb    mdns_enable_callback;
+    void                   *mdns_enable_cb_context;
+} sir_mdns_offload_info_t, *sir_mdns_offload_info;
+
+typedef struct
+{
+    tANI_U8 bss_idx;
+    tANI_U32 fqdn_type;
+    tANI_U32 fqdn_len;
+    tANI_U8 fqdn_data[MAX_MDNS_FQDN_LEN];
+    mdns_fqdn_req_cb    mdns_fqdn_callback;
+    void                *mdns_fqdn_cb_context;
+
+} sir_mdns_fqdn_info_t, *sir_mdns_fqdn_info;
+
+typedef struct
+{
+    tANI_U8 bss_idx;
+    tANI_U32 resourceRecord_count;
+    tANI_U32 resp_len;
+    tANI_U8 resp_data[MAX_MDNS_RESP_LEN];
+    mdns_resp_req_cb    mdns_resp_callback;
+    void                *mdns_resp_cb_context;
+} sir_mdns_resp_info_t, *sir_mdns_resp_info;
+
+typedef struct
+{
+    tANI_U8 bss_idx;
+} sir_get_mdns_stats_info_t, *sir_get_mdns_stats_info;
+#endif /* MDNS_OFFLOAD */
+
 typedef PACKED_PRE struct PACKED_POST
 {
     tANI_U32             requestId;
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 69a9cda..8fbf945 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -781,6 +781,12 @@
 #ifdef DHCP_SERVER_OFFLOAD
 #define SIR_HAL_SET_DHCP_SERVER_OFFLOAD_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 294)
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+#define SIR_HAL_SET_MDNS_OFFLOAD           (SIR_HAL_ITC_MSG_TYPES_BEGIN + 295)
+#define SIR_HAL_SET_MDNS_FQDN              (SIR_HAL_ITC_MSG_TYPES_BEGIN + 296)
+#define SIR_HAL_SET_MDNS_RESPONSE          (SIR_HAL_ITC_MSG_TYPES_BEGIN + 297)
+#define SIR_HAL_GET_MDNS_STATUS            (SIR_HAL_ITC_MSG_TYPES_BEGIN + 398)
+#endif /* MDNS_OFFLOAD */
 #define SIR_HAL_MSG_TYPES_END              (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 // CFG message types
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 48e19fd..2c13297 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -3982,7 +3982,17 @@
 #endif /* SAP_AUTH_OFFLOAD */
 #ifdef DHCP_SERVER_OFFLOAD
 eHalStatus sme_set_dhcp_srv_offload(tHalHandle hal,
-				    sir_dhcp_srv_offload_info_t *dhcp_srv_info);
+                                   sir_dhcp_srv_offload_info_t *dhcp_srv_info);
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+eHalStatus sme_set_mdns_offload(tHalHandle hal,
+                                 sir_mdns_offload_info_t *mdns_info);
+
+eHalStatus sme_set_mdns_fqdn(tHalHandle hal,
+                             sir_mdns_fqdn_info_t *mdns_fqdn);
+
+eHalStatus sme_set_mdns_resp(tHalHandle hal,
+                             sir_mdns_resp_info_t *mdns_resp);
+#endif /* MDNS_OFFLOAD */
 #endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 2567b25..dd9421b 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -14661,3 +14661,161 @@
 	return status;
 }
 #endif /* DHCP_SERVER_OFFLOAD */
+
+#ifdef MDNS_OFFLOAD
+/**
+ * sme_set_mdns_offload() - sme API to set mdns offload enable/disable
+ * @hal: handle to hal pointer
+ * @mdns_info: pointer to mdns offload info
+ *
+ * Return - eHalStatus
+ */
+eHalStatus sme_set_mdns_offload(tHalHandle hal,
+                                sir_mdns_offload_info_t *mdns_info)
+{
+    vos_msg_t vos_msg;
+    sir_mdns_offload_info_t *mdns_offload;
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+    mdns_offload = vos_mem_malloc(sizeof(*mdns_offload));
+
+    if (!mdns_offload) {
+        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+              "%s: Not able to allocate memory for WDA_SET_MDNS_OFFLOAD_CMD",
+              __func__);
+        return eHAL_STATUS_E_MALLOC_FAILED;
+    }
+
+    vos_mem_copy(mdns_offload, mdns_info, sizeof(*mdns_offload));
+
+    status = sme_AcquireGlobalLock(&mac->sme);
+    if (eHAL_STATUS_SUCCESS == status) {
+        /* serialize the req through MC thread */
+        vos_msg.type     = WDA_SET_MDNS_OFFLOAD_CMD;
+        vos_msg.bodyptr  = mdns_offload;
+
+        if (!VOS_IS_STATUS_SUCCESS(
+                    vos_mq_post_message(VOS_MODULE_ID_WDA,
+                                &vos_msg))) {
+            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                   "%s: Not able to post WDA_SET_MDNS_OFFLOAD_CMD to WDA!",
+                   __func__);
+            vos_mem_free(mdns_offload);
+            status = eHAL_STATUS_FAILURE;
+        }
+        sme_ReleaseGlobalLock(&mac->sme);
+    } else {
+        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+               "%s: sme_AcquireGlobalLock error!",
+               __func__);
+        vos_mem_free(mdns_offload);
+    }
+
+    return (status);
+}
+
+/**
+ * sme_set_mdns_fqdn() - SME API to set mDNS Fqdn info
+ * @hal: hal handle
+ * @mdns_fqdn: mDNS Fqdn info struct
+ *
+ * Return - return eHalStatus
+ */
+eHalStatus sme_set_mdns_fqdn(tHalHandle hal,
+                 sir_mdns_fqdn_info_t *mdns_fqdn)
+{
+    vos_msg_t vos_msg;
+    sir_mdns_fqdn_info_t *fqdn_info;
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+    fqdn_info = vos_mem_malloc(sizeof(*fqdn_info));
+
+    if (!fqdn_info) {
+        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+              "%s: Not able to allocate memory for WDA_SET_MDNS_FQDN_CMD",
+              __func__);
+        return eHAL_STATUS_E_MALLOC_FAILED;
+    }
+
+    vos_mem_copy(fqdn_info, mdns_fqdn, sizeof(*fqdn_info));
+
+    status = sme_AcquireGlobalLock(&mac->sme);
+    if (eHAL_STATUS_SUCCESS == status) {
+        /* serialize the req through MC thread */
+        vos_msg.type     = WDA_SET_MDNS_FQDN_CMD;
+        vos_msg.bodyptr  = fqdn_info;
+
+        if (!VOS_IS_STATUS_SUCCESS(
+                    vos_mq_post_message(VOS_MODULE_ID_WDA,
+                                &vos_msg))) {
+            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                   "%s: Not able to post WDA_SET_MDNS_FQDN_CMD to WDA!",
+                   __func__);
+            vos_mem_free(fqdn_info);
+            status = eHAL_STATUS_FAILURE;
+        }
+        sme_ReleaseGlobalLock(&mac->sme);
+    } else {
+        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+               "%s: sme_AcquireGlobalLock error!",
+               __func__);
+        vos_mem_free(fqdn_info);
+    }
+
+    return (status);
+}
+
+/**
+ * sme_set_mdns_resp() - SME API to set mDNS response info
+ * @hal: hal handle
+ * @mdns_resp : mDNS response info struct
+ *
+ * Return - eHalStatus
+ */
+eHalStatus sme_set_mdns_resp(tHalHandle hal,
+                 sir_mdns_resp_info_t *mdns_resp)
+{
+    vos_msg_t vos_msg;
+    sir_mdns_resp_info_t *resp_info;
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+    resp_info = vos_mem_malloc(sizeof(*resp_info));
+
+    if (!resp_info) {
+        VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+              "%s: Not able to allocate memory for WDA_SET_MDNS_RESPONSE_CMD",
+              __func__);
+        return eHAL_STATUS_E_MALLOC_FAILED;
+    }
+
+    vos_mem_copy(resp_info, mdns_resp, sizeof(*resp_info));
+
+    status = sme_AcquireGlobalLock(&mac->sme);
+    if (eHAL_STATUS_SUCCESS == status) {
+        /* serialize the req through MC thread */
+        vos_msg.type     = WDA_SET_MDNS_RESPONSE_CMD;
+        vos_msg.bodyptr  = resp_info;
+
+        if (!VOS_IS_STATUS_SUCCESS(
+                    vos_mq_post_message(VOS_MODULE_ID_WDA,
+                                &vos_msg))) {
+            VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+                   "%s: Not able to post WDA_SET_MDNS_RESPONSE_CMD to WDA!",
+                   __func__);
+            vos_mem_free(resp_info);
+            status = eHAL_STATUS_FAILURE;
+        }
+        sme_ReleaseGlobalLock(&mac->sme);
+    } else {
+        VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+               "%s: sme_AcquireGlobalLock error!",
+               __func__);
+        vos_mem_free(resp_info);
+    }
+
+    return (status);
+}
+#endif /* MDNS_OFFLOAD */
diff --git a/CORE/SYS/legacy/src/utils/src/macTrace.c b/CORE/SYS/legacy/src/utils/src/macTrace.c
index db5ce8d..a805b43 100644
--- a/CORE/SYS/legacy/src/utils/src/macTrace.c
+++ b/CORE/SYS/legacy/src/utils/src/macTrace.c
@@ -909,6 +909,12 @@
 #ifdef DHCP_SERVER_OFFLOAD
         CASE_RETURN_STRING(WDA_SET_DHCP_SERVER_OFFLOAD_REQ);
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+        CASE_RETURN_STRING(WDA_SET_MDNS_OFFLOAD_CMD);
+        CASE_RETURN_STRING(WDA_SET_MDNS_FQDN_CMD);
+        CASE_RETURN_STRING(WDA_SET_MDNS_RESPONSE_CMD);
+        CASE_RETURN_STRING(WDA_GET_MDNS_STATUS_CMD);
+#endif
         default:
             return((tANI_U8*) "UNKNOWN" );
             break;
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index 06cbaf8..5fab319 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1299,6 +1299,12 @@
 #ifdef DHCP_SERVER_OFFLOAD
 #define WDA_SET_DHCP_SERVER_OFFLOAD_REQ     SIR_HAL_SET_DHCP_SERVER_OFFLOAD_REQ
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+#define WDA_SET_MDNS_OFFLOAD_CMD              SIR_HAL_SET_MDNS_OFFLOAD
+#define WDA_SET_MDNS_FQDN_CMD                 SIR_HAL_SET_MDNS_FQDN
+#define WDA_SET_MDNS_RESPONSE_CMD             SIR_HAL_SET_MDNS_RESPONSE
+#define WDA_GET_MDNS_STATUS_CMD               SIR_HAL_GET_MDNS_STATUS
+#endif /* MDNS_OFFLOAD */
 
 tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
 
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index da7c8c2..5e8f6f7 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -2559,10 +2559,271 @@
 }
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+/**
+ * wda_mdns_enable_rsp_callback() - response to the mdns enable server offload
+ * @wdi_rsp: pointer to the mdns enable offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_mdns_enable_rsp_callback(wdi_mdns_enable_offload_rsp_param_t*
+                  wdi_rsp,
+                  void* user_data)
+{
+    tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+    sir_mdns_offload_info_t *mdns_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 ;
+    }
+
+    mdns_offload_info = (sir_mdns_offload_info_t *)
+        wda_params->wdaMsgParam;
+
+    if(mdns_offload_info->mdns_enable_callback)
+    {
+        mdns_offload_info->mdns_enable_callback(mdns_offload_info->
+                         mdns_enable_cb_context,
+                         CONVERT_WDI2VOS_STATUS(wdi_rsp->
+                                    status));
+    }
+    else
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "%s: mdns_enable callback is NULL", __func__);
+    }
+
+    status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+    if (status)
+    {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "%s: MDNS 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;
+}
+
+/**
+ * wda_mdns_fqdn_rsp_callback() - response to the mdns fqdn offload
+ * @wdi_rsp: pointer to the mdns fqdn offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_mdns_fqdn_rsp_callback(wdi_mdns_set_fqdn_rsp_param_t*
+                wdi_rsp,
+                void* user_data)
+{
+    tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+    sir_mdns_fqdn_info_t *mdns_fqdn_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 ;
+    }
+
+    mdns_fqdn_info = (sir_mdns_fqdn_info_t *)
+        wda_params->wdaMsgParam;
+
+    if(mdns_fqdn_info->mdns_fqdn_callback)
+    {
+        mdns_fqdn_info->mdns_fqdn_callback(mdns_fqdn_info->
+                       mdns_fqdn_cb_context,
+                       CONVERT_WDI2VOS_STATUS(wdi_rsp->
+                                  status));
+    }
+    else
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "%s: mdns_fqdn callback is NULL", __func__);
+    }
+
+    status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+    if (status)
+    {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "%s: MDNS FQDN 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;
+}
+
+/**
+ * wda_mdns_resp_rsp_callback() - response to the mdns resp offload
+ * @wdi_rsp: pointer to the mdns fqdn offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_mdns_resp_rsp_callback
+(
+ wdi_mdns_set_rsp_param_t*
+ wdi_rsp,
+ void* user_data)
+{
+    tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+    sir_mdns_resp_info_t *mdns_resp_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 ;
+    }
+
+    mdns_resp_info = (sir_mdns_resp_info_t *)
+        wda_params->wdaMsgParam;
+
+    if(mdns_resp_info->mdns_resp_callback)
+    {
+        mdns_resp_info->mdns_resp_callback(mdns_resp_info->
+                       mdns_resp_cb_context,
+                       CONVERT_WDI2VOS_STATUS(wdi_rsp->
+                                  status));
+    }
+    else
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "%s: mdns_fqdn callback is NULL", __func__);
+    }
+
+    status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+    if (status)
+    {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "%s: MDNS FQDN 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;
+}
+
+/**
+ * wda_get_stats_rsp_callback() - response to the mdns stats offload
+ * @wdi_rsp: pointer to the mdns fqdn offload response
+ * @user_data: pointer to user data
+ *
+ * Return: None
+ */
+void wda_get_stats_rsp_callback
+(
+ wdi_mdns_stats_rsp_param_t*
+ wdi_rsp,
+ void* user_data)
+{
+    tWDA_ReqParams *wda_params = (tWDA_ReqParams *)user_data;
+    sir_get_mdns_stats_info_t *mdns_stats_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 ;
+    }
+
+    mdns_stats_info = (sir_get_mdns_stats_info_t *)
+        wda_params->wdaMsgParam;
+
+    status = CONVERT_WDI2VOS_STATUS(wdi_rsp->status);
+    if (status)
+    {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "%s: MDNS FQDN 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 /* MDNS_OFFLOAD */
+
 /*
  * FUNCTION: WDA_wdiCompleteCB
  * call the voss call back function
- */ 
+ */
 void WDA_stopCallback(WDI_Status status, void* pUserData)
 {
    tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
@@ -15657,6 +15918,324 @@
 }
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+/**
+ * wda_set_mdns_offload_req() - wda api to set mdns offload
+ * @wda_handle: wda handle
+ * @mdns_offload_info: mdns offload info
+ *
+ * Return - 0 for success or else failure
+ */
+static int
+wda_set_mdns_offload_req(tWDA_CbContext *wda_handle,
+             sir_mdns_offload_info_t *mdns_offload_info)
+{
+    wdi_mdns_enable_offload_cmd_req *mdns_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 == mdns_offload_info)
+    {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "%s: set_mdns_offload received NULL",
+              __func__);
+        VOS_ASSERT(0) ;
+        return VOS_STATUS_E_FAULT;
+    }
+
+    mdns_info = (wdi_mdns_enable_offload_cmd_req *)
+        vos_mem_malloc(sizeof(*mdns_info));
+    if (!mdns_info) {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "Failed to allocate buffer to send "
+              "set_mdns_offload cmd");
+        vos_mem_free(mdns_offload_info);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    vos_mem_zero(mdns_info, sizeof(*mdns_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(mdns_info);
+        vos_mem_free(mdns_offload_info);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    mdns_info->bss_idx = mdns_offload_info->bss_idx;
+    mdns_info->enable = mdns_offload_info->enable;
+
+    wda_params->pWdaContext = wda_handle;
+    wda_params->wdaMsgParam = mdns_offload_info;
+    wda_params->wdaWdiApiMsgParam = (void *)mdns_info;
+
+    wstatus = wdi_set_mdns_offload_req(mdns_info,
+                    (wdi_mdns_enable_rsp_cb)
+                     wda_mdns_enable_rsp_callback,
+                     wda_params);
+    if(IS_WDI_STATUS_FAILURE(wstatus))
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "Failed to send wdi_set_mdns_offload_req 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,
+          "mdns enabled!");
+    return status;
+
+}
+
+/**
+ * wda_set_mdns_fqdn_req() - wda api to set mdns fqdn offload
+ * @wda_handle: wda handle
+ * @mdns_fqdn_info: mdns fqdn offload info
+ *
+ * Return - 0 for success or else failure
+ */
+static int
+wda_set_mdns_fqdn_req(tWDA_CbContext *wda_handle,
+              sir_mdns_fqdn_info_t *mdns_fqdn_info)
+{
+    wdi_mdns_set_fqdn_cmd_req *fqdn_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 == mdns_fqdn_info)
+    {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "%s: set_mdns_fqdn received NULL",
+              __func__);
+        VOS_ASSERT(0) ;
+        return VOS_STATUS_E_FAULT;
+    }
+
+    fqdn_info = (wdi_mdns_set_fqdn_cmd_req *)
+        vos_mem_malloc(sizeof(*fqdn_info));
+    if (!fqdn_info) {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "Failed to allocate buffer to send "
+              "set_mdns_fqdn cmd");
+        vos_mem_free(mdns_fqdn_info);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    vos_mem_zero(fqdn_info, sizeof(*fqdn_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(fqdn_info);
+        vos_mem_free(mdns_fqdn_info);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    fqdn_info->bss_idx = mdns_fqdn_info->bss_idx;
+    fqdn_info->type = mdns_fqdn_info->fqdn_type;
+    fqdn_info->fqdn_len = mdns_fqdn_info->fqdn_len;
+    vos_mem_copy(fqdn_info->fqdn_data, mdns_fqdn_info->fqdn_data,
+             mdns_fqdn_info->fqdn_len);
+    fqdn_info->fqdn_data[mdns_fqdn_info->fqdn_len] = '\0';
+
+    wda_params->pWdaContext = wda_handle;
+    wda_params->wdaMsgParam = mdns_fqdn_info;
+    wda_params->wdaWdiApiMsgParam = (void *)fqdn_info;
+
+    wstatus = wdi_set_mdns_fqdn_req(fqdn_info,
+                    (wdi_mdns_fqdn_rsp_cb)
+                     wda_mdns_fqdn_rsp_callback,
+                     wda_params);
+    if(IS_WDI_STATUS_FAILURE(wstatus))
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "Failed to send wdi_set_mdns_fqdn_req 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,
+          "mDNS FQDN set");
+    return status;
+}
+
+/**
+ * wda_set_mdns_response_req() - wda api to set mdns resp offload
+ * @wda_handle: wda handle
+ * @mdns_rsp_info: mdns resp offload info
+ *
+ * Return - 0 for success or else failure
+ */
+static int
+wda_set_mdns_response_req(tWDA_CbContext *wda_handle,
+              sir_mdns_resp_info_t *mdns_rsp_info)
+{
+    wdi_mdns_set_resp_req *rsp_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 == mdns_rsp_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;
+    }
+
+    rsp_info = (wdi_mdns_set_resp_req *)
+        vos_mem_malloc(sizeof(*rsp_info));
+    if (!rsp_info) {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "Failed to allocate buffer to send "
+              "wdi_set_mdns_response_req cmd");
+        vos_mem_free(mdns_rsp_info);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    vos_mem_zero(rsp_info, sizeof(*rsp_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(rsp_info);
+        vos_mem_free(mdns_rsp_info);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    rsp_info->bss_idx = mdns_rsp_info->bss_idx;
+    rsp_info->ar_count = mdns_rsp_info->resourceRecord_count;
+    rsp_info->resp_len = mdns_rsp_info->resp_len;
+    vos_mem_copy(rsp_info->resp_data, mdns_rsp_info->resp_data,
+             mdns_rsp_info->resp_len);
+    rsp_info->resp_data[mdns_rsp_info->resp_len] = '\0';
+
+    wda_params->pWdaContext = wda_handle;
+    wda_params->wdaMsgParam = mdns_rsp_info;
+    wda_params->wdaWdiApiMsgParam = (void *)rsp_info;
+
+    wstatus = wdi_set_mdns_response_req(rsp_info,
+                    (wdi_mdns_resp_rsp_cb)
+                     wda_mdns_resp_rsp_callback,
+                     wda_params);
+    if(IS_WDI_STATUS_FAILURE(wstatus))
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "Failed to send wdi_set_mdns_response_req 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,
+          "mDNS Response set!");
+    return status;
+}
+
+/**
+ * wda_get_mdns_stats_req() - wda api to get mdns stats
+ * @wda_handle: wda handle
+ * @mdns_info: mdns info
+ *
+ * Return - 0 for success or else failure
+ */
+static int
+wda_get_mdns_stats_req(tWDA_CbContext *wda_handle,
+               sir_get_mdns_stats_info_t *mdns_info)
+{
+    wdi_mdns_get_stats_req *status_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 == mdns_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;
+    }
+
+    status_info = (wdi_mdns_get_stats_req *)
+        vos_mem_malloc(sizeof(*status_info));
+    if (!status_info) {
+        VOS_TRACE(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+              "Failed to allocate buffer to send "
+              "wdi_set_mdns_response_req cmd");
+        vos_mem_free(mdns_info);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    vos_mem_zero(status_info, sizeof(*status_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(status_info);
+        vos_mem_free(mdns_info);
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    status_info->bss_idx = mdns_info->bss_idx;
+
+    wda_params->pWdaContext = wda_handle;
+    wda_params->wdaMsgParam = mdns_info;
+    wda_params->wdaWdiApiMsgParam = (void *)status_info;
+
+    wstatus = wdi_get_mdns_stats_req(status_info,
+                    (wdi_get_stats_rsp_cb)
+                     wda_get_stats_rsp_callback,
+                     wda_params);
+    if(IS_WDI_STATUS_FAILURE(wstatus))
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               "Failed to send wdi_set_mdns_response_req 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,
+          "Get mDNS stats");
+    return status;
+}
+#endif /* MDNS_OFFLOAD */
 
 /*
  * FUNCTION: WDA_McProcessMsg
@@ -16591,8 +17170,24 @@
          break;
       }
 #endif /* DHCP_SERVER_OFFLOAD */
-
-
+#ifdef MDNS_OFFLOAD
+      case WDA_SET_MDNS_OFFLOAD_CMD:
+         wda_set_mdns_offload_req(pWDA,
+              (sir_mdns_offload_info_t *)pMsg->bodyptr);
+      break;
+      case WDA_SET_MDNS_FQDN_CMD:
+         wda_set_mdns_fqdn_req(pWDA,
+              (sir_mdns_fqdn_info_t *)pMsg->bodyptr);
+      break;
+      case WDA_SET_MDNS_RESPONSE_CMD:
+         wda_set_mdns_response_req(pWDA,
+              (sir_mdns_resp_info_t *)pMsg->bodyptr);
+      break;
+      case WDA_GET_MDNS_STATUS_CMD:
+         wda_get_mdns_stats_req(pWDA,
+              (sir_get_mdns_stats_info_t *) pMsg->bodyptr);
+      break;
+#endif /* MDNS_OFFLOAD */
       case WDA_NAN_REQUEST:
       {
          WDA_ProcessNanRequest( pWDA, (tNanRequest *)pMsg->bodyptr);
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 782f704..952d920 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -6469,6 +6469,121 @@
 } wdi_dhcp_server_offload_rsp_param_t;
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+/**
+ * The purpose of the multicast Domain Name System (mDNS) is to resolve host
+ * names to IP addresses within small networks that do not include a local
+ * name server. It utilizes essentially the same programming interfaces, packet
+ * formats and operating semantics as the unicast DNS, and the advantage is
+ * zero configuration service while no need for central or global server.
+ * Based on mDNS, the DNS-SD (Service Discovery) allows clients to discover a
+ * named list of services by type in a specified domain using standard
+ * DNS queries. Here, we provide the ability to advertise the available
+ * services by responding to mDNS queries.
+ */
+
+/**
+ * wdi_mdns_enable_offload_cmd_req - mdns enable request
+ * @bss_idx: bss index
+ * @enable: enable
+ */
+typedef struct {
+    wpt_uint8 bss_idx;
+    wpt_uint32 enable;
+} wdi_mdns_enable_offload_cmd_req;
+
+/**
+ * wdi_mdns_enable_offload_rsp_param_t - mDNS enable offload response
+ * @status: status for the command success or failure
+ */
+typedef struct
+{
+    wpt_uint32   status;
+} wdi_mdns_enable_offload_rsp_param_t;
+
+#define WMI_MAX_MDNS_FQDN_LEN         64
+#define WMI_MAX_MDNS_RESP_LEN         512
+#define WMI_MDNS_FQDN_TYPE_GENERAL    0
+#define WMI_MDNS_FQDN_TYPE_UNIQUE     1
+
+/**
+ * wdi_mdns_set_fqdn_cmd_req - set fqdn request
+ * @bss_idx: bss index
+ * @type: type of fqdn, general or unique
+ * @fqdn_len: length of fqdn
+ * @fqdn_data: TLV byte stream of fqdn data of length fqdn_len fully-qualified
+ *	domain name to check if match with the received queries
+ */
+typedef struct {
+    wpt_uint8 bss_idx;
+    wpt_uint32 type;
+    wpt_uint32 fqdn_len;
+    wpt_uint8 fqdn_data[WMI_MAX_MDNS_FQDN_LEN];
+} wdi_mdns_set_fqdn_cmd_req;
+
+/**
+ * wdi_mdns_set_fqdn_rsp_param_t - mDNS set fqdn response
+ * @status: status for the command success or failure
+ */
+typedef struct
+{
+    wpt_uint32   status;
+} wdi_mdns_set_fqdn_rsp_param_t;
+
+/**
+ * wdi_mdns_set_resp_req - mDNS response request
+ * @bss_idx: bss index
+ * @ar_count: Answer Resource Record count
+ * @resp_len: length of response
+ * @resp_data: TLV byte stream of resp data of length resp_len responses consisits of Resource Records
+ */
+typedef struct {
+    wpt_uint8 bss_idx;
+    wpt_uint32 ar_count;
+    wpt_uint32 resp_len;
+    wpt_uint8 resp_data[WMI_MAX_MDNS_RESP_LEN];
+} wdi_mdns_set_resp_req;
+
+/**
+ * wdi_mdns_set_rsp_param_t - mDNS set response rsp
+ * @status: status for the command success or failure
+ */
+typedef struct
+{
+    wpt_uint32   status;
+} wdi_mdns_set_rsp_param_t;
+
+/**
+ * wdi_mdns_get_stats_req - get mdns stats request
+ * @bss_idx: bss index
+ */
+typedef struct {
+    wpt_uint8 bss_idx;
+} wdi_mdns_get_stats_req;
+
+/**
+ * wdi_mdns_stats_rsp_t - mdns stats
+ * @bss_idx: bss index
+ * @current_ts: curTimestamp in milliseconds
+ * @last_querry_ts: last received Query in milliseconds
+ * @last_resp_ts: last sent Response in milliseconds
+ * @tot_queries: stats of received queries
+ * @tot_matches: stats of macth queries
+ * @tot_rsp: stats of responses
+ * @status: indicate the current status of mDNS offload
+ */
+typedef struct {
+    wpt_uint8 bss_idx;
+    wpt_uint32 current_ts;
+    wpt_uint32 last_querry_ts;
+    wpt_uint32 last_resp_ts;
+    wpt_uint32 tot_queries;
+    wpt_uint32 tot_matches;
+    wpt_uint32 tot_rsp;
+    wpt_uint32 status;
+} wdi_mdns_stats_rsp_param_t;
+#endif /* MDNS_OFFLOAD */
+
 /**
  * struct WDI_FwrMemDumpReqType - firmware memory dump request details.
 .*.@FWMemDumpReqCb - Associated Callback
@@ -8502,6 +8617,13 @@
 #ifdef DHCP_SERVER_OFFLOAD
 typedef void (*wdi_dhcp_srv_offload_rsp_cb)(void *event_data,void *user_data);
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+typedef void (*wdi_mdns_enable_rsp_cb)(void *event_data,void *user_data);
+typedef void (*wdi_mdns_fqdn_rsp_cb)(void *event_data,void *user_data);
+typedef void (*wdi_mdns_resp_rsp_cb)(void *event_data,void *user_data);
+typedef void (*wdi_get_stats_rsp_cb)(void *event_data,void *user_data);
+#endif /* MDNS_OFFLOAD */
+
 
 /*========================================================================
  *     Function Declarations and Documentation
@@ -12306,4 +12428,38 @@
 );
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+WDI_Status
+wdi_set_mdns_offload_req
+(
+   wdi_mdns_enable_offload_cmd_req *mdns_info,
+   wdi_mdns_enable_rsp_cb wdi_mdns_enable_rsp_callback,
+   void *user_data
+);
+
+WDI_Status
+wdi_set_mdns_fqdn_req
+(
+   wdi_mdns_set_fqdn_cmd_req *mdns_info,
+   wdi_mdns_fqdn_rsp_cb wdi_mdns_fqdn_rsp_callback,
+   void *user_data
+);
+
+WDI_Status
+wdi_set_mdns_response_req
+(
+   wdi_mdns_set_resp_req *mdns_info,
+   wdi_mdns_resp_rsp_cb wdi_mdns_resp_rsp_callback,
+   void *user_data
+);
+
+WDI_Status
+wdi_get_mdns_stats_req
+(
+   wdi_mdns_get_stats_req *mdns_info,
+   wdi_get_stats_rsp_cb wdi_get_stats_rsp_callback,
+   void *user_data
+);
+#endif /* MDNS_OFFLOAD */
+
 #endif /* #ifndef WLAN_QCT_WDI_H */
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
index 3455220..a85761c 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
@@ -495,6 +495,10 @@
 #endif
 
   WDI_DHCP_SERVER_OFFLOAD_REQ                    = 118,
+  WDI_MDNS_ENABLE_OFFLOAD_REQ                    = 119,
+  WDI_MDNS_FQDN_OFFLOAD_REQ                      = 120,
+  WDI_MDNS_RESP_OFFLOAD_REQ                      = 121,
+  WDI_MDNS_STATS_OFFLOAD_REQ                     = 122,
 
   WDI_MAX_REQ,
 
@@ -876,6 +880,10 @@
   WDI_PER_ROAM_SCAN_TRIGGER_RSP                  = 117,
 #endif
   WDI_DHCP_SERVER_OFFLOAD_RSP                    = 118,
+  WDI_MDNS_ENABLE_OFFLOAD_RSP                    = 119,
+  WDI_MDNS_FQDN_OFFLOAD_RSP                      = 120,
+  WDI_MDNS_RESP_OFFLOAD_RSP                      = 121,
+  WDI_MDNS_STATS_OFFLOAD_RSP                     = 122,
 
   /*-------------------------------------------------------------------------
     Indications
@@ -6715,5 +6723,63 @@
 );
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+WDI_Status
+wdi_mdns_enable_offload_req
+(
+  WDI_ControlBlockType *wdi_ctx,
+  WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_enable_offload_rsp
+(
+  WDI_ControlBlockType *wdi_ctx,
+  WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_fqdn_offload_req
+(
+  WDI_ControlBlockType *wdi_ctx,
+  WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_fqdn_offload_rsp
+(
+  WDI_ControlBlockType *wdi_ctx,
+  WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_resp_offload_req
+(
+  WDI_ControlBlockType *wdi_ctx,
+  WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_mdns_resp_offload_rsp
+(
+  WDI_ControlBlockType *wdi_ctx,
+  WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_get_mdns_stats_offload_req
+(
+  WDI_ControlBlockType *wdi_ctx,
+  WDI_EventInfoType *event_data
+);
+
+WDI_Status
+wdi_get_mdns_stats_offload_rsp
+(
+  WDI_ControlBlockType *wdi_ctx,
+  WDI_EventInfoType *event_data
+);
+#endif /* MDNS_OFFLOAD */
+
 #endif /*WLAN_QCT_WDI_I_H*/
 
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index eefcfc1..4206760 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -524,6 +524,17 @@
 #else
   NULL,
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+  wdi_mdns_enable_offload_req,   /* WDI_MDNS_ENABLE_OFFLOAD_REQ */
+  wdi_mdns_fqdn_offload_req,     /* WDI_MDNS_FQDN_OFFLOAD_REQ */
+  wdi_mdns_resp_offload_req,     /* WDI_MDNS_RESP_OFFLOAD_REQ */
+  wdi_get_mdns_stats_offload_req, /* WDI_GET_MDNS_STATS_OFFLOAD_REQ */
+#else
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+#endif /* MDNS_OFFLOAD */
 
   /*-------------------------------------------------------------------------
     Indications
@@ -854,6 +865,17 @@
 #else
     NULL,
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+    wdi_mdns_enable_offload_rsp, /* WDI_MDNS_ENABLE_OFFLOAD_RSP */
+    wdi_mdns_fqdn_offload_rsp, /* WDI_MDNS_FQDN_OFFLOAD_RSP */
+    wdi_mdns_resp_offload_rsp, /* WDI_MDNS_RESP_OFFLOAD_RSP */
+    wdi_get_mdns_stats_offload_rsp, /* WDI_MDNS_STATS_OFFLOAD_RSP */
+#else
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+#endif /* MDNS_OFFLOAD */
   /*---------------------------------------------------------------------
     Indications
   ---------------------------------------------------------------------*/
@@ -1320,6 +1342,12 @@
 #ifdef DHCP_SERVER_OFFLOAD
     CASE_RETURN_STRING( WDI_DHCP_SERVER_OFFLOAD_REQ );
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+    CASE_RETURN_STRING( WDI_MDNS_ENABLE_OFFLOAD_REQ );
+    CASE_RETURN_STRING( WDI_MDNS_FQDN_OFFLOAD_REQ );
+    CASE_RETURN_STRING( WDI_MDNS_RESP_OFFLOAD_REQ );
+    CASE_RETURN_STRING( WDI_MDNS_STATS_OFFLOAD_REQ );
+#endif /* MDNS_OFFLOAD */
     default:
         return "Unknown WDI MessageId";
   }
@@ -1365,6 +1393,163 @@
 }
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+/**
+ * wdi_set_mdns_offload_req() - wdi api to set mdns enable offload
+ * @mdns_info: pointer to dhcp server offload
+ * @wdi_mdns_enable_offload_rsp_callback: response callback
+ * @user_data: pointer to user data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_set_mdns_offload_req
+
+(
+ wdi_mdns_enable_offload_cmd_req *mdns_info,
+ wdi_mdns_enable_rsp_cb wdi_mdns_enable_offload_rsp_callback,
+ void *user_data
+)
+{
+    WDI_EventInfoType wdi_event_data;
+
+    if ( eWLAN_PAL_FALSE == gWDIInitialized )
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+               "WDI API call before module is initialized - Fail request");
+        return WDI_STATUS_E_NOT_ALLOWED;
+    }
+
+    /*-------------------------------------------------------------------
+      Fill in Event data and post to the Main FSM
+      -----------------------------------------------------------------*/
+    wdi_event_data.wdiRequest      = WDI_MDNS_ENABLE_OFFLOAD_REQ;
+    wdi_event_data.pEventData      = mdns_info;
+    wdi_event_data.uEventDataSize  = sizeof(*mdns_info);
+    wdi_event_data.pCBfnc           = wdi_mdns_enable_offload_rsp_callback;
+    wdi_event_data.pUserData       = user_data;
+
+    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data);
+}
+
+/**
+ * wdi_set_mdns_fqdn_req() - wdi api to set mdns fqdn request
+ * @fqdn_info: pointer to dhcp server offload
+ * @wdi_mdns_fqdn_offload_rsp_callback: response callback
+ * @user_data: pointer to user data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_set_mdns_fqdn_req
+
+(
+ wdi_mdns_set_fqdn_cmd_req *fqdn_info,
+ wdi_mdns_fqdn_rsp_cb wdi_mdns_fqdn_offload_rsp_callback,
+ void *user_data
+)
+{
+    WDI_EventInfoType wdi_event_data;
+
+    if ( eWLAN_PAL_FALSE == gWDIInitialized )
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+               "WDI API call before module is initialized - Fail request");
+        return WDI_STATUS_E_NOT_ALLOWED;
+    }
+
+    /*-------------------------------------------------------------------
+      Fill in Event data and post to the Main FSM
+      -----------------------------------------------------------------*/
+    wdi_event_data.wdiRequest      = WDI_MDNS_FQDN_OFFLOAD_REQ;
+    wdi_event_data.pEventData      = fqdn_info;
+    wdi_event_data.uEventDataSize  = sizeof(*fqdn_info);
+    wdi_event_data.pCBfnc           = wdi_mdns_fqdn_offload_rsp_callback;
+    wdi_event_data.pUserData       = user_data;
+
+    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data);
+}
+
+/**
+ * wdi_set_mdns_response_req() - wdi api to mdns response
+ * @resp_info: pointer to mdns response
+ * @wdi_mdns_resp_offload_rsp_callback: response callback
+ * @user_data: pointer to user data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_set_mdns_response_req
+
+(
+ wdi_mdns_set_resp_req *resp_info,
+ wdi_mdns_resp_rsp_cb wdi_mdns_resp_offload_rsp_callback,
+ void *user_data
+)
+{
+    WDI_EventInfoType wdi_event_data;
+
+    if ( eWLAN_PAL_FALSE == gWDIInitialized )
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+               "WDI API call before module is initialized - Fail request");
+        return WDI_STATUS_E_NOT_ALLOWED;
+    }
+
+    /*-------------------------------------------------------------------
+      Fill in Event data and post to the Main FSM
+      -----------------------------------------------------------------*/
+    wdi_event_data.wdiRequest      = WDI_MDNS_RESP_OFFLOAD_REQ;
+    wdi_event_data.pEventData      = resp_info;
+    wdi_event_data.uEventDataSize  = sizeof(*resp_info);
+    wdi_event_data.pCBfnc           = wdi_mdns_resp_offload_rsp_callback;
+    wdi_event_data.pUserData       = user_data;
+
+    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data);
+}
+
+/**
+ * wdi_get_mdns_stats_req() - wdi api to get mdns stats
+ * @stats_info: pointer to mdns stats info
+ * @wdi_get_stats_offload_rsp_callback: response callback
+ * @user_data: pointer to user data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_get_mdns_stats_req
+(
+ wdi_mdns_get_stats_req *stats_info,
+ wdi_get_stats_rsp_cb wdi_get_stats_offload_rsp_callback,
+ void *user_data
+)
+{
+    WDI_EventInfoType wdi_event_data;
+
+    if ( eWLAN_PAL_FALSE == gWDIInitialized )
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+               "WDI API call before module is initialized - Fail request");
+        return WDI_STATUS_E_NOT_ALLOWED;
+    }
+
+    /*-------------------------------------------------------------------
+      Fill in Event data and post to the Main FSM
+      -----------------------------------------------------------------*/
+    wdi_event_data.wdiRequest      = WDI_MDNS_STATS_OFFLOAD_REQ;
+    wdi_event_data.pEventData      = stats_info;
+    wdi_event_data.uEventDataSize  = sizeof(*stats_info);
+    wdi_event_data.pCBfnc           = wdi_get_stats_offload_rsp_callback;
+    wdi_event_data.pUserData       = user_data;
+
+    return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdi_event_data);
+}
+#endif /* MDNS_OFFLOAD */
+
 /**
  @brief WDI_getRespMsgString prints the WDI resonse message in string.
 
@@ -24831,6 +25016,16 @@
   case WDI_DHCP_SERVER_OFFLOAD_REQ:
       return WLAN_HAL_DHCP_SERVER_OFFLOAD_REQ;
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+  case WDI_MDNS_ENABLE_OFFLOAD_REQ:
+      return WLAN_HAL_MDNS_ENABLE_OFFLOAD_REQ;
+  case WDI_MDNS_FQDN_OFFLOAD_REQ:
+      return WLAN_HAL_MDNS_FQDN_OFFLOAD_REQ;
+  case WDI_MDNS_RESP_OFFLOAD_REQ:
+      return WLAN_HAL_MDNS_RESP_OFFLOAD_REQ;
+  case WDI_MDNS_STATS_OFFLOAD_REQ:
+      return WLAN_HAL_MDNS_STATS_OFFLOAD_REQ;
+#endif /* MDNS_OFFLOAD */
   default:
     return WLAN_HAL_MSG_MAX;
   }
@@ -25204,6 +25399,16 @@
   case WLAN_HAL_DHCP_SERVER_OFFLOAD_RSP:
        return WDI_DHCP_SERVER_OFFLOAD_RSP;
 #endif /* DHCP_SERVER_OFFLOAD */
+#ifdef MDNS_OFFLOAD
+  case WLAN_HAL_MDNS_ENABLE_OFFLOAD_RSP:
+       return WDI_MDNS_ENABLE_OFFLOAD_RSP;
+  case WLAN_HAL_MDNS_FQDN_OFFLOAD_RSP:
+       return WDI_MDNS_FQDN_OFFLOAD_RSP;
+  case WLAN_HAL_MDNS_RESP_OFFLOAD_RSP:
+       return WDI_MDNS_RESP_OFFLOAD_RSP;
+  case WLAN_HAL_MDNS_STATS_OFFLOAD_RSP:
+       return WDI_MDNS_STATS_OFFLOAD_RSP;
+#endif /* MDNS_OFFLOAD */
   default:
     return eDRIVER_TYPE_MAX;
   }
@@ -33876,7 +34081,7 @@
 {
 	wdi_dhcp_srv_offload_rsp_cb wdi_dhcp_srv_offload_rsp_callback;
 
-	WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+	WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
 		   "%s: Enter ", __func__);
 	/*-------------------------------------------------------------------
 	  Sanity check
@@ -33900,6 +34105,168 @@
 }
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+/**
+ * wdi_mdns_enable_offload_rsp() - wdi api for the mdns enable response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ *	WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_enable_offload_rsp
+(
+    WDI_ControlBlockType *wdi_ctx,
+    WDI_EventInfoType *event_data
+)
+{
+    wdi_mdns_enable_rsp_cb wdi_mdns_rsp_callback;
+
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+           "%s: Enter ", __func__);
+    /*-------------------------------------------------------------------
+      Sanity check
+      -----------------------------------------------------------------*/
+    if ((NULL == wdi_ctx) || (NULL == event_data) ||
+        (NULL == event_data->pEventData))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+               "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_rsp_callback =
+        (wdi_mdns_enable_rsp_cb)wdi_ctx->pfncRspCB;
+
+    wdi_mdns_rsp_callback((void *) event_data->pEventData,
+                      wdi_ctx->pRspCBUserData);
+
+    return WDI_STATUS_SUCCESS;
+}
+
+/**
+ * wdi_mdns_fqdn_offload_rsp() - wdi api for the mdns fqdn response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_fqdn_offload_rsp
+(
+    WDI_ControlBlockType *wdi_ctx,
+    WDI_EventInfoType *event_data
+)
+{
+    wdi_mdns_enable_rsp_cb wdi_mdns_rsp_callback;
+
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+           "%s: Enter ", __func__);
+    /*-------------------------------------------------------------------
+      Sanity check
+      -----------------------------------------------------------------*/
+    if ((NULL == wdi_ctx) || (NULL == event_data) ||
+        (NULL == event_data->pEventData))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+               "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_rsp_callback =
+        (wdi_mdns_enable_rsp_cb)wdi_ctx->pfncRspCB;
+
+    wdi_mdns_rsp_callback((void *) event_data->pEventData,
+                      wdi_ctx->pRspCBUserData);
+
+    return WDI_STATUS_SUCCESS;
+}
+
+/**
+ * wdi_mdns_resp_offload_rsp() - wdi api for the mdns resp response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_resp_offload_rsp
+(
+    WDI_ControlBlockType *wdi_ctx,
+    WDI_EventInfoType *event_data
+)
+{
+    wdi_mdns_resp_rsp_cb wdi_mdns_rsp_callback;
+
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+           "%s: Enter ", __func__);
+    /*-------------------------------------------------------------------
+      Sanity check
+      -----------------------------------------------------------------*/
+    if ((NULL == wdi_ctx) || (NULL == event_data) ||
+        (NULL == event_data->pEventData))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+               "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_rsp_callback =
+        (wdi_mdns_resp_rsp_cb)wdi_ctx->pfncRspCB;
+
+    wdi_mdns_rsp_callback((void *) event_data->pEventData,
+                      wdi_ctx->pRspCBUserData);
+
+    return WDI_STATUS_SUCCESS;
+}
+
+/**
+ * wdi_get_mdns_stats_offload_rsp() - wdi api for the mdns stats response
+ * @wdi_ctx: pointer to the wdi context
+ * @event_data: pointer to the event data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_get_mdns_stats_offload_rsp
+(
+    WDI_ControlBlockType *wdi_ctx,
+    WDI_EventInfoType *event_data
+)
+{
+    wdi_get_stats_rsp_cb wdi_mdns_rsp_callback;
+
+    WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+           "%s: Enter ", __func__);
+    /*-------------------------------------------------------------------
+      Sanity check
+      -----------------------------------------------------------------*/
+    if ((NULL == wdi_ctx) || (NULL == event_data) ||
+        (NULL == event_data->pEventData))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+               "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_rsp_callback =
+        (wdi_get_stats_rsp_cb)wdi_ctx->pfncRspCB;
+
+    wdi_mdns_rsp_callback((void *) event_data->pEventData,
+                      wdi_ctx->pRspCBUserData);
+
+    return WDI_STATUS_SUCCESS;
+}
+#endif /* MDNS_OFFLOAD */
+
 WDI_Status
 WDI_ProcessMonStartRsp
 (
@@ -36923,6 +37290,365 @@
 }
 #endif /* DHCP_SERVER_OFFLOAD */
 
+#ifdef MDNS_OFFLOAD
+/**
+ * wdi_mdns_enable_offload_req() - wdi api for dhcp server offload
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_enable_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+ )
+{
+    wdi_mdns_enable_offload_cmd_req *wdi_mdns_enable_info;
+    wpt_uint8 *buff  = NULL;
+    wpt_uint16 data_offset = 0;
+    wpt_uint16 size = 0;
+    WDI_Status wdi_status;
+    hal_mdns_enable_offload_req_msg_t mdns_enable_req;
+    wdi_mdns_enable_rsp_cb wdi_mdns_enable_rsp_callback;;
+
+    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+          "%s: %d Enter",__func__, __LINE__);
+
+    /*------------------------------------------------------------------
+      Sanity check
+      ------------------------------------------------------------------*/
+    if ((NULL == wdi_ctx) || (NULL == event_data) ||
+        (NULL == event_data->pEventData))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+               "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_enable_info = (wdi_mdns_enable_offload_cmd_req *)
+        event_data->pEventData;
+
+    /*-------------------------------------------------------------------
+      Get message buffer
+      -----------------------------------------------------------------*/
+    if (( WDI_STATUS_SUCCESS !=
+          WDI_GetMessageBuffer(wdi_ctx,
+                   WDI_MDNS_ENABLE_OFFLOAD_REQ,
+                   sizeof(mdns_enable_req.
+                      mdns_enable_req_params),
+                   &buff, &data_offset, &size))||
+        (size < (data_offset +
+             sizeof(mdns_enable_req.mdns_enable_req_params))))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+               "Unable to get send buffer in GetFrameLog Req");
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    mdns_enable_req.mdns_enable_req_params.bss_idx =
+        wdi_mdns_enable_info->bss_idx;
+    mdns_enable_req.mdns_enable_req_params.enable =
+        wdi_mdns_enable_info->enable;
+
+    wdi_mdns_enable_rsp_callback = (wdi_mdns_enable_rsp_cb)
+        event_data->pCBfnc;
+
+    wpalMemoryCopy(buff+data_offset,
+               &mdns_enable_req.mdns_enable_req_params,
+               sizeof(mdns_enable_req.
+                  mdns_enable_req_params));
+
+    /*-------------------------------------------------------------------
+      Send Suspend Request to HAL
+      -----------------------------------------------------------------*/
+    wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+                 wdi_mdns_enable_rsp_callback,
+                 event_data->pUserData,
+                 WDI_MDNS_ENABLE_OFFLOAD_RSP);
+    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+          "%s: %d Exit",__func__, __LINE__);
+    return wdi_status;
+}
+
+/**
+ * wdi_mdns_fqdn_offload_req() - wdi api for mdns fqdn offload
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_fqdn_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+ )
+{
+    wdi_mdns_set_fqdn_cmd_req *wdi_mdns_fqdn_info;
+    wpt_uint8 *buff  = NULL;
+    wpt_uint16 buf_size, data_offset = 0;
+    wpt_uint16 temp_size, size = 0;
+    WDI_Status wdi_status;
+    hal_mdns_fqdn_offload_req_param_t mdns_fqdn;
+    wdi_mdns_fqdn_rsp_cb wdi_mdns_fqdn_rsp_callback;;
+
+    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+          "%s: %d Enter",__func__, __LINE__);
+
+    /*------------------------------------------------------------------
+      Sanity check
+      ------------------------------------------------------------------*/
+    if ((NULL == wdi_ctx) || (NULL == event_data) ||
+        (NULL == event_data->pEventData))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+               "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_fqdn_info = (wdi_mdns_set_fqdn_cmd_req *)
+        event_data->pEventData;
+
+    mdns_fqdn.bss_idx = wdi_mdns_fqdn_info->bss_idx;
+    mdns_fqdn.type = wdi_mdns_fqdn_info->type;
+    mdns_fqdn.fqdn_len = wdi_mdns_fqdn_info->fqdn_len;
+
+    buf_size = sizeof(mdns_fqdn) + mdns_fqdn.fqdn_len -
+        sizeof(mdns_fqdn.fqdn_data[1]);
+
+    /*-------------------------------------------------------------------
+      Get message buffer
+      -----------------------------------------------------------------*/
+    if (( WDI_STATUS_SUCCESS !=
+          WDI_GetMessageBuffer(wdi_ctx,
+                   WDI_MDNS_FQDN_OFFLOAD_REQ,
+                   buf_size,
+                   &buff, &data_offset, &size))||
+        (size < (data_offset + buf_size)))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+               "Unable to get send buffer in GetFrameLog Req");
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_fqdn_rsp_callback = (wdi_mdns_fqdn_rsp_cb)
+        event_data->pCBfnc;
+
+    temp_size = 0;
+    wpalMemoryCopy(buff+data_offset+temp_size,
+            &mdns_fqdn.bss_idx,
+            sizeof(mdns_fqdn.bss_idx));
+    temp_size += sizeof(mdns_fqdn.bss_idx);
+    wpalMemoryCopy(buff+data_offset+temp_size,
+            &mdns_fqdn.type,
+            sizeof(mdns_fqdn.type));
+    temp_size += sizeof(mdns_fqdn.type);
+    wpalMemoryCopy(buff+data_offset+temp_size,
+            &mdns_fqdn.fqdn_len,
+            sizeof(mdns_fqdn.fqdn_len));
+    temp_size += sizeof(mdns_fqdn.fqdn_len);
+    wpalMemoryCopy(buff+data_offset+temp_size,
+            wdi_mdns_fqdn_info->fqdn_data,
+            wdi_mdns_fqdn_info->fqdn_len);
+
+    /*-------------------------------------------------------------------
+      Send Suspend Request to HAL
+      -----------------------------------------------------------------*/
+    wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+                 wdi_mdns_fqdn_rsp_callback,
+                 event_data->pUserData,
+                 WDI_MDNS_FQDN_OFFLOAD_RSP);
+    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+          "%s: %d Exit",__func__, __LINE__);
+    return wdi_status;
+}
+
+/**
+ * wdi_mdns_resp_offload_req() - wdi api for mdns response offload
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_mdns_resp_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+ )
+{
+    wdi_mdns_set_resp_req *wdi_mdns_resp_info;
+    wpt_uint8 *buff  = NULL;
+    wpt_uint16 buf_size, data_offset = 0;
+    wpt_uint16 temp_size, size = 0;
+    WDI_Status wdi_status;
+    hal_mdns_resp_offload_req_param_t mdns_resp;
+    wdi_mdns_resp_rsp_cb wdi_mdns_resp_rsp_callback;;
+
+    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+          "%s: %d Enter",__func__, __LINE__);
+
+    /*------------------------------------------------------------------
+      Sanity check
+      ------------------------------------------------------------------*/
+    if ((NULL == wdi_ctx) || (NULL == event_data) ||
+        (NULL == event_data->pEventData))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+               "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_resp_info = (wdi_mdns_set_resp_req *)
+        event_data->pEventData;
+
+    mdns_resp.bss_idx = wdi_mdns_resp_info->bss_idx;
+    mdns_resp.ar_count = wdi_mdns_resp_info->ar_count;
+    mdns_resp.resp_len = wdi_mdns_resp_info->resp_len;
+
+    buf_size = sizeof(mdns_resp) + mdns_resp.resp_len -
+        sizeof(mdns_resp.resp_data[1]);
+
+    /*-------------------------------------------------------------------
+      Get message buffer
+      -----------------------------------------------------------------*/
+    if (( WDI_STATUS_SUCCESS !=
+          WDI_GetMessageBuffer(wdi_ctx,
+                   WDI_MDNS_RESP_OFFLOAD_REQ,
+                   buf_size,
+                   &buff, &data_offset, &size))||
+        (size < (data_offset + buf_size)))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+               "Unable to get send buffer in GetFrameLog Req");
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_resp_rsp_callback = (wdi_mdns_resp_rsp_cb)
+        event_data->pCBfnc;
+
+    temp_size = 0;
+    wpalMemoryCopy(buff+data_offset+temp_size,
+            &mdns_resp.bss_idx,
+            sizeof(mdns_resp.bss_idx));
+    temp_size += sizeof(mdns_resp.bss_idx);
+    wpalMemoryCopy(buff+data_offset+temp_size,
+            &mdns_resp.ar_count,
+            sizeof(mdns_resp.ar_count));
+    temp_size += sizeof(mdns_resp.ar_count);
+    wpalMemoryCopy(buff+data_offset+temp_size,
+            &mdns_resp.resp_len,
+            sizeof(mdns_resp.resp_len));
+    temp_size += sizeof(mdns_resp.resp_len);
+    wpalMemoryCopy(buff+data_offset+temp_size,
+            &wdi_mdns_resp_info->resp_data,
+            wdi_mdns_resp_info->resp_len);
+
+    /*-------------------------------------------------------------------
+      Send Suspend Request to HAL
+      -----------------------------------------------------------------*/
+    wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+                 wdi_mdns_resp_rsp_callback,
+                 event_data->pUserData,
+                 WDI_MDNS_RESP_OFFLOAD_RSP);
+    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+          "%s: %d Exit",__func__, __LINE__);
+    return wdi_status;
+}
+
+/**
+ * wdi_get_mdns_stats_offload_req() - wdi api for mdns stats offload
+ * @wdi_ctx: pointer to wdi context
+ * @event_data: pointer to event data
+ *
+ * Return: WDI_Status
+ *    WDI_STATUS_SUCCESS - success or else failure status
+ */
+WDI_Status
+wdi_get_mdns_stats_offload_req
+(
+ WDI_ControlBlockType *wdi_ctx,
+ WDI_EventInfoType *event_data
+ )
+{
+    wdi_mdns_get_stats_req *wdi_mdns_stats_info;
+    wpt_uint8 *buff  = NULL;
+    wpt_uint16 data_offset = 0;
+    wpt_uint16 size = 0;
+    WDI_Status wdi_status;
+    hal_mdns_stats_offload_req_msg_t mdns_stats_req;
+    wdi_get_stats_rsp_cb wdi_mdns_stats_rsp_callback;;
+
+    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+          "%s: %d Enter",__func__, __LINE__);
+
+    /*------------------------------------------------------------------
+      Sanity check
+      ------------------------------------------------------------------*/
+    if ((NULL == wdi_ctx) || (NULL == event_data) ||
+        (NULL == event_data->pEventData))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+               "%s: Invalid parameters", __func__);
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    wdi_mdns_stats_info = (wdi_mdns_get_stats_req *)
+        event_data->pEventData;
+
+    /*-------------------------------------------------------------------
+      Get message buffer
+      -----------------------------------------------------------------*/
+    if (( WDI_STATUS_SUCCESS !=
+          WDI_GetMessageBuffer(wdi_ctx,
+                   WDI_MDNS_STATS_OFFLOAD_REQ,
+                   sizeof(mdns_stats_req.
+                      mdns_stats_req_params),
+                   &buff, &data_offset, &size))||
+        (size < (data_offset +
+             sizeof(mdns_stats_req.mdns_stats_req_params))))
+    {
+        WPAL_TRACE(eWLAN_MODULE_DAL_CTRL,  eWLAN_PAL_TRACE_LEVEL_FATAL,
+               "Unable to get send buffer in GetFrameLog Req");
+        WDI_ASSERT(0);
+        return WDI_STATUS_E_FAILURE;
+    }
+
+    mdns_stats_req.mdns_stats_req_params.bss_idx =
+        wdi_mdns_stats_info->bss_idx;
+
+    wdi_mdns_stats_rsp_callback = (wdi_get_stats_rsp_cb)
+        event_data->pCBfnc;
+
+    wpalMemoryCopy(buff+data_offset,
+               &mdns_stats_req.mdns_stats_req_params,
+               sizeof(mdns_stats_req.
+                  mdns_stats_req_params));
+
+    /*-------------------------------------------------------------------
+      Send Suspend Request to HAL
+      -----------------------------------------------------------------*/
+    wdi_status = WDI_SendMsg(wdi_ctx, buff, size,
+                 wdi_mdns_stats_rsp_callback,
+                 event_data->pUserData,
+                 WDI_MDNS_STATS_OFFLOAD_RSP);
+    VOS_TRACE(VOS_MODULE_ID_WDI, VOS_TRACE_LEVEL_INFO,
+          "%s: %d Exit",__func__, __LINE__);
+    return wdi_status;
+}
+#endif /* MDNS_OFFLOAD */
 
 /**
  @brief Process FWLoggingInit Request
diff --git a/Kbuild b/Kbuild
index c2a7ea0..bfcf34f 100644
--- a/Kbuild
+++ b/Kbuild
@@ -29,6 +29,9 @@
 # JB kernel has CPU enablement patches, so enable
     CONFIG_PRIMA_WLAN_11AC_HIGH_TP := y
 
+#Flag to enable mDNS feature
+    CONFIG_MDNS_OFFLOAD_SUPPORT := y
+
 #Flag to enable TDLS feature
     CONFIG_QCOM_TDLS := y
 
@@ -688,6 +691,10 @@
 CDEFINES += -DWLAN_FEATURE_OFFLOAD_PACKETS
 endif
 
+ifeq ($(CONFIG_MDNS_OFFLOAD_SUPPORT), y)
+CDEFINES += -DMDNS_OFFLOAD
+endif
+
 KBUILD_CPPFLAGS += $(CDEFINES)
 
 # Module information used by KBuild framework
diff --git a/firmware_bin/WCNSS_qcom_cfg.ini b/firmware_bin/WCNSS_qcom_cfg.ini
index ea0c74e..dbb0968 100644
--- a/firmware_bin/WCNSS_qcom_cfg.ini
+++ b/firmware_bin/WCNSS_qcom_cfg.ini
@@ -495,6 +495,34 @@
 # min 100 (default)
 # max 255
 gDHCPStartLsb=100
+
+# mDNS enable
+gMDNSOffloadEnable=1
+# mDNS FQDN query
+gMDNSFqdn="_GoProRemote._tcp.local"
+# mDNS UFQDN query
+gMDNSUniqueFqdn="service._GoProRemote._tcp.local"
+# mDNS response typeA
+gMDNSResponseTypeA="goprobp-D89685121212.local"
+# mDNS response typeAIpv4Addr
+gMDNSResponseTypeAIpv4Addr=0xc0a80102
+# mDNS response typeTXT
+gMDNSResponseTypeTXT="GoProBP-D89685121212._GoProRemote._tcp.local"
+# mDNS response typeTXTContent
+gMDNSResponseTypeTXTContent="Device=HERO 3+-BAWA Model=BAWA Version=HD3.11.02.00 Wifi Version=4.0.36.0 Protocol Version=2"
+# mDNS response typePTR
+gMDNSResponseTypePTR="_GoProRemote._tcp.local"
+# mDNS response typePTRDomainName
+gMDNSResponseTypePTRDomainName="GoProBP-D89685121212._GoProRemote._tcp.local"
+# mDNS response typeSRV
+gMDNSResponseTypeSRV="GoProBP-D89685121212._GoProRemote._tcp.local"
+# mDNS response typeSRVTarget
+gMDNSResponseTypeSRVTarget="goprobp-D89685121212.local"
+# mDNS response typeSRVPriority
+gMDNSResponseTypeSRVPriority=0
+# mDNS response typeSRVWeight
+gMDNSResponseTypeSRVWeight=0
+
 END
 
 # Note: Configuration parser would not read anything past the END marker