diff options
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/llcp/commands.c | 18 | ||||
-rw-r--r-- | net/nfc/llcp/llcp.c | 14 | ||||
-rw-r--r-- | net/nfc/llcp/llcp.h | 3 | ||||
-rw-r--r-- | net/nfc/netlink.c | 152 | ||||
-rw-r--r-- | net/nfc/nfc.h | 6 |
5 files changed, 174 insertions, 19 deletions
diff --git a/net/nfc/llcp/commands.c b/net/nfc/llcp/commands.c index 79415353cc28..ed2d17312d61 100644 --- a/net/nfc/llcp/commands.c +++ b/net/nfc/llcp/commands.c | |||
@@ -316,8 +316,7 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
316 | struct sk_buff *skb; | 316 | struct sk_buff *skb; |
317 | u8 *service_name_tlv = NULL, service_name_tlv_length; | 317 | u8 *service_name_tlv = NULL, service_name_tlv_length; |
318 | u8 *miux_tlv = NULL, miux_tlv_length; | 318 | u8 *miux_tlv = NULL, miux_tlv_length; |
319 | u8 *rw_tlv = NULL, rw_tlv_length, rw; | 319 | u8 *rw_tlv = NULL, rw_tlv_length; |
320 | __be16 miux; | ||
321 | int err; | 320 | int err; |
322 | u16 size = 0; | 321 | u16 size = 0; |
323 | 322 | ||
@@ -335,13 +334,11 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
335 | size += service_name_tlv_length; | 334 | size += service_name_tlv_length; |
336 | } | 335 | } |
337 | 336 | ||
338 | miux = cpu_to_be16(LLCP_MAX_MIUX); | 337 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, |
339 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | ||
340 | &miux_tlv_length); | 338 | &miux_tlv_length); |
341 | size += miux_tlv_length; | 339 | size += miux_tlv_length; |
342 | 340 | ||
343 | rw = LLCP_MAX_RW; | 341 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length); |
344 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); | ||
345 | size += rw_tlv_length; | 342 | size += rw_tlv_length; |
346 | 343 | ||
347 | pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); | 344 | pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); |
@@ -378,8 +375,7 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) | |||
378 | struct nfc_llcp_local *local; | 375 | struct nfc_llcp_local *local; |
379 | struct sk_buff *skb; | 376 | struct sk_buff *skb; |
380 | u8 *miux_tlv = NULL, miux_tlv_length; | 377 | u8 *miux_tlv = NULL, miux_tlv_length; |
381 | u8 *rw_tlv = NULL, rw_tlv_length, rw; | 378 | u8 *rw_tlv = NULL, rw_tlv_length; |
382 | __be16 miux; | ||
383 | int err; | 379 | int err; |
384 | u16 size = 0; | 380 | u16 size = 0; |
385 | 381 | ||
@@ -389,13 +385,11 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) | |||
389 | if (local == NULL) | 385 | if (local == NULL) |
390 | return -ENODEV; | 386 | return -ENODEV; |
391 | 387 | ||
392 | miux = cpu_to_be16(LLCP_MAX_MIUX); | 388 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, |
393 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | ||
394 | &miux_tlv_length); | 389 | &miux_tlv_length); |
395 | size += miux_tlv_length; | 390 | size += miux_tlv_length; |
396 | 391 | ||
397 | rw = LLCP_MAX_RW; | 392 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length); |
398 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); | ||
399 | size += rw_tlv_length; | 393 | size += rw_tlv_length; |
400 | 394 | ||
401 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); | 395 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); |
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 2e23bd348ebd..f6804532047a 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c | |||
@@ -467,10 +467,9 @@ static u8 nfc_llcp_reserve_sdp_ssap(struct nfc_llcp_local *local) | |||
467 | static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | 467 | static int nfc_llcp_build_gb(struct nfc_llcp_local *local) |
468 | { | 468 | { |
469 | u8 *gb_cur, *version_tlv, version, version_length; | 469 | u8 *gb_cur, *version_tlv, version, version_length; |
470 | u8 *lto_tlv, lto, lto_length; | 470 | u8 *lto_tlv, lto_length; |
471 | u8 *wks_tlv, wks_length; | 471 | u8 *wks_tlv, wks_length; |
472 | u8 *miux_tlv, miux_length; | 472 | u8 *miux_tlv, miux_length; |
473 | __be16 miux; | ||
474 | u8 gb_len = 0; | 473 | u8 gb_len = 0; |
475 | int ret = 0; | 474 | int ret = 0; |
476 | 475 | ||
@@ -479,9 +478,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | |||
479 | 1, &version_length); | 478 | 1, &version_length); |
480 | gb_len += version_length; | 479 | gb_len += version_length; |
481 | 480 | ||
482 | /* 1500 ms */ | 481 | lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, &local->lto, 1, <o_length); |
483 | lto = 150; | ||
484 | lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, <o, 1, <o_length); | ||
485 | gb_len += lto_length; | 482 | gb_len += lto_length; |
486 | 483 | ||
487 | pr_debug("Local wks 0x%lx\n", local->local_wks); | 484 | pr_debug("Local wks 0x%lx\n", local->local_wks); |
@@ -489,8 +486,7 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | |||
489 | &wks_length); | 486 | &wks_length); |
490 | gb_len += wks_length; | 487 | gb_len += wks_length; |
491 | 488 | ||
492 | miux = cpu_to_be16(LLCP_MAX_MIUX); | 489 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, |
493 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | ||
494 | &miux_length); | 490 | &miux_length); |
495 | gb_len += miux_length; | 491 | gb_len += miux_length; |
496 | 492 | ||
@@ -1383,6 +1379,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) | |||
1383 | rwlock_init(&local->connecting_sockets.lock); | 1379 | rwlock_init(&local->connecting_sockets.lock); |
1384 | rwlock_init(&local->raw_sockets.lock); | 1380 | rwlock_init(&local->raw_sockets.lock); |
1385 | 1381 | ||
1382 | local->lto = 150; /* 1500 ms */ | ||
1383 | local->rw = LLCP_MAX_RW; | ||
1384 | local->miux = cpu_to_be16(LLCP_MAX_MIUX); | ||
1385 | |||
1386 | nfc_llcp_build_gb(local); | 1386 | nfc_llcp_build_gb(local); |
1387 | 1387 | ||
1388 | local->remote_miu = LLCP_DEFAULT_MIU; | 1388 | local->remote_miu = LLCP_DEFAULT_MIU; |
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h index 276da3a6a589..0d62366f8cc3 100644 --- a/net/nfc/llcp/llcp.h +++ b/net/nfc/llcp/llcp.h | |||
@@ -64,6 +64,9 @@ struct nfc_llcp_local { | |||
64 | u32 target_idx; | 64 | u32 target_idx; |
65 | u8 rf_mode; | 65 | u8 rf_mode; |
66 | u8 comm_mode; | 66 | u8 comm_mode; |
67 | u8 lto; | ||
68 | u8 rw; | ||
69 | __be16 miux; | ||
67 | unsigned long local_wks; /* Well known services */ | 70 | unsigned long local_wks; /* Well known services */ |
68 | unsigned long local_sdp; /* Local services */ | 71 | unsigned long local_sdp; /* Local services */ |
69 | unsigned long local_sap; /* Local SAPs, not available for discovery */ | 72 | unsigned long local_sap; /* Local SAPs, not available for discovery */ |
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 614cfd0470b7..3568ae16786d 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
@@ -29,6 +29,8 @@ | |||
29 | 29 | ||
30 | #include "nfc.h" | 30 | #include "nfc.h" |
31 | 31 | ||
32 | #include "llcp/llcp.h" | ||
33 | |||
32 | static struct genl_multicast_group nfc_genl_event_mcgrp = { | 34 | static struct genl_multicast_group nfc_genl_event_mcgrp = { |
33 | .name = NFC_GENL_MCAST_EVENT_NAME, | 35 | .name = NFC_GENL_MCAST_EVENT_NAME, |
34 | }; | 36 | }; |
@@ -716,6 +718,146 @@ static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info) | |||
716 | return rc; | 718 | return rc; |
717 | } | 719 | } |
718 | 720 | ||
721 | static int nfc_genl_send_params(struct sk_buff *msg, | ||
722 | struct nfc_llcp_local *local, | ||
723 | u32 portid, u32 seq) | ||
724 | { | ||
725 | void *hdr; | ||
726 | |||
727 | hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, 0, | ||
728 | NFC_CMD_LLC_GET_PARAMS); | ||
729 | if (!hdr) | ||
730 | return -EMSGSIZE; | ||
731 | |||
732 | if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, local->dev->idx) || | ||
733 | nla_put_u8(msg, NFC_ATTR_LLC_PARAM_LTO, local->lto) || | ||
734 | nla_put_u8(msg, NFC_ATTR_LLC_PARAM_RW, local->rw) || | ||
735 | nla_put_u16(msg, NFC_ATTR_LLC_PARAM_MIUX, be16_to_cpu(local->miux))) | ||
736 | goto nla_put_failure; | ||
737 | |||
738 | return genlmsg_end(msg, hdr); | ||
739 | |||
740 | nla_put_failure: | ||
741 | |||
742 | genlmsg_cancel(msg, hdr); | ||
743 | return -EMSGSIZE; | ||
744 | } | ||
745 | |||
746 | static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info) | ||
747 | { | ||
748 | struct nfc_dev *dev; | ||
749 | struct nfc_llcp_local *local; | ||
750 | int rc = 0; | ||
751 | struct sk_buff *msg = NULL; | ||
752 | u32 idx; | ||
753 | |||
754 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX]) | ||
755 | return -EINVAL; | ||
756 | |||
757 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); | ||
758 | |||
759 | dev = nfc_get_device(idx); | ||
760 | if (!dev) | ||
761 | return -ENODEV; | ||
762 | |||
763 | device_lock(&dev->dev); | ||
764 | |||
765 | local = nfc_llcp_find_local(dev); | ||
766 | if (!local) { | ||
767 | rc = -ENODEV; | ||
768 | goto exit; | ||
769 | } | ||
770 | |||
771 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
772 | if (!msg) { | ||
773 | rc = -ENOMEM; | ||
774 | goto exit; | ||
775 | } | ||
776 | |||
777 | rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq); | ||
778 | |||
779 | exit: | ||
780 | device_unlock(&dev->dev); | ||
781 | |||
782 | nfc_put_device(dev); | ||
783 | |||
784 | if (rc < 0) { | ||
785 | if (msg) | ||
786 | nlmsg_free(msg); | ||
787 | |||
788 | return rc; | ||
789 | } | ||
790 | |||
791 | return genlmsg_reply(msg, info); | ||
792 | } | ||
793 | |||
794 | static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info) | ||
795 | { | ||
796 | struct nfc_dev *dev; | ||
797 | struct nfc_llcp_local *local; | ||
798 | u8 rw = 0; | ||
799 | u16 miux = 0; | ||
800 | u32 idx; | ||
801 | int rc = 0; | ||
802 | |||
803 | if (!info->attrs[NFC_ATTR_DEVICE_INDEX] || | ||
804 | (!info->attrs[NFC_ATTR_LLC_PARAM_LTO] && | ||
805 | !info->attrs[NFC_ATTR_LLC_PARAM_RW] && | ||
806 | !info->attrs[NFC_ATTR_LLC_PARAM_MIUX])) | ||
807 | return -EINVAL; | ||
808 | |||
809 | if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) { | ||
810 | rw = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_RW]); | ||
811 | |||
812 | if (rw > LLCP_MAX_RW) | ||
813 | return -EINVAL; | ||
814 | } | ||
815 | |||
816 | if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) { | ||
817 | miux = nla_get_u16(info->attrs[NFC_ATTR_LLC_PARAM_MIUX]); | ||
818 | |||
819 | if (miux > LLCP_MAX_MIUX) | ||
820 | return -EINVAL; | ||
821 | } | ||
822 | |||
823 | idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]); | ||
824 | |||
825 | dev = nfc_get_device(idx); | ||
826 | if (!dev) | ||
827 | return -ENODEV; | ||
828 | |||
829 | device_lock(&dev->dev); | ||
830 | |||
831 | local = nfc_llcp_find_local(dev); | ||
832 | if (!local) { | ||
833 | nfc_put_device(dev); | ||
834 | rc = -ENODEV; | ||
835 | goto exit; | ||
836 | } | ||
837 | |||
838 | if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) { | ||
839 | if (dev->dep_link_up) { | ||
840 | rc = -EINPROGRESS; | ||
841 | goto exit; | ||
842 | } | ||
843 | |||
844 | local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]); | ||
845 | } | ||
846 | |||
847 | if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) | ||
848 | local->rw = rw; | ||
849 | |||
850 | if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) | ||
851 | local->miux = cpu_to_be16(miux); | ||
852 | |||
853 | exit: | ||
854 | device_unlock(&dev->dev); | ||
855 | |||
856 | nfc_put_device(dev); | ||
857 | |||
858 | return rc; | ||
859 | } | ||
860 | |||
719 | static struct genl_ops nfc_genl_ops[] = { | 861 | static struct genl_ops nfc_genl_ops[] = { |
720 | { | 862 | { |
721 | .cmd = NFC_CMD_GET_DEVICE, | 863 | .cmd = NFC_CMD_GET_DEVICE, |
@@ -760,6 +902,16 @@ static struct genl_ops nfc_genl_ops[] = { | |||
760 | .done = nfc_genl_dump_targets_done, | 902 | .done = nfc_genl_dump_targets_done, |
761 | .policy = nfc_genl_policy, | 903 | .policy = nfc_genl_policy, |
762 | }, | 904 | }, |
905 | { | ||
906 | .cmd = NFC_CMD_LLC_GET_PARAMS, | ||
907 | .doit = nfc_genl_llc_get_params, | ||
908 | .policy = nfc_genl_policy, | ||
909 | }, | ||
910 | { | ||
911 | .cmd = NFC_CMD_LLC_SET_PARAMS, | ||
912 | .doit = nfc_genl_llc_set_params, | ||
913 | .policy = nfc_genl_policy, | ||
914 | }, | ||
763 | }; | 915 | }; |
764 | 916 | ||
765 | 917 | ||
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index c5e42b79a418..87d914d2876a 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h | |||
@@ -56,6 +56,7 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev); | |||
56 | int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); | 56 | int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); |
57 | u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); | 57 | u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); |
58 | int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); | 58 | int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); |
59 | struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev); | ||
59 | int __init nfc_llcp_init(void); | 60 | int __init nfc_llcp_init(void); |
60 | void nfc_llcp_exit(void); | 61 | void nfc_llcp_exit(void); |
61 | 62 | ||
@@ -97,6 +98,11 @@ static inline int nfc_llcp_data_received(struct nfc_dev *dev, | |||
97 | return 0; | 98 | return 0; |
98 | } | 99 | } |
99 | 100 | ||
101 | static inline struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev) | ||
102 | { | ||
103 | return NULL; | ||
104 | } | ||
105 | |||
100 | static inline int nfc_llcp_init(void) | 106 | static inline int nfc_llcp_init(void) |
101 | { | 107 | { |
102 | return 0; | 108 | return 0; |