aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2005-08-11 02:39:33 -0400
committerJames Ketrenos <jketreno@linux.intel.com>2005-11-07 18:50:50 -0500
commit6de9f7f27defe6f1a2d33d0b78af6b1a0ad18330 (patch)
treeb30d488ffce4501c659cce7b9e43c82ebbdbddd3 /drivers/net/wireless
parent22501c8ed70398178e8c8d55e65da97b7e7fb610 (diff)
Fix firmware error when setting tx_power.
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ipw2200.c131
1 files changed, 55 insertions, 76 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 105b1146f396..f825aa462c99 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -2084,6 +2084,50 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
2084 return 0; 2084 return 0;
2085} 2085}
2086 2086
2087static int ipw_set_tx_power(struct ipw_priv *priv)
2088{
2089 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
2090 struct ipw_tx_power tx_power;
2091 s8 max_power;
2092 int i;
2093
2094 memset(&tx_power, 0, sizeof(tx_power));
2095
2096 /* configure device for 'G' band */
2097 tx_power.ieee_mode = IPW_G_MODE;
2098 tx_power.num_channels = geo->bg_channels;
2099 for (i = 0; i < geo->bg_channels; i++) {
2100 max_power = geo->bg[i].max_power;
2101 tx_power.channels_tx_power[i].channel_number =
2102 geo->bg[i].channel;
2103 tx_power.channels_tx_power[i].tx_power = max_power ?
2104 min(max_power, priv->tx_power) : priv->tx_power;
2105 }
2106 if (ipw_send_tx_power(priv, &tx_power))
2107 return -EIO;
2108
2109 /* configure device to also handle 'B' band */
2110 tx_power.ieee_mode = IPW_B_MODE;
2111 if (ipw_send_tx_power(priv, &tx_power))
2112 return -EIO;
2113
2114 /* configure device to also handle 'A' band */
2115 if (priv->ieee->abg_true) {
2116 tx_power.ieee_mode = IPW_A_MODE;
2117 tx_power.num_channels = geo->a_channels;
2118 for (i = 0; i < tx_power.num_channels; i++) {
2119 max_power = geo->a[i].max_power;
2120 tx_power.channels_tx_power[i].channel_number =
2121 geo->a[i].channel;
2122 tx_power.channels_tx_power[i].tx_power = max_power ?
2123 min(max_power, priv->tx_power) : priv->tx_power;
2124 }
2125 if (ipw_send_tx_power(priv, &tx_power))
2126 return -EIO;
2127 }
2128 return 0;
2129}
2130
2087static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts) 2131static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
2088{ 2132{
2089 struct ipw_rts_threshold rts_threshold = { 2133 struct ipw_rts_threshold rts_threshold = {
@@ -8869,79 +8913,33 @@ static int ipw_wx_set_txpow(struct net_device *dev,
8869 union iwreq_data *wrqu, char *extra) 8913 union iwreq_data *wrqu, char *extra)
8870{ 8914{
8871 struct ipw_priv *priv = ieee80211_priv(dev); 8915 struct ipw_priv *priv = ieee80211_priv(dev);
8872 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); 8916 int err = 0;
8873 struct ipw_tx_power tx_power;
8874 int i;
8875 8917
8876 down(&priv->sem); 8918 down(&priv->sem);
8877 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) { 8919 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
8878 up(&priv->sem); 8920 err = -EINPROGRESS;
8879 return -EINPROGRESS; 8921 goto out;
8880 } 8922 }
8881 8923
8882 if (!wrqu->power.fixed) 8924 if (!wrqu->power.fixed)
8883 wrqu->power.value = IPW_TX_POWER_DEFAULT; 8925 wrqu->power.value = IPW_TX_POWER_DEFAULT;
8884 8926
8885 if (wrqu->power.flags != IW_TXPOW_DBM) { 8927 if (wrqu->power.flags != IW_TXPOW_DBM) {
8886 up(&priv->sem); 8928 err = -EINVAL;
8887 return -EINVAL; 8929 goto out;
8888 } 8930 }
8889 8931
8890 if ((wrqu->power.value > IPW_TX_POWER_MAX) || 8932 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
8891 (wrqu->power.value < IPW_TX_POWER_MIN)) { 8933 (wrqu->power.value < IPW_TX_POWER_MIN)) {
8892 up(&priv->sem); 8934 err = -EINVAL;
8893 return -EINVAL; 8935 goto out;
8894 } 8936 }
8895 8937
8896 priv->tx_power = wrqu->power.value; 8938 priv->tx_power = wrqu->power.value;
8897 8939 err = ipw_set_tx_power(priv);
8898 memset(&tx_power, 0, sizeof(tx_power)); 8940 out:
8899
8900 /* configure device for 'G' band */
8901 tx_power.ieee_mode = IPW_G_MODE;
8902 tx_power.num_channels = geo->bg_channels;
8903 for (i = 0; i < geo->bg_channels; i++) {
8904 int max_power = geo->bg[i].max_power;
8905
8906 tx_power.channels_tx_power[i].channel_number = i + 1;
8907 if (max_power != 0 && priv->tx_power > max_power)
8908 tx_power.channels_tx_power[i].tx_power = max_power;
8909 else
8910 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
8911 }
8912 if (ipw_send_tx_power(priv, &tx_power))
8913 goto error;
8914
8915 /* configure device to also handle 'B' band */
8916 tx_power.ieee_mode = IPW_B_MODE;
8917 if (ipw_send_tx_power(priv, &tx_power))
8918 goto error;
8919
8920 /* configure device to also handle 'A' band */
8921 if (priv->ieee->abg_true) {
8922 tx_power.ieee_mode = IPW_A_MODE;
8923 tx_power.num_channels = geo->a_channels;
8924 for (i = 0; i < geo->a_channels; i++) {
8925 int max_power = geo->a[i].max_power;
8926
8927 tx_power.channels_tx_power[i].channel_number = i + 1;
8928 if (max_power != 0 && priv->tx_power > max_power)
8929 tx_power.channels_tx_power[i].tx_power =
8930 max_power;
8931 else
8932 tx_power.channels_tx_power[i].tx_power =
8933 priv->tx_power;
8934 }
8935 if (ipw_send_tx_power(priv, &tx_power))
8936 goto error;
8937 }
8938
8939 up(&priv->sem);
8940 return 0;
8941
8942 error:
8943 up(&priv->sem); 8941 up(&priv->sem);
8944 return -EIO; 8942 return err;
8945} 8943}
8946 8944
8947static int ipw_wx_get_txpow(struct net_device *dev, 8945static int ipw_wx_get_txpow(struct net_device *dev,
@@ -10426,29 +10424,10 @@ static int init_supported_rates(struct ipw_priv *priv,
10426 10424
10427static int ipw_config(struct ipw_priv *priv) 10425static int ipw_config(struct ipw_priv *priv)
10428{ 10426{
10429 int i;
10430 struct ipw_tx_power tx_power;
10431
10432 memset(&priv->sys_config, 0, sizeof(priv->sys_config));
10433 memset(&tx_power, 0, sizeof(tx_power));
10434
10435 /* This is only called from ipw_up, which resets/reloads the firmware 10427 /* This is only called from ipw_up, which resets/reloads the firmware
10436 so, we don't need to first disable the card before we configure 10428 so, we don't need to first disable the card before we configure
10437 it */ 10429 it */
10438 10430 if (ipw_set_tx_power(priv))
10439 /* configure device for 'G' band */
10440 tx_power.ieee_mode = IPW_G_MODE;
10441 tx_power.num_channels = 11;
10442 for (i = 0; i < 11; i++) {
10443 tx_power.channels_tx_power[i].channel_number = i + 1;
10444 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
10445 }
10446 if (ipw_send_tx_power(priv, &tx_power))
10447 goto error;
10448
10449 /* configure device to also handle 'B' band */
10450 tx_power.ieee_mode = IPW_B_MODE;
10451 if (ipw_send_tx_power(priv, &tx_power))
10452 goto error; 10431 goto error;
10453 10432
10454 /* initialize adapter address */ 10433 /* initialize adapter address */