diff options
author | Zhu Yi <yi.zhu@intel.com> | 2005-08-11 02:39:33 -0400 |
---|---|---|
committer | James Ketrenos <jketreno@linux.intel.com> | 2005-11-07 18:50:50 -0500 |
commit | 6de9f7f27defe6f1a2d33d0b78af6b1a0ad18330 (patch) | |
tree | b30d488ffce4501c659cce7b9e43c82ebbdbddd3 /drivers | |
parent | 22501c8ed70398178e8c8d55e65da97b7e7fb610 (diff) |
Fix firmware error when setting tx_power.
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 131 |
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 | ||
2087 | static 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 | |||
2087 | static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts) | 2131 | static 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 | ||
8947 | static int ipw_wx_get_txpow(struct net_device *dev, | 8945 | static int ipw_wx_get_txpow(struct net_device *dev, |
@@ -10426,29 +10424,10 @@ static int init_supported_rates(struct ipw_priv *priv, | |||
10426 | 10424 | ||
10427 | static int ipw_config(struct ipw_priv *priv) | 10425 | static 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 */ |