aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/cmd.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2008-03-03 06:15:39 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-06 17:09:48 -0500
commit9e1228d00a8e959dd3f4d0bd7949fda1ce11b314 (patch)
tree686cd8d7a7d759ed81767098064fbf6e1e6565cf /drivers/net/wireless/libertas/cmd.c
parent17744ff6ae7eafe33dac9772f2ef9ab5fb738db8 (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.c127
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
341static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, 341static 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
367static int lbs_cmd_802_11_key_material(struct lbs_private *priv, 363int 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
409done:
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: