aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/wext.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-05-25 16:46:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-06-11 14:28:42 -0400
commitef9a264b7a288a07c43ddb244c4f9ab0e8df90e4 (patch)
tree67dad09f719d1e91cb168143db2215b9a84dd942 /drivers/net/wireless/libertas/wext.c
parentd43fb8ee3dab261e475d4f5189cf86182139b7f4 (diff)
[PATCH] libertas: move channel changing into association framework
Handle channel changes through the deferred association framework rather than directly. Fixes errors when setting channels along with other parameters like mode and SSID. 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.c182
1 files changed, 31 insertions, 151 deletions
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 518371a76c36..40dd08018b49 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -157,103 +157,6 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,
157 return cfp; 157 return cfp;
158} 158}
159 159
160static int updatecurrentchannel(wlan_private * priv)
161{
162 int ret;
163
164 /*
165 ** the channel in f/w could be out of sync, get the current channel
166 */
167 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
168 cmd_opt_802_11_rf_channel_get,
169 cmd_option_waitforrsp, 0, NULL);
170
171 lbs_deb_wext("current channel %d\n",
172 priv->adapter->curbssparams.channel);
173
174 return ret;
175}
176
177static int setcurrentchannel(wlan_private * priv, int channel)
178{
179 lbs_deb_wext("set channel %d\n", channel);
180
181 /*
182 ** Current channel is not set to adhocchannel requested, set channel
183 */
184 return (libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel,
185 cmd_opt_802_11_rf_channel_set,
186 cmd_option_waitforrsp, 0, &channel));
187}
188
189static int changeadhocchannel(wlan_private * priv, int channel)
190{
191 int ret = 0;
192 struct WLAN_802_11_SSID curadhocssid;
193 struct bss_descriptor * join_bss = NULL;
194 wlan_adapter *adapter = priv->adapter;
195
196 adapter->adhocchannel = channel;
197
198 updatecurrentchannel(priv);
199
200 if (adapter->curbssparams.channel == adapter->adhocchannel) {
201 /* adhocchannel is set to the current channel already */
202 goto out;
203 }
204
205 lbs_deb_wext("updating channel from %d to %d\n",
206 adapter->curbssparams.channel, adapter->adhocchannel);
207
208 setcurrentchannel(priv, adapter->adhocchannel);
209
210 updatecurrentchannel(priv);
211
212 if (adapter->curbssparams.channel != adapter->adhocchannel) {
213 lbs_deb_wext("failed to updated channel to %d, channel = %d\n",
214 adapter->adhocchannel, adapter->curbssparams.channel);
215 ret = -1;
216 goto out;
217 }
218
219 if (adapter->connect_status != libertas_connected)
220 goto out;
221
222 lbs_deb_wext("channel changed while in IBSS\n");
223
224 /* Copy the current ssid */
225 memcpy(&curadhocssid, &adapter->curbssparams.ssid,
226 sizeof(struct WLAN_802_11_SSID));
227
228 /* Exit Adhoc mode */
229 lbs_deb_wext("in changeadhocchannel(): sending Adhoc stop\n");
230 ret = libertas_stop_adhoc_network(priv);
231 if (ret)
232 goto out;
233
234 /* Scan for the network, do not save previous results. Stale
235 * scan data will cause us to join a non-existant adhoc network
236 */
237 libertas_send_specific_SSID_scan(priv, &curadhocssid, 1);
238
239 /* find out the BSSID that matches the current SSID */
240 join_bss = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL,
241 IW_MODE_ADHOC);
242
243 if (join_bss) {
244 lbs_deb_wext("SSID found in list, so join\n");
245 libertas_join_adhoc_network(priv, join_bss);
246 } else {
247 lbs_deb_wext("SSID not found in list, "
248 "creating AdHoc with SSID '%s'\n",
249 curadhocssid.ssid);
250 libertas_start_adhoc_network(priv, &curadhocssid);
251 }
252
253out:
254 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
255 return ret;
256}
257 160
258/** 161/**
259 * @brief Set Radio On/OFF 162 * @brief Set Radio On/OFF
@@ -1228,82 +1131,59 @@ out:
1228static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info, 1131static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
1229 struct iw_freq *fwrq, char *extra) 1132 struct iw_freq *fwrq, char *extra)
1230{ 1133{
1231 int ret = 0; 1134 int ret = -EINVAL;
1232 wlan_private *priv = dev->priv; 1135 wlan_private *priv = dev->priv;
1233 wlan_adapter *adapter = priv->adapter; 1136 wlan_adapter *adapter = priv->adapter;
1234 int rc = -EINPROGRESS; /* Call commit handler */
1235 struct chan_freq_power *cfp; 1137 struct chan_freq_power *cfp;
1138 struct assoc_request * assoc_req;
1236 1139
1237 lbs_deb_enter(LBS_DEB_WEXT); 1140 lbs_deb_enter(LBS_DEB_WEXT);
1238 1141
1239 /* 1142 mutex_lock(&adapter->lock);
1240 * If setting by frequency, convert to a channel 1143 assoc_req = wlan_get_association_request(adapter);
1241 */ 1144 if (!assoc_req) {
1242 if (fwrq->e == 1) { 1145 ret = -ENOMEM;
1146 goto out;
1147 }
1243 1148
1149 /* If setting by frequency, convert to a channel */
1150 if (fwrq->e == 1) {
1244 long f = fwrq->m / 100000; 1151 long f = fwrq->m / 100000;
1245 int c = 0;
1246 1152
1247 cfp = find_cfp_by_band_and_freq(adapter, 0, f); 1153 cfp = find_cfp_by_band_and_freq(adapter, 0, f);
1248 if (!cfp) { 1154 if (!cfp) {
1249 lbs_deb_wext("invalid freq %ld\n", f); 1155 lbs_deb_wext("invalid freq %ld\n", f);
1250 return -EINVAL; 1156 goto out;
1251 } 1157 }
1252 1158
1253 c = (int)cfp->channel;
1254
1255 if (c < 0)
1256 return -EINVAL;
1257
1258 fwrq->e = 0; 1159 fwrq->e = 0;
1259 fwrq->m = c; 1160 fwrq->m = (int) cfp->channel;
1260 } 1161 }
1261 1162
1262 /* 1163 /* Setting by channel number */
1263 * Setting by channel number
1264 */
1265 if (fwrq->m > 1000 || fwrq->e > 0) { 1164 if (fwrq->m > 1000 || fwrq->e > 0) {
1266 rc = -EOPNOTSUPP; 1165 goto out;
1267 } else { 1166 }
1268 int channel = fwrq->m;
1269 1167
1270 cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, channel); 1168 cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m);
1271 if (!cfp) { 1169 if (!cfp) {
1272 rc = -EINVAL; 1170 goto out;
1273 } else {
1274 if (adapter->mode == IW_MODE_ADHOC) {
1275 rc = changeadhocchannel(priv, channel);
1276 /* If station is WEP enabled, send the
1277 * command to set WEP in firmware
1278 */
1279 if (adapter->secinfo.wep_enabled) {
1280 lbs_deb_wext("set_freq: WEP enabled\n");
1281 ret = libertas_prepare_and_send_command(priv,
1282 cmd_802_11_set_wep,
1283 cmd_act_add,
1284 cmd_option_waitforrsp,
1285 0,
1286 NULL);
1287
1288 if (ret) {
1289 rc = ret;
1290 goto out;
1291 }
1292
1293 adapter->currentpacketfilter |=
1294 cmd_act_mac_wep_enable;
1295
1296 libertas_set_mac_packet_filter(priv);
1297 }
1298 } else {
1299 rc = -EOPNOTSUPP;
1300 }
1301 }
1302 } 1171 }
1303 1172
1173 assoc_req->channel = fwrq->m;
1174 ret = 0;
1175
1304out: 1176out:
1305 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", rc); 1177 if (ret == 0) {
1306 return rc; 1178 set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);
1179 wlan_postpone_association_work(priv);
1180 } else {
1181 wlan_cancel_association_work(priv);
1182 }
1183 mutex_unlock(&adapter->lock);
1184
1185 lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
1186 return ret;
1307} 1187}
1308 1188
1309/** 1189/**