aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/llcp/commands.c18
-rw-r--r--net/nfc/llcp/llcp.c14
-rw-r--r--net/nfc/llcp/llcp.h3
-rw-r--r--net/nfc/netlink.c152
-rw-r--r--net/nfc/nfc.h6
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)
467static int nfc_llcp_build_gb(struct nfc_llcp_local *local) 467static 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, &lto_length);
483 lto = 150;
484 lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, &lto, 1, &lto_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
32static struct genl_multicast_group nfc_genl_event_mcgrp = { 34static 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
721static 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
740nla_put_failure:
741
742 genlmsg_cancel(msg, hdr);
743 return -EMSGSIZE;
744}
745
746static 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
779exit:
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
794static 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
853exit:
854 device_unlock(&dev->dev);
855
856 nfc_put_device(dev);
857
858 return rc;
859}
860
719static struct genl_ops nfc_genl_ops[] = { 861static 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);
56int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len); 56int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len);
57u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len); 57u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
58int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb); 58int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb);
59struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
59int __init nfc_llcp_init(void); 60int __init nfc_llcp_init(void);
60void nfc_llcp_exit(void); 61void 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
101static inline struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev)
102{
103 return NULL;
104}
105
100static inline int nfc_llcp_init(void) 106static inline int nfc_llcp_init(void)
101{ 107{
102 return 0; 108 return 0;