aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/nci/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc/nci/core.c')
-rw-r--r--net/nfc/nci/core.c91
1 files changed, 90 insertions, 1 deletions
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index f81efe13985a..acf9abb7d99b 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -176,6 +176,27 @@ static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)
176 (1 + ((*num) * sizeof(struct disc_map_config))), &cmd); 176 (1 + ((*num) * sizeof(struct disc_map_config))), &cmd);
177} 177}
178 178
179struct nci_set_config_param {
180 __u8 id;
181 size_t len;
182 __u8 *val;
183};
184
185static void nci_set_config_req(struct nci_dev *ndev, unsigned long opt)
186{
187 struct nci_set_config_param *param = (struct nci_set_config_param *)opt;
188 struct nci_core_set_config_cmd cmd;
189
190 BUG_ON(param->len > NCI_MAX_PARAM_LEN);
191
192 cmd.num_params = 1;
193 cmd.param.id = param->id;
194 cmd.param.len = param->len;
195 memcpy(cmd.param.val, param->val, param->len);
196
197 nci_send_cmd(ndev, NCI_OP_CORE_SET_CONFIG_CMD, (3 + param->len), &cmd);
198}
199
179static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt) 200static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
180{ 201{
181 struct nci_rf_disc_cmd cmd; 202 struct nci_rf_disc_cmd cmd;
@@ -388,6 +409,32 @@ static int nci_dev_down(struct nfc_dev *nfc_dev)
388 return nci_close_device(ndev); 409 return nci_close_device(ndev);
389} 410}
390 411
412static int nci_set_local_general_bytes(struct nfc_dev *nfc_dev)
413{
414 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
415 struct nci_set_config_param param;
416 __u8 local_gb[NFC_MAX_GT_LEN];
417 int i, rc = 0;
418
419 param.val = nfc_get_local_general_bytes(nfc_dev, &param.len);
420 if ((param.val == NULL) || (param.len == 0))
421 return rc;
422
423 if (param.len > NCI_MAX_PARAM_LEN)
424 return -EINVAL;
425
426 for (i = 0; i < param.len; i++)
427 local_gb[param.len-1-i] = param.val[i];
428
429 param.id = NCI_PN_ATR_REQ_GEN_BYTES;
430 param.val = local_gb;
431
432 rc = nci_request(ndev, nci_set_config_req, (unsigned long)&param,
433 msecs_to_jiffies(NCI_SET_CONFIG_TIMEOUT));
434
435 return rc;
436}
437
391static int nci_start_poll(struct nfc_dev *nfc_dev, 438static int nci_start_poll(struct nfc_dev *nfc_dev,
392 __u32 im_protocols, __u32 tm_protocols) 439 __u32 im_protocols, __u32 tm_protocols)
393{ 440{
@@ -415,6 +462,14 @@ static int nci_start_poll(struct nfc_dev *nfc_dev,
415 return -EBUSY; 462 return -EBUSY;
416 } 463 }
417 464
465 if (im_protocols & NFC_PROTO_NFC_DEP_MASK) {
466 rc = nci_set_local_general_bytes(nfc_dev);
467 if (rc) {
468 pr_err("failed to set local general bytes\n");
469 return rc;
470 }
471 }
472
418 rc = nci_request(ndev, nci_rf_discover_req, im_protocols, 473 rc = nci_request(ndev, nci_rf_discover_req, im_protocols,
419 msecs_to_jiffies(NCI_RF_DISC_TIMEOUT)); 474 msecs_to_jiffies(NCI_RF_DISC_TIMEOUT));
420 475
@@ -509,7 +564,7 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev,
509{ 564{
510 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); 565 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
511 566
512 pr_debug("target_idx %d\n", target->idx); 567 pr_debug("entry\n");
513 568
514 if (!ndev->target_active_prot) { 569 if (!ndev->target_active_prot) {
515 pr_err("unable to deactivate target, no active target\n"); 570 pr_err("unable to deactivate target, no active target\n");
@@ -524,6 +579,38 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev,
524 } 579 }
525} 580}
526 581
582
583static int nci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target,
584 __u8 comm_mode, __u8 *gb, size_t gb_len)
585{
586 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
587 int rc;
588
589 pr_debug("target_idx %d, comm_mode %d\n", target->idx, comm_mode);
590
591 rc = nci_activate_target(nfc_dev, target, NFC_PROTO_NFC_DEP);
592 if (rc)
593 return rc;
594
595 rc = nfc_set_remote_general_bytes(nfc_dev, ndev->remote_gb,
596 ndev->remote_gb_len);
597 if (!rc)
598 rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_PASSIVE,
599 NFC_RF_INITIATOR);
600
601 return rc;
602}
603
604static int nci_dep_link_down(struct nfc_dev *nfc_dev)
605{
606 pr_debug("entry\n");
607
608 nci_deactivate_target(nfc_dev, NULL);
609
610 return 0;
611}
612
613
527static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, 614static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target,
528 struct sk_buff *skb, 615 struct sk_buff *skb,
529 data_exchange_cb_t cb, void *cb_context) 616 data_exchange_cb_t cb, void *cb_context)
@@ -557,6 +644,8 @@ static struct nfc_ops nci_nfc_ops = {
557 .dev_down = nci_dev_down, 644 .dev_down = nci_dev_down,
558 .start_poll = nci_start_poll, 645 .start_poll = nci_start_poll,
559 .stop_poll = nci_stop_poll, 646 .stop_poll = nci_stop_poll,
647 .dep_link_up = nci_dep_link_up,
648 .dep_link_down = nci_dep_link_down,
560 .activate_target = nci_activate_target, 649 .activate_target = nci_activate_target,
561 .deactivate_target = nci_deactivate_target, 650 .deactivate_target = nci_deactivate_target,
562 .im_transceive = nci_transceive, 651 .im_transceive = nci_transceive,