aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2008-05-24 05:59:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-03 15:00:17 -0400
commit85319f933a703a92652a8f23339f1ec1694cd594 (patch)
treedbf8cfc55fa2dd3c5b72379ba98c920bbf027b11 /drivers
parent553381c430f0e65e87ed1b5cee841a04c8a47b58 (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.c2
-rw-r--r--drivers/net/wireless/libertas/cmd.c67
-rw-r--r--drivers/net/wireless/libertas/cmd.h2
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c20
-rw-r--r--drivers/net/wireless/libertas/dev.h5
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h2
-rw-r--r--drivers/net/wireless/libertas/main.c2
-rw-r--r--drivers/net/wireless/libertas/rx.c4
-rw-r--r--drivers/net/wireless/libertas/wext.c27
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
679static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, 679static __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
707int 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}
732EXPORT_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);
48int lbs_suspend(struct lbs_private *priv); 48int lbs_suspend(struct lbs_private *priv);
49void lbs_resume(struct lbs_private *priv); 49void lbs_resume(struct lbs_private *priv);
50 50
51int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
52 uint16_t cmd_action);
51int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv, 53int 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);
53int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, 55int 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
206static 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
222static int lbs_ret_802_11_rssi(struct lbs_private *priv, 206static 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
502struct cmd_ds_802_11_rate_adapt_rateset { 502struct 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
1048out: 1057out:
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;