aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/debugfs.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-12-18 02:01:37 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:07:51 -0500
commit5844d12ea30bacae9224db6561a16e86ad31c6e5 (patch)
tree2487845a1cc973a9a81511497b48dcef7e0e93d9 /drivers/net/wireless/libertas/debugfs.c
parentf15ebb63b36eca5fa68fabd04ab2f7840bc67205 (diff)
libertas: convert SUBSCRIBE_EVENT to a direct command
Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/debugfs.c')
-rw-r--r--drivers/net/wireless/libertas/debugfs.c282
1 files changed, 131 insertions, 151 deletions
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 44be3929c027..fd67b770dd78 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -347,20 +347,19 @@ static ssize_t lbs_setuserscan(struct file *file,
347 * and returns a pointer to the first data byte of the TLV, or to NULL 347 * and returns a pointer to the first data byte of the TLV, or to NULL
348 * if the TLV hasn't been found. 348 * if the TLV hasn't been found.
349 */ 349 */
350static void *lbs_tlv_find(u16 tlv_type, const u8 *tlv, u16 size) 350static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size)
351{ 351{
352 __le16 le_type = cpu_to_le16(tlv_type);
353 ssize_t pos = 0;
354 struct mrvlietypesheader *tlv_h; 352 struct mrvlietypesheader *tlv_h;
353 uint16_t length;
354 ssize_t pos = 0;
355
355 while (pos < size) { 356 while (pos < size) {
356 u16 length;
357 tlv_h = (struct mrvlietypesheader *) tlv; 357 tlv_h = (struct mrvlietypesheader *) tlv;
358 if (tlv_h->type == le_type) 358 if (!tlv_h->len)
359 return tlv_h;
360 if (tlv_h->len == 0)
361 return NULL; 359 return NULL;
362 length = le16_to_cpu(tlv_h->len) + 360 if (tlv_h->type == cpu_to_le16(tlv_type))
363 sizeof(struct mrvlietypesheader); 361 return tlv_h;
362 length = le16_to_cpu(tlv_h->len) + sizeof(*tlv_h);
364 pos += length; 363 pos += length;
365 tlv += length; 364 tlv += length;
366 } 365 }
@@ -368,100 +367,100 @@ static void *lbs_tlv_find(u16 tlv_type, const u8 *tlv, u16 size)
368} 367}
369 368
370 369
371/* 370static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask,
372 * This just gets the bitmap of currently subscribed events. Used when 371 struct file *file, char __user *userbuf,
373 * adding an additonal event subscription. 372 size_t count, loff_t *ppos)
374 */
375static u16 lbs_get_events_bitmap(struct lbs_private *priv)
376{
377 ssize_t res;
378
379 struct cmd_ds_802_11_subscribe_event *events = kzalloc(
380 sizeof(struct cmd_ds_802_11_subscribe_event),
381 GFP_KERNEL);
382
383 res = lbs_prepare_and_send_command(priv,
384 CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_GET,
385 CMD_OPTION_WAITFORRSP, 0, events);
386
387 if (res) {
388 kfree(events);
389 return 0;
390 }
391 return le16_to_cpu(events->events);
392}
393
394
395static ssize_t lbs_threshold_read(
396 u16 tlv_type, u16 event_mask,
397 struct file *file, char __user *userbuf,
398 size_t count, loff_t *ppos)
399{ 373{
374 struct cmd_ds_802_11_subscribe_event *subscribed;
375 struct mrvlietypes_thresholds *got;
400 struct lbs_private *priv = file->private_data; 376 struct lbs_private *priv = file->private_data;
401 ssize_t res = 0; 377 ssize_t ret = 0;
402 size_t pos = 0; 378 size_t pos = 0;
403 unsigned long addr = get_zeroed_page(GFP_KERNEL); 379 char *buf;
404 char *buf = (char *)addr;
405 u8 value; 380 u8 value;
406 u8 freq; 381 u8 freq;
407 int events = 0; 382 int events = 0;
408 383
409 struct cmd_ds_802_11_subscribe_event *subscribed = kzalloc( 384 buf = (char *)get_zeroed_page(GFP_KERNEL);
410 sizeof(struct cmd_ds_802_11_subscribe_event), 385 if (!buf)
411 GFP_KERNEL); 386 return -ENOMEM;
412 struct mrvlietypes_thresholds *got;
413 387
414 res = lbs_prepare_and_send_command(priv, 388 subscribed = kzalloc(sizeof(*subscribed), GFP_KERNEL);
415 CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_GET, 389 if (!subscribed) {
416 CMD_OPTION_WAITFORRSP, 0, subscribed); 390 ret = -ENOMEM;
417 if (res) { 391 goto out_page;
418 kfree(subscribed);
419 return res;
420 } 392 }
421 393
394 subscribed->hdr.size = cpu_to_le16(sizeof(*subscribed));
395 subscribed->action = cpu_to_le16(CMD_ACT_GET);
396
397 ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, subscribed);
398 if (ret)
399 goto out_cmd;
400
422 got = lbs_tlv_find(tlv_type, subscribed->tlv, sizeof(subscribed->tlv)); 401 got = lbs_tlv_find(tlv_type, subscribed->tlv, sizeof(subscribed->tlv));
423 if (got) { 402 if (got) {
424 value = got->value; 403 value = got->value;
425 freq = got->freq; 404 freq = got->freq;
426 events = le16_to_cpu(subscribed->events); 405 events = le16_to_cpu(subscribed->events);
427 }
428 kfree(subscribed);
429 406
430 if (got)
431 pos += snprintf(buf, len, "%d %d %d\n", value, freq, 407 pos += snprintf(buf, len, "%d %d %d\n", value, freq,
432 !!(events & event_mask)); 408 !!(events & event_mask));
409 }
433 410
434 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 411 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
435 412
436 free_page(addr); 413 out_cmd:
437 return res; 414 kfree(subscribed);
415
416 out_page:
417 free_page((unsigned long)buf);
418 return ret;
438} 419}
439 420
440 421
441static ssize_t lbs_threshold_write( 422static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
442 u16 tlv_type, u16 event_mask, 423 struct file *file,
443 struct file *file, 424 const char __user *userbuf, size_t count,
444 const char __user *userbuf, 425 loff_t *ppos)
445 size_t count, loff_t *ppos)
446{ 426{
447 struct lbs_private *priv = file->private_data;
448 ssize_t res, buf_size;
449 int value, freq, curr_mask, new_mask;
450 unsigned long addr = get_zeroed_page(GFP_KERNEL);
451 char *buf = (char *)addr;
452 struct cmd_ds_802_11_subscribe_event *events; 427 struct cmd_ds_802_11_subscribe_event *events;
428 struct mrvlietypes_thresholds *tlv;
429 struct lbs_private *priv = file->private_data;
430 ssize_t buf_size;
431 int value, freq, new_mask;
432 uint16_t curr_mask;
433 char *buf;
434 int ret;
435
436 buf = (char *)get_zeroed_page(GFP_KERNEL);
437 if (!buf)
438 return -ENOMEM;
453 439
454 buf_size = min(count, len - 1); 440 buf_size = min(count, len - 1);
455 if (copy_from_user(buf, userbuf, buf_size)) { 441 if (copy_from_user(buf, userbuf, buf_size)) {
456 res = -EFAULT; 442 ret = -EFAULT;
457 goto out_unlock; 443 goto out_page;
458 } 444 }
459 res = sscanf(buf, "%d %d %d", &value, &freq, &new_mask); 445 ret = sscanf(buf, "%d %d %d", &value, &freq, &new_mask);
460 if (res != 3) { 446 if (ret != 3) {
461 res = -EFAULT; 447 ret = -EINVAL;
462 goto out_unlock; 448 goto out_page;
463 } 449 }
464 curr_mask = lbs_get_events_bitmap(priv); 450 events = kzalloc(sizeof(*events), GFP_KERNEL);
451 if (!events) {
452 ret = -ENOMEM;
453 goto out_page;
454 }
455
456 events->hdr.size = cpu_to_le16(sizeof(*events));
457 events->action = cpu_to_le16(CMD_ACT_GET);
458
459 ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events);
460 if (ret)
461 goto out_events;
462
463 curr_mask = le16_to_cpu(events->events);
465 464
466 if (new_mask) 465 if (new_mask)
467 new_mask = curr_mask | event_mask; 466 new_mask = curr_mask | event_mask;
@@ -469,147 +468,128 @@ static ssize_t lbs_threshold_write(
469 new_mask = curr_mask & ~event_mask; 468 new_mask = curr_mask & ~event_mask;
470 469
471 /* Now everything is set and we can send stuff down to the firmware */ 470 /* Now everything is set and we can send stuff down to the firmware */
472 events = kzalloc(
473 sizeof(struct cmd_ds_802_11_subscribe_event),
474 GFP_KERNEL);
475 if (events) {
476 struct mrvlietypes_thresholds *tlv =
477 (struct mrvlietypes_thresholds *) events->tlv;
478 events->action = cpu_to_le16(CMD_ACT_SET);
479 events->events = cpu_to_le16(new_mask);
480 tlv->header.type = cpu_to_le16(tlv_type);
481 tlv->header.len = cpu_to_le16(
482 sizeof(struct mrvlietypes_thresholds) -
483 sizeof(struct mrvlietypesheader));
484 tlv->value = value;
485 if (tlv_type != TLV_TYPE_BCNMISS)
486 tlv->freq = freq;
487 lbs_prepare_and_send_command(priv,
488 CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_SET,
489 CMD_OPTION_WAITFORRSP, 0, events);
490 kfree(events);
491 }
492 471
493 res = count; 472 tlv = (void *)events->tlv;
494out_unlock: 473
495 free_page(addr); 474 events->action = cpu_to_le16(CMD_ACT_SET);
496 return res; 475 events->events = cpu_to_le16(new_mask);
476 tlv->header.type = cpu_to_le16(tlv_type);
477 tlv->header.len = cpu_to_le16(sizeof(*tlv) - sizeof(tlv->header));
478 tlv->value = value;
479 if (tlv_type != TLV_TYPE_BCNMISS)
480 tlv->freq = freq;
481
482 /* The command header, the event mask, and the one TLV */
483 events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 2 + sizeof(*tlv));
484
485 ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events);
486
487 if (!ret)
488 ret = count;
489 out_events:
490 kfree(events);
491 out_page:
492 free_page((unsigned long)buf);
493 return ret;
497} 494}
498 495
499 496
500static ssize_t lbs_lowrssi_read( 497static ssize_t lbs_lowrssi_read(struct file *file, char __user *userbuf,
501 struct file *file, char __user *userbuf, 498 size_t count, loff_t *ppos)
502 size_t count, loff_t *ppos)
503{ 499{
504 return lbs_threshold_read(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW, 500 return lbs_threshold_read(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW,
505 file, userbuf, count, ppos); 501 file, userbuf, count, ppos);
506} 502}
507 503
508 504
509static ssize_t lbs_lowrssi_write( 505static ssize_t lbs_lowrssi_write(struct file *file, const char __user *userbuf,
510 struct file *file, const char __user *userbuf, 506 size_t count, loff_t *ppos)
511 size_t count, loff_t *ppos)
512{ 507{
513 return lbs_threshold_write(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW, 508 return lbs_threshold_write(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW,
514 file, userbuf, count, ppos); 509 file, userbuf, count, ppos);
515} 510}
516 511
517 512
518static ssize_t lbs_lowsnr_read( 513static ssize_t lbs_lowsnr_read(struct file *file, char __user *userbuf,
519 struct file *file, char __user *userbuf, 514 size_t count, loff_t *ppos)
520 size_t count, loff_t *ppos)
521{ 515{
522 return lbs_threshold_read(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW, 516 return lbs_threshold_read(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW,
523 file, userbuf, count, ppos); 517 file, userbuf, count, ppos);
524} 518}
525 519
526 520
527static ssize_t lbs_lowsnr_write( 521static ssize_t lbs_lowsnr_write(struct file *file, const char __user *userbuf,
528 struct file *file, const char __user *userbuf, 522 size_t count, loff_t *ppos)
529 size_t count, loff_t *ppos)
530{ 523{
531 return lbs_threshold_write(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW, 524 return lbs_threshold_write(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW,
532 file, userbuf, count, ppos); 525 file, userbuf, count, ppos);
533} 526}
534 527
535 528
536static ssize_t lbs_failcount_read( 529static ssize_t lbs_failcount_read(struct file *file, char __user *userbuf,
537 struct file *file, char __user *userbuf, 530 size_t count, loff_t *ppos)
538 size_t count, loff_t *ppos)
539{ 531{
540 return lbs_threshold_read(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT, 532 return lbs_threshold_read(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT,
541 file, userbuf, count, ppos); 533 file, userbuf, count, ppos);
542} 534}
543 535
544 536
545static ssize_t lbs_failcount_write( 537static ssize_t lbs_failcount_write(struct file *file, const char __user *userbuf,
546 struct file *file, const char __user *userbuf, 538 size_t count, loff_t *ppos)
547 size_t count, loff_t *ppos)
548{ 539{
549 return lbs_threshold_write(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT, 540 return lbs_threshold_write(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT,
550 file, userbuf, count, ppos); 541 file, userbuf, count, ppos);
551} 542}
552 543
553 544
554static ssize_t lbs_highrssi_read( 545static ssize_t lbs_highrssi_read(struct file *file, char __user *userbuf,
555 struct file *file, char __user *userbuf, 546 size_t count, loff_t *ppos)
556 size_t count, loff_t *ppos)
557{ 547{
558 return lbs_threshold_read(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH, 548 return lbs_threshold_read(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH,
559 file, userbuf, count, ppos); 549 file, userbuf, count, ppos);
560} 550}
561 551
562 552
563static ssize_t lbs_highrssi_write( 553static ssize_t lbs_highrssi_write(struct file *file, const char __user *userbuf,
564 struct file *file, const char __user *userbuf, 554 size_t count, loff_t *ppos)
565 size_t count, loff_t *ppos)
566{ 555{
567 return lbs_threshold_write(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH, 556 return lbs_threshold_write(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH,
568 file, userbuf, count, ppos); 557 file, userbuf, count, ppos);
569} 558}
570 559
571 560
572static ssize_t lbs_highsnr_read( 561static ssize_t lbs_highsnr_read(struct file *file, char __user *userbuf,
573 struct file *file, char __user *userbuf, 562 size_t count, loff_t *ppos)
574 size_t count, loff_t *ppos)
575{ 563{
576 return lbs_threshold_read(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH, 564 return lbs_threshold_read(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH,
577 file, userbuf, count, ppos); 565 file, userbuf, count, ppos);
578} 566}
579 567
580 568
581static ssize_t lbs_highsnr_write( 569static ssize_t lbs_highsnr_write(struct file *file, const char __user *userbuf,
582 struct file *file, const char __user *userbuf, 570 size_t count, loff_t *ppos)
583 size_t count, loff_t *ppos)
584{ 571{
585 return lbs_threshold_write(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH, 572 return lbs_threshold_write(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH,
586 file, userbuf, count, ppos); 573 file, userbuf, count, ppos);
587} 574}
588 575
589static ssize_t lbs_bcnmiss_read( 576static ssize_t lbs_bcnmiss_read(struct file *file, char __user *userbuf,
590 struct file *file, char __user *userbuf, 577 size_t count, loff_t *ppos)
591 size_t count, loff_t *ppos)
592{ 578{
593 return lbs_threshold_read(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS, 579 return lbs_threshold_read(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS,
594 file, userbuf, count, ppos); 580 file, userbuf, count, ppos);
595} 581}
596 582
597 583
598static ssize_t lbs_bcnmiss_write( 584static ssize_t lbs_bcnmiss_write(struct file *file, const char __user *userbuf,
599 struct file *file, const char __user *userbuf, 585 size_t count, loff_t *ppos)
600 size_t count, loff_t *ppos)
601{ 586{
602 return lbs_threshold_write(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS, 587 return lbs_threshold_write(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS,
603 file, userbuf, count, ppos); 588 file, userbuf, count, ppos);
604} 589}
605 590
606 591
607 592
608
609
610
611
612
613static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf, 593static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
614 size_t count, loff_t *ppos) 594 size_t count, loff_t *ppos)
615{ 595{