aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/libertas/assoc.c390
-rw-r--r--drivers/net/wireless/libertas/assoc.h20
-rw-r--r--drivers/net/wireless/libertas/cmd.c340
-rw-r--r--drivers/net/wireless/libertas/cmd.h9
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c47
5 files changed, 410 insertions, 396 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index b8bdba67ad17..17e76ac4179c 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -154,6 +154,396 @@ static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth
154} 154}
155 155
156 156
157int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
158 struct assoc_request *assoc)
159{
160 struct cmd_ds_802_11_set_wep cmd;
161 int ret = 0;
162
163 lbs_deb_enter(LBS_DEB_CMD);
164
165 memset(&cmd, 0, sizeof(cmd));
166 cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP);
167 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
168
169 cmd.action = cpu_to_le16(cmd_action);
170
171 if (cmd_action == CMD_ACT_ADD) {
172 int i;
173
174 /* default tx key index */
175 cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx &
176 CMD_WEP_KEY_INDEX_MASK);
177
178 /* Copy key types and material to host command structure */
179 for (i = 0; i < 4; i++) {
180 struct enc_key *pkey = &assoc->wep_keys[i];
181
182 switch (pkey->len) {
183 case KEY_LEN_WEP_40:
184 cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
185 memmove(cmd.keymaterial[i], pkey->key, pkey->len);
186 lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i);
187 break;
188 case KEY_LEN_WEP_104:
189 cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
190 memmove(cmd.keymaterial[i], pkey->key, pkey->len);
191 lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i);
192 break;
193 case 0:
194 break;
195 default:
196 lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
197 i, pkey->len);
198 ret = -1;
199 goto done;
200 break;
201 }
202 }
203 } else if (cmd_action == CMD_ACT_REMOVE) {
204 /* ACT_REMOVE clears _all_ WEP keys */
205
206 /* default tx key index */
207 cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx &
208 CMD_WEP_KEY_INDEX_MASK);
209 lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx);
210 }
211
212 ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
213done:
214 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
215 return ret;
216}
217
218int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
219 uint16_t *enable)
220{
221 struct cmd_ds_802_11_enable_rsn cmd;
222 int ret;
223
224 lbs_deb_enter(LBS_DEB_CMD);
225
226 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
227 cmd.action = cpu_to_le16(cmd_action);
228
229 if (cmd_action == CMD_ACT_GET)
230 cmd.enable = 0;
231 else {
232 if (*enable)
233 cmd.enable = cpu_to_le16(CMD_ENABLE_RSN);
234 else
235 cmd.enable = cpu_to_le16(CMD_DISABLE_RSN);
236 lbs_deb_cmd("ENABLE_RSN: %d\n", *enable);
237 }
238
239 ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
240 if (!ret && cmd_action == CMD_ACT_GET)
241 *enable = le16_to_cpu(cmd.enable);
242
243 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
244 return ret;
245}
246
247static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam,
248 struct enc_key *key)
249{
250 lbs_deb_enter(LBS_DEB_CMD);
251
252 if (key->flags & KEY_INFO_WPA_ENABLED)
253 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
254 if (key->flags & KEY_INFO_WPA_UNICAST)
255 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
256 if (key->flags & KEY_INFO_WPA_MCAST)
257 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
258
259 keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
260 keyparam->keytypeid = cpu_to_le16(key->type);
261 keyparam->keylen = cpu_to_le16(key->len);
262 memcpy(keyparam->key, key->key, key->len);
263
264 /* Length field doesn't include the {type,length} header */
265 keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4);
266 lbs_deb_leave(LBS_DEB_CMD);
267}
268
269int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
270 struct assoc_request *assoc)
271{
272 struct cmd_ds_802_11_key_material cmd;
273 int ret = 0;
274 int index = 0;
275
276 lbs_deb_enter(LBS_DEB_CMD);
277
278 cmd.action = cpu_to_le16(cmd_action);
279 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
280
281 if (cmd_action == CMD_ACT_GET) {
282 cmd.hdr.size = cpu_to_le16(S_DS_GEN + 2);
283 } else {
284 memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet));
285
286 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) {
287 set_one_wpa_key(&cmd.keyParamSet[index],
288 &assoc->wpa_unicast_key);
289 index++;
290 }
291
292 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) {
293 set_one_wpa_key(&cmd.keyParamSet[index],
294 &assoc->wpa_mcast_key);
295 index++;
296 }
297
298 /* The common header and as many keys as we included */
299 cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd),
300 keyParamSet[index]));
301 }
302 ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
303 /* Copy the returned key to driver private data */
304 if (!ret && cmd_action == CMD_ACT_GET) {
305 void *buf_ptr = cmd.keyParamSet;
306 void *resp_end = &(&cmd)[1];
307
308 while (buf_ptr < resp_end) {
309 struct MrvlIEtype_keyParamSet *keyparam = buf_ptr;
310 struct enc_key *key;
311 uint16_t param_set_len = le16_to_cpu(keyparam->length);
312 uint16_t key_len = le16_to_cpu(keyparam->keylen);
313 uint16_t key_flags = le16_to_cpu(keyparam->keyinfo);
314 uint16_t key_type = le16_to_cpu(keyparam->keytypeid);
315 void *end;
316
317 end = (void *)keyparam + sizeof(keyparam->type)
318 + sizeof(keyparam->length) + param_set_len;
319
320 /* Make sure we don't access past the end of the IEs */
321 if (end > resp_end)
322 break;
323
324 if (key_flags & KEY_INFO_WPA_UNICAST)
325 key = &priv->wpa_unicast_key;
326 else if (key_flags & KEY_INFO_WPA_MCAST)
327 key = &priv->wpa_mcast_key;
328 else
329 break;
330
331 /* Copy returned key into driver */
332 memset(key, 0, sizeof(struct enc_key));
333 if (key_len > sizeof(key->key))
334 break;
335 key->type = key_type;
336 key->flags = key_flags;
337 key->len = key_len;
338 memcpy(key->key, keyparam->key, key->len);
339
340 buf_ptr = end + 1;
341 }
342 }
343
344 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
345 return ret;
346}
347
348static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok)
349{
350/* Bit Rate
351* 15:13 Reserved
352* 12 54 Mbps
353* 11 48 Mbps
354* 10 36 Mbps
355* 9 24 Mbps
356* 8 18 Mbps
357* 7 12 Mbps
358* 6 9 Mbps
359* 5 6 Mbps
360* 4 Reserved
361* 3 11 Mbps
362* 2 5.5 Mbps
363* 1 2 Mbps
364* 0 1 Mbps
365**/
366
367 uint16_t ratemask;
368 int i = lbs_data_rate_to_fw_index(rate);
369 if (lower_rates_ok)
370 ratemask = (0x1fef >> (12 - i));
371 else
372 ratemask = (1 << i);
373 return cpu_to_le16(ratemask);
374}
375
376int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
377 uint16_t cmd_action)
378{
379 struct cmd_ds_802_11_rate_adapt_rateset cmd;
380 int ret;
381
382 lbs_deb_enter(LBS_DEB_CMD);
383
384 if (!priv->cur_rate && !priv->enablehwauto)
385 return -EINVAL;
386
387 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
388
389 cmd.action = cpu_to_le16(cmd_action);
390 cmd.enablehwauto = cpu_to_le16(priv->enablehwauto);
391 cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto);
392 ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd);
393 if (!ret && cmd_action == CMD_ACT_GET) {
394 priv->ratebitmap = le16_to_cpu(cmd.bitmap);
395 priv->enablehwauto = le16_to_cpu(cmd.enablehwauto);
396 }
397
398 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
399 return ret;
400}
401
402/**
403 * @brief Set the data rate
404 *
405 * @param priv A pointer to struct lbs_private structure
406 * @param rate The desired data rate, or 0 to clear a locked rate
407 *
408 * @return 0 on success, error on failure
409 */
410int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
411{
412 struct cmd_ds_802_11_data_rate cmd;
413 int ret = 0;
414
415 lbs_deb_enter(LBS_DEB_CMD);
416
417 memset(&cmd, 0, sizeof(cmd));
418 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
419
420 if (rate > 0) {
421 cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE);
422 cmd.rates[0] = lbs_data_rate_to_fw_index(rate);
423 if (cmd.rates[0] == 0) {
424 lbs_deb_cmd("DATA_RATE: invalid requested rate of"
425 " 0x%02X\n", rate);
426 ret = 0;
427 goto out;
428 }
429 lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]);
430 } else {
431 cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO);
432 lbs_deb_cmd("DATA_RATE: setting auto\n");
433 }
434
435 ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
436 if (ret)
437 goto out;
438
439 lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof(cmd));
440
441 /* FIXME: get actual rates FW can do if this command actually returns
442 * all data rates supported.
443 */
444 priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]);
445 lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate);
446
447out:
448 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
449 return ret;
450}
451
452
453int lbs_cmd_802_11_rssi(struct lbs_private *priv,
454 struct cmd_ds_command *cmd)
455{
456
457 lbs_deb_enter(LBS_DEB_CMD);
458 cmd->command = cpu_to_le16(CMD_802_11_RSSI);
459 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
460 cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
461
462 /* reset Beacon SNR/NF/RSSI values */
463 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
464 priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
465 priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
466 priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
467 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
468 priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
469
470 lbs_deb_leave(LBS_DEB_CMD);
471 return 0;
472}
473
474int lbs_ret_802_11_rssi(struct lbs_private *priv,
475 struct cmd_ds_command *resp)
476{
477 struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
478
479 lbs_deb_enter(LBS_DEB_CMD);
480
481 /* store the non average value */
482 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR);
483 priv->NF[TYPE_BEACON][TYPE_NOAVG] =
484 get_unaligned_le16(&rssirsp->noisefloor);
485
486 priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR);
487 priv->NF[TYPE_BEACON][TYPE_AVG] =
488 get_unaligned_le16(&rssirsp->avgnoisefloor);
489
490 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
491 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
492 priv->NF[TYPE_BEACON][TYPE_NOAVG]);
493
494 priv->RSSI[TYPE_BEACON][TYPE_AVG] =
495 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
496 priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
497
498 lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
499 priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
500 priv->RSSI[TYPE_BEACON][TYPE_AVG]);
501
502 lbs_deb_leave(LBS_DEB_CMD);
503 return 0;
504}
505
506
507int lbs_cmd_bcn_ctrl(struct lbs_private *priv,
508 struct cmd_ds_command *cmd,
509 u16 cmd_action)
510{
511 struct cmd_ds_802_11_beacon_control
512 *bcn_ctrl = &cmd->params.bcn_ctrl;
513
514 lbs_deb_enter(LBS_DEB_CMD);
515 cmd->size =
516 cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control)
517 + S_DS_GEN);
518 cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL);
519
520 bcn_ctrl->action = cpu_to_le16(cmd_action);
521 bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable);
522 bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period);
523
524 lbs_deb_leave(LBS_DEB_CMD);
525 return 0;
526}
527
528int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv,
529 struct cmd_ds_command *resp)
530{
531 struct cmd_ds_802_11_beacon_control *bcn_ctrl =
532 &resp->params.bcn_ctrl;
533
534 lbs_deb_enter(LBS_DEB_CMD);
535
536 if (bcn_ctrl->action == CMD_ACT_GET) {
537 priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable);
538 priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period);
539 }
540
541 lbs_deb_enter(LBS_DEB_CMD);
542 return 0;
543}
544
545
546
157static int lbs_assoc_post(struct lbs_private *priv, 547static int lbs_assoc_post(struct lbs_private *priv,
158 struct cmd_ds_802_11_associate_response *resp) 548 struct cmd_ds_802_11_associate_response *resp)
159{ 549{
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
index d8c266895dd3..40621b789fc5 100644
--- a/drivers/net/wireless/libertas/assoc.h
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -132,4 +132,24 @@ int lbs_adhoc_stop(struct lbs_private *priv);
132int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, 132int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
133 u8 bssid[ETH_ALEN], u16 reason); 133 u8 bssid[ETH_ALEN], u16 reason);
134 134
135int lbs_cmd_802_11_rssi(struct lbs_private *priv,
136 struct cmd_ds_command *cmd);
137int lbs_ret_802_11_rssi(struct lbs_private *priv,
138 struct cmd_ds_command *resp);
139
140int lbs_cmd_bcn_ctrl(struct lbs_private *priv,
141 struct cmd_ds_command *cmd,
142 u16 cmd_action);
143int lbs_ret_802_11_bcn_ctrl(struct lbs_private *priv,
144 struct cmd_ds_command *resp);
145
146int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
147 struct assoc_request *assoc);
148
149int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
150 uint16_t *enable);
151
152int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
153 struct assoc_request *assoc);
154
135#endif /* _LBS_ASSOC_H */ 155#endif /* _LBS_ASSOC_H */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 076cf7e625fb..d1cfcd25a506 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -364,197 +364,6 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
364 return ret; 364 return ret;
365} 365}
366 366
367int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
368 struct assoc_request *assoc)
369{
370 struct cmd_ds_802_11_set_wep cmd;
371 int ret = 0;
372
373 lbs_deb_enter(LBS_DEB_CMD);
374
375 memset(&cmd, 0, sizeof(cmd));
376 cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP);
377 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
378
379 cmd.action = cpu_to_le16(cmd_action);
380
381 if (cmd_action == CMD_ACT_ADD) {
382 int i;
383
384 /* default tx key index */
385 cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx &
386 CMD_WEP_KEY_INDEX_MASK);
387
388 /* Copy key types and material to host command structure */
389 for (i = 0; i < 4; i++) {
390 struct enc_key *pkey = &assoc->wep_keys[i];
391
392 switch (pkey->len) {
393 case KEY_LEN_WEP_40:
394 cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
395 memmove(cmd.keymaterial[i], pkey->key, pkey->len);
396 lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i);
397 break;
398 case KEY_LEN_WEP_104:
399 cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
400 memmove(cmd.keymaterial[i], pkey->key, pkey->len);
401 lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i);
402 break;
403 case 0:
404 break;
405 default:
406 lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
407 i, pkey->len);
408 ret = -1;
409 goto done;
410 break;
411 }
412 }
413 } else if (cmd_action == CMD_ACT_REMOVE) {
414 /* ACT_REMOVE clears _all_ WEP keys */
415
416 /* default tx key index */
417 cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx &
418 CMD_WEP_KEY_INDEX_MASK);
419 lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx);
420 }
421
422 ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
423done:
424 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
425 return ret;
426}
427
428int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
429 uint16_t *enable)
430{
431 struct cmd_ds_802_11_enable_rsn cmd;
432 int ret;
433
434 lbs_deb_enter(LBS_DEB_CMD);
435
436 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
437 cmd.action = cpu_to_le16(cmd_action);
438
439 if (cmd_action == CMD_ACT_GET)
440 cmd.enable = 0;
441 else {
442 if (*enable)
443 cmd.enable = cpu_to_le16(CMD_ENABLE_RSN);
444 else
445 cmd.enable = cpu_to_le16(CMD_DISABLE_RSN);
446 lbs_deb_cmd("ENABLE_RSN: %d\n", *enable);
447 }
448
449 ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
450 if (!ret && cmd_action == CMD_ACT_GET)
451 *enable = le16_to_cpu(cmd.enable);
452
453 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
454 return ret;
455}
456
457static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam,
458 struct enc_key *key)
459{
460 lbs_deb_enter(LBS_DEB_CMD);
461
462 if (key->flags & KEY_INFO_WPA_ENABLED)
463 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
464 if (key->flags & KEY_INFO_WPA_UNICAST)
465 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
466 if (key->flags & KEY_INFO_WPA_MCAST)
467 keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
468
469 keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
470 keyparam->keytypeid = cpu_to_le16(key->type);
471 keyparam->keylen = cpu_to_le16(key->len);
472 memcpy(keyparam->key, key->key, key->len);
473
474 /* Length field doesn't include the {type,length} header */
475 keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4);
476 lbs_deb_leave(LBS_DEB_CMD);
477}
478
479int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
480 struct assoc_request *assoc)
481{
482 struct cmd_ds_802_11_key_material cmd;
483 int ret = 0;
484 int index = 0;
485
486 lbs_deb_enter(LBS_DEB_CMD);
487
488 cmd.action = cpu_to_le16(cmd_action);
489 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
490
491 if (cmd_action == CMD_ACT_GET) {
492 cmd.hdr.size = cpu_to_le16(S_DS_GEN + 2);
493 } else {
494 memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet));
495
496 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) {
497 set_one_wpa_key(&cmd.keyParamSet[index],
498 &assoc->wpa_unicast_key);
499 index++;
500 }
501
502 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) {
503 set_one_wpa_key(&cmd.keyParamSet[index],
504 &assoc->wpa_mcast_key);
505 index++;
506 }
507
508 /* The common header and as many keys as we included */
509 cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd),
510 keyParamSet[index]));
511 }
512 ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
513 /* Copy the returned key to driver private data */
514 if (!ret && cmd_action == CMD_ACT_GET) {
515 void *buf_ptr = cmd.keyParamSet;
516 void *resp_end = &(&cmd)[1];
517
518 while (buf_ptr < resp_end) {
519 struct MrvlIEtype_keyParamSet *keyparam = buf_ptr;
520 struct enc_key *key;
521 uint16_t param_set_len = le16_to_cpu(keyparam->length);
522 uint16_t key_len = le16_to_cpu(keyparam->keylen);
523 uint16_t key_flags = le16_to_cpu(keyparam->keyinfo);
524 uint16_t key_type = le16_to_cpu(keyparam->keytypeid);
525 void *end;
526
527 end = (void *)keyparam + sizeof(keyparam->type)
528 + sizeof(keyparam->length) + param_set_len;
529
530 /* Make sure we don't access past the end of the IEs */
531 if (end > resp_end)
532 break;
533
534 if (key_flags & KEY_INFO_WPA_UNICAST)
535 key = &priv->wpa_unicast_key;
536 else if (key_flags & KEY_INFO_WPA_MCAST)
537 key = &priv->wpa_mcast_key;
538 else
539 break;
540
541 /* Copy returned key into driver */
542 memset(key, 0, sizeof(struct enc_key));
543 if (key_len > sizeof(key->key))
544 break;
545 key->type = key_type;
546 key->flags = key_flags;
547 key->len = key_len;
548 memcpy(key->key, keyparam->key, key->len);
549
550 buf_ptr = end + 1;
551 }
552 }
553
554 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
555 return ret;
556}
557
558/** 367/**
559 * @brief Set an SNMP MIB value 368 * @brief Set an SNMP MIB value
560 * 369 *
@@ -736,111 +545,6 @@ static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd,
736 return 0; 545 return 0;
737} 546}
738 547
739static __le16 lbs_rate_to_fw_bitmap(int rate, int lower_rates_ok)
740{
741/* Bit Rate
742* 15:13 Reserved
743* 12 54 Mbps
744* 11 48 Mbps
745* 10 36 Mbps
746* 9 24 Mbps
747* 8 18 Mbps
748* 7 12 Mbps
749* 6 9 Mbps
750* 5 6 Mbps
751* 4 Reserved
752* 3 11 Mbps
753* 2 5.5 Mbps
754* 1 2 Mbps
755* 0 1 Mbps
756**/
757
758 uint16_t ratemask;
759 int i = lbs_data_rate_to_fw_index(rate);
760 if (lower_rates_ok)
761 ratemask = (0x1fef >> (12 - i));
762 else
763 ratemask = (1 << i);
764 return cpu_to_le16(ratemask);
765}
766
767int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
768 uint16_t cmd_action)
769{
770 struct cmd_ds_802_11_rate_adapt_rateset cmd;
771 int ret;
772
773 lbs_deb_enter(LBS_DEB_CMD);
774
775 if (!priv->cur_rate && !priv->enablehwauto)
776 return -EINVAL;
777
778 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
779
780 cmd.action = cpu_to_le16(cmd_action);
781 cmd.enablehwauto = cpu_to_le16(priv->enablehwauto);
782 cmd.bitmap = lbs_rate_to_fw_bitmap(priv->cur_rate, priv->enablehwauto);
783 ret = lbs_cmd_with_response(priv, CMD_802_11_RATE_ADAPT_RATESET, &cmd);
784 if (!ret && cmd_action == CMD_ACT_GET) {
785 priv->ratebitmap = le16_to_cpu(cmd.bitmap);
786 priv->enablehwauto = le16_to_cpu(cmd.enablehwauto);
787 }
788
789 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
790 return ret;
791}
792EXPORT_SYMBOL_GPL(lbs_cmd_802_11_rate_adapt_rateset);
793
794/**
795 * @brief Set the data rate
796 *
797 * @param priv A pointer to struct lbs_private structure
798 * @param rate The desired data rate, or 0 to clear a locked rate
799 *
800 * @return 0 on success, error on failure
801 */
802int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
803{
804 struct cmd_ds_802_11_data_rate cmd;
805 int ret = 0;
806
807 lbs_deb_enter(LBS_DEB_CMD);
808
809 memset(&cmd, 0, sizeof(cmd));
810 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
811
812 if (rate > 0) {
813 cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE);
814 cmd.rates[0] = lbs_data_rate_to_fw_index(rate);
815 if (cmd.rates[0] == 0) {
816 lbs_deb_cmd("DATA_RATE: invalid requested rate of"
817 " 0x%02X\n", rate);
818 ret = 0;
819 goto out;
820 }
821 lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]);
822 } else {
823 cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO);
824 lbs_deb_cmd("DATA_RATE: setting auto\n");
825 }
826
827 ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
828 if (ret)
829 goto out;
830
831 lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
832
833 /* FIXME: get actual rates FW can do if this command actually returns
834 * all data rates supported.
835 */
836 priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]);
837 lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate);
838
839out:
840 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
841 return ret;
842}
843
844/** 548/**
845 * @brief Get the radio channel 549 * @brief Get the radio channel
846 * 550 *
@@ -923,27 +627,6 @@ out:
923 return ret; 627 return ret;
924} 628}
925 629
926static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
927 struct cmd_ds_command *cmd)
928{
929
930 lbs_deb_enter(LBS_DEB_CMD);
931 cmd->command = cpu_to_le16(CMD_802_11_RSSI);
932 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
933 cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
934
935 /* reset Beacon SNR/NF/RSSI values */
936 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
937 priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
938 priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
939 priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
940 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
941 priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
942
943 lbs_deb_leave(LBS_DEB_CMD);
944 return 0;
945}
946
947static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr, 630static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr,
948 u8 cmd_action, void *pdata_buf) 631 u8 cmd_action, void *pdata_buf)
949{ 632{
@@ -1183,27 +866,6 @@ int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
1183 return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); 866 return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
1184} 867}
1185 868
1186static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
1187 struct cmd_ds_command *cmd,
1188 u16 cmd_action)
1189{
1190 struct cmd_ds_802_11_beacon_control
1191 *bcn_ctrl = &cmd->params.bcn_ctrl;
1192
1193 lbs_deb_enter(LBS_DEB_CMD);
1194 cmd->size =
1195 cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control)
1196 + S_DS_GEN);
1197 cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL);
1198
1199 bcn_ctrl->action = cpu_to_le16(cmd_action);
1200 bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable);
1201 bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period);
1202
1203 lbs_deb_leave(LBS_DEB_CMD);
1204 return 0;
1205}
1206
1207static void lbs_queue_cmd(struct lbs_private *priv, 869static void lbs_queue_cmd(struct lbs_private *priv,
1208 struct cmd_ctrl_node *cmdnode) 870 struct cmd_ctrl_node *cmdnode)
1209{ 871{
@@ -2179,5 +1841,3 @@ done:
2179 return ret; 1841 return ret;
2180} 1842}
2181EXPORT_SYMBOL_GPL(__lbs_cmd); 1843EXPORT_SYMBOL_GPL(__lbs_cmd);
2182
2183
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 9d29b578799a..2862748aef70 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -135,15 +135,6 @@ int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
135int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, 135int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
136 uint16_t cmd_action); 136 uint16_t cmd_action);
137 137
138int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
139 struct assoc_request *assoc);
140
141int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
142 uint16_t *enable);
143
144int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
145 struct assoc_request *assoc);
146
147int lbs_set_tx_power(struct lbs_private *priv, s16 dbm); 138int lbs_set_tx_power(struct lbs_private *priv, s16 dbm);
148 139
149int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep); 140int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep);
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 6e2103885959..0312f2496f74 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -148,53 +148,6 @@ static int lbs_ret_reg_access(struct lbs_private *priv,
148 return ret; 148 return ret;
149} 149}
150 150
151static int lbs_ret_802_11_rssi(struct lbs_private *priv,
152 struct cmd_ds_command *resp)
153{
154 struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
155
156 lbs_deb_enter(LBS_DEB_CMD);
157
158 /* store the non average value */
159 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR);
160 priv->NF[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->noisefloor);
161
162 priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR);
163 priv->NF[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgnoisefloor);
164
165 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
166 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
167 priv->NF[TYPE_BEACON][TYPE_NOAVG]);
168
169 priv->RSSI[TYPE_BEACON][TYPE_AVG] =
170 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
171 priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
172
173 lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
174 priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
175 priv->RSSI[TYPE_BEACON][TYPE_AVG]);
176
177 lbs_deb_leave(LBS_DEB_CMD);
178 return 0;
179}
180
181static int lbs_ret_802_11_bcn_ctrl(struct lbs_private * priv,
182 struct cmd_ds_command *resp)
183{
184 struct cmd_ds_802_11_beacon_control *bcn_ctrl =
185 &resp->params.bcn_ctrl;
186
187 lbs_deb_enter(LBS_DEB_CMD);
188
189 if (bcn_ctrl->action == CMD_ACT_GET) {
190 priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable);
191 priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period);
192 }
193
194 lbs_deb_enter(LBS_DEB_CMD);
195 return 0;
196}
197
198static inline int handle_cmd_response(struct lbs_private *priv, 151static inline int handle_cmd_response(struct lbs_private *priv,
199 struct cmd_header *cmd_response) 152 struct cmd_header *cmd_response)
200{ 153{