diff options
author | David Woodhouse <dwmw2@infradead.org> | 2008-03-03 06:15:39 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-03-06 17:09:48 -0500 |
commit | 9e1228d00a8e959dd3f4d0bd7949fda1ce11b314 (patch) | |
tree | 686cd8d7a7d759ed81767098064fbf6e1e6565cf /drivers/net/wireless/libertas/cmd.c | |
parent | 17744ff6ae7eafe33dac9772f2ef9ab5fb738db8 (diff) |
libertas: convert KEY_MATERIAL to a direct command
The struct enc_key probably wants to die too, but that can come later.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Acked-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/cmd.c')
-rw-r--r-- | drivers/net/wireless/libertas/cmd.c | 127 |
1 files changed, 75 insertions, 52 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 3f9074df91e4..34edc7d11da8 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -338,75 +338,103 @@ int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action, | |||
338 | return ret; | 338 | return ret; |
339 | } | 339 | } |
340 | 340 | ||
341 | static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, | 341 | static void set_one_wpa_key(struct MrvlIEtype_keyParamSet *keyparam, |
342 | struct enc_key * pkey) | 342 | struct enc_key *key) |
343 | { | 343 | { |
344 | lbs_deb_enter(LBS_DEB_CMD); | 344 | lbs_deb_enter(LBS_DEB_CMD); |
345 | 345 | ||
346 | if (pkey->flags & KEY_INFO_WPA_ENABLED) { | 346 | if (key->flags & KEY_INFO_WPA_ENABLED) |
347 | pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); | 347 | keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED); |
348 | } | 348 | if (key->flags & KEY_INFO_WPA_UNICAST) |
349 | if (pkey->flags & KEY_INFO_WPA_UNICAST) { | 349 | keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); |
350 | pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST); | 350 | if (key->flags & KEY_INFO_WPA_MCAST) |
351 | } | 351 | keyparam->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); |
352 | if (pkey->flags & KEY_INFO_WPA_MCAST) { | ||
353 | pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST); | ||
354 | } | ||
355 | 352 | ||
356 | pkeyparamset->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); | 353 | keyparam->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL); |
357 | pkeyparamset->keytypeid = cpu_to_le16(pkey->type); | 354 | keyparam->keytypeid = cpu_to_le16(key->type); |
358 | pkeyparamset->keylen = cpu_to_le16(pkey->len); | 355 | keyparam->keylen = cpu_to_le16(key->len); |
359 | memcpy(pkeyparamset->key, pkey->key, pkey->len); | 356 | memcpy(keyparam->key, key->key, key->len); |
360 | pkeyparamset->length = cpu_to_le16( sizeof(pkeyparamset->keytypeid) | 357 | |
361 | + sizeof(pkeyparamset->keyinfo) | 358 | /* Length field doesn't include the {type,length} header */ |
362 | + sizeof(pkeyparamset->keylen) | 359 | keyparam->length = cpu_to_le16(sizeof(*keyparam) - 4); |
363 | + sizeof(pkeyparamset->key)); | ||
364 | lbs_deb_leave(LBS_DEB_CMD); | 360 | lbs_deb_leave(LBS_DEB_CMD); |
365 | } | 361 | } |
366 | 362 | ||
367 | static int lbs_cmd_802_11_key_material(struct lbs_private *priv, | 363 | int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action, |
368 | struct cmd_ds_command *cmd, | 364 | struct assoc_request *assoc) |
369 | u16 cmd_action, | ||
370 | u32 cmd_oid, void *pdata_buf) | ||
371 | { | 365 | { |
372 | struct cmd_ds_802_11_key_material *pkeymaterial = | 366 | struct cmd_ds_802_11_key_material cmd; |
373 | &cmd->params.keymaterial; | ||
374 | struct assoc_request * assoc_req = pdata_buf; | ||
375 | int ret = 0; | 367 | int ret = 0; |
376 | int index = 0; | 368 | int index = 0; |
377 | 369 | ||
378 | lbs_deb_enter(LBS_DEB_CMD); | 370 | lbs_deb_enter(LBS_DEB_CMD); |
379 | 371 | ||
380 | cmd->command = cpu_to_le16(CMD_802_11_KEY_MATERIAL); | 372 | cmd.action = cpu_to_le16(cmd_action); |
381 | pkeymaterial->action = cpu_to_le16(cmd_action); | 373 | cmd.hdr.size = cpu_to_le16(sizeof(cmd)); |
382 | 374 | ||
383 | if (cmd_action == CMD_ACT_GET) { | 375 | if (cmd_action == CMD_ACT_GET) { |
384 | cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action)); | 376 | cmd.hdr.size = cpu_to_le16(S_DS_GEN + 2); |
385 | ret = 0; | 377 | } else { |
386 | goto done; | 378 | memset(cmd.keyParamSet, 0, sizeof(cmd.keyParamSet)); |
387 | } | ||
388 | 379 | ||
389 | memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet)); | 380 | if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc->flags)) { |
381 | set_one_wpa_key(&cmd.keyParamSet[index], | ||
382 | &assoc->wpa_unicast_key); | ||
383 | index++; | ||
384 | } | ||
390 | 385 | ||
391 | if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { | 386 | if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc->flags)) { |
392 | set_one_wpa_key(&pkeymaterial->keyParamSet[index], | 387 | set_one_wpa_key(&cmd.keyParamSet[index], |
393 | &assoc_req->wpa_unicast_key); | 388 | &assoc->wpa_mcast_key); |
394 | index++; | 389 | index++; |
395 | } | 390 | } |
396 | 391 | ||
397 | if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { | 392 | /* The common header and as many keys as we included */ |
398 | set_one_wpa_key(&pkeymaterial->keyParamSet[index], | 393 | cmd.hdr.size = cpu_to_le16(offsetof(typeof(cmd), |
399 | &assoc_req->wpa_mcast_key); | 394 | keyParamSet[index])); |
400 | index++; | ||
401 | } | 395 | } |
396 | ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd); | ||
397 | /* Copy the returned key to driver private data */ | ||
398 | if (!ret && cmd_action == CMD_ACT_GET) { | ||
399 | void *buf_ptr = cmd.keyParamSet; | ||
400 | void *resp_end = &(&cmd)[1]; | ||
401 | |||
402 | while (buf_ptr < resp_end) { | ||
403 | struct MrvlIEtype_keyParamSet *keyparam = buf_ptr; | ||
404 | struct enc_key *key; | ||
405 | uint16_t param_set_len = le16_to_cpu(keyparam->length); | ||
406 | uint16_t key_len = le16_to_cpu(keyparam->keylen); | ||
407 | uint16_t key_flags = le16_to_cpu(keyparam->keyinfo); | ||
408 | uint16_t key_type = le16_to_cpu(keyparam->keytypeid); | ||
409 | void *end; | ||
410 | |||
411 | end = (void *)keyparam + sizeof(keyparam->type) | ||
412 | + sizeof(keyparam->length) + param_set_len; | ||
413 | |||
414 | /* Make sure we don't access past the end of the IEs */ | ||
415 | if (end > resp_end) | ||
416 | break; | ||
402 | 417 | ||
403 | cmd->size = cpu_to_le16( S_DS_GEN | 418 | if (key_flags & KEY_INFO_WPA_UNICAST) |
404 | + sizeof (pkeymaterial->action) | 419 | key = &priv->wpa_unicast_key; |
405 | + (index * sizeof(struct MrvlIEtype_keyParamSet))); | 420 | else if (key_flags & KEY_INFO_WPA_MCAST) |
421 | key = &priv->wpa_mcast_key; | ||
422 | else | ||
423 | break; | ||
406 | 424 | ||
407 | ret = 0; | 425 | /* Copy returned key into driver */ |
426 | memset(key, 0, sizeof(struct enc_key)); | ||
427 | if (key_len > sizeof(key->key)) | ||
428 | break; | ||
429 | key->type = key_type; | ||
430 | key->flags = key_flags; | ||
431 | key->len = key_len; | ||
432 | memcpy(key->key, keyparam->key, key->len); | ||
433 | |||
434 | buf_ptr = end + 1; | ||
435 | } | ||
436 | } | ||
408 | 437 | ||
409 | done: | ||
410 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); | 438 | lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); |
411 | return ret; | 439 | return ret; |
412 | } | 440 | } |
@@ -1435,11 +1463,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv, | |||
1435 | ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr); | 1463 | ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr); |
1436 | break; | 1464 | break; |
1437 | 1465 | ||
1438 | case CMD_802_11_KEY_MATERIAL: | ||
1439 | ret = lbs_cmd_802_11_key_material(priv, cmdptr, cmd_action, | ||
1440 | cmd_oid, pdata_buf); | ||
1441 | break; | ||
1442 | |||
1443 | case CMD_802_11_PAIRWISE_TSC: | 1466 | case CMD_802_11_PAIRWISE_TSC: |
1444 | break; | 1467 | break; |
1445 | case CMD_802_11_GROUP_TSC: | 1468 | case CMD_802_11_GROUP_TSC: |