return ret;
 }
 
+static unsigned int wl1271_get_fw_ver_quirks(struct wl1271 *wl)
+{
+       unsigned int quirks = 0;
+       unsigned int *fw_ver = wl->chip.fw_ver;
+
+       /* Only for wl127x */
+       if ((fw_ver[FW_VER_CHIP] == FW_VER_CHIP_WL127X) &&
+           /* Check STA version */
+           (((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
+             (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_STA_MIN)) ||
+            /* Check AP version */
+            ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP) &&
+             (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_AP_MIN))))
+               quirks |= WL12XX_QUIRK_USE_2_SPARE_BLOCKS;
+
+       return quirks;
+}
+
 int wl1271_plt_start(struct wl1271 *wl)
 {
        int retries = WL1271_BOOT_RETRIES;
                wl->state = WL1271_STATE_PLT;
                wl1271_notice("firmware booted in PLT mode (%s)",
                              wl->chip.fw_ver_str);
+
+               /* Check if any quirks are needed with older fw versions */
+               wl->quirks |= wl1271_get_fw_ver_quirks(wl);
                goto out;
 
 irq_disable:
        strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
                sizeof(wiphy->fw_version));
 
+       /* Check if any quirks are needed with older fw versions */
+       wl->quirks |= wl1271_get_fw_ver_quirks(wl);
+
        /*
         * Now we know if 11a is supported (info from the NVS), so disable
         * 11a channels if not supported
 
        u32 len;
        u32 total_blocks;
        int id, ret = -EBUSY;
+       u32 spare_blocks;
+
+       if (unlikely(wl->quirks & WL12XX_QUIRK_USE_2_SPARE_BLOCKS))
+               spare_blocks = 2;
+       else
+               spare_blocks = 1;
 
        if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
                return -EAGAIN;
                len = total_len;
 
        total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
-               TX_HW_BLOCK_SPARE;
+               spare_blocks;
 
        if (total_blocks <= wl->tx_blocks_available) {
                desc = (struct wl1271_tx_hw_descr *)skb_push(
                if (wl->chip.id == CHIP_ID_1283_PG20) {
                        desc->wl128x_mem.total_mem_blocks = total_blocks;
                } else {
-                       desc->wl127x_mem.extra_blocks = TX_HW_BLOCK_SPARE;
+                       desc->wl127x_mem.extra_blocks = spare_blocks;
                        desc->wl127x_mem.total_mem_blocks = total_blocks;
                }
 
 
 #ifndef __TX_H__
 #define __TX_H__
 
-#define TX_HW_BLOCK_SPARE                2
 #define TX_HW_BLOCK_SIZE                 252
 
 #define TX_HW_MGMT_PKT_LIFETIME_TU       2000
 
 
 struct wl1271;
 
-#define WL12XX_NUM_FW_VER 5
+enum {
+       FW_VER_CHIP,
+       FW_VER_IF_TYPE,
+       FW_VER_MAJOR,
+       FW_VER_SUBTYPE,
+       FW_VER_MINOR,
+
+       NUM_FW_VER
+};
+
+#define FW_VER_CHIP_WL127X 6
+#define FW_VER_CHIP_WL128X 7
+
+#define FW_VER_IF_TYPE_STA 1
+#define FW_VER_IF_TYPE_AP  2
+
+#define FW_VER_MINOR_1_SPARE_STA_MIN 58
+#define FW_VER_MINOR_1_SPARE_AP_MIN  47
 
-/* FIXME: I'm not sure about this structure name */
 struct wl1271_chip {
        u32 id;
        char fw_ver_str[ETHTOOL_BUSINFO_LEN];
-       unsigned int fw_ver[WL12XX_NUM_FW_VER];
+       unsigned int fw_ver[NUM_FW_VER];
 };
 
 struct wl1271_stats {
 /* Each RX/TX transaction requires an end-of-transaction transfer */
 #define WL12XX_QUIRK_END_OF_TRANSACTION        BIT(0)
 
+/*
+ * Older firmwares use 2 spare TX blocks
+ * (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47)
+ */
+#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1)
+
 #endif