iwlegacy: fix tx_power initialization

priv->tx_power_next is not initialized to max supported power,
but instead default value is used, what cause errors like

[ 58.597834] iwl3945 0000:03:00.0: Requested user TXPOWER 15 above upper limit 14.
[ 58.597839] iwl3945 0000:03:00.0: Error setting Tx power (-22).

if maximum tx power read from the eeprom is smaller than default.
In consequence card is unable to initialize properly. Fix the problem
and cleanup tx power initialization.

Reported-and-tested-by: Robin Dong <hao.bigrat@gmail.com>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by Stanislaw Gruszka and committed by John W. Linville 332704a5 50f68712

+11 -28
-2
drivers/net/wireless/iwlegacy/iwl-3945-hw.h
··· 74 /* RSSI to dBm */ 75 #define IWL39_RSSI_OFFSET 95 76 77 - #define IWL_DEFAULT_TX_POWER 0x0F 78 - 79 /* 80 * EEPROM related constants, enums, and structures. 81 */
··· 74 /* RSSI to dBm */ 75 #define IWL39_RSSI_OFFSET 95 76 77 /* 78 * EEPROM related constants, enums, and structures. 79 */
-3
drivers/net/wireless/iwlegacy/iwl-4965-hw.h
··· 804 805 #define IWL4965_DEFAULT_TX_RETRY 15 806 807 - /* Limit range of txpower output target to be between these values */ 808 - #define IWL4965_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm: 1 milliwatt */ 809 - 810 /* EEPROM */ 811 #define IWL4965_FIRST_AMPDU_QUEUE 10 812
··· 804 805 #define IWL4965_DEFAULT_TX_RETRY 15 806 807 /* EEPROM */ 808 #define IWL4965_FIRST_AMPDU_QUEUE 10 809
+11 -6
drivers/net/wireless/iwlegacy/iwl-core.c
··· 160 struct ieee80211_channel *geo_ch; 161 struct ieee80211_rate *rates; 162 int i = 0; 163 164 if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || 165 priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { ··· 236 237 geo_ch->flags |= ch->ht40_extension_channel; 238 239 - if (ch->max_power_avg > priv->tx_power_device_lmt) 240 - priv->tx_power_device_lmt = ch->max_power_avg; 241 } else { 242 geo_ch->flags |= IEEE80211_CHAN_DISABLED; 243 } ··· 249 "restricted" : "valid", 250 geo_ch->flags); 251 } 252 253 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && 254 priv->cfg->sku & IWL_SKU_A) { ··· 1129 if (!priv->cfg->ops->lib->send_tx_power) 1130 return -EOPNOTSUPP; 1131 1132 - if (tx_power < IWL4965_TX_POWER_TARGET_POWER_MIN) { 1133 IWL_WARN(priv, 1134 - "Requested user TXPOWER %d below lower limit %d.\n", 1135 - tx_power, 1136 - IWL4965_TX_POWER_TARGET_POWER_MIN); 1137 return -EINVAL; 1138 } 1139
··· 160 struct ieee80211_channel *geo_ch; 161 struct ieee80211_rate *rates; 162 int i = 0; 163 + s8 max_tx_power = 0; 164 165 if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || 166 priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { ··· 235 236 geo_ch->flags |= ch->ht40_extension_channel; 237 238 + if (ch->max_power_avg > max_tx_power) 239 + max_tx_power = ch->max_power_avg; 240 } else { 241 geo_ch->flags |= IEEE80211_CHAN_DISABLED; 242 } ··· 248 "restricted" : "valid", 249 geo_ch->flags); 250 } 251 + 252 + priv->tx_power_device_lmt = max_tx_power; 253 + priv->tx_power_user_lmt = max_tx_power; 254 + priv->tx_power_next = max_tx_power; 255 256 if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && 257 priv->cfg->sku & IWL_SKU_A) { ··· 1124 if (!priv->cfg->ops->lib->send_tx_power) 1125 return -EOPNOTSUPP; 1126 1127 + /* 0 dBm mean 1 milliwatt */ 1128 + if (tx_power < 0) { 1129 IWL_WARN(priv, 1130 + "Requested user TXPOWER %d below 1 mW.\n", 1131 + tx_power); 1132 return -EINVAL; 1133 } 1134
-7
drivers/net/wireless/iwlegacy/iwl-eeprom.c
··· 471 flags & EEPROM_CHANNEL_RADAR)) 472 ? "" : "not "); 473 474 - /* Set the tx_power_user_lmt to the highest power 475 - * supported by any channel */ 476 - if (eeprom_ch_info[ch].max_power_avg > 477 - priv->tx_power_user_lmt) 478 - priv->tx_power_user_lmt = 479 - eeprom_ch_info[ch].max_power_avg; 480 - 481 ch_info++; 482 } 483 }
··· 471 flags & EEPROM_CHANNEL_RADAR)) 472 ? "" : "not "); 473 474 ch_info++; 475 } 476 }
-4
drivers/net/wireless/iwlegacy/iwl3945-base.c
··· 3825 priv->force_reset[IWL_FW_RESET].reset_duration = 3826 IWL_DELAY_NEXT_FORCE_FW_RELOAD; 3827 3828 - 3829 - priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; 3830 - priv->tx_power_next = IWL_DEFAULT_TX_POWER; 3831 - 3832 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { 3833 IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", 3834 eeprom->version);
··· 3825 priv->force_reset[IWL_FW_RESET].reset_duration = 3826 IWL_DELAY_NEXT_FORCE_FW_RELOAD; 3827 3828 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { 3829 IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", 3830 eeprom->version);
-6
drivers/net/wireless/iwlegacy/iwl4965-base.c
··· 3140 3141 iwl_legacy_init_scan_params(priv); 3142 3143 - /* Set the tx_power_user_lmt to the lowest power level 3144 - * this value will get overwritten by channel max power avg 3145 - * from eeprom */ 3146 - priv->tx_power_user_lmt = IWL4965_TX_POWER_TARGET_POWER_MIN; 3147 - priv->tx_power_next = IWL4965_TX_POWER_TARGET_POWER_MIN; 3148 - 3149 ret = iwl_legacy_init_channel_map(priv); 3150 if (ret) { 3151 IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
··· 3140 3141 iwl_legacy_init_scan_params(priv); 3142 3143 ret = iwl_legacy_init_channel_map(priv); 3144 if (ret) { 3145 IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);