Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFC Digital: Add initiator NFC-DEP support

This adds support for NFC-DEP protocol in initiator mode for NFC-A and
NFC-F technologies.

When a target is detected, the process flow is as follow:

For NFC-A technology:
1 - The digital stack receives a SEL_RES as the reply of the SEL_REQ
command.
2 - If b7 of SEL_RES is set, the peer device is configure for NFC-DEP
protocol. NFC core is notified through nfc_targets_found().
Execution continues at step 4.
3 - Otherwise, it's a tag and the NFC core is notified. Detection
ends.
4 - The digital stacks sends an ATR_REQ command containing a randomly
generated NFCID3 and the general bytes obtained from the LLCP layer
of NFC core.

For NFC-F technology:
1 - The digital stack receives a SENSF_RES as the reply of the
SENSF_REQ command.
2 - If B1 and B2 of NFCID2 are 0x01 and 0xFE respectively, the peer
device is configured for NFC-DEP protocol. NFC core is notified
through nfc_targets_found(). Execution continues at step 4.
3 - Otherwise it's a type 3 tag. NFC core is notified. Detection
ends.
4 - The digital stacks sends an ATR_REQ command containing the NFC-F
NFCID2 as NFCID3 and the general bytes obtained from the LLCP layer
of NFC core.

For both technologies:
5 - The digital stacks receives the ATR_RES response containing the
NFCID3 and the general bytes of the peer device.
6 - The digital stack notifies NFC core that the DEP link is up through
nfc_dep_link_up().
7 - The NFC core performs data exchange through tm_transceive().
8 - The digital stack sends a DEP_REQ command containing an I PDU with
the data from NFC core.
9 - The digital stack receives a DEP_RES command
10 - If the DEP_RES response contains a supervisor PDU with timeout
extension request (RTOX) the digital stack sends a DEP_REQ
command containing a supervisor PDU acknowledging the RTOX
request. The execution continues at step 9.
11 - If the DEP_RES response contains an I PDU, the response data is
passed back to NFC core through the response callback. The
execution continues at step 8.

Signed-off-by: Thierry Escande <thierry.escande@linux.intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Thierry Escande and committed by
Samuel Ortiz
7d0911c0 8c0695e4

+435 -6
+1 -1
net/nfc/Makefile
··· 10 10 nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \ 11 11 llcp_sock.o 12 12 13 - nfc_digital-objs := digital_core.o digital_technology.o 13 + nfc_digital-objs := digital_core.o digital_technology.o digital_dep.o
+14
net/nfc/digital.h
··· 35 35 #define DIGITAL_MAX_HEADER_LEN 7 36 36 #define DIGITAL_CRC_LEN 2 37 37 38 + #define DIGITAL_SENSF_NFCID2_NFC_DEP_B1 0x01 39 + #define DIGITAL_SENSF_NFCID2_NFC_DEP_B2 0xFE 40 + 41 + #define DIGITAL_SENS_RES_NFC_DEP 0x0100 42 + #define DIGITAL_SEL_RES_NFC_DEP 0x40 43 + #define DIGITAL_SENSF_FELICA_SC 0xFFFF 44 + 38 45 #define DIGITAL_DRV_CAPS_IN_CRC(ddev) \ 39 46 ((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_IN_CRC) 40 47 #define DIGITAL_DRV_CAPS_TG_CRC(ddev) \ ··· 78 71 struct nfc_target *target, u8 protocol); 79 72 80 73 int digital_in_recv_mifare_res(struct sk_buff *resp); 74 + 75 + int digital_in_send_atr_req(struct nfc_digital_dev *ddev, 76 + struct nfc_target *target, __u8 comm_mode, __u8 *gb, 77 + size_t gb_len); 78 + int digital_in_send_dep_req(struct nfc_digital_dev *ddev, 79 + struct nfc_target *target, struct sk_buff *skb, 80 + struct digital_data_exch *data_exch); 81 81 82 82 typedef u16 (*crc_func_t)(u16, const u8 *, size_t); 83 83
+28 -4
net/nfc/digital_core.c
··· 18 18 #include "digital.h" 19 19 20 20 #define DIGITAL_PROTO_NFCA_RF_TECH \ 21 - (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK) 21 + (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_NFC_DEP_MASK) 22 22 23 - #define DIGITAL_PROTO_NFCF_RF_TECH (NFC_PROTO_FELICA_MASK) 23 + #define DIGITAL_PROTO_NFCF_RF_TECH \ 24 + (NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK) 24 25 25 26 struct digital_cmd { 26 27 struct list_head queue; ··· 261 260 add_crc = digital_skb_add_crc_f; 262 261 break; 263 262 263 + case NFC_PROTO_NFC_DEP: 264 + if (rf_tech == NFC_DIGITAL_RF_TECH_106A) { 265 + framing = NFC_DIGITAL_FRAMING_NFCA_NFC_DEP; 266 + check_crc = digital_skb_check_crc_a; 267 + add_crc = digital_skb_add_crc_a; 268 + } else { 269 + framing = NFC_DIGITAL_FRAMING_NFCF_NFC_DEP; 270 + check_crc = digital_skb_check_crc_f; 271 + add_crc = digital_skb_add_crc_f; 272 + } 273 + break; 274 + 264 275 default: 265 276 PR_ERR("Invalid protocol %d", protocol); 266 277 return -EINVAL; ··· 466 453 struct nfc_target *target, 467 454 __u8 comm_mode, __u8 *gb, size_t gb_len) 468 455 { 469 - return -EOPNOTSUPP; 456 + struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); 457 + 458 + return digital_in_send_atr_req(ddev, target, comm_mode, gb, gb_len); 470 459 } 471 460 472 461 static int digital_dep_link_down(struct nfc_dev *nfc_dev) 473 462 { 474 - return -EOPNOTSUPP; 463 + struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev); 464 + 465 + ddev->curr_protocol = 0; 466 + 467 + return 0; 475 468 } 476 469 477 470 static int digital_activate_target(struct nfc_dev *nfc_dev, ··· 542 523 data_exch->cb = cb; 543 524 data_exch->cb_context = cb_context; 544 525 526 + if (ddev->curr_protocol == NFC_PROTO_NFC_DEP) 527 + return digital_in_send_dep_req(ddev, target, skb, data_exch); 528 + 545 529 ddev->skb_add_crc(skb); 546 530 547 531 return digital_in_send_cmd(ddev, skb, 500, digital_in_send_complete, ··· 600 578 ddev->protocols |= NFC_PROTO_MIFARE_MASK; 601 579 if (supported_protocols & NFC_PROTO_FELICA_MASK) 602 580 ddev->protocols |= NFC_PROTO_FELICA_MASK; 581 + if (supported_protocols & NFC_PROTO_NFC_DEP_MASK) 582 + ddev->protocols |= NFC_PROTO_NFC_DEP_MASK; 603 583 604 584 ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN; 605 585 ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN;
+381
net/nfc/digital_dep.c
··· 1 + /* 2 + * NFC Digital Protocol stack 3 + * Copyright (c) 2013, Intel Corporation. 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2, as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + */ 15 + 16 + #include "digital.h" 17 + 18 + #define DIGITAL_NFC_DEP_FRAME_DIR_OUT 0xD4 19 + #define DIGITAL_NFC_DEP_FRAME_DIR_IN 0xD5 20 + 21 + #define DIGITAL_NFC_DEP_NFCA_SOD_SB 0xF0 22 + 23 + #define DIGITAL_CMD_ATR_REQ 0x00 24 + #define DIGITAL_CMD_ATR_RES 0x01 25 + #define DIGITAL_CMD_PSL_REQ 0x04 26 + #define DIGITAL_CMD_PSL_RES 0x05 27 + #define DIGITAL_CMD_DEP_REQ 0x06 28 + #define DIGITAL_CMD_DEP_RES 0x07 29 + 30 + #define DIGITAL_ATR_REQ_MIN_SIZE 16 31 + #define DIGITAL_ATR_REQ_MAX_SIZE 64 32 + 33 + #define DIGITAL_NFCID3_LEN ((u8)8) 34 + #define DIGITAL_LR_BITS_PAYLOAD_SIZE_254B 0x30 35 + #define DIGITAL_GB_BIT 0x02 36 + 37 + #define DIGITAL_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0) 38 + 39 + #define DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT 0x10 40 + 41 + #define DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb) \ 42 + ((pfb) & DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT) 43 + #define DIGITAL_NFC_DEP_MI_BIT_SET(pfb) ((pfb) & 0x10) 44 + #define DIGITAL_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08) 45 + #define DIGITAL_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04) 46 + #define DIGITAL_NFC_DEP_PFB_PNI(pfb) ((pfb) & 0x03) 47 + 48 + #define DIGITAL_NFC_DEP_PFB_I_PDU 0x00 49 + #define DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU 0x40 50 + #define DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU 0x80 51 + 52 + struct digital_atr_req { 53 + u8 dir; 54 + u8 cmd; 55 + u8 nfcid3[10]; 56 + u8 did; 57 + u8 bs; 58 + u8 br; 59 + u8 pp; 60 + u8 gb[0]; 61 + } __packed; 62 + 63 + struct digital_atr_res { 64 + u8 dir; 65 + u8 cmd; 66 + u8 nfcid3[10]; 67 + u8 did; 68 + u8 bs; 69 + u8 br; 70 + u8 to; 71 + u8 pp; 72 + u8 gb[0]; 73 + } __packed; 74 + 75 + struct digital_psl_req { 76 + u8 dir; 77 + u8 cmd; 78 + u8 did; 79 + u8 brs; 80 + u8 fsl; 81 + } __packed; 82 + 83 + struct digital_psl_res { 84 + u8 dir; 85 + u8 cmd; 86 + u8 did; 87 + } __packed; 88 + 89 + struct digital_dep_req_res { 90 + u8 dir; 91 + u8 cmd; 92 + u8 pfb; 93 + } __packed; 94 + 95 + static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, 96 + struct sk_buff *resp); 97 + 98 + static void digital_skb_push_dep_sod(struct nfc_digital_dev *ddev, 99 + struct sk_buff *skb) 100 + { 101 + skb_push(skb, sizeof(u8)); 102 + 103 + skb->data[0] = skb->len; 104 + 105 + if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A) 106 + *skb_push(skb, sizeof(u8)) = DIGITAL_NFC_DEP_NFCA_SOD_SB; 107 + } 108 + 109 + static int digital_skb_pull_dep_sod(struct nfc_digital_dev *ddev, 110 + struct sk_buff *skb) 111 + { 112 + u8 size; 113 + 114 + if (skb->len < 2) 115 + return -EIO; 116 + 117 + if (ddev->curr_rf_tech == NFC_DIGITAL_RF_TECH_106A) 118 + skb_pull(skb, sizeof(u8)); 119 + 120 + size = skb->data[0]; 121 + if (size != skb->len) 122 + return -EIO; 123 + 124 + skb_pull(skb, sizeof(u8)); 125 + 126 + return 0; 127 + } 128 + 129 + static void digital_in_recv_atr_res(struct nfc_digital_dev *ddev, void *arg, 130 + struct sk_buff *resp) 131 + { 132 + struct nfc_target *target = arg; 133 + struct digital_atr_res *atr_res; 134 + u8 gb_len; 135 + int rc; 136 + 137 + if (IS_ERR(resp)) { 138 + rc = PTR_ERR(resp); 139 + resp = NULL; 140 + goto exit; 141 + } 142 + 143 + rc = ddev->skb_check_crc(resp); 144 + if (rc) { 145 + PROTOCOL_ERR("14.4.1.6"); 146 + goto exit; 147 + } 148 + 149 + rc = digital_skb_pull_dep_sod(ddev, resp); 150 + if (rc) { 151 + PROTOCOL_ERR("14.4.1.2"); 152 + goto exit; 153 + } 154 + 155 + if (resp->len < sizeof(struct digital_atr_res)) { 156 + rc = -EIO; 157 + goto exit; 158 + } 159 + 160 + gb_len = resp->len - sizeof(struct digital_atr_res); 161 + 162 + atr_res = (struct digital_atr_res *)resp->data; 163 + 164 + rc = nfc_set_remote_general_bytes(ddev->nfc_dev, atr_res->gb, gb_len); 165 + if (rc) 166 + goto exit; 167 + 168 + rc = nfc_dep_link_is_up(ddev->nfc_dev, target->idx, NFC_COMM_ACTIVE, 169 + NFC_RF_INITIATOR); 170 + 171 + ddev->curr_nfc_dep_pni = 0; 172 + 173 + exit: 174 + dev_kfree_skb(resp); 175 + 176 + if (rc) 177 + ddev->curr_protocol = 0; 178 + } 179 + 180 + int digital_in_send_atr_req(struct nfc_digital_dev *ddev, 181 + struct nfc_target *target, __u8 comm_mode, __u8 *gb, 182 + size_t gb_len) 183 + { 184 + struct sk_buff *skb; 185 + struct digital_atr_req *atr_req; 186 + uint size; 187 + 188 + size = DIGITAL_ATR_REQ_MIN_SIZE + gb_len; 189 + 190 + if (size > DIGITAL_ATR_REQ_MAX_SIZE) { 191 + PROTOCOL_ERR("14.6.1.1"); 192 + return -EINVAL; 193 + } 194 + 195 + skb = digital_skb_alloc(ddev, size); 196 + if (!skb) 197 + return -ENOMEM; 198 + 199 + skb_put(skb, sizeof(struct digital_atr_req)); 200 + 201 + atr_req = (struct digital_atr_req *)skb->data; 202 + memset(atr_req, 0, sizeof(struct digital_atr_req)); 203 + 204 + atr_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT; 205 + atr_req->cmd = DIGITAL_CMD_ATR_REQ; 206 + if (target->nfcid2_len) 207 + memcpy(atr_req->nfcid3, target->nfcid2, 208 + max(target->nfcid2_len, DIGITAL_NFCID3_LEN)); 209 + else 210 + get_random_bytes(atr_req->nfcid3, DIGITAL_NFCID3_LEN); 211 + 212 + atr_req->did = 0; 213 + atr_req->bs = 0; 214 + atr_req->br = 0; 215 + 216 + atr_req->pp = DIGITAL_LR_BITS_PAYLOAD_SIZE_254B; 217 + 218 + if (gb_len) { 219 + atr_req->pp |= DIGITAL_GB_BIT; 220 + memcpy(skb_put(skb, gb_len), gb, gb_len); 221 + } 222 + 223 + digital_skb_push_dep_sod(ddev, skb); 224 + 225 + ddev->skb_add_crc(skb); 226 + 227 + digital_in_send_cmd(ddev, skb, 500, digital_in_recv_atr_res, target); 228 + 229 + return 0; 230 + } 231 + 232 + static int digital_in_send_rtox(struct nfc_digital_dev *ddev, 233 + struct digital_data_exch *data_exch, u8 rtox) 234 + { 235 + struct digital_dep_req_res *dep_req; 236 + struct sk_buff *skb; 237 + int rc; 238 + 239 + skb = digital_skb_alloc(ddev, 1); 240 + if (!skb) 241 + return -ENOMEM; 242 + 243 + *skb_put(skb, 1) = rtox; 244 + 245 + skb_push(skb, sizeof(struct digital_dep_req_res)); 246 + 247 + dep_req = (struct digital_dep_req_res *)skb->data; 248 + 249 + dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT; 250 + dep_req->cmd = DIGITAL_CMD_DEP_REQ; 251 + dep_req->pfb = DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU | 252 + DIGITAL_NFC_DEP_PFB_TIMEOUT_BIT; 253 + 254 + digital_skb_push_dep_sod(ddev, skb); 255 + 256 + ddev->skb_add_crc(skb); 257 + 258 + rc = digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, 259 + data_exch); 260 + 261 + return rc; 262 + } 263 + 264 + static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, 265 + struct sk_buff *resp) 266 + { 267 + struct digital_data_exch *data_exch = arg; 268 + struct digital_dep_req_res *dep_res; 269 + u8 pfb; 270 + uint size; 271 + int rc; 272 + 273 + if (IS_ERR(resp)) { 274 + rc = PTR_ERR(resp); 275 + resp = NULL; 276 + goto exit; 277 + } 278 + 279 + rc = ddev->skb_check_crc(resp); 280 + if (rc) { 281 + PROTOCOL_ERR("14.4.1.6"); 282 + goto error; 283 + } 284 + 285 + rc = digital_skb_pull_dep_sod(ddev, resp); 286 + if (rc) { 287 + PROTOCOL_ERR("14.4.1.2"); 288 + goto exit; 289 + } 290 + 291 + dep_res = (struct digital_dep_req_res *)resp->data; 292 + 293 + if (resp->len < sizeof(struct digital_dep_req_res) || 294 + dep_res->dir != DIGITAL_NFC_DEP_FRAME_DIR_IN || 295 + dep_res->cmd != DIGITAL_CMD_DEP_RES) { 296 + rc = -EIO; 297 + goto error; 298 + } 299 + 300 + pfb = dep_res->pfb; 301 + 302 + switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) { 303 + case DIGITAL_NFC_DEP_PFB_I_PDU: 304 + if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { 305 + PROTOCOL_ERR("14.12.3.3"); 306 + rc = -EIO; 307 + goto error; 308 + } 309 + 310 + ddev->curr_nfc_dep_pni = 311 + DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); 312 + rc = 0; 313 + break; 314 + 315 + case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: 316 + PR_ERR("Received a ACK/NACK PDU"); 317 + rc = -EIO; 318 + goto error; 319 + 320 + case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: 321 + if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { 322 + rc = -EINVAL; 323 + goto error; 324 + } 325 + 326 + rc = digital_in_send_rtox(ddev, data_exch, resp->data[3]); 327 + if (rc) 328 + goto error; 329 + 330 + kfree_skb(resp); 331 + return; 332 + } 333 + 334 + if (DIGITAL_NFC_DEP_MI_BIT_SET(pfb)) { 335 + PR_ERR("MI bit set. Chained PDU not supported."); 336 + rc = -EIO; 337 + goto error; 338 + } 339 + 340 + size = sizeof(struct digital_dep_req_res); 341 + 342 + if (DIGITAL_NFC_DEP_DID_BIT_SET(pfb)) 343 + size++; 344 + 345 + if (size > resp->len) { 346 + rc = -EIO; 347 + goto error; 348 + } 349 + 350 + skb_pull(resp, size); 351 + 352 + exit: 353 + data_exch->cb(data_exch->cb_context, resp, rc); 354 + 355 + error: 356 + kfree(data_exch); 357 + 358 + if (rc) 359 + kfree_skb(resp); 360 + } 361 + 362 + int digital_in_send_dep_req(struct nfc_digital_dev *ddev, 363 + struct nfc_target *target, struct sk_buff *skb, 364 + struct digital_data_exch *data_exch) 365 + { 366 + struct digital_dep_req_res *dep_req; 367 + 368 + skb_push(skb, sizeof(struct digital_dep_req_res)); 369 + 370 + dep_req = (struct digital_dep_req_res *)skb->data; 371 + dep_req->dir = DIGITAL_NFC_DEP_FRAME_DIR_OUT; 372 + dep_req->cmd = DIGITAL_CMD_DEP_REQ; 373 + dep_req->pfb = ddev->curr_nfc_dep_pni; 374 + 375 + digital_skb_push_dep_sod(ddev, skb); 376 + 377 + ddev->skb_add_crc(skb); 378 + 379 + return digital_in_send_cmd(ddev, skb, 1500, digital_in_recv_dep_res, 380 + data_exch); 381 + }
+11 -1
net/nfc/digital_technology.c
··· 28 28 29 29 #define DIGITAL_SEL_RES_NFCID1_COMPLETE(sel_res) (!((sel_res) & 0x04)) 30 30 #define DIGITAL_SEL_RES_IS_T2T(sel_res) (!((sel_res) & 0x60)) 31 + #define DIGITAL_SEL_RES_IS_NFC_DEP(sel_res) ((sel_res) & 0x40) 31 32 32 33 #define DIGITAL_SENS_RES_IS_T1T(sens_res) (((sens_res) & 0x000C) == 0x000C) 33 34 #define DIGITAL_SENS_RES_IS_VALID(sens_res) \ ··· 122 121 123 122 if (DIGITAL_SEL_RES_IS_T2T(sel_res)) { 124 123 nfc_proto = NFC_PROTO_MIFARE; 124 + } else if (DIGITAL_SEL_RES_IS_NFC_DEP(sel_res)) { 125 + nfc_proto = NFC_PROTO_NFC_DEP; 125 126 } else { 126 127 rc = -EOPNOTSUPP; 127 128 goto exit; ··· 382 379 struct sk_buff *resp) 383 380 { 384 381 int rc; 382 + u8 proto; 385 383 struct nfc_target target; 386 384 struct digital_sensf_res *sensf_res; 387 385 ··· 417 413 memcpy(target.nfcid2, sensf_res->nfcid2, NFC_NFCID2_MAXSIZE); 418 414 target.nfcid2_len = NFC_NFCID2_MAXSIZE; 419 415 420 - rc = digital_target_found(ddev, &target, NFC_PROTO_FELICA); 416 + if (target.nfcid2[0] == DIGITAL_SENSF_NFCID2_NFC_DEP_B1 && 417 + target.nfcid2[1] == DIGITAL_SENSF_NFCID2_NFC_DEP_B2) 418 + proto = NFC_PROTO_NFC_DEP; 419 + else 420 + proto = NFC_PROTO_FELICA; 421 + 422 + rc = digital_target_found(ddev, &target, proto); 421 423 422 424 exit: 423 425 dev_kfree_skb(resp);