aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k/phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/phy.c')
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index ffe253ab9be7..eff3323efb4b 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1386,38 +1386,39 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1386 goto done; 1386 goto done;
1387 1387
1388 /* Calibration has finished, get the results and re-run */ 1388 /* Calibration has finished, get the results and re-run */
1389
1390 /* work around empty results which can apparently happen on 5212 */
1389 for (i = 0; i <= 10; i++) { 1391 for (i = 0; i <= 10; i++) {
1390 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); 1392 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
1391 i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); 1393 i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
1392 q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q); 1394 q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
1395 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1396 "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
1397 if (i_pwr && q_pwr)
1398 break;
1393 } 1399 }
1394 1400
1395 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; 1401 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1396 q_coffd = q_pwr >> 7; 1402 q_coffd = q_pwr >> 7;
1397 1403
1398 /* No correction */ 1404 /* protect against divide by 0 and loss of sign bits */
1399 if (i_coffd == 0 || q_coffd == 0) 1405 if (i_coffd == 0 || q_coffd < 2)
1400 goto done; 1406 goto done;
1401 1407
1402 i_coff = ((-iq_corr) / i_coffd); 1408 i_coff = (-iq_corr) / i_coffd;
1409 i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */
1403 1410
1404 /* Boundary check */ 1411 q_coff = (i_pwr / q_coffd) - 128;
1405 if (i_coff > 31) 1412 q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */
1406 i_coff = 31;
1407 if (i_coff < -32)
1408 i_coff = -32;
1409 1413
1410 q_coff = (((s32)i_pwr / q_coffd) - 128); 1414 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1415 "new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
1416 i_coff, q_coff, i_coffd, q_coffd);
1411 1417
1412 /* Boundary check */ 1418 /* Commit new I/Q values (set enable bit last to match HAL sources) */
1413 if (q_coff > 15) 1419 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff);
1414 q_coff = 15; 1420 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff);
1415 if (q_coff < -16) 1421 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
1416 q_coff = -16;
1417
1418 /* Commit new I/Q value */
1419 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
1420 ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
1421 1422
1422 /* Re-enable calibration -if we don't we'll commit 1423 /* Re-enable calibration -if we don't we'll commit
1423 * the same values again and again */ 1424 * the same values again and again */