diff options
-rw-r--r-- | drivers/nfc/pn533.c | 27 | ||||
-rw-r--r-- | include/linux/nfc.h | 7 | ||||
-rw-r--r-- | include/net/nfc/nfc.h | 4 | ||||
-rw-r--r-- | net/nfc/core.c | 35 | ||||
-rw-r--r-- | net/nfc/netlink.c | 62 | ||||
-rw-r--r-- | net/nfc/nfc.h | 3 |
6 files changed, 136 insertions, 2 deletions
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 605a08a62e45..c6b9bc5ac6e6 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
@@ -260,6 +260,10 @@ struct pn533_cmd_jump_dep_response { | |||
260 | #define PN533_INIT_TARGET_PASSIVE 0x1 | 260 | #define PN533_INIT_TARGET_PASSIVE 0x1 |
261 | #define PN533_INIT_TARGET_DEP 0x2 | 261 | #define PN533_INIT_TARGET_DEP 0x2 |
262 | 262 | ||
263 | #define PN533_INIT_TARGET_RESP_FRAME_MASK 0x3 | ||
264 | #define PN533_INIT_TARGET_RESP_ACTIVE 0x1 | ||
265 | #define PN533_INIT_TARGET_RESP_DEP 0x4 | ||
266 | |||
263 | struct pn533_cmd_init_target { | 267 | struct pn533_cmd_init_target { |
264 | u8 mode; | 268 | u8 mode; |
265 | u8 mifare[6]; | 269 | u8 mifare[6]; |
@@ -1128,10 +1132,13 @@ static int pn533_init_target_frame(struct pn533_frame *frame, | |||
1128 | return 0; | 1132 | return 0; |
1129 | } | 1133 | } |
1130 | 1134 | ||
1135 | #define ATR_REQ_GB_OFFSET 17 | ||
1131 | static int pn533_init_target_complete(struct pn533 *dev, void *arg, | 1136 | static int pn533_init_target_complete(struct pn533 *dev, void *arg, |
1132 | u8 *params, int params_len) | 1137 | u8 *params, int params_len) |
1133 | { | 1138 | { |
1134 | struct pn533_cmd_init_target_response *resp; | 1139 | struct pn533_cmd_init_target_response *resp; |
1140 | u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb; | ||
1141 | size_t gb_len; | ||
1135 | 1142 | ||
1136 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); | 1143 | nfc_dev_dbg(&dev->interface->dev, "%s", __func__); |
1137 | 1144 | ||
@@ -1143,11 +1150,27 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg, | |||
1143 | return params_len; | 1150 | return params_len; |
1144 | } | 1151 | } |
1145 | 1152 | ||
1153 | if (params_len < ATR_REQ_GB_OFFSET + 1) | ||
1154 | return -EINVAL; | ||
1155 | |||
1146 | resp = (struct pn533_cmd_init_target_response *) params; | 1156 | resp = (struct pn533_cmd_init_target_response *) params; |
1147 | 1157 | ||
1148 | nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x\n", resp->mode); | 1158 | nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x param len %d\n", |
1159 | resp->mode, params_len); | ||
1149 | 1160 | ||
1150 | return 0; | 1161 | frame = resp->mode & PN533_INIT_TARGET_RESP_FRAME_MASK; |
1162 | if (frame == PN533_INIT_TARGET_RESP_ACTIVE) | ||
1163 | comm_mode = NFC_COMM_ACTIVE; | ||
1164 | |||
1165 | /* Again, only DEP */ | ||
1166 | if ((resp->mode & PN533_INIT_TARGET_RESP_DEP) == 0) | ||
1167 | return -EOPNOTSUPP; | ||
1168 | |||
1169 | gb = resp->cmd + ATR_REQ_GB_OFFSET; | ||
1170 | gb_len = params_len - (ATR_REQ_GB_OFFSET + 1); | ||
1171 | |||
1172 | return nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK, | ||
1173 | comm_mode, gb, gb_len); | ||
1151 | } | 1174 | } |
1152 | 1175 | ||
1153 | static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) | 1176 | static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols) |
diff --git a/include/linux/nfc.h b/include/linux/nfc.h index 548715881fb0..d124e9273fcb 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h | |||
@@ -56,6 +56,10 @@ | |||
56 | * %NFC_ATTR_PROTOCOLS) | 56 | * %NFC_ATTR_PROTOCOLS) |
57 | * @NFC_EVENT_DEVICE_REMOVED: event emitted when a device is removed | 57 | * @NFC_EVENT_DEVICE_REMOVED: event emitted when a device is removed |
58 | * (it sends %NFC_ATTR_DEVICE_INDEX) | 58 | * (it sends %NFC_ATTR_DEVICE_INDEX) |
59 | * @NFC_EVENT_TM_ACTIVATED: event emitted when the adapter is activated in | ||
60 | * target mode. | ||
61 | * @NFC_EVENT_DEVICE_DEACTIVATED: event emitted when the adapter is deactivated | ||
62 | * from target mode. | ||
59 | */ | 63 | */ |
60 | enum nfc_commands { | 64 | enum nfc_commands { |
61 | NFC_CMD_UNSPEC, | 65 | NFC_CMD_UNSPEC, |
@@ -71,6 +75,8 @@ enum nfc_commands { | |||
71 | NFC_EVENT_DEVICE_ADDED, | 75 | NFC_EVENT_DEVICE_ADDED, |
72 | NFC_EVENT_DEVICE_REMOVED, | 76 | NFC_EVENT_DEVICE_REMOVED, |
73 | NFC_EVENT_TARGET_LOST, | 77 | NFC_EVENT_TARGET_LOST, |
78 | NFC_EVENT_TM_ACTIVATED, | ||
79 | NFC_EVENT_TM_DEACTIVATED, | ||
74 | /* private: internal use only */ | 80 | /* private: internal use only */ |
75 | __NFC_CMD_AFTER_LAST | 81 | __NFC_CMD_AFTER_LAST |
76 | }; | 82 | }; |
@@ -122,6 +128,7 @@ enum nfc_attrs { | |||
122 | #define NFC_NFCID1_MAXSIZE 10 | 128 | #define NFC_NFCID1_MAXSIZE 10 |
123 | #define NFC_SENSB_RES_MAXSIZE 12 | 129 | #define NFC_SENSB_RES_MAXSIZE 12 |
124 | #define NFC_SENSF_RES_MAXSIZE 18 | 130 | #define NFC_SENSF_RES_MAXSIZE 18 |
131 | #define NFC_GB_MAXSIZE 48 | ||
125 | 132 | ||
126 | /* NFC protocols */ | 133 | /* NFC protocols */ |
127 | #define NFC_PROTO_JEWEL 1 | 134 | #define NFC_PROTO_JEWEL 1 |
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 97aa0e81aa83..41573b4bd78a 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h | |||
@@ -198,4 +198,8 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx); | |||
198 | int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, | 198 | int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, |
199 | u8 comm_mode, u8 rf_mode); | 199 | u8 comm_mode, u8 rf_mode); |
200 | 200 | ||
201 | int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, | ||
202 | u8 *gb, size_t gb_len); | ||
203 | int nfc_tm_deactivated(struct nfc_dev *dev); | ||
204 | |||
201 | #endif /* __NET_NFC_H */ | 205 | #endif /* __NET_NFC_H */ |
diff --git a/net/nfc/core.c b/net/nfc/core.c index c83717bfcb8a..17f147430b7c 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -455,6 +455,41 @@ u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len) | |||
455 | } | 455 | } |
456 | EXPORT_SYMBOL(nfc_get_local_general_bytes); | 456 | EXPORT_SYMBOL(nfc_get_local_general_bytes); |
457 | 457 | ||
458 | int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode, | ||
459 | u8 *gb, size_t gb_len) | ||
460 | { | ||
461 | int rc; | ||
462 | |||
463 | device_lock(&dev->dev); | ||
464 | |||
465 | dev->polling = false; | ||
466 | |||
467 | if (gb != NULL) { | ||
468 | rc = nfc_set_remote_general_bytes(dev, gb, gb_len); | ||
469 | if (rc < 0) | ||
470 | goto out; | ||
471 | } | ||
472 | |||
473 | if (protocol == NFC_PROTO_NFC_DEP_MASK) | ||
474 | nfc_dep_link_is_up(dev, 0, comm_mode, NFC_RF_TARGET); | ||
475 | |||
476 | rc = nfc_genl_tm_activated(dev, protocol); | ||
477 | |||
478 | out: | ||
479 | device_unlock(&dev->dev); | ||
480 | |||
481 | return rc; | ||
482 | } | ||
483 | EXPORT_SYMBOL(nfc_tm_activated); | ||
484 | |||
485 | int nfc_tm_deactivated(struct nfc_dev *dev) | ||
486 | { | ||
487 | dev->dep_link_up = false; | ||
488 | |||
489 | return nfc_genl_tm_deactivated(dev); | ||
490 | } | ||
491 | EXPORT_SYMBOL(nfc_tm_deactivated); | ||
492 | |||
458 | /** | 493 | /** |
459 | * nfc_alloc_send_skb - allocate a skb for data exchange responses | 494 | * nfc_alloc_send_skb - allocate a skb for data exchange responses |
460 | * | 495 | * |
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index a18fd56798fc..21eaa9b5c6bf 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
@@ -221,6 +221,68 @@ free_msg: | |||
221 | return -EMSGSIZE; | 221 | return -EMSGSIZE; |
222 | } | 222 | } |
223 | 223 | ||
224 | int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol) | ||
225 | { | ||
226 | struct sk_buff *msg; | ||
227 | void *hdr; | ||
228 | |||
229 | msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
230 | if (!msg) | ||
231 | return -ENOMEM; | ||
232 | |||
233 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, | ||
234 | NFC_EVENT_TM_ACTIVATED); | ||
235 | if (!hdr) | ||
236 | goto free_msg; | ||
237 | |||
238 | if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) | ||
239 | goto nla_put_failure; | ||
240 | if (nla_put_u32(msg, NFC_ATTR_TM_PROTOCOLS, protocol)) | ||
241 | goto nla_put_failure; | ||
242 | |||
243 | genlmsg_end(msg, hdr); | ||
244 | |||
245 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | ||
246 | |||
247 | return 0; | ||
248 | |||
249 | nla_put_failure: | ||
250 | genlmsg_cancel(msg, hdr); | ||
251 | free_msg: | ||
252 | nlmsg_free(msg); | ||
253 | return -EMSGSIZE; | ||
254 | } | ||
255 | |||
256 | int nfc_genl_tm_deactivated(struct nfc_dev *dev) | ||
257 | { | ||
258 | struct sk_buff *msg; | ||
259 | void *hdr; | ||
260 | |||
261 | msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); | ||
262 | if (!msg) | ||
263 | return -ENOMEM; | ||
264 | |||
265 | hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0, | ||
266 | NFC_EVENT_TM_DEACTIVATED); | ||
267 | if (!hdr) | ||
268 | goto free_msg; | ||
269 | |||
270 | if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx)) | ||
271 | goto nla_put_failure; | ||
272 | |||
273 | genlmsg_end(msg, hdr); | ||
274 | |||
275 | genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL); | ||
276 | |||
277 | return 0; | ||
278 | |||
279 | nla_put_failure: | ||
280 | genlmsg_cancel(msg, hdr); | ||
281 | free_msg: | ||
282 | nlmsg_free(msg); | ||
283 | return -EMSGSIZE; | ||
284 | } | ||
285 | |||
224 | int nfc_genl_device_added(struct nfc_dev *dev) | 286 | int nfc_genl_device_added(struct nfc_dev *dev) |
225 | { | 287 | { |
226 | struct sk_buff *msg; | 288 | struct sk_buff *msg; |
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h index 7d9708f2a66c..cd9fcbe57464 100644 --- a/net/nfc/nfc.h +++ b/net/nfc/nfc.h | |||
@@ -128,6 +128,9 @@ int nfc_genl_dep_link_up_event(struct nfc_dev *dev, u32 target_idx, | |||
128 | u8 comm_mode, u8 rf_mode); | 128 | u8 comm_mode, u8 rf_mode); |
129 | int nfc_genl_dep_link_down_event(struct nfc_dev *dev); | 129 | int nfc_genl_dep_link_down_event(struct nfc_dev *dev); |
130 | 130 | ||
131 | int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol); | ||
132 | int nfc_genl_tm_deactivated(struct nfc_dev *dev); | ||
133 | |||
131 | struct nfc_dev *nfc_get_device(unsigned int idx); | 134 | struct nfc_dev *nfc_get_device(unsigned int idx); |
132 | 135 | ||
133 | static inline void nfc_put_device(struct nfc_dev *dev) | 136 | static inline void nfc_put_device(struct nfc_dev *dev) |