Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[pandora-kernel.git] / drivers / net / wireless / ath9k / hw.c
index 272c758..98bc25c 100644 (file)
@@ -329,7 +329,7 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah)
        ah->ah_config.ofdm_trig_high = 500;
        ah->ah_config.cck_trig_high = 200;
        ah->ah_config.cck_trig_low = 100;
-       ah->ah_config.enable_ani = 0;
+       ah->ah_config.enable_ani = 1;
        ah->ah_config.noise_immunity_level = 4;
        ah->ah_config.ofdm_weaksignal_det = 1;
        ah->ah_config.cck_weaksignal_thr = 0;
@@ -5867,7 +5867,6 @@ bool ath9k_hw_reset(struct ath_hal *ah,
                    bool bChannelChange,
                    int *status)
 {
-#define FAIL(_code)     do { ecode = _code; goto bad; } while (0)
        u32 saveLedState;
        struct ath_hal_5416 *ahp = AH5416(ah);
        struct ath9k_channel *curchan = ah->ah_curchan;
@@ -5889,11 +5888,14 @@ bool ath9k_hw_reset(struct ath_hal *ah,
                DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
                         "%s: invalid channel %u/0x%x; no mapping\n",
                         __func__, chan->channel, chan->channelFlags);
-               FAIL(-EINVAL);
+               ecode = -EINVAL;
+               goto bad;
        }
 
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
-               return false;
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
+               ecode = -EIO;
+               goto bad;
+       }
 
        if (curchan)
                ath9k_hw_getnf(ah, curchan);
@@ -5930,7 +5932,8 @@ bool ath9k_hw_reset(struct ath_hal *ah,
        if (!ath9k_hw_chip_reset(ah, chan)) {
                DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
                         __func__);
-               FAIL(-EIO);
+               ecode = -EINVAL;
+               goto bad;
        }
 
        if (AR_SREV_9280(ah)) {
@@ -5947,8 +5950,10 @@ bool ath9k_hw_reset(struct ath_hal *ah,
        }
 
        ecode = ath9k_hw_process_ini(ah, chan, macmode);
-       if (ecode != 0)
+       if (ecode != 0) {
+               ecode = -EINVAL;
                goto bad;
+       }
 
        if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
                ath9k_hw_set_delta_slope(ah, chan);
@@ -5961,7 +5966,8 @@ bool ath9k_hw_reset(struct ath_hal *ah,
        if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
                DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
                         "%s: error setting board options\n", __func__);
-               FAIL(-EIO);
+               ecode = -EIO;
+               goto bad;
        }
 
        ath9k_hw_decrease_chain_power(ah, chan);
@@ -5989,11 +5995,15 @@ bool ath9k_hw_reset(struct ath_hal *ah,
        REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
 
        if (AR_SREV_9280_10_OR_LATER(ah)) {
-               if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
-                       FAIL(-EIO);
+               if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
+                       ecode = -EIO;
+                       goto bad;
+               }
        } else {
-               if (!(ath9k_hw_set_channel(ah, chan)))
-                       FAIL(-EIO);
+               if (!(ath9k_hw_set_channel(ah, chan))) {
+                       ecode = -EIO;
+                       goto bad;
+               }
        }
 
        for (i = 0; i < AR_NUM_DCU; i++)
@@ -6027,8 +6037,10 @@ bool ath9k_hw_reset(struct ath_hal *ah,
 
        ath9k_hw_init_bb(ah, chan);
 
-       if (!ath9k_hw_init_cal(ah, chan))
-               FAIL(-ENODEV);
+       if (!ath9k_hw_init_cal(ah, chan)){
+               ecode = -EIO;;
+               goto bad;
+       }
 
        rx_chainmask = ahp->ah_rxchainmask;
        if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
@@ -6064,7 +6076,6 @@ bad:
        if (status)
                *status = ecode;
        return false;
-#undef FAIL
 }
 
 bool ath9k_hw_phy_disable(struct ath_hal *ah)
@@ -8405,23 +8416,48 @@ u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
        }
 }
 
-int16_t
+/* We can tune this as we go by monitoring really low values */
+#define ATH9K_NF_TOO_LOW       -60
+
+/* AR5416 may return very high value (like -31 dBm), in those cases the nf
+ * is incorrect and we should use the static NF value. Later we can try to
+ * find out why they are reporting these values */
+static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf)
+{
+       if (nf > ATH9K_NF_TOO_LOW) {
+               DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
+                        "%s: noise floor value detected (%d) is "
+                       "lower than what we think is a "
+                       "reasonable value (%d)\n",
+                        __func__, nf, ATH9K_NF_TOO_LOW);
+               return false;
+       }
+       return true;
+}
+
+s16
 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
 {
        struct ath9k_channel *ichan;
+       s16 nf;
 
        ichan = ath9k_regd_check_channel(ah, chan);
        if (ichan == NULL) {
                DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
                         "%s: invalid channel %u/0x%x; no mapping\n",
                         __func__, chan->channel, chan->channelFlags);
-               return 0;
+               return ATH_DEFAULT_NOISE_FLOOR;
        }
        if (ichan->rawNoiseFloor == 0) {
                enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
-               return NOISE_FLOOR[mode];
+               nf = NOISE_FLOOR[mode];
        } else
-               return ichan->rawNoiseFloor;
+               nf = ichan->rawNoiseFloor;
+
+       if (!ath9k_hw_nf_in_range(ah, nf))
+               nf = ATH_DEFAULT_NOISE_FLOOR;
+
+       return nf;
 }
 
 bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)