diff options
author | Dan Williams <dcbw@redhat.com> | 2007-08-02 11:40:45 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:49:48 -0400 |
commit | 8c5127657549d055ac9d709cdea73902a6ef392c (patch) | |
tree | 33e72a0b55165d51652a002ab6929857f0e2facc /drivers/net/wireless/libertas/wext.c | |
parent | e52414728b930f0adcbc38c6498dd03b3568fe99 (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.c | 163 |
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 | */ | ||
27 | static 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 | */ | ||
197 | static 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 | */ |
217 | static int get_active_data_rates(wlan_adapter * adapter, | 187 | static 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 | ||
243 | static int wlan_get_name(struct net_device *dev, struct iw_request_info *info, | 199 | static 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 | */ | ||
1089 | u32 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 | */ | ||
1103 | u8 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 | |||
1115 | static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, | 1037 | static 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 | ||
1076 | out: | ||
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 | } |