diff options
author | Javier Cardona <javier@cozybit.com> | 2008-05-24 05:59:49 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-03 15:00:17 -0400 |
commit | 85319f933a703a92652a8f23339f1ec1694cd594 (patch) | |
tree | dbf8cfc55fa2dd3c5b72379ba98c920bbf027b11 /drivers | |
parent | 553381c430f0e65e87ed1b5cee841a04c8a47b58 (diff) |
libertas: rate adaptation configuration via iwconfig.
Implemented rate adaptation support via 'iwconfig rate' API. It is now
possible to specify a bit-rate value and append 'auto'. That will configure
rate adaptation to use all bit-rates equal or lower than than selected value.
Made lbs_cmd_802_11_rate_adapt_rateset a direct command.
Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Acked-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmd.c | 67 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmd.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/cmdresp.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/dev.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/hostcmd.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/rx.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/wext.c | 27 |
9 files changed, 75 insertions, 56 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 953a44f750e1..a267d6e65f03 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -1250,7 +1250,7 @@ static int get_common_rates(struct lbs_private *priv, | |||
1250 | lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size); | 1250 | lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size); |
1251 | lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate); | 1251 | lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate); |
1252 | 1252 | ||
1253 | if (!priv->auto_rate) { | 1253 | if (!priv->enablehwauto) { |
1254 | for (i = 0; i < tmp_size; i++) { | 1254 | for (i = 0; i < tmp_size; i++) { |
1255 | if (tmp[i] == priv->cur_rate) | 1255 | if (tmp[i] == priv->cur_rate) |
1256 | goto done; | 1256 | goto done; |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index e8d0144eb8bb..cf261d3487fd 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -676,26 +676,60 @@ static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd, | |||
676 | return 0; | 676 | return 0; |
677 | } | 677 | } |
678 | 678 | ||
679 | static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, | 679 | static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok) |
680 | struct cmd_ds_command *cmd, | ||
681 | u16 cmd_action) | ||
682 | { | 680 | { |
683 | struct cmd_ds_802_11_rate_adapt_rateset | 681 | /* Bit Rate |
684 | *rateadapt = &cmd->params.rateset; | 682 | * 15:13 Reserved |
683 | * 12 54 Mbps | ||
684 | * 11 48 Mbps | ||
685 | * 10 36 Mbps | ||
686 | * 9 24 Mbps | ||
687 | * 8 18 Mbps | ||
688 | * 7 12 Mbps | ||
689 | * 6 9 Mbps | ||
690 | * 5 6 Mbps | ||
691 | * 4 Reserved | ||
692 | * 3 11 Mbps | ||
693 | * 2 5.5 Mbps | ||
694 | * 1 2 Mbps | ||
695 | * 0 1 Mbps | ||
696 | **/ | ||
697 | |||
698 | uint16_t ratemask; | ||
699 | int i = lbs_data_rate_to_fw_index(rate); | ||
700 | if (lower_rates_ok) | ||
701 | ratemask = (0x1fef >> (12 - i)); | ||
702 | else | ||
703 | ratemask = (1 << i); | ||
704 | return cpu_to_le16(ratemask); | ||
705 | } | ||
706 | |||
707 | int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, | ||
708 | uint16_t cmd_action) | ||
709 | { | ||
710 | struct cmd_ds_802_11_rate_adapt_rateset cmd; | ||
711 | int ret; | ||
685 | 712 | ||
686 | lbs_deb_enter(LBS_DEB_CMD); | 713 | lbs_deb_enter(LBS_DEB_CMD); |
687 | cmd->size = | ||
688 | cpu_to_le16(sizeof(struct cmd_ds_802_11_rate_adapt_rateset) | ||
689 | + S_DS_GEN); | ||
690 | cmd->command = cpu_to_le16(CMD_802_11_RATE_ADAPT_RATESET); | ||
691 | 714 | ||
692 | rateadapt->action = cpu_to_le16(cmd_action); | 715 | if (!priv->cur_rate && !priv->enablehwauto) |
693 | rateadapt->enablehwauto = cpu_to_le16(priv->enablehwauto); | 716 | return -EINVAL; |
694 | rateadapt->bitmap = cpu_to_le16(priv->ratebitmap); | ||
695 | 717 | ||
696 | lbs_deb_leave(LBS_DEB_CMD); | 718 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
697 | return 0; | 719 | |
720 | cmd.action = cpu_to_le16(cmd_action); | ||
721 | cmd.enablehwauto = cpu_to_le16(priv->enablehwauto); | ||
722 | cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto); | ||
723 | ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd); | ||
724 | if (!ret && cmd_action == CMD_ACT_GET) { | ||
725 | priv->ratebitmap = le16_to_cpu(cmd.bitmap); | ||
726 | priv->enablehwauto = le16_to_cpu(cmd.enablehwauto); | ||
727 | } | ||
728 | |||
729 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | ||
730 | return ret; | ||
698 | } | 731 | } |
732 | EXPORT_SYMBOL_GPL(lbs_cmd_802_11_rate_adapt_rateset); | ||
699 | 733 | ||
700 | /** | 734 | /** |
701 | * @brief Set the data rate | 735 | * @brief Set the data rate |
@@ -1378,11 +1412,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, | |||
1378 | cmd_action, pdata_buf); | 1412 | cmd_action, pdata_buf); |
1379 | break; | 1413 | break; |
1380 | 1414 | ||
1381 | case CMD_802_11_RATE_ADAPT_RATESET: | ||
1382 | ret = lbs_cmd_802_11_rate_adapt_rateset(priv, | ||
1383 | cmdptr, cmd_action); | ||
1384 | break; | ||
1385 | |||
1386 | case CMD_802_11_MONITOR_MODE: | 1415 | case CMD_802_11_MONITOR_MODE: |
1387 | ret = lbs_cmd_802_11_monitor_mode(cmdptr, | 1416 | ret = lbs_cmd_802_11_monitor_mode(cmdptr, |
1388 | cmd_action, pdata_buf); | 1417 | cmd_action, pdata_buf); |
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h index 00d290e2818f..a53b51f8bdb4 100644 --- a/drivers/net/wireless/libertas/cmd.h +++ b/drivers/net/wireless/libertas/cmd.h | |||
@@ -48,6 +48,8 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria); | |||
48 | int lbs_suspend(struct lbs_private *priv); | 48 | int lbs_suspend(struct lbs_private *priv); |
49 | void lbs_resume(struct lbs_private *priv); | 49 | void lbs_resume(struct lbs_private *priv); |
50 | 50 | ||
51 | int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, | ||
52 | uint16_t cmd_action); | ||
51 | int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv, | 53 | int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv, |
52 | uint16_t cmd_action, uint16_t *timeout); | 54 | uint16_t cmd_action, uint16_t *timeout); |
53 | int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, | 55 | int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, |
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 4c3c5ec16f98..24de3c3cf877 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c | |||
@@ -203,22 +203,6 @@ static int lbs_ret_802_11_rf_tx_power(struct lbs_private *priv, | |||
203 | return 0; | 203 | return 0; |
204 | } | 204 | } |
205 | 205 | ||
206 | static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv, | ||
207 | struct cmd_ds_command *resp) | ||
208 | { | ||
209 | struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset; | ||
210 | |||
211 | lbs_deb_enter(LBS_DEB_CMD); | ||
212 | |||
213 | if (rates->action == CMD_ACT_GET) { | ||
214 | priv->enablehwauto = le16_to_cpu(rates->enablehwauto); | ||
215 | priv->ratebitmap = le16_to_cpu(rates->bitmap); | ||
216 | } | ||
217 | |||
218 | lbs_deb_leave(LBS_DEB_CMD); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | static int lbs_ret_802_11_rssi(struct lbs_private *priv, | 206 | static int lbs_ret_802_11_rssi(struct lbs_private *priv, |
223 | struct cmd_ds_command *resp) | 207 | struct cmd_ds_command *resp) |
224 | { | 208 | { |
@@ -321,10 +305,6 @@ static inline int handle_cmd_response(struct lbs_private *priv, | |||
321 | case CMD_RET(CMD_802_11_BEACON_STOP): | 305 | case CMD_RET(CMD_802_11_BEACON_STOP): |
322 | break; | 306 | break; |
323 | 307 | ||
324 | case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET): | ||
325 | ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp); | ||
326 | break; | ||
327 | |||
328 | case CMD_RET(CMD_802_11_RSSI): | 308 | case CMD_RET(CMD_802_11_RSSI): |
329 | ret = lbs_ret_802_11_rssi(priv, resp); | 309 | ret = lbs_ret_802_11_rssi(priv, resp); |
330 | break; | 310 | break; |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 0a9fc5136783..f5bb40c54d85 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -237,8 +237,8 @@ struct lbs_private { | |||
237 | /** 802.11 statistics */ | 237 | /** 802.11 statistics */ |
238 | // struct cmd_DS_802_11_GET_STAT wlan802_11Stat; | 238 | // struct cmd_DS_802_11_GET_STAT wlan802_11Stat; |
239 | 239 | ||
240 | u16 enablehwauto; | 240 | uint16_t enablehwauto; |
241 | u16 ratebitmap; | 241 | uint16_t ratebitmap; |
242 | 242 | ||
243 | u32 fragthsd; | 243 | u32 fragthsd; |
244 | u32 rtsthsd; | 244 | u32 rtsthsd; |
@@ -296,7 +296,6 @@ struct lbs_private { | |||
296 | 296 | ||
297 | /** data rate stuff */ | 297 | /** data rate stuff */ |
298 | u8 cur_rate; | 298 | u8 cur_rate; |
299 | u8 auto_rate; | ||
300 | 299 | ||
301 | /** RF calibration data */ | 300 | /** RF calibration data */ |
302 | 301 | ||
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index c36ab3162238..913b480211a9 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h | |||
@@ -500,6 +500,7 @@ struct cmd_ds_802_11_data_rate { | |||
500 | }; | 500 | }; |
501 | 501 | ||
502 | struct cmd_ds_802_11_rate_adapt_rateset { | 502 | struct cmd_ds_802_11_rate_adapt_rateset { |
503 | struct cmd_header hdr; | ||
503 | __le16 action; | 504 | __le16 action; |
504 | __le16 enablehwauto; | 505 | __le16 enablehwauto; |
505 | __le16 bitmap; | 506 | __le16 bitmap; |
@@ -703,7 +704,6 @@ struct cmd_ds_command { | |||
703 | struct cmd_ds_802_11_rf_tx_power txp; | 704 | struct cmd_ds_802_11_rf_tx_power txp; |
704 | struct cmd_ds_802_11_rf_antenna rant; | 705 | struct cmd_ds_802_11_rf_antenna rant; |
705 | struct cmd_ds_802_11_monitor_mode monitor; | 706 | struct cmd_ds_802_11_monitor_mode monitor; |
706 | struct cmd_ds_802_11_rate_adapt_rateset rateset; | ||
707 | struct cmd_ds_802_11_ad_hoc_join adj; | 707 | struct cmd_ds_802_11_ad_hoc_join adj; |
708 | struct cmd_ds_802_11_rssi rssi; | 708 | struct cmd_ds_802_11_rssi rssi; |
709 | struct cmd_ds_802_11_rssi_rsp rssirsp; | 709 | struct cmd_ds_802_11_rssi_rsp rssirsp; |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index faa4db1838b6..039e09a8b024 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -1044,7 +1044,7 @@ static int lbs_init_adapter(struct lbs_private *priv) | |||
1044 | priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; | 1044 | priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; |
1045 | priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; | 1045 | priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; |
1046 | priv->radioon = RADIO_ON; | 1046 | priv->radioon = RADIO_ON; |
1047 | priv->auto_rate = 1; | 1047 | priv->enablehwauto = 1; |
1048 | priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; | 1048 | priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; |
1049 | priv->psmode = LBS802_11POWERMODECAM; | 1049 | priv->psmode = LBS802_11POWERMODECAM; |
1050 | priv->psstate = PS_STATE_FULL_POWER; | 1050 | priv->psstate = PS_STATE_FULL_POWER; |
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 05af7316f698..5749f22b296f 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c | |||
@@ -237,7 +237,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | |||
237 | /* Take the data rate from the rxpd structure | 237 | /* Take the data rate from the rxpd structure |
238 | * only if the rate is auto | 238 | * only if the rate is auto |
239 | */ | 239 | */ |
240 | if (priv->auto_rate) | 240 | if (priv->enablehwauto) |
241 | priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate); | 241 | priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate); |
242 | 242 | ||
243 | lbs_compute_rssi(priv, p_rx_pd); | 243 | lbs_compute_rssi(priv, p_rx_pd); |
@@ -383,7 +383,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, | |||
383 | /* Take the data rate from the rxpd structure | 383 | /* Take the data rate from the rxpd structure |
384 | * only if the rate is auto | 384 | * only if the rate is auto |
385 | */ | 385 | */ |
386 | if (priv->auto_rate) | 386 | if (priv->enablehwauto) |
387 | priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate); | 387 | priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate); |
388 | 388 | ||
389 | lbs_compute_rssi(priv, prxpd); | 389 | lbs_compute_rssi(priv, prxpd); |
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index d4b19f11b785..8b3ed77860b3 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c | |||
@@ -1021,29 +1021,38 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, | |||
1021 | 1021 | ||
1022 | lbs_deb_enter(LBS_DEB_WEXT); | 1022 | lbs_deb_enter(LBS_DEB_WEXT); |
1023 | lbs_deb_wext("vwrq->value %d\n", vwrq->value); | 1023 | lbs_deb_wext("vwrq->value %d\n", vwrq->value); |
1024 | lbs_deb_wext("vwrq->fixed %d\n", vwrq->fixed); | ||
1025 | |||
1026 | if (vwrq->fixed && vwrq->value == -1) | ||
1027 | goto out; | ||
1024 | 1028 | ||
1025 | /* Auto rate? */ | 1029 | /* Auto rate? */ |
1026 | if (vwrq->value == -1) { | 1030 | priv->enablehwauto = !vwrq->fixed; |
1027 | priv->auto_rate = 1; | 1031 | |
1032 | if (vwrq->value == -1) | ||
1028 | priv->cur_rate = 0; | 1033 | priv->cur_rate = 0; |
1029 | } else { | 1034 | else { |
1030 | if (vwrq->value % 100000) | 1035 | if (vwrq->value % 100000) |
1031 | goto out; | 1036 | goto out; |
1032 | 1037 | ||
1038 | new_rate = vwrq->value / 500000; | ||
1039 | priv->cur_rate = new_rate; | ||
1040 | /* the rest is only needed for lbs_set_data_rate() */ | ||
1033 | memset(rates, 0, sizeof(rates)); | 1041 | memset(rates, 0, sizeof(rates)); |
1034 | copy_active_data_rates(priv, rates); | 1042 | copy_active_data_rates(priv, rates); |
1035 | new_rate = vwrq->value / 500000; | ||
1036 | if (!memchr(rates, new_rate, sizeof(rates))) { | 1043 | if (!memchr(rates, new_rate, sizeof(rates))) { |
1037 | lbs_pr_alert("fixed data rate 0x%X out of range\n", | 1044 | lbs_pr_alert("fixed data rate 0x%X out of range\n", |
1038 | new_rate); | 1045 | new_rate); |
1039 | goto out; | 1046 | goto out; |
1040 | } | 1047 | } |
1041 | |||
1042 | priv->cur_rate = new_rate; | ||
1043 | priv->auto_rate = 0; | ||
1044 | } | 1048 | } |
1045 | 1049 | ||
1046 | ret = lbs_set_data_rate(priv, new_rate); | 1050 | /* Try the newer command first (Firmware Spec 5.1 and above) */ |
1051 | ret = lbs_cmd_802_11_rate_adapt_rateset(priv, CMD_ACT_SET); | ||
1052 | |||
1053 | /* Fallback to older version */ | ||
1054 | if (ret) | ||
1055 | ret = lbs_set_data_rate(priv, new_rate); | ||
1047 | 1056 | ||
1048 | out: | 1057 | out: |
1049 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); | 1058 | lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); |
@@ -1060,7 +1069,7 @@ static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info, | |||
1060 | if (priv->connect_status == LBS_CONNECTED) { | 1069 | if (priv->connect_status == LBS_CONNECTED) { |
1061 | vwrq->value = priv->cur_rate * 500000; | 1070 | vwrq->value = priv->cur_rate * 500000; |
1062 | 1071 | ||
1063 | if (priv->auto_rate) | 1072 | if (priv->enablehwauto) |
1064 | vwrq->fixed = 0; | 1073 | vwrq->fixed = 0; |
1065 | else | 1074 | else |
1066 | vwrq->fixed = 1; | 1075 | vwrq->fixed = 1; |