aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/wext.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-08-02 11:40:45 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:49:48 -0400
commit8c5127657549d055ac9d709cdea73902a6ef392c (patch)
tree33e72a0b55165d51652a002ab6929857f0e2facc /drivers/net/wireless/libertas/wext.c
parente52414728b930f0adcbc38c6498dd03b3568fe99 (diff)
[PATCH] libertas: simplify and clean up data rate handling
Remove unused/duplicated fields and consolidate static data rate arrays, for example the libertas_supported_rates[] and datarates[] arrays in the bss_descriptor structure, and the libertas_supported_rates field in the wlan_adapter structure. Introduce libertas_fw_index_to_data_rate and libertas_data_rate_to_fw_index functions and use them everywhere firmware requires a rate index rather than a rate array. The firmware requires the 4 basic rates to have the MSB set, but most other stuff doesn't, like WEXT and mesh ioctls. Therefore, only set the MSB on basic rates when pushing rate arrays to firmware instead of doing a ton of (rate & 0x7f) everywhere. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/wext.c')
-rw-r--r--drivers/net/wireless/libertas/wext.c163
1 files changed, 40 insertions, 123 deletions
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 115f02c010a1..0b805e32993a 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -22,14 +22,6 @@
22 22
23 23
24/** 24/**
25 * the rates supported by the card
26 */
27static u8 libertas_wlan_data_rates[WLAN_SUPPORTED_RATES] =
28 { 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
29 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
30};
31
32/**
33 * @brief Convert mw value to dbm value 25 * @brief Convert mw value to dbm value
34 * 26 *
35 * @param mw the value of mw 27 * @param mw the value of mw
@@ -187,57 +179,21 @@ int wlan_radio_ioctl(wlan_private * priv, u8 option)
187} 179}
188 180
189/** 181/**
190 * @brief Copy rates 182 * @brief Copy active data rates based on adapter mode and status
191 *
192 * @param dest A pointer to Dest Buf
193 * @param src A pointer to Src Buf
194 * @param len The len of Src Buf
195 * @return Number of rates copyed
196 */
197static inline int copyrates(u8 * dest, int pos, u8 * src, int len)
198{
199 int i;
200
201 for (i = 0; i < len && src[i]; i++, pos++) {
202 if (pos >= sizeof(u8) * WLAN_SUPPORTED_RATES)
203 break;
204 dest[pos] = src[i];
205 }
206
207 return pos;
208}
209
210/**
211 * @brief Get active data rates
212 * 183 *
213 * @param adapter A pointer to wlan_adapter structure 184 * @param adapter A pointer to wlan_adapter structure
214 * @param rate The buf to return the active rates 185 * @param rate The buf to return the active rates
215 * @return The number of rates
216 */ 186 */
217static int get_active_data_rates(wlan_adapter * adapter, 187static void copy_active_data_rates(wlan_adapter * adapter, u8 * rates)
218 u8* rates)
219{ 188{
220 int k = 0;
221
222 lbs_deb_enter(LBS_DEB_WEXT); 189 lbs_deb_enter(LBS_DEB_WEXT);
223 190
224 if (adapter->connect_status != LIBERTAS_CONNECTED) { 191 if (adapter->connect_status != LIBERTAS_CONNECTED)
225 if (adapter->mode == IW_MODE_INFRA) { 192 memcpy(rates, libertas_bg_rates, MAX_RATES);
226 lbs_deb_wext("infra\n"); 193 else
227 k = copyrates(rates, k, libertas_supported_rates, 194 memcpy(rates, adapter->curbssparams.rates, MAX_RATES);
228 sizeof(libertas_supported_rates));
229 } else {
230 lbs_deb_wext("Adhoc G\n");
231 k = copyrates(rates, k, libertas_adhoc_rates_g,
232 sizeof(libertas_adhoc_rates_g));
233 }
234 } else {
235 k = copyrates(rates, 0, adapter->curbssparams.datarates,
236 adapter->curbssparams.numofrates);
237 }
238 195
239 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", k); 196 lbs_deb_leave(LBS_DEB_WEXT);
240 return k;
241} 197}
242 198
243static int wlan_get_name(struct net_device *dev, struct iw_request_info *info, 199static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,
@@ -673,7 +629,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
673 wlan_adapter *adapter = priv->adapter; 629 wlan_adapter *adapter = priv->adapter;
674 struct iw_range *range = (struct iw_range *)extra; 630 struct iw_range *range = (struct iw_range *)extra;
675 struct chan_freq_power *cfp; 631 struct chan_freq_power *cfp;
676 u8 rates[WLAN_SUPPORTED_RATES]; 632 u8 rates[MAX_RATES + 1];
677 633
678 u8 flag = 0; 634 u8 flag = 0;
679 635
@@ -686,12 +642,10 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
686 range->max_nwid = 0; 642 range->max_nwid = 0;
687 643
688 memset(rates, 0, sizeof(rates)); 644 memset(rates, 0, sizeof(rates));
689 range->num_bitrates = get_active_data_rates(adapter, rates); 645 copy_active_data_rates(adapter, rates);
690 646 range->num_bitrates = strnlen(rates, IW_MAX_BITRATES);
691 for (i = 0; i < min_t(__u8, range->num_bitrates, IW_MAX_BITRATES) && rates[i]; 647 for (i = 0; i < range->num_bitrates; i++)
692 i++) { 648 range->bitrate[i] = rates[i] * 500000;
693 range->bitrate[i] = (rates[i] & 0x7f) * 500000;
694 }
695 range->num_bitrates = i; 649 range->num_bitrates = i;
696 lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES, 650 lbs_deb_wext("IW_MAX_BITRATES %d, num_bitrates %d\n", IW_MAX_BITRATES,
697 range->num_bitrates); 651 range->num_bitrates);
@@ -1080,88 +1034,46 @@ out:
1080 return ret; 1034 return ret;
1081} 1035}
1082 1036
1083/**
1084 * @brief use index to get the data rate
1085 *
1086 * @param index The index of data rate
1087 * @return data rate or 0
1088 */
1089u32 libertas_index_to_data_rate(u8 index)
1090{
1091 if (index >= sizeof(libertas_wlan_data_rates))
1092 index = 0;
1093
1094 return libertas_wlan_data_rates[index];
1095}
1096
1097/**
1098 * @brief use rate to get the index
1099 *
1100 * @param rate data rate
1101 * @return index or 0
1102 */
1103u8 libertas_data_rate_to_index(u32 rate)
1104{
1105 u8 *ptr;
1106
1107 if (rate)
1108 if ((ptr = memchr(libertas_wlan_data_rates, (u8) rate,
1109 sizeof(libertas_wlan_data_rates))))
1110 return (ptr - libertas_wlan_data_rates);
1111
1112 return 0;
1113}
1114
1115static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, 1037static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
1116 struct iw_param *vwrq, char *extra) 1038 struct iw_param *vwrq, char *extra)
1117{ 1039{
1118 wlan_private *priv = dev->priv; 1040 wlan_private *priv = dev->priv;
1119 wlan_adapter *adapter = priv->adapter; 1041 wlan_adapter *adapter = priv->adapter;
1120 u32 data_rate; 1042 u32 new_rate;
1121 u16 action; 1043 u16 action;
1122 int ret = 0; 1044 int ret = -EINVAL;
1123 u8 rates[WLAN_SUPPORTED_RATES]; 1045 u8 rates[MAX_RATES + 1];
1124 u8 *rate;
1125 1046
1126 lbs_deb_enter(LBS_DEB_WEXT); 1047 lbs_deb_enter(LBS_DEB_WEXT);
1127
1128 lbs_deb_wext("vwrq->value %d\n", vwrq->value); 1048 lbs_deb_wext("vwrq->value %d\n", vwrq->value);
1129 1049
1050 /* Auto rate? */
1130 if (vwrq->value == -1) { 1051 if (vwrq->value == -1) {
1131 action = CMD_ACT_SET_TX_AUTO; // Auto 1052 action = CMD_ACT_SET_TX_AUTO;
1132 adapter->is_datarate_auto = 1; 1053 adapter->auto_rate = 1;
1133 adapter->datarate = 0; 1054 adapter->cur_rate = 0;
1134 } else { 1055 } else {
1135 if (vwrq->value % 100000) { 1056 if (vwrq->value % 100000)
1136 return -EINVAL; 1057 goto out;
1137 }
1138
1139 data_rate = vwrq->value / 500000;
1140 1058
1141 memset(rates, 0, sizeof(rates)); 1059 memset(rates, 0, sizeof(rates));
1142 get_active_data_rates(adapter, rates); 1060 copy_active_data_rates(adapter, rates);
1143 rate = rates; 1061 new_rate = vwrq->value / 500000;
1144 while (*rate) { 1062 if (!memchr(rates, new_rate, sizeof(rates))) {
1145 lbs_deb_wext("rate=0x%X, wanted data_rate 0x%X\n", *rate, 1063 lbs_pr_alert("fixed data rate 0x%X out of range\n",
1146 data_rate); 1064 new_rate);
1147 if ((*rate & 0x7f) == (data_rate & 0x7f)) 1065 goto out;
1148 break;
1149 rate++;
1150 }
1151 if (!*rate) {
1152 lbs_pr_alert("fixed data rate 0x%X out "
1153 "of range\n", data_rate);
1154 return -EINVAL;
1155 } 1066 }
1156 1067
1157 adapter->datarate = data_rate; 1068 adapter->cur_rate = new_rate;
1158 action = CMD_ACT_SET_TX_FIX_RATE; 1069 action = CMD_ACT_SET_TX_FIX_RATE;
1159 adapter->is_datarate_auto = 0; 1070 adapter->auto_rate = 0;
1160 } 1071 }
1161 1072
1162 ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE, 1073 ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE,
1163 action, CMD_OPTION_WAITFORRSP, 0, NULL); 1074 action, CMD_OPTION_WAITFORRSP, 0, NULL);
1164 1075
1076out:
1165 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret); 1077 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1166 return ret; 1078 return ret;
1167} 1079}
@@ -1174,14 +1086,19 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,
1174 1086
1175 lbs_deb_enter(LBS_DEB_WEXT); 1087 lbs_deb_enter(LBS_DEB_WEXT);
1176 1088
1177 if (adapter->is_datarate_auto) { 1089 if (adapter->connect_status == LIBERTAS_CONNECTED) {
1178 vwrq->fixed = 0; 1090 vwrq->value = adapter->cur_rate * 500000;
1091
1092 if (adapter->auto_rate)
1093 vwrq->fixed = 0;
1094 else
1095 vwrq->fixed = 1;
1096
1179 } else { 1097 } else {
1180 vwrq->fixed = 1; 1098 vwrq->fixed = 0;
1099 vwrq->value = 0;
1181 } 1100 }
1182 1101
1183 vwrq->value = adapter->datarate * 500000;
1184
1185 lbs_deb_leave(LBS_DEB_WEXT); 1102 lbs_deb_leave(LBS_DEB_WEXT);
1186 return 0; 1103 return 0;
1187} 1104}