* Fix rf_size for RF2112A * Add some stuff i got from decompiling binary HAL (also work in progress) Changes-licensed-under: ISC Signed-off-by: Nick Kossifidis <mickflemm@xxxxxxxxx> --- diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c index 5a9619b..da11ce6 100644 --- a/drivers/net/wireless/ath5k/phy.c +++ b/drivers/net/wireless/ath5k/phy.c @@ -1385,6 +1385,7 @@ done: /* * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111 + * TODO: Gain optimization */ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode) @@ -1475,6 +1476,24 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, ee->ee_xpd[ee_mode], 1, 4, 0, true)) return -EINVAL; +#ifdef notyet + if (channel->hw_value & (half_rate_chanel || quarter_rate_channel)) { + + val = (channel->hw_value & half_rate_chanel) ? 16 : 31; + if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], + 31, 5, 19, 0, true)) + return -EINVAL; + + if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], + val, 5, 24, 0, true)) + return -EINVAL; + + if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], + 3, 2, 49, 0, true)) + return -EINVAL; + } +#endif + /* Write RF values */ for (i = 0; i < rf_size; i++) { AR5K_REG_WAIT(i); @@ -1486,6 +1505,7 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, /* * Read EEPROM Calibration data, modify RF Banks and Initialize RF5112 + * TODO: Gain optimization */ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode) @@ -1504,7 +1524,7 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A && !test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) { rf_ini = rfregs_2112a; - rf_size = ARRAY_SIZE(rfregs_5112a); + rf_size = ARRAY_SIZE(rfregs_2112a); if (mode < 2) { ATH5K_ERR(ah->ah_sc,"invalid channel mode: %i\n",mode); return -EINVAL; @@ -1552,9 +1572,9 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, /* For 11a, Turbo and XR */ ee_mode = AR5K_EEPROM_MODE_11A; obdb = channel->center_freq >= 5725 ? 3 : - (channel->center_freq >= 5500 ? 2 : + (channel->center_freq >= 5500 ? 2 : (channel->center_freq >= 5260 ? 1 : - (channel->center_freq > 4000 ? 0 : -1))); + (channel->center_freq > 4000 ? 0 : -1))); if (obdb == -1) return -EINVAL; @@ -1569,9 +1589,55 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, } ath5k_hw_rfregs_op(rf, ah->ah_offset[6], - ee->ee_x_gain[ee_mode], 2, 270, 0, true); + ee->ee_x_gain[ee_mode], 2, 270, 0, true); ath5k_hw_rfregs_op(rf, ah->ah_offset[6], - ee->ee_x_gain[ee_mode], 2, 257, 0, true); + ee->ee_x_gain[ee_mode], 2, 257, 0, true); + +#ifdef notyet + if (channel->hw_value & CHANNEL_OFDM) { + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + val, 1, 168, 3, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + val, 1, 169, 3, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + val, 1, 170, 3, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + val, 1, 174, 3, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + val, 1, 175, 3, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + val, 1, 176, 3, true); + } + + if (ah->ah_radio_5ghz_revision == AR5K_SREV_RAD_5112A || + ah->ah_radio_5ghz_revision == AR5K_SREV_RAD_5112B || + ah->ah_radio_5ghz_revision == AR5K_SREV_RAD_2112A || + ah->ah_radio_5ghz_revision == AR5K_SREV_RAD_2112B) { + + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + 2, 2, 90, 2, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + 2, 2, 92, 2, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + 2, 2, 94, 2, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + 2, 1, 254, 2, true); + } + + if (ah->ah_phy_revision >= 0x41) { + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + 1, 1, 281, 1, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + 1, 2, 1, 3, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + 1, 2, 3, 3, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + 1, 1, 139, 3, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[6], + 1, 1, 140, 3, true); + } +#endif + if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], ee->ee_xpd[ee_mode], 1, 302, 0, true)) @@ -1582,6 +1648,17 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, ee->ee_i_gain[ee_mode], 6, 14, 0, true)) return -EINVAL; +#ifdef notyet + if (channel->hw_value & (half_rate_chanel || quarter_rate_channel)) { + + val = (channel->hw_value & half_rate_chanel) ? 8 : 15; + ath5k_hw_rfregs_op(rf, ah->ah_offset[7], + 15, 4, 58, 0, true); + ath5k_hw_rfregs_op(rf, ah->ah_offset[7], + val, 4, 70, 0, true); + } +#endif + /* Write RF values */ for (i = 0; i < rf_size; i++) ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register); @@ -1666,6 +1743,19 @@ static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah, * is used because calibration data would be * different between different cards and would result * different RF_BUFFER settings) + * + * Update: This happens most of the times but disassembly + * of binary HAL shows there are minor changes that we should + * implement (check below). + */ + + /* TODO: + * Write 2GHz ob/db on 2413 (3,168,0 / 3,165,0) + * Write 2GHz ob/db on 5413 (3,241,0 / 3,238,0) + * Write 5GHz ob/db on 5413 (3,247,9 / 3,244,0) + * Write 2GHz ob/db on 2425 (3,193,0 / 3,190,0) + * + * Figure out the rest... */ /* Write RF values */ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html