28 #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
30 #include <linux/module.h>
31 #include <linux/types.h>
34 #include <linux/export.h>
35 #include <linux/sched.h>
36 #include <linux/bitops.h>
69 static int __nci_request(
struct nci_dev *ndev,
71 unsigned long opt,
__u32 timeout)
84 pr_debug(
"wait_for_completion return %ld\n", completion_rc);
86 if (completion_rc > 0) {
101 pr_err(
"wait_for_completion_interruptible_timeout failed %ld\n",
104 rc = ((completion_rc == 0) ? (-
ETIMEDOUT) : (completion_rc));
112 static inline int nci_request(
struct nci_dev *ndev,
115 unsigned long opt,
__u32 timeout)
124 rc = __nci_request(ndev,
req, opt, timeout);
130 static void nci_reset_req(
struct nci_dev *ndev,
unsigned long opt)
138 static void nci_init_req(
struct nci_dev *ndev,
unsigned long opt)
143 static void nci_init_complete_req(
struct nci_dev *ndev,
unsigned long opt)
185 static void nci_set_config_req(
struct nci_dev *ndev,
unsigned long opt)
200 static void nci_rf_discover_req(
struct nci_dev *ndev,
unsigned long opt)
205 cmd.num_disc_configs = 0;
212 cmd.disc_configs[
cmd.num_disc_configs].rf_tech_and_mode =
214 cmd.disc_configs[
cmd.num_disc_configs].frequency = 1;
215 cmd.num_disc_configs++;
220 cmd.disc_configs[
cmd.num_disc_configs].rf_tech_and_mode =
222 cmd.disc_configs[
cmd.num_disc_configs].frequency = 1;
223 cmd.num_disc_configs++;
228 || protocols & NFC_PROTO_NFC_DEP_MASK)) {
229 cmd.disc_configs[
cmd.num_disc_configs].rf_tech_and_mode =
231 cmd.disc_configs[
cmd.num_disc_configs].frequency = 1;
232 cmd.num_disc_configs++;
245 static void nci_rf_discover_select_req(
struct nci_dev *ndev,
unsigned long opt)
272 static void nci_rf_deactivate_req(
struct nci_dev *ndev,
unsigned long opt)
282 static int nci_open_device(
struct nci_dev *ndev)
293 if (ndev->
ops->open(ndev)) {
302 rc = __nci_request(ndev, nci_reset_req, 0,
306 rc = __nci_request(ndev, nci_init_req, 0,
311 rc = __nci_request(ndev, nci_init_complete_req, 0,
327 ndev->
ops->close(ndev);
336 static int nci_close_device(
struct nci_dev *ndev)
338 nci_req_cancel(ndev,
ENODEV);
361 __nci_request(ndev, nci_reset_req, 0,
370 ndev->
ops->close(ndev);
381 static void nci_cmd_timer(
unsigned long arg)
383 struct nci_dev *ndev = (
void *) arg;
390 static void nci_data_timer(
unsigned long arg)
392 struct nci_dev *ndev = (
void *) arg;
400 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
402 return nci_open_device(ndev);
407 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
409 return nci_close_device(ndev);
414 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
420 if ((param.val ==
NULL) || (param.len == 0))
426 for (i = 0; i < param.len; i++)
427 local_gb[param.len-1-i] = param.val[i];
430 param.val = local_gb;
432 rc = nci_request(ndev, nci_set_config_req, (
unsigned long)¶m,
438 static int nci_start_poll(
struct nfc_dev *nfc_dev,
441 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
446 pr_err(
"unable to start poll, since poll is already active\n");
451 pr_err(
"there is an active target\n");
457 pr_debug(
"target active or w4 select, implicitly deactivate\n");
459 rc = nci_request(ndev, nci_rf_deactivate_req, 0,
465 if (im_protocols & NFC_PROTO_NFC_DEP_MASK) {
466 rc = nci_set_local_general_bytes(nfc_dev);
468 pr_err(
"failed to set local general bytes\n");
473 rc = nci_request(ndev, nci_rf_discover_req, im_protocols,
482 static void nci_stop_poll(
struct nfc_dev *nfc_dev)
484 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
488 pr_err(
"unable to stop poll, since poll is not active\n");
492 nci_request(ndev, nci_rf_deactivate_req, 0,
496 static int nci_activate_target(
struct nfc_dev *nfc_dev,
499 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
505 pr_debug(
"target_idx %d, protocol 0x%x\n", target->
idx, protocol);
509 pr_err(
"there is no available target to activate\n");
514 pr_err(
"there is already an active target\n");
526 pr_err(
"unable to find the selected target\n");
531 pr_err(
"target does not support the requested protocol 0x%x\n",
551 rc = nci_request(ndev, nci_rf_discover_select_req,
552 (
unsigned long)¶m,
562 static void nci_deactivate_target(
struct nfc_dev *nfc_dev,
565 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
570 pr_err(
"unable to deactivate target, no active target\n");
577 nci_request(ndev, nci_rf_deactivate_req, 0,
583 static int nci_dep_link_up(
struct nfc_dev *nfc_dev,
struct nfc_target *target,
584 __u8 comm_mode,
__u8 *gb,
size_t gb_len)
586 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
589 pr_debug(
"target_idx %d, comm_mode %d\n", target->
idx, comm_mode);
604 static int nci_dep_link_down(
struct nfc_dev *nfc_dev)
608 nci_deactivate_target(nfc_dev,
NULL);
614 static int nci_transceive(
struct nfc_dev *nfc_dev,
struct nfc_target *target,
618 struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
624 pr_err(
"unable to exchange data, no active target\n");
642 static struct nfc_ops nci_nfc_ops = {
643 .dev_up = nci_dev_up,
644 .dev_down = nci_dev_down,
645 .start_poll = nci_start_poll,
646 .stop_poll = nci_stop_poll,
647 .dep_link_up = nci_dep_link_up,
648 .dep_link_down = nci_dep_link_down,
649 .activate_target = nci_activate_target,
650 .deactivate_target = nci_deactivate_target,
651 .im_transceive = nci_transceive,
663 __u32 supported_protocols,
668 pr_debug(
"supported_protocols 0x%x\n", supported_protocols);
673 if (!supported_protocols)
691 nfc_set_drvdata(ndev->
nfc_dev, ndev);
708 nfc_free_device(ndev->
nfc_dev);
731 snprintf(name,
sizeof(name),
"%s_nci_cmd_wq", dev_name(dev));
739 snprintf(name,
sizeof(name),
"%s_nci_rx_wq", dev_name(dev));
743 goto destroy_cmd_wq_exit;
747 snprintf(name,
sizeof(name),
"%s_nci_tx_wq", dev_name(dev));
751 goto destroy_rx_wq_exit;
754 skb_queue_head_init(&ndev->
cmd_q);
755 skb_queue_head_init(&ndev->
rx_q);
756 skb_queue_head_init(&ndev->
tx_q);
759 (
unsigned long) ndev);
761 (
unsigned long) ndev);
788 nci_close_device(ndev);
823 static int nci_send_frame(
struct sk_buff *skb)
837 return ndev->
ops->send(skb);
846 pr_debug(
"opcode 0x%x, plen %d\n", opcode, plen);
850 pr_err(
"no memory for command\n");
865 skb->
dev = (
void *) ndev;
893 pr_debug(
"NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d\n",
961 pr_debug(
"NCI TX: MT=cmd, PBF=%d, GID=0x%x, OID=0x%x, plen=%d\n",