ath9k_hw: Fix magnitude/phase average in TxIQ Calibration
authorRajkumar Manoharan <rmanohar@qca.qualcomm.com>
Tue, 6 Sep 2011 16:29:51 +0000 (21:59 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 14 Sep 2011 17:56:33 +0000 (13:56 -0400)
The commit "ath9k_hw: Fix Tx IQ Calibration hang issue in
AR9003 chips" did not consider more than one potential sample
while calculating magnitude/phase average if more than one
sample has the same value which could affect post-processing
of outlier detection that causes an undesirable Tx IQ
correction value will be assigned to tx gain settings where
outlier happens.

Cc: Kai Shi <kaishi@qca.qualcomm.com>
Reported-by: Paul Stewart <pstew@google.com>
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: Paul Stewart <pstew@google.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath9k/ar9003_calib.c

index fa35a02..3319a67 100644 (file)
@@ -615,11 +615,10 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
 {
        int mp_max = -64, max_idx = 0;
        int mp_min = 63, min_idx = 0;
-       int mp_avg = 0, i, outlier_idx = 0;
+       int mp_avg = 0, i, outlier_idx = 0, mp_count = 0;
 
        /* find min/max mismatch across all calibrated gains */
        for (i = 0; i < nmeasurement; i++) {
-               mp_avg += mp_coeff[i];
                if (mp_coeff[i] > mp_max) {
                        mp_max = mp_coeff[i];
                        max_idx = i;
@@ -632,10 +631,20 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
        /* find average (exclude max abs value) */
        for (i = 0; i < nmeasurement; i++) {
                if ((abs(mp_coeff[i]) < abs(mp_max)) ||
-                   (abs(mp_coeff[i]) < abs(mp_min)))
+                   (abs(mp_coeff[i]) < abs(mp_min))) {
                        mp_avg += mp_coeff[i];
+                       mp_count++;
+               }
        }
-       mp_avg /= (nmeasurement - 1);
+
+       /*
+        * finding mean magnitude/phase if possible, otherwise
+        * just use the last value as the mean
+        */
+       if (mp_count)
+               mp_avg /= mp_count;
+       else
+               mp_avg = mp_coeff[nmeasurement - 1];
 
        /* detect outlier */
        if (abs(mp_max - mp_min) > max_delta) {