ar9280_hw_olc_temp_compensation(ah);
 }
 
-static bool ar9002_hw_calibrate(struct ath_hw *ah,
-                               struct ath9k_channel *chan,
-                               u8 rxchainmask,
-                               bool longcal)
+static int ar9002_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+                              u8 rxchainmask, bool longcal)
 {
        bool iscaldone = true;
        struct ath9k_cal_list *currCal = ah->cal_list_curr;
        bool nfcal, nfcal_pending = false;
+       int ret;
 
        nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
        if (ah->caldata)
                         * NF is slow time-variant, so it is OK to use a
                         * historical value.
                         */
-                       ath9k_hw_loadnf(ah, ah->curchan);
+                       ret = ath9k_hw_loadnf(ah, ah->curchan);
+                       if (ret < 0)
+                               return ret;
                }
 
                if (longcal) {
 
        return iscaldone;
 }
 
-static bool ar9003_hw_calibrate(struct ath_hw *ah,
-                               struct ath9k_channel *chan,
-                               u8 rxchainmask,
-                               bool longcal)
+static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+                              u8 rxchainmask, bool longcal)
 {
        bool iscaldone = true;
        struct ath9k_cal_list *currCal = ah->cal_list_curr;
+       int ret;
 
        /*
         * For given calibration:
                 * NF is slow time-variant, so it is OK to use a historical
                 * value.
                 */
-               ath9k_hw_loadnf(ah, ah->curchan);
+               ret = ath9k_hw_loadnf(ah, ah->curchan);
+               if (ret < 0)
+                       return ret;
 
                /* start NF calibration, without updating BB NF register */
                ath9k_hw_start_nfcal(ah, false);
 
        REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
 }
 
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 {
        struct ath9k_nfcal_hist *h = NULL;
        unsigned i, j;
                ath_dbg(common, ANY,
                        "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
                        REG_READ(ah, AR_PHY_AGC_CONTROL));
-               return;
+               return -ETIMEDOUT;
        }
 
        /*
                }
        }
        REGWRITE_BUFFER_FLUSH(ah);
+
+       return 0;
 }
 
 
 
 
 bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
 void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update);
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
+int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
 bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
                                  struct ath9k_channel *chan);
 
                [RESET_TYPE_MAC_HANG] = "MAC Hang",
                [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
                [RESET_TYPE_MCI] = "MCI Reset",
+               [RESET_TYPE_CALIBRATION] = "Calibration error",
        };
        char buf[512];
        unsigned int len = 0;
 
        RESET_TYPE_MAC_HANG,
        RESET_TYPE_BEACON_STUCK,
        RESET_TYPE_MCI,
+       RESET_TYPE_CALIBRATION,
        __RESET_TYPE_MAX
 };
 
 
        ath9k_hw_ops(ah)->set_desc_link(ds, link);
 }
 
-static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
-                                     struct ath9k_channel *chan,
-                                     u8 rxchainmask,
-                                     bool longcal)
+static inline int ath9k_hw_calibrate(struct ath_hw *ah,
+                                    struct ath9k_channel *chan,
+                                    u8 rxchainmask, bool longcal)
 {
        return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
 }
 
                                     bool power_off);
        void (*rx_enable)(struct ath_hw *ah);
        void (*set_desc_link)(void *ds, u32 link);
-       bool (*calibrate)(struct ath_hw *ah,
-                         struct ath9k_channel *chan,
-                         u8 rxchainmask,
-                         bool longcal);
+       int (*calibrate)(struct ath_hw *ah, struct ath9k_channel *chan,
+                        u8 rxchainmask, bool longcal);
        bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked,
                        u32 *sync_cause_p);
        void (*set_txdesc)(struct ath_hw *ah, void *ds,
 
 
        /* Perform calibration if necessary */
        if (longcal || shortcal) {
-               common->ani.caldone =
-                       ath9k_hw_calibrate(ah, ah->curchan,
-                                          ah->rxchainmask, longcal);
+               int ret = ath9k_hw_calibrate(ah, ah->curchan, ah->rxchainmask,
+                                            longcal);
+               if (ret < 0) {
+                       common->ani.caldone = 0;
+                       ath9k_queue_reset(sc, RESET_TYPE_CALIBRATION);
+                       return;
+               }
+
+               common->ani.caldone = ret;
        }
 
        ath_dbg(common, ANI,