static void wl12xx_irq_update_links_status(struct wl1271 *wl,
                                           struct wl12xx_vif *wlvif,
-                                          struct wl_fw_status *status)
+                                          struct wl_fw_status_2 *status)
 {
        struct wl1271_link *lnk;
        u32 cur_fw_ps_map;
 }
 
 static void wl12xx_fw_status(struct wl1271 *wl,
-                            struct wl_fw_status *status)
+                            struct wl_fw_status_1 *status_1,
+                            struct wl_fw_status_2 *status_2)
 {
        struct wl12xx_vif *wlvif;
        struct timespec ts;
        int i;
        size_t status_len;
 
-       status_len = sizeof(*status) + wl->fw_status_priv_len;
+       status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
+               sizeof(*status_2) + wl->fw_status_priv_len;
 
-       wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status,
+       wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1,
                             status_len, false);
 
        wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
                     "drv_rx_counter = %d, tx_results_counter = %d)",
-                    status->intr,
-                    status->fw_rx_counter,
-                    status->drv_rx_counter,
-                    status->tx_results_counter);
+                    status_1->intr,
+                    status_1->fw_rx_counter,
+                    status_1->drv_rx_counter,
+                    status_1->tx_results_counter);
 
        for (i = 0; i < NUM_TX_QUEUES; i++) {
                /* prevent wrap-around in freed-packets counter */
                wl->tx_allocated_pkts[i] -=
-                               (status->counters.tx_released_pkts[i] -
+                               (status_2->counters.tx_released_pkts[i] -
                                wl->tx_pkts_freed[i]) & 0xff;
 
-               wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i];
+               wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i];
        }
 
        /* prevent wrap-around in total blocks counter */
        if (likely(wl->tx_blocks_freed <=
-                  le32_to_cpu(status->total_released_blks)))
-               freed_blocks = le32_to_cpu(status->total_released_blks) -
+                  le32_to_cpu(status_2->total_released_blks)))
+               freed_blocks = le32_to_cpu(status_2->total_released_blks) -
                               wl->tx_blocks_freed;
        else
                freed_blocks = 0x100000000LL - wl->tx_blocks_freed +
-                              le32_to_cpu(status->total_released_blks);
+                              le32_to_cpu(status_2->total_released_blks);
 
-       wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks);
+       wl->tx_blocks_freed = le32_to_cpu(status_2->total_released_blks);
 
        wl->tx_allocated_blocks -= freed_blocks;
 
                        cancel_delayed_work(&wl->tx_watchdog_work);
        }
 
-       avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks;
+       avail = le32_to_cpu(status_2->tx_total) - wl->tx_allocated_blocks;
 
        /*
         * The FW might change the total number of TX memblocks before
 
        /* for AP update num of allocated TX blocks per link and ps status */
        wl12xx_for_each_wlvif_ap(wl, wlvif) {
-               wl12xx_irq_update_links_status(wl, wlvif, status);
+               wl12xx_irq_update_links_status(wl, wlvif, status_2);
        }
 
        /* update the host-chipset time offset */
        getnstimeofday(&ts);
        wl->time_offset = (timespec_to_ns(&ts) >> 10) -
-               (s64)le32_to_cpu(status->fw_localtime);
+               (s64)le32_to_cpu(status_2->fw_localtime);
 }
 
 static void wl1271_flush_deferred_work(struct wl1271 *wl)
                clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
                smp_mb__after_clear_bit();
 
-               wl12xx_fw_status(wl, wl->fw_status);
+               wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
 
                wlcore_hw_tx_immediate_compl(wl);
 
-               intr = le32_to_cpu(wl->fw_status->intr);
+               intr = le32_to_cpu(wl->fw_status_1->intr);
                intr &= WL1271_INTR_MASK;
                if (!intr) {
                        done = true;
                if (likely(intr & WL1271_ACX_INTR_DATA)) {
                        wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
 
-                       wl12xx_rx(wl, wl->fw_status);
+                       wl12xx_rx(wl, wl->fw_status_1);
 
                        /* Check if any tx blocks were freed */
                        spin_lock_irqsave(&wl->wl_lock, flags);
                wl12xx_cmd_stop_fwlog(wl);
 
        /* Read the first memory block address */
-       wl12xx_fw_status(wl, wl->fw_status);
-       first_addr = le32_to_cpu(wl->fw_status->log_start_addr);
+       wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
+       first_addr = le32_to_cpu(wl->fw_status_2->log_start_addr);
        if (!first_addr)
                goto out;
 
 
 static int wl1271_setup(struct wl1271 *wl)
 {
-       wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL);
-       if (!wl->fw_status)
+       wl->fw_status_1 = kmalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
+                                 sizeof(*wl->fw_status_2), GFP_KERNEL);
+       if (!wl->fw_status_1)
                return -ENOMEM;
 
+       wl->fw_status_2 = (struct wl_fw_status_2 *)
+                               (((u8 *) wl->fw_status_1) +
+                               WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc));
+
        wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
        if (!wl->tx_res_if) {
-               kfree(wl->fw_status);
+               kfree(wl->fw_status_1);
                return -ENOMEM;
        }
 
 
        wl1271_debugfs_reset(wl);
 
-       kfree(wl->fw_status);
-       wl->fw_status = NULL;
+       kfree(wl->fw_status_1);
+       wl->fw_status_1 = NULL;
+       wl->fw_status_2 = NULL;
        kfree(wl->tx_res_if);
        wl->tx_res_if = NULL;
        kfree(wl->target_mem_map);
        kfree(wl->nvs);
        wl->nvs = NULL;
 
-       kfree(wl->fw_status);
+       kfree(wl->fw_status_1);
        kfree(wl->tx_res_if);
        destroy_workqueue(wl->freezable_wq);