aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/wext.c
diff options
context:
space:
mode:
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}