aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/nci
diff options
context:
space:
mode:
authorJulien Lefrique <lefrique@marvell.com>2014-10-21 10:52:46 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2014-11-28 08:07:51 -0500
commita99903ec4566eeeaaaf611499cae00abbe844938 (patch)
tree67fa8332a70691e99011ca0289e25ec227ce3fb7 /net/nfc/nci
parent90d78c13965859d87622b37a221ebf29522585a8 (diff)
NFC: NCI: Handle Target mode activation
Changes: * Extract the Listen mode activation parameters from RF_INTF_ACTIVATED_NTF. * Store the General Bytes of ATR_REQ. * Signal that Target mode is activated in case of an activation in NFC-DEP. * Update the NCI state accordingly. * Use the various constants defined in nfc.h. * Fix the ATR_REQ and ATR_RES maximum size. As per NCI 1.0 and NCI 1.1, the Activation Parameters for both Poll and Listen mode contain all the bytes of ATR_REQ/ATR_RES starting and including Byte 3 as defined in [DIGITAL]. In [DIGITAL], the maximum size of ATR_REQ/ATR_RES is 64 bytes and they are numbered starting from Byte 1. Signed-off-by: Julien Lefrique <lefrique@marvell.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc/nci')
-rw-r--r--net/nfc/nci/ntf.c133
1 files changed, 109 insertions, 24 deletions
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
index 205b35f666db..46b2a90ac55a 100644
--- a/net/nfc/nci/ntf.c
+++ b/net/nfc/nci/ntf.c
@@ -167,6 +167,18 @@ static __u8 *nci_extract_rf_params_nfcv_passive_poll(struct nci_dev *ndev,
167 return data; 167 return data;
168} 168}
169 169
170static __u8 *nci_extract_rf_params_nfcf_passive_listen(struct nci_dev *ndev,
171 struct rf_tech_specific_params_nfcf_listen *nfcf_listen,
172 __u8 *data)
173{
174 nfcf_listen->local_nfcid2_len = min_t(__u8, *data++,
175 NFC_NFCID2_MAXSIZE);
176 memcpy(nfcf_listen->local_nfcid2, data, nfcf_listen->local_nfcid2_len);
177 data += nfcf_listen->local_nfcid2_len;
178
179 return data;
180}
181
170__u32 nci_get_prop_rf_protocol(struct nci_dev *ndev, __u8 rf_protocol) 182__u32 nci_get_prop_rf_protocol(struct nci_dev *ndev, __u8 rf_protocol)
171{ 183{
172 if (ndev->ops->get_rfprotocol) 184 if (ndev->ops->get_rfprotocol)
@@ -401,17 +413,29 @@ static int nci_extract_activation_params_nfc_dep(struct nci_dev *ndev,
401 struct nci_rf_intf_activated_ntf *ntf, __u8 *data) 413 struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
402{ 414{
403 struct activation_params_poll_nfc_dep *poll; 415 struct activation_params_poll_nfc_dep *poll;
416 struct activation_params_listen_nfc_dep *listen;
404 417
405 switch (ntf->activation_rf_tech_and_mode) { 418 switch (ntf->activation_rf_tech_and_mode) {
406 case NCI_NFC_A_PASSIVE_POLL_MODE: 419 case NCI_NFC_A_PASSIVE_POLL_MODE:
407 case NCI_NFC_F_PASSIVE_POLL_MODE: 420 case NCI_NFC_F_PASSIVE_POLL_MODE:
408 poll = &ntf->activation_params.poll_nfc_dep; 421 poll = &ntf->activation_params.poll_nfc_dep;
409 poll->atr_res_len = min_t(__u8, *data++, 63); 422 poll->atr_res_len = min_t(__u8, *data++,
423 NFC_ATR_RES_MAXSIZE - 2);
410 pr_debug("atr_res_len %d\n", poll->atr_res_len); 424 pr_debug("atr_res_len %d\n", poll->atr_res_len);
411 if (poll->atr_res_len > 0) 425 if (poll->atr_res_len > 0)
412 memcpy(poll->atr_res, data, poll->atr_res_len); 426 memcpy(poll->atr_res, data, poll->atr_res_len);
413 break; 427 break;
414 428
429 case NCI_NFC_A_PASSIVE_LISTEN_MODE:
430 case NCI_NFC_F_PASSIVE_LISTEN_MODE:
431 listen = &ntf->activation_params.listen_nfc_dep;
432 listen->atr_req_len = min_t(__u8, *data++,
433 NFC_ATR_REQ_MAXSIZE - 2);
434 pr_debug("atr_req_len %d\n", listen->atr_req_len);
435 if (listen->atr_req_len > 0)
436 memcpy(listen->atr_req, data, listen->atr_req_len);
437 break;
438
415 default: 439 default:
416 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", 440 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
417 ntf->activation_rf_tech_and_mode); 441 ntf->activation_rf_tech_and_mode);
@@ -444,6 +468,50 @@ static void nci_target_auto_activated(struct nci_dev *ndev,
444 nfc_targets_found(ndev->nfc_dev, ndev->targets, ndev->n_targets); 468 nfc_targets_found(ndev->nfc_dev, ndev->targets, ndev->n_targets);
445} 469}
446 470
471static int nci_store_general_bytes_nfc_dep(struct nci_dev *ndev,
472 struct nci_rf_intf_activated_ntf *ntf)
473{
474 ndev->remote_gb_len = 0;
475
476 if (ntf->activation_params_len <= 0)
477 return NCI_STATUS_OK;
478
479 switch (ntf->activation_rf_tech_and_mode) {
480 case NCI_NFC_A_PASSIVE_POLL_MODE:
481 case NCI_NFC_F_PASSIVE_POLL_MODE:
482 /* ATR_RES general bytes at offset 15 */
483 ndev->remote_gb_len = min_t(__u8,
484 (ntf->activation_params.poll_nfc_dep.atr_res_len
485 - NFC_ATR_RES_GT_OFFSET),
486 NFC_MAX_GT_LEN);
487 memcpy(ndev->remote_gb,
488 (ntf->activation_params.poll_nfc_dep .atr_res
489 + NFC_ATR_RES_GT_OFFSET),
490 ndev->remote_gb_len);
491 break;
492
493 case NCI_NFC_A_PASSIVE_LISTEN_MODE:
494 case NCI_NFC_F_PASSIVE_LISTEN_MODE:
495 /* ATR_REQ general bytes at offset 14 */
496 ndev->remote_gb_len = min_t(__u8,
497 (ntf->activation_params.listen_nfc_dep.atr_req_len
498 - NFC_ATR_REQ_GT_OFFSET),
499 NFC_MAX_GT_LEN);
500 memcpy(ndev->remote_gb,
501 (ntf->activation_params.listen_nfc_dep.atr_req
502 + NFC_ATR_REQ_GT_OFFSET),
503 ndev->remote_gb_len);
504 break;
505
506 default:
507 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
508 ntf->activation_rf_tech_and_mode);
509 return NCI_STATUS_RF_PROTOCOL_ERROR;
510 }
511
512 return NCI_STATUS_OK;
513}
514
447static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, 515static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
448 struct sk_buff *skb) 516 struct sk_buff *skb)
449{ 517{
@@ -493,6 +561,16 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
493 &(ntf.rf_tech_specific_params.nfcv_poll), data); 561 &(ntf.rf_tech_specific_params.nfcv_poll), data);
494 break; 562 break;
495 563
564 case NCI_NFC_A_PASSIVE_LISTEN_MODE:
565 /* no RF technology specific parameters */
566 break;
567
568 case NCI_NFC_F_PASSIVE_LISTEN_MODE:
569 data = nci_extract_rf_params_nfcf_passive_listen(ndev,
570 &(ntf.rf_tech_specific_params.nfcf_listen),
571 data);
572 break;
573
496 default: 574 default:
497 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", 575 pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
498 ntf.activation_rf_tech_and_mode); 576 ntf.activation_rf_tech_and_mode);
@@ -546,32 +624,39 @@ exit:
546 624
547 /* store general bytes to be reported later in dep_link_up */ 625 /* store general bytes to be reported later in dep_link_up */
548 if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) { 626 if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) {
549 ndev->remote_gb_len = 0; 627 err = nci_store_general_bytes_nfc_dep(ndev, &ntf);
550 628 if (err != NCI_STATUS_OK)
551 if (ntf.activation_params_len > 0) { 629 pr_err("unable to store general bytes\n");
552 /* ATR_RES general bytes at offset 15 */
553 ndev->remote_gb_len = min_t(__u8,
554 (ntf.activation_params
555 .poll_nfc_dep.atr_res_len
556 - NFC_ATR_RES_GT_OFFSET),
557 NFC_MAX_GT_LEN);
558 memcpy(ndev->remote_gb,
559 (ntf.activation_params.poll_nfc_dep
560 .atr_res + NFC_ATR_RES_GT_OFFSET),
561 ndev->remote_gb_len);
562 }
563 } 630 }
564 } 631 }
565 632
566 if (atomic_read(&ndev->state) == NCI_DISCOVERY) { 633 if (!(ntf.activation_rf_tech_and_mode & NCI_RF_TECH_MODE_LISTEN_MASK)) {
567 /* A single target was found and activated automatically */ 634 /* Poll mode */
568 atomic_set(&ndev->state, NCI_POLL_ACTIVE); 635 if (atomic_read(&ndev->state) == NCI_DISCOVERY) {
569 if (err == NCI_STATUS_OK) 636 /* A single target was found and activated
570 nci_target_auto_activated(ndev, &ntf); 637 * automatically */
571 } else { /* ndev->state == NCI_W4_HOST_SELECT */ 638 atomic_set(&ndev->state, NCI_POLL_ACTIVE);
572 /* A selected target was activated, so complete the request */ 639 if (err == NCI_STATUS_OK)
573 atomic_set(&ndev->state, NCI_POLL_ACTIVE); 640 nci_target_auto_activated(ndev, &ntf);
574 nci_req_complete(ndev, err); 641 } else { /* ndev->state == NCI_W4_HOST_SELECT */
642 /* A selected target was activated, so complete the
643 * request */
644 atomic_set(&ndev->state, NCI_POLL_ACTIVE);
645 nci_req_complete(ndev, err);
646 }
647 } else {
648 /* Listen mode */
649 atomic_set(&ndev->state, NCI_LISTEN_ACTIVE);
650 if (err == NCI_STATUS_OK &&
651 ntf.rf_protocol == NCI_RF_PROTOCOL_NFC_DEP) {
652 err = nfc_tm_activated(ndev->nfc_dev,
653 NFC_PROTO_NFC_DEP_MASK,
654 NFC_COMM_PASSIVE,
655 ndev->remote_gb,
656 ndev->remote_gb_len);
657 if (err != NCI_STATUS_OK)
658 pr_err("error when signaling tm activation\n");
659 }
575 } 660 }
576} 661}
577 662