diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
index 7894102f03eb0..b2535ad458d72 100644
--- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
@@ -1714,3 +1714,89 @@ int mwifiex_ret_wakeup_reason(struct mwifiex_private *priv,
 
 	return 0;
 }
+
+static int mwifiex_download_vdll_block(struct mwifiex_adapter *adapter, u32 offset,
+				       u16 block_len)
+{
+	int ret;
+	struct host_cmd_ds_gen *cmd_hdr = NULL;
+	u16 msg_len = block_len + sizeof(*cmd_hdr);
+	struct sk_buff *skb;
+	u32 fw_offset;
+
+	block_len = min(block_len, adapter->vdll_len - offset);
+
+	if (offset > adapter->vdll_len)
+		return -EINVAL;
+
+	if (adapter->cmd_sent) {
+		mwifiex_dbg(adapter, MSG, "%s: adapter is busy\n", __func__);
+		return -EBUSY;
+	}
+
+	skb = dev_alloc_skb(msg_len + MWIFIEX_TYPE_LEN);
+	if (!skb) {
+		mwifiex_dbg(adapter, ERROR,
+				"SLEEP_CFM: dev_alloc_skb failed\n");
+		return -ENOMEM;
+	}
+
+	skb_put(skb, msg_len);
+
+	cmd_hdr = (void *)skb->data;
+	cmd_hdr->command = cpu_to_le16(HostCmd_CMD_VDLL);
+	cmd_hdr->seq_num = cpu_to_le16(0xFF00);
+	cmd_hdr->size = cpu_to_le16(msg_len);
+
+	fw_offset = adapter->firmware->size - adapter->vdll_len + offset;
+	memcpy(skb->data + sizeof(*cmd_hdr), adapter->firmware->data + fw_offset, block_len);
+
+	skb_push(skb, adapter->intf_hdr_len);
+
+	ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_VDLL, skb, NULL);
+	if (ret < 0)
+		mwifiex_dbg(adapter, MSG, "DNLD_VDLL: Host to Card Failed\n");
+
+	dev_kfree_skb_any(skb);
+
+	return ret;
+
+}
+
+int mwifiex_process_vdll_event(struct mwifiex_private *priv, struct sk_buff *event_skb)
+{
+	int status = 0;
+	struct mwifiex_vdll_ind *ind;
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	ind = (struct mwifiex_vdll_ind *)(event_skb->data + sizeof(u32));
+
+	switch (le16_to_cpu(ind->type)) {
+	case VDLL_IND_TYPE_REQ:
+		mwifiex_download_vdll_block(adapter, le32_to_cpu(ind->offset),
+					    le16_to_cpu(ind->block_len));
+		break;
+	case VDLL_IND_TYPE_OFFSET:
+		adapter->vdll_len = le32_to_cpu(ind->offset);
+		mwifiex_dbg(adapter, MSG, "VDLL_IND (OFFSET): offset=0x%x\n",
+			    adapter->vdll_len);
+		break;
+	case VDLL_IND_TYPE_ERR_SIG:
+		mwifiex_dbg(adapter, MSG, "VDLL_IND (SIG ERR).\n");
+		break;
+	case VDLL_IND_TYPE_ERR_ID:
+		mwifiex_dbg(adapter, MSG, "VDLL_IND (ID ERR).\n");
+		break;
+	case VDLL_IND_TYPE_SEC_ERR_ID:
+		mwifiex_dbg(adapter, MSG, "VDLL_IND (SECURE ERR).\n");
+		break;
+	case VDLL_IND_TYPE_INTF_RESET:
+		mwifiex_dbg(adapter, MSG, "VDLL_IND (INTF_RESET)\n");
+		break;
+	default:
+		mwifiex_dbg(adapter, MSG, "unknown vdll ind type=%d\n", ind->type);
+		break;
+	}
+
+	return status;
+}
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index e91def0afa14d..f8312f7ba9ac9 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -406,6 +406,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define HostCmd_CMD_FW_DUMP_EVENT		      0x0125
 #define HostCmd_CMD_SDIO_SP_RX_AGGR_CFG               0x0223
 #define HostCmd_CMD_STA_CONFIGURE		      0x023f
+#define HostCmd_CMD_VDLL			      0x0240
 #define HostCmd_CMD_CHAN_REGION_CFG		      0x0242
 #define HostCmd_CMD_PACKET_AGGR_CTRL		      0x0251
 #define HostCmd_CMD_ADD_NEW_STATION		      0x025f
@@ -584,6 +585,7 @@ enum mwifiex_channel_flags {
 #define EVENT_FW_DUMP_INFO		0x00000073
 #define EVENT_TX_STATUS_REPORT		0x00000074
 #define EVENT_BT_COEX_WLAN_PARA_CHANGE	0X00000076
+#define EVENT_VDLL_IND			0x00000081
 
 #define EVENT_ID_MASK                   0xffff
 #define BSS_NUM_MASK                    0xf
@@ -2449,4 +2451,18 @@ struct hw_spec_max_conn {
 	u8 max_sta_conn;
 } __packed;
 
+#define VDLL_IND_TYPE_REQ		0 /* req host side download vdll block */
+#define VDLL_IND_TYPE_OFFSET		1 /* notify vdll start offset in firmware image */
+#define VDLL_IND_TYPE_ERR_SIG		2 /* notify vdll download error: signature error */
+#define VDLL_IND_TYPE_ERR_ID		3 /* notify vdll download error: ID error */
+#define VDLL_IND_TYPE_SEC_ERR_ID	4 /* notify vdll download error: Secure error */
+#define VDLL_IND_TYPE_INTF_RESET	5 /* req host side interface reset */
+
+struct mwifiex_vdll_ind {
+	__le16 type;
+	__le16 vdllId;
+	__le32 offset;
+	__le16 block_len;
+} __packed;
+
 #endif /* !_MWIFIEX_FW_H_ */
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index 529863edd7a25..8b7edde32bb5d 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -132,6 +132,7 @@ enum {
 #define MWIFIEX_TYPE_DATA				0
 #define MWIFIEX_TYPE_AGGR_DATA				10
 #define MWIFIEX_TYPE_EVENT				3
+#define MWIFIEX_TYPE_VDLL				4
 
 #define MAX_BITMAP_RATES_SIZE			18
 
@@ -1045,6 +1046,8 @@ struct mwifiex_adapter {
 	struct delayed_work devdump_work;
 
 	bool ignore_btcoex_events;
+
+	u32 vdll_len;
 };
 
 void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
@@ -1256,6 +1259,7 @@ int mwifiex_cmd_802_11_bg_scan_config(struct mwifiex_private *priv,
 				      struct host_cmd_ds_command *cmd,
 				      void *data_buf);
 int mwifiex_stop_bg_scan(struct mwifiex_private *priv);
+int mwifiex_process_vdll_event(struct mwifiex_private *priv, struct sk_buff *event_skb);
 
 /*
  * This function checks if the queuing is RA based or not.
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index b5f3821a6a8f2..d142e70a7f0e1 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -1088,6 +1088,10 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
 		mwifiex_dbg(adapter, EVENT, "event: firmware debug info\n");
 		mwifiex_fw_dump_info_event(priv, adapter->event_skb);
 		break;
+	case EVENT_VDLL_IND:
+		mwifiex_dbg(adapter, EVENT, "event: VDLL event\n");
+		mwifiex_process_vdll_event(priv, adapter->event_skb);
+		break;
 	/* Debugging event; not used, but let's not print an ERROR for it. */
 	case EVENT_UNKNOWN_DEBUG:
 		mwifiex_dbg(adapter, EVENT, "event: debug\n");
diff --git a/drivers/net/wireless/marvell/mwifiex/uap_event.c b/drivers/net/wireless/marvell/mwifiex/uap_event.c
index 58ef5020a46a7..80a9c433db64a 100644
--- a/drivers/net/wireless/marvell/mwifiex/uap_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/uap_event.c
@@ -317,6 +317,10 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
 		memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg));
 		break;
 
+	case EVENT_VDLL_IND:
+		mwifiex_dbg(adapter, EVENT, "event: handle VDLL event...\n");
+		mwifiex_process_vdll_event(priv, adapter->event_skb);
+		break;
 	default:
 		mwifiex_dbg(adapter, EVENT,
 			    "event: unknown event id: %#x\n", eventcause);
