diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2013-05-10 10:15:32 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-06-14 07:45:01 -0400 |
commit | c531c9ec2969860c98a8a47f501c4874278388d3 (patch) | |
tree | 34aaa44a59a07980ac9f615381924221f110cf59 /net/nfc | |
parent | ee656e9d0993144f4e4ad261aefeeaab9554cd3f (diff) |
NFC: Add secure element enablement internal API
Called via netlink, this API will enable or disable a specific secure
element. When a secure element is enabled, it will handle card emulation
and more generically ISO-DEP target mode, i.e. all target mode cases
except for p2p target mode.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/core.c | 110 | ||||
-rw-r--r-- | net/nfc/nfc.h | 3 |
2 files changed, 109 insertions, 4 deletions
diff --git a/net/nfc/core.c b/net/nfc/core.c index 5b60b9ddfc8f..dc96a83aa6ab 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -528,6 +528,108 @@ error: | |||
528 | return rc; | 528 | return rc; |
529 | } | 529 | } |
530 | 530 | ||
531 | static struct nfc_se *find_se(struct nfc_dev *dev, u32 se_idx) | ||
532 | { | ||
533 | struct nfc_se *se, *n; | ||
534 | |||
535 | list_for_each_entry_safe(se, n, &dev->secure_elements, list) | ||
536 | if (se->idx == se_idx) | ||
537 | return se; | ||
538 | |||
539 | return NULL; | ||
540 | } | ||
541 | |||
542 | int nfc_enable_se(struct nfc_dev *dev, u32 se_idx) | ||
543 | { | ||
544 | |||
545 | struct nfc_se *se; | ||
546 | int rc; | ||
547 | |||
548 | pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx); | ||
549 | |||
550 | device_lock(&dev->dev); | ||
551 | |||
552 | if (!device_is_registered(&dev->dev)) { | ||
553 | rc = -ENODEV; | ||
554 | goto error; | ||
555 | } | ||
556 | |||
557 | if (!dev->dev_up) { | ||
558 | rc = -ENODEV; | ||
559 | goto error; | ||
560 | } | ||
561 | |||
562 | if (dev->polling) { | ||
563 | rc = -EBUSY; | ||
564 | goto error; | ||
565 | } | ||
566 | |||
567 | if (!dev->ops->enable_se || !dev->ops->disable_se) { | ||
568 | rc = -EOPNOTSUPP; | ||
569 | goto error; | ||
570 | } | ||
571 | |||
572 | se = find_se(dev, se_idx); | ||
573 | if (!se) { | ||
574 | rc = -EINVAL; | ||
575 | goto error; | ||
576 | } | ||
577 | |||
578 | if (se->type == NFC_SE_ENABLED) { | ||
579 | rc = -EALREADY; | ||
580 | goto error; | ||
581 | } | ||
582 | |||
583 | rc = dev->ops->enable_se(dev, se_idx); | ||
584 | |||
585 | error: | ||
586 | device_unlock(&dev->dev); | ||
587 | return rc; | ||
588 | } | ||
589 | |||
590 | int nfc_disable_se(struct nfc_dev *dev, u32 se_idx) | ||
591 | { | ||
592 | |||
593 | struct nfc_se *se; | ||
594 | int rc; | ||
595 | |||
596 | pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx); | ||
597 | |||
598 | device_lock(&dev->dev); | ||
599 | |||
600 | if (!device_is_registered(&dev->dev)) { | ||
601 | rc = -ENODEV; | ||
602 | goto error; | ||
603 | } | ||
604 | |||
605 | if (!dev->dev_up) { | ||
606 | rc = -ENODEV; | ||
607 | goto error; | ||
608 | } | ||
609 | |||
610 | if (!dev->ops->enable_se || !dev->ops->disable_se) { | ||
611 | rc = -EOPNOTSUPP; | ||
612 | goto error; | ||
613 | } | ||
614 | |||
615 | se = find_se(dev, se_idx); | ||
616 | if (!se) { | ||
617 | rc = -EINVAL; | ||
618 | goto error; | ||
619 | } | ||
620 | |||
621 | if (se->type == NFC_SE_DISABLED) { | ||
622 | rc = -EALREADY; | ||
623 | goto error; | ||
624 | } | ||
625 | |||
626 | rc = dev->ops->disable_se(dev, se_idx); | ||
627 | |||
628 | error: | ||
629 | device_unlock(&dev->dev); | ||
630 | return rc; | ||
631 | } | ||
632 | |||
531 | int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) | 633 | int nfc_set_remote_general_bytes(struct nfc_dev *dev, u8 *gb, u8 gb_len) |
532 | { | 634 | { |
533 | pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len); | 635 | pr_debug("dev_name=%s gb_len=%d\n", dev_name(&dev->dev), gb_len); |
@@ -762,14 +864,14 @@ EXPORT_SYMBOL(nfc_driver_failure); | |||
762 | 864 | ||
763 | int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type) | 865 | int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type) |
764 | { | 866 | { |
765 | struct nfc_se *se, *n; | 867 | struct nfc_se *se; |
766 | int rc; | 868 | int rc; |
767 | 869 | ||
768 | pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx); | 870 | pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx); |
769 | 871 | ||
770 | list_for_each_entry_safe(se, n, &dev->secure_elements, list) | 872 | se = find_se(dev, se_idx); |
771 | if (se->idx == se_idx) | 873 | if (se) |
772 | return -EALREADY; | 874 | return -EALREADY; |
773 | 875 | ||
774 | se = kzalloc(sizeof(struct nfc_se), GFP_KERNEL); | 876 | se = kzalloc(sizeof(struct nfc_se), GFP_KERNEL); |
775 | if (!se) | 877 | if (!se) |
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index a6aeee094aa4..ee85a1fc1b24 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h | |||
@@ -147,4 +147,7 @@ int nfc_deactivate_target(struct nfc_dev *dev, u32 target_idx); | |||
147 | int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, | 147 | int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, |
148 | data_exchange_cb_t cb, void *cb_context); | 148 | data_exchange_cb_t cb, void *cb_context); |
149 | 149 | ||
150 | int nfc_enable_se(struct nfc_dev *dev, u32 se_idx); | ||
151 | int nfc_disable_se(struct nfc_dev *dev, u32 se_idx); | ||
152 | |||
150 | #endif /* __LOCAL_NFC_H */ | 153 | #endif /* __LOCAL_NFC_H */ |