return 0;
 }
 
+static int ath10k_bmi_lz_data_large(struct ath10k *ar, const void *buffer, u32 length)
+{
+       struct bmi_cmd *cmd;
+       u32 hdrlen = sizeof(cmd->id) + sizeof(cmd->lz_data);
+       u32 txlen;
+       int ret;
+       size_t buf_len;
+
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "large bmi lz data buffer 0x%pK length %d\n",
+                  buffer, length);
+
+       if (ar->bmi.done_sent) {
+               ath10k_warn(ar, "command disallowed\n");
+               return -EBUSY;
+       }
+
+       buf_len = sizeof(*cmd) + BMI_MAX_LARGE_DATA_SIZE - BMI_MAX_DATA_SIZE;
+       cmd = kzalloc(buf_len, GFP_KERNEL);
+       if (!cmd)
+               return -ENOMEM;
+
+       while (length) {
+               txlen = min(length, BMI_MAX_LARGE_DATA_SIZE - hdrlen);
+
+               WARN_ON_ONCE(txlen & 3);
+
+               cmd->id          = __cpu_to_le32(BMI_LZ_DATA);
+               cmd->lz_data.len = __cpu_to_le32(txlen);
+               memcpy(cmd->lz_data.payload, buffer, txlen);
+
+               ret = ath10k_hif_exchange_bmi_msg(ar, cmd, hdrlen + txlen,
+                                                 NULL, NULL);
+               if (ret) {
+                       ath10k_warn(ar, "unable to write to the device\n");
+                       return ret;
+               }
+
+               buffer += txlen;
+               length -= txlen;
+       }
+
+       kfree(cmd);
+
+       return 0;
+}
+
 int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
 {
        struct bmi_cmd cmd;
        if (trailer_len > 0)
                memcpy(trailer, buffer + head_len, trailer_len);
 
-       ret = ath10k_bmi_lz_data(ar, buffer, head_len);
+       if (ar->hw_params.bmi_large_size_download)
+               ret = ath10k_bmi_lz_data_large(ar, buffer, head_len);
+       else
+               ret = ath10k_bmi_lz_data(ar, buffer, head_len);
+
        if (ret)
                return ret;
 
 
                        sizeof(u32) + \
                        sizeof(u32))
 
+/* Maximum data size used for large BMI transfers */
+#define BMI_MAX_LARGE_DATA_SIZE        2048
+
+/* len = cmd + addr + length */
+#define BMI_MAX_LARGE_CMDBUF_SIZE (BMI_MAX_LARGE_DATA_SIZE + \
+                       sizeof(u32) + \
+                       sizeof(u32) + \
+                       sizeof(u32))
+
 /* BMI Commands */
 
 enum bmi_cmd_id {
 int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result);
 int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address);
 int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length);
+
 int ath10k_bmi_fast_download(struct ath10k *ar, u32 address,
                             const void *buffer, u32 length);
 int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val);