diff options
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 | } |