diff options
author | Nishant Sarmukadam <nishants@marvell.com> | 2010-11-12 20:23:48 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-16 16:37:02 -0500 |
commit | 41fdf0974d9eb81215cb578211a6d8f8a022a9eb (patch) | |
tree | c0cea67948bbe01648e91a97df8db603a2a3689a /drivers/net/wireless/mwl8k.c | |
parent | a1fe24b0fd8bf16b4e551ae3fb785bfc574b9ffb (diff) |
mwl8k: rf_tx_power cmd not supported by AP firmware APIv1
APIv1 AP firmware does not support the RF_TX_POWER command. It
supports the similar TX_POWER command.
Signed-off-by: Pradeep Nemavat <pnemavat@marvell.com>
Signed-off-by: Nishant Sarmukadam <nishants@marvell.com>
Signed-off-by: Brian Cavagnolo <brian@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r-- | drivers/net/wireless/mwl8k.c | 78 |
1 files changed, 72 insertions, 6 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index f152a25be59f..cfda87a595e3 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -285,8 +285,9 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { | |||
285 | }; | 285 | }; |
286 | 286 | ||
287 | /* Set or get info from Firmware */ | 287 | /* Set or get info from Firmware */ |
288 | #define MWL8K_CMD_SET 0x0001 | ||
289 | #define MWL8K_CMD_GET 0x0000 | 288 | #define MWL8K_CMD_GET 0x0000 |
289 | #define MWL8K_CMD_SET 0x0001 | ||
290 | #define MWL8K_CMD_SET_LIST 0x0002 | ||
290 | 291 | ||
291 | /* Firmware command codes */ | 292 | /* Firmware command codes */ |
292 | #define MWL8K_CMD_CODE_DNLD 0x0001 | 293 | #define MWL8K_CMD_CODE_DNLD 0x0001 |
@@ -296,6 +297,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { | |||
296 | #define MWL8K_CMD_GET_STAT 0x0014 | 297 | #define MWL8K_CMD_GET_STAT 0x0014 |
297 | #define MWL8K_CMD_RADIO_CONTROL 0x001c | 298 | #define MWL8K_CMD_RADIO_CONTROL 0x001c |
298 | #define MWL8K_CMD_RF_TX_POWER 0x001e | 299 | #define MWL8K_CMD_RF_TX_POWER 0x001e |
300 | #define MWL8K_CMD_TX_POWER 0x001f | ||
299 | #define MWL8K_CMD_RF_ANTENNA 0x0020 | 301 | #define MWL8K_CMD_RF_ANTENNA 0x0020 |
300 | #define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */ | 302 | #define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */ |
301 | #define MWL8K_CMD_SET_PRE_SCAN 0x0107 | 303 | #define MWL8K_CMD_SET_PRE_SCAN 0x0107 |
@@ -333,6 +335,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) | |||
333 | MWL8K_CMDNAME(GET_STAT); | 335 | MWL8K_CMDNAME(GET_STAT); |
334 | MWL8K_CMDNAME(RADIO_CONTROL); | 336 | MWL8K_CMDNAME(RADIO_CONTROL); |
335 | MWL8K_CMDNAME(RF_TX_POWER); | 337 | MWL8K_CMDNAME(RF_TX_POWER); |
338 | MWL8K_CMDNAME(TX_POWER); | ||
336 | MWL8K_CMDNAME(RF_ANTENNA); | 339 | MWL8K_CMDNAME(RF_ANTENNA); |
337 | MWL8K_CMDNAME(SET_BEACON); | 340 | MWL8K_CMDNAME(SET_BEACON); |
338 | MWL8K_CMDNAME(SET_PRE_SCAN); | 341 | MWL8K_CMDNAME(SET_PRE_SCAN); |
@@ -2084,7 +2087,7 @@ mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble) | |||
2084 | /* | 2087 | /* |
2085 | * CMD_RF_TX_POWER. | 2088 | * CMD_RF_TX_POWER. |
2086 | */ | 2089 | */ |
2087 | #define MWL8K_TX_POWER_LEVEL_TOTAL 8 | 2090 | #define MWL8K_RF_TX_POWER_LEVEL_TOTAL 8 |
2088 | 2091 | ||
2089 | struct mwl8k_cmd_rf_tx_power { | 2092 | struct mwl8k_cmd_rf_tx_power { |
2090 | struct mwl8k_cmd_pkt header; | 2093 | struct mwl8k_cmd_pkt header; |
@@ -2092,7 +2095,7 @@ struct mwl8k_cmd_rf_tx_power { | |||
2092 | __le16 support_level; | 2095 | __le16 support_level; |
2093 | __le16 current_level; | 2096 | __le16 current_level; |
2094 | __le16 reserved; | 2097 | __le16 reserved; |
2095 | __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; | 2098 | __le16 power_level_list[MWL8K_RF_TX_POWER_LEVEL_TOTAL]; |
2096 | } __packed; | 2099 | } __packed; |
2097 | 2100 | ||
2098 | static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm) | 2101 | static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm) |
@@ -2116,6 +2119,65 @@ static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm) | |||
2116 | } | 2119 | } |
2117 | 2120 | ||
2118 | /* | 2121 | /* |
2122 | * CMD_TX_POWER. | ||
2123 | */ | ||
2124 | #define MWL8K_TX_POWER_LEVEL_TOTAL 12 | ||
2125 | |||
2126 | struct mwl8k_cmd_tx_power { | ||
2127 | struct mwl8k_cmd_pkt header; | ||
2128 | __le16 action; | ||
2129 | __le16 band; | ||
2130 | __le16 channel; | ||
2131 | __le16 bw; | ||
2132 | __le16 sub_ch; | ||
2133 | __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL]; | ||
2134 | } __attribute__((packed)); | ||
2135 | |||
2136 | static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, | ||
2137 | struct ieee80211_conf *conf, | ||
2138 | unsigned short pwr) | ||
2139 | { | ||
2140 | struct ieee80211_channel *channel = conf->channel; | ||
2141 | struct mwl8k_cmd_tx_power *cmd; | ||
2142 | int rc; | ||
2143 | int i; | ||
2144 | |||
2145 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | ||
2146 | if (cmd == NULL) | ||
2147 | return -ENOMEM; | ||
2148 | |||
2149 | cmd->header.code = cpu_to_le16(MWL8K_CMD_TX_POWER); | ||
2150 | cmd->header.length = cpu_to_le16(sizeof(*cmd)); | ||
2151 | cmd->action = cpu_to_le16(MWL8K_CMD_SET_LIST); | ||
2152 | |||
2153 | if (channel->band == IEEE80211_BAND_2GHZ) | ||
2154 | cmd->band = cpu_to_le16(0x1); | ||
2155 | else if (channel->band == IEEE80211_BAND_5GHZ) | ||
2156 | cmd->band = cpu_to_le16(0x4); | ||
2157 | |||
2158 | cmd->channel = channel->hw_value; | ||
2159 | |||
2160 | if (conf->channel_type == NL80211_CHAN_NO_HT || | ||
2161 | conf->channel_type == NL80211_CHAN_HT20) { | ||
2162 | cmd->bw = cpu_to_le16(0x2); | ||
2163 | } else { | ||
2164 | cmd->bw = cpu_to_le16(0x4); | ||
2165 | if (conf->channel_type == NL80211_CHAN_HT40MINUS) | ||
2166 | cmd->sub_ch = cpu_to_le16(0x3); | ||
2167 | else if (conf->channel_type == NL80211_CHAN_HT40PLUS) | ||
2168 | cmd->sub_ch = cpu_to_le16(0x1); | ||
2169 | } | ||
2170 | |||
2171 | for (i = 0; i < MWL8K_TX_POWER_LEVEL_TOTAL; i++) | ||
2172 | cmd->power_level_list[i] = cpu_to_le16(pwr); | ||
2173 | |||
2174 | rc = mwl8k_post_cmd(hw, &cmd->header); | ||
2175 | kfree(cmd); | ||
2176 | |||
2177 | return rc; | ||
2178 | } | ||
2179 | |||
2180 | /* | ||
2119 | * CMD_RF_ANTENNA. | 2181 | * CMD_RF_ANTENNA. |
2120 | */ | 2182 | */ |
2121 | struct mwl8k_cmd_rf_antenna { | 2183 | struct mwl8k_cmd_rf_antenna { |
@@ -3377,15 +3439,19 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) | |||
3377 | 3439 | ||
3378 | if (conf->power_level > 18) | 3440 | if (conf->power_level > 18) |
3379 | conf->power_level = 18; | 3441 | conf->power_level = 18; |
3380 | rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); | ||
3381 | if (rc) | ||
3382 | goto out; | ||
3383 | 3442 | ||
3384 | if (priv->ap_fw) { | 3443 | if (priv->ap_fw) { |
3444 | rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level); | ||
3445 | if (rc) | ||
3446 | goto out; | ||
3447 | |||
3385 | rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7); | 3448 | rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x7); |
3386 | if (!rc) | 3449 | if (!rc) |
3387 | rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7); | 3450 | rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_TX, 0x7); |
3388 | } else { | 3451 | } else { |
3452 | rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); | ||
3453 | if (rc) | ||
3454 | goto out; | ||
3389 | rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7); | 3455 | rc = mwl8k_cmd_mimo_config(hw, 0x7, 0x7); |
3390 | } | 3456 | } |
3391 | 3457 | ||