17cbe0ff3SThierry Escande /* 27cbe0ff3SThierry Escande * NFC hardware simulation driver 37cbe0ff3SThierry Escande * Copyright (c) 2013, Intel Corporation. 47cbe0ff3SThierry Escande * 57cbe0ff3SThierry Escande * This program is free software; you can redistribute it and/or modify it 67cbe0ff3SThierry Escande * under the terms and conditions of the GNU General Public License, 77cbe0ff3SThierry Escande * version 2, as published by the Free Software Foundation. 87cbe0ff3SThierry Escande * 97cbe0ff3SThierry Escande * This program is distributed in the hope it will be useful, but WITHOUT 107cbe0ff3SThierry Escande * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 117cbe0ff3SThierry Escande * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 127cbe0ff3SThierry Escande * more details. 137cbe0ff3SThierry Escande * 147cbe0ff3SThierry Escande */ 157cbe0ff3SThierry Escande 167cbe0ff3SThierry Escande #include <linux/device.h> 177cbe0ff3SThierry Escande #include <linux/kernel.h> 187cbe0ff3SThierry Escande #include <linux/module.h> 197cbe0ff3SThierry Escande #include <linux/nfc.h> 207cbe0ff3SThierry Escande #include <net/nfc/nfc.h> 217cbe0ff3SThierry Escande 22073a625fSJoe Perches #define DEV_ERR(_dev, fmt, args...) nfc_err(&_dev->nfc_dev->dev, \ 237cbe0ff3SThierry Escande "%s: " fmt, __func__, ## args) 247cbe0ff3SThierry Escande 25b4834839SJoe Perches #define DEV_DBG(_dev, fmt, args...) dev_dbg(&_dev->nfc_dev->dev, \ 267cbe0ff3SThierry Escande "%s: " fmt, __func__, ## args) 277cbe0ff3SThierry Escande 287cbe0ff3SThierry Escande #define NFCSIM_VERSION "0.1" 297cbe0ff3SThierry Escande 307cbe0ff3SThierry Escande #define NFCSIM_POLL_NONE 0 317cbe0ff3SThierry Escande #define NFCSIM_POLL_INITIATOR 1 327cbe0ff3SThierry Escande #define NFCSIM_POLL_TARGET 2 337cbe0ff3SThierry Escande #define NFCSIM_POLL_DUAL (NFCSIM_POLL_INITIATOR | NFCSIM_POLL_TARGET) 347cbe0ff3SThierry Escande 35*a440f1aaSSaurabh Sengar #define RX_DEFAULT_DELAY 5 36*a440f1aaSSaurabh Sengar 377cbe0ff3SThierry Escande struct nfcsim { 387cbe0ff3SThierry Escande struct nfc_dev *nfc_dev; 397cbe0ff3SThierry Escande 407cbe0ff3SThierry Escande struct mutex lock; 417cbe0ff3SThierry Escande 427cbe0ff3SThierry Escande struct delayed_work recv_work; 437cbe0ff3SThierry Escande 447cbe0ff3SThierry Escande struct sk_buff *clone_skb; 457cbe0ff3SThierry Escande 467cbe0ff3SThierry Escande struct delayed_work poll_work; 477cbe0ff3SThierry Escande u8 polling_mode; 487cbe0ff3SThierry Escande u8 curr_polling_mode; 497cbe0ff3SThierry Escande 507cbe0ff3SThierry Escande u8 shutting_down; 517cbe0ff3SThierry Escande 527cbe0ff3SThierry Escande u8 up; 537cbe0ff3SThierry Escande 547cbe0ff3SThierry Escande u8 initiator; 557cbe0ff3SThierry Escande 56*a440f1aaSSaurabh Sengar u32 rx_delay; 57*a440f1aaSSaurabh Sengar 587cbe0ff3SThierry Escande data_exchange_cb_t cb; 597cbe0ff3SThierry Escande void *cb_context; 607cbe0ff3SThierry Escande 617cbe0ff3SThierry Escande struct nfcsim *peer_dev; 627cbe0ff3SThierry Escande }; 637cbe0ff3SThierry Escande 647cbe0ff3SThierry Escande static struct nfcsim *dev0; 657cbe0ff3SThierry Escande static struct nfcsim *dev1; 667cbe0ff3SThierry Escande 6740dac370SThierry Escande static struct workqueue_struct *wq; 687cbe0ff3SThierry Escande 697cbe0ff3SThierry Escande static void nfcsim_cleanup_dev(struct nfcsim *dev, u8 shutdown) 707cbe0ff3SThierry Escande { 71b4834839SJoe Perches DEV_DBG(dev, "shutdown=%d\n", shutdown); 727cbe0ff3SThierry Escande 737cbe0ff3SThierry Escande mutex_lock(&dev->lock); 747cbe0ff3SThierry Escande 757cbe0ff3SThierry Escande dev->polling_mode = NFCSIM_POLL_NONE; 767cbe0ff3SThierry Escande dev->shutting_down = shutdown; 777cbe0ff3SThierry Escande dev->cb = NULL; 787cbe0ff3SThierry Escande dev_kfree_skb(dev->clone_skb); 797cbe0ff3SThierry Escande dev->clone_skb = NULL; 807cbe0ff3SThierry Escande 817cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 827cbe0ff3SThierry Escande 837cbe0ff3SThierry Escande cancel_delayed_work_sync(&dev->poll_work); 847cbe0ff3SThierry Escande cancel_delayed_work_sync(&dev->recv_work); 857cbe0ff3SThierry Escande } 867cbe0ff3SThierry Escande 877cbe0ff3SThierry Escande static int nfcsim_target_found(struct nfcsim *dev) 887cbe0ff3SThierry Escande { 897cbe0ff3SThierry Escande struct nfc_target nfc_tgt; 907cbe0ff3SThierry Escande 91b4834839SJoe Perches DEV_DBG(dev, "\n"); 927cbe0ff3SThierry Escande 937cbe0ff3SThierry Escande memset(&nfc_tgt, 0, sizeof(struct nfc_target)); 947cbe0ff3SThierry Escande 957cbe0ff3SThierry Escande nfc_tgt.supported_protocols = NFC_PROTO_NFC_DEP_MASK; 967cbe0ff3SThierry Escande nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1); 977cbe0ff3SThierry Escande 987cbe0ff3SThierry Escande return 0; 997cbe0ff3SThierry Escande } 1007cbe0ff3SThierry Escande 1017cbe0ff3SThierry Escande static int nfcsim_dev_up(struct nfc_dev *nfc_dev) 1027cbe0ff3SThierry Escande { 1037cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 1047cbe0ff3SThierry Escande 105b4834839SJoe Perches DEV_DBG(dev, "\n"); 1067cbe0ff3SThierry Escande 1077cbe0ff3SThierry Escande mutex_lock(&dev->lock); 1087cbe0ff3SThierry Escande 1097cbe0ff3SThierry Escande dev->up = 1; 1107cbe0ff3SThierry Escande 1117cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 1127cbe0ff3SThierry Escande 1137cbe0ff3SThierry Escande return 0; 1147cbe0ff3SThierry Escande } 1157cbe0ff3SThierry Escande 1167cbe0ff3SThierry Escande static int nfcsim_dev_down(struct nfc_dev *nfc_dev) 1177cbe0ff3SThierry Escande { 1187cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 1197cbe0ff3SThierry Escande 120b4834839SJoe Perches DEV_DBG(dev, "\n"); 1217cbe0ff3SThierry Escande 1227cbe0ff3SThierry Escande mutex_lock(&dev->lock); 1237cbe0ff3SThierry Escande 1247cbe0ff3SThierry Escande dev->up = 0; 1257cbe0ff3SThierry Escande 1267cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 1277cbe0ff3SThierry Escande 1287cbe0ff3SThierry Escande return 0; 1297cbe0ff3SThierry Escande } 1307cbe0ff3SThierry Escande 1317cbe0ff3SThierry Escande static int nfcsim_dep_link_up(struct nfc_dev *nfc_dev, 1327cbe0ff3SThierry Escande struct nfc_target *target, 1337cbe0ff3SThierry Escande u8 comm_mode, u8 *gb, size_t gb_len) 1347cbe0ff3SThierry Escande { 1357cbe0ff3SThierry Escande int rc; 1367cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 1377cbe0ff3SThierry Escande struct nfcsim *peer = dev->peer_dev; 1387cbe0ff3SThierry Escande u8 *remote_gb; 1397cbe0ff3SThierry Escande size_t remote_gb_len; 1407cbe0ff3SThierry Escande 1417cbe0ff3SThierry Escande DEV_DBG(dev, "target_idx: %d, comm_mode: %d\n", target->idx, comm_mode); 1427cbe0ff3SThierry Escande 1437cbe0ff3SThierry Escande mutex_lock(&peer->lock); 1447cbe0ff3SThierry Escande 1457cbe0ff3SThierry Escande nfc_tm_activated(peer->nfc_dev, NFC_PROTO_NFC_DEP_MASK, 1467cbe0ff3SThierry Escande NFC_COMM_ACTIVE, gb, gb_len); 1477cbe0ff3SThierry Escande 1487cbe0ff3SThierry Escande remote_gb = nfc_get_local_general_bytes(peer->nfc_dev, &remote_gb_len); 1497cbe0ff3SThierry Escande if (!remote_gb) { 150073a625fSJoe Perches DEV_ERR(peer, "Can't get remote general bytes\n"); 1517cbe0ff3SThierry Escande 1527cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 1537cbe0ff3SThierry Escande return -EINVAL; 1547cbe0ff3SThierry Escande } 1557cbe0ff3SThierry Escande 1567cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 1577cbe0ff3SThierry Escande 1587cbe0ff3SThierry Escande mutex_lock(&dev->lock); 1597cbe0ff3SThierry Escande 1607cbe0ff3SThierry Escande rc = nfc_set_remote_general_bytes(nfc_dev, remote_gb, remote_gb_len); 1617cbe0ff3SThierry Escande if (rc) { 162073a625fSJoe Perches DEV_ERR(dev, "Can't set remote general bytes\n"); 1637cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 1647cbe0ff3SThierry Escande return rc; 1657cbe0ff3SThierry Escande } 1667cbe0ff3SThierry Escande 1677cbe0ff3SThierry Escande rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_ACTIVE, 1687cbe0ff3SThierry Escande NFC_RF_INITIATOR); 1697cbe0ff3SThierry Escande 1707cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 1717cbe0ff3SThierry Escande 1727cbe0ff3SThierry Escande return rc; 1737cbe0ff3SThierry Escande } 1747cbe0ff3SThierry Escande 1757cbe0ff3SThierry Escande static int nfcsim_dep_link_down(struct nfc_dev *nfc_dev) 1767cbe0ff3SThierry Escande { 1777cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 1787cbe0ff3SThierry Escande 179b4834839SJoe Perches DEV_DBG(dev, "\n"); 1807cbe0ff3SThierry Escande 1817cbe0ff3SThierry Escande nfcsim_cleanup_dev(dev, 0); 1827cbe0ff3SThierry Escande 1837cbe0ff3SThierry Escande return 0; 1847cbe0ff3SThierry Escande } 1857cbe0ff3SThierry Escande 1867cbe0ff3SThierry Escande static int nfcsim_start_poll(struct nfc_dev *nfc_dev, 1877cbe0ff3SThierry Escande u32 im_protocols, u32 tm_protocols) 1887cbe0ff3SThierry Escande { 1897cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 1907cbe0ff3SThierry Escande int rc; 1917cbe0ff3SThierry Escande 1927cbe0ff3SThierry Escande mutex_lock(&dev->lock); 1937cbe0ff3SThierry Escande 1947cbe0ff3SThierry Escande if (dev->polling_mode != NFCSIM_POLL_NONE) { 195073a625fSJoe Perches DEV_ERR(dev, "Already in polling mode\n"); 1967cbe0ff3SThierry Escande rc = -EBUSY; 1977cbe0ff3SThierry Escande goto exit; 1987cbe0ff3SThierry Escande } 1997cbe0ff3SThierry Escande 2007cbe0ff3SThierry Escande if (im_protocols & NFC_PROTO_NFC_DEP_MASK) 2017cbe0ff3SThierry Escande dev->polling_mode |= NFCSIM_POLL_INITIATOR; 2027cbe0ff3SThierry Escande 2037cbe0ff3SThierry Escande if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) 2047cbe0ff3SThierry Escande dev->polling_mode |= NFCSIM_POLL_TARGET; 2057cbe0ff3SThierry Escande 2067cbe0ff3SThierry Escande if (dev->polling_mode == NFCSIM_POLL_NONE) { 207073a625fSJoe Perches DEV_ERR(dev, "Unsupported polling mode\n"); 2087cbe0ff3SThierry Escande rc = -EINVAL; 2097cbe0ff3SThierry Escande goto exit; 2107cbe0ff3SThierry Escande } 2117cbe0ff3SThierry Escande 2127cbe0ff3SThierry Escande dev->initiator = 0; 2137cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_NONE; 2147cbe0ff3SThierry Escande 2157cbe0ff3SThierry Escande queue_delayed_work(wq, &dev->poll_work, 0); 2167cbe0ff3SThierry Escande 217b4834839SJoe Perches DEV_DBG(dev, "Start polling: im: 0x%X, tm: 0x%X\n", im_protocols, 2187cbe0ff3SThierry Escande tm_protocols); 2197cbe0ff3SThierry Escande 2207cbe0ff3SThierry Escande rc = 0; 2217cbe0ff3SThierry Escande exit: 2227cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 2237cbe0ff3SThierry Escande 2247cbe0ff3SThierry Escande return rc; 2257cbe0ff3SThierry Escande } 2267cbe0ff3SThierry Escande 2277cbe0ff3SThierry Escande static void nfcsim_stop_poll(struct nfc_dev *nfc_dev) 2287cbe0ff3SThierry Escande { 2297cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 2307cbe0ff3SThierry Escande 231b4834839SJoe Perches DEV_DBG(dev, "Stop poll\n"); 2327cbe0ff3SThierry Escande 2337cbe0ff3SThierry Escande mutex_lock(&dev->lock); 2347cbe0ff3SThierry Escande 2357cbe0ff3SThierry Escande dev->polling_mode = NFCSIM_POLL_NONE; 2367cbe0ff3SThierry Escande 2377cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 2387cbe0ff3SThierry Escande 2397cbe0ff3SThierry Escande cancel_delayed_work_sync(&dev->poll_work); 2407cbe0ff3SThierry Escande } 2417cbe0ff3SThierry Escande 2427cbe0ff3SThierry Escande static int nfcsim_activate_target(struct nfc_dev *nfc_dev, 2437cbe0ff3SThierry Escande struct nfc_target *target, u32 protocol) 2447cbe0ff3SThierry Escande { 2457cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 2467cbe0ff3SThierry Escande 247b4834839SJoe Perches DEV_DBG(dev, "\n"); 2487cbe0ff3SThierry Escande 2497cbe0ff3SThierry Escande return -ENOTSUPP; 2507cbe0ff3SThierry Escande } 2517cbe0ff3SThierry Escande 2527cbe0ff3SThierry Escande static void nfcsim_deactivate_target(struct nfc_dev *nfc_dev, 25396d4581fSChristophe Ricard struct nfc_target *target, u8 mode) 2547cbe0ff3SThierry Escande { 2557cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 2567cbe0ff3SThierry Escande 257b4834839SJoe Perches DEV_DBG(dev, "\n"); 2587cbe0ff3SThierry Escande } 2597cbe0ff3SThierry Escande 2607cbe0ff3SThierry Escande static void nfcsim_wq_recv(struct work_struct *work) 2617cbe0ff3SThierry Escande { 2627cbe0ff3SThierry Escande struct nfcsim *dev = container_of(work, struct nfcsim, 2637cbe0ff3SThierry Escande recv_work.work); 2647cbe0ff3SThierry Escande 2657cbe0ff3SThierry Escande mutex_lock(&dev->lock); 2667cbe0ff3SThierry Escande 2677cbe0ff3SThierry Escande if (dev->shutting_down || !dev->up || !dev->clone_skb) { 2687cbe0ff3SThierry Escande dev_kfree_skb(dev->clone_skb); 2697cbe0ff3SThierry Escande goto exit; 2707cbe0ff3SThierry Escande } 2717cbe0ff3SThierry Escande 2727cbe0ff3SThierry Escande if (dev->initiator) { 2737cbe0ff3SThierry Escande if (!dev->cb) { 274073a625fSJoe Perches DEV_ERR(dev, "Null recv callback\n"); 2757cbe0ff3SThierry Escande dev_kfree_skb(dev->clone_skb); 2767cbe0ff3SThierry Escande goto exit; 2777cbe0ff3SThierry Escande } 2787cbe0ff3SThierry Escande 2797cbe0ff3SThierry Escande dev->cb(dev->cb_context, dev->clone_skb, 0); 2807cbe0ff3SThierry Escande dev->cb = NULL; 2817cbe0ff3SThierry Escande } else { 2827cbe0ff3SThierry Escande nfc_tm_data_received(dev->nfc_dev, dev->clone_skb); 2837cbe0ff3SThierry Escande } 2847cbe0ff3SThierry Escande 2857cbe0ff3SThierry Escande exit: 2867cbe0ff3SThierry Escande dev->clone_skb = NULL; 2877cbe0ff3SThierry Escande 2887cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 2897cbe0ff3SThierry Escande } 2907cbe0ff3SThierry Escande 2917cbe0ff3SThierry Escande static int nfcsim_tx(struct nfc_dev *nfc_dev, struct nfc_target *target, 2927cbe0ff3SThierry Escande struct sk_buff *skb, data_exchange_cb_t cb, 2937cbe0ff3SThierry Escande void *cb_context) 2947cbe0ff3SThierry Escande { 2957cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 2967cbe0ff3SThierry Escande struct nfcsim *peer = dev->peer_dev; 2977cbe0ff3SThierry Escande int err; 2987cbe0ff3SThierry Escande 2997cbe0ff3SThierry Escande mutex_lock(&dev->lock); 3007cbe0ff3SThierry Escande 3017cbe0ff3SThierry Escande if (dev->shutting_down || !dev->up) { 3027cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 3037cbe0ff3SThierry Escande err = -ENODEV; 3047cbe0ff3SThierry Escande goto exit; 3057cbe0ff3SThierry Escande } 3067cbe0ff3SThierry Escande 3077cbe0ff3SThierry Escande dev->cb = cb; 3087cbe0ff3SThierry Escande dev->cb_context = cb_context; 3097cbe0ff3SThierry Escande 3107cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 3117cbe0ff3SThierry Escande 3127cbe0ff3SThierry Escande mutex_lock(&peer->lock); 3137cbe0ff3SThierry Escande 3147cbe0ff3SThierry Escande peer->clone_skb = skb_clone(skb, GFP_KERNEL); 3157cbe0ff3SThierry Escande 3167cbe0ff3SThierry Escande if (!peer->clone_skb) { 317073a625fSJoe Perches DEV_ERR(dev, "skb_clone failed\n"); 3187cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 3197cbe0ff3SThierry Escande err = -ENOMEM; 3207cbe0ff3SThierry Escande goto exit; 3217cbe0ff3SThierry Escande } 3227cbe0ff3SThierry Escande 3237cbe0ff3SThierry Escande /* This simulates an arbitrary transmission delay between the 2 devices. 3247cbe0ff3SThierry Escande * If packet transmission occurs immediately between them, we have a 3257cbe0ff3SThierry Escande * non-stop flow of several tens of thousands SYMM packets per second 3267cbe0ff3SThierry Escande * and a burning cpu. 3277cbe0ff3SThierry Escande */ 328*a440f1aaSSaurabh Sengar queue_delayed_work(wq, &peer->recv_work, 329*a440f1aaSSaurabh Sengar msecs_to_jiffies(dev->rx_delay)); 3307cbe0ff3SThierry Escande 3317cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 3327cbe0ff3SThierry Escande 3337cbe0ff3SThierry Escande err = 0; 3347cbe0ff3SThierry Escande exit: 3357cbe0ff3SThierry Escande dev_kfree_skb(skb); 3367cbe0ff3SThierry Escande 3377cbe0ff3SThierry Escande return err; 3387cbe0ff3SThierry Escande } 3397cbe0ff3SThierry Escande 3407cbe0ff3SThierry Escande static int nfcsim_im_transceive(struct nfc_dev *nfc_dev, 3417cbe0ff3SThierry Escande struct nfc_target *target, struct sk_buff *skb, 3427cbe0ff3SThierry Escande data_exchange_cb_t cb, void *cb_context) 3437cbe0ff3SThierry Escande { 3447cbe0ff3SThierry Escande return nfcsim_tx(nfc_dev, target, skb, cb, cb_context); 3457cbe0ff3SThierry Escande } 3467cbe0ff3SThierry Escande 3477cbe0ff3SThierry Escande static int nfcsim_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) 3487cbe0ff3SThierry Escande { 3497cbe0ff3SThierry Escande return nfcsim_tx(nfc_dev, NULL, skb, NULL, NULL); 3507cbe0ff3SThierry Escande } 3517cbe0ff3SThierry Escande 3527cbe0ff3SThierry Escande static struct nfc_ops nfcsim_nfc_ops = { 3537cbe0ff3SThierry Escande .dev_up = nfcsim_dev_up, 3547cbe0ff3SThierry Escande .dev_down = nfcsim_dev_down, 3557cbe0ff3SThierry Escande .dep_link_up = nfcsim_dep_link_up, 3567cbe0ff3SThierry Escande .dep_link_down = nfcsim_dep_link_down, 3577cbe0ff3SThierry Escande .start_poll = nfcsim_start_poll, 3587cbe0ff3SThierry Escande .stop_poll = nfcsim_stop_poll, 3597cbe0ff3SThierry Escande .activate_target = nfcsim_activate_target, 3607cbe0ff3SThierry Escande .deactivate_target = nfcsim_deactivate_target, 3617cbe0ff3SThierry Escande .im_transceive = nfcsim_im_transceive, 3627cbe0ff3SThierry Escande .tm_send = nfcsim_tm_send, 3637cbe0ff3SThierry Escande }; 3647cbe0ff3SThierry Escande 3657cbe0ff3SThierry Escande static void nfcsim_set_polling_mode(struct nfcsim *dev) 3667cbe0ff3SThierry Escande { 3677cbe0ff3SThierry Escande if (dev->polling_mode == NFCSIM_POLL_NONE) { 3687cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_NONE; 3697cbe0ff3SThierry Escande return; 3707cbe0ff3SThierry Escande } 3717cbe0ff3SThierry Escande 3727cbe0ff3SThierry Escande if (dev->curr_polling_mode == NFCSIM_POLL_NONE) { 3737cbe0ff3SThierry Escande if (dev->polling_mode & NFCSIM_POLL_INITIATOR) 3747cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_INITIATOR; 3757cbe0ff3SThierry Escande else 3767cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_TARGET; 3777cbe0ff3SThierry Escande 3787cbe0ff3SThierry Escande return; 3797cbe0ff3SThierry Escande } 3807cbe0ff3SThierry Escande 3817cbe0ff3SThierry Escande if (dev->polling_mode == NFCSIM_POLL_DUAL) { 3827cbe0ff3SThierry Escande if (dev->curr_polling_mode == NFCSIM_POLL_TARGET) 3837cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_INITIATOR; 3847cbe0ff3SThierry Escande else 3857cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_TARGET; 3867cbe0ff3SThierry Escande } 3877cbe0ff3SThierry Escande } 3887cbe0ff3SThierry Escande 3897cbe0ff3SThierry Escande static void nfcsim_wq_poll(struct work_struct *work) 3907cbe0ff3SThierry Escande { 3917cbe0ff3SThierry Escande struct nfcsim *dev = container_of(work, struct nfcsim, poll_work.work); 3927cbe0ff3SThierry Escande struct nfcsim *peer = dev->peer_dev; 3937cbe0ff3SThierry Escande 3947cbe0ff3SThierry Escande /* These work items run on an ordered workqueue and are therefore 3957cbe0ff3SThierry Escande * serialized. So we can take both mutexes without being dead locked. 3967cbe0ff3SThierry Escande */ 3977cbe0ff3SThierry Escande mutex_lock(&dev->lock); 3987cbe0ff3SThierry Escande mutex_lock(&peer->lock); 3997cbe0ff3SThierry Escande 4007cbe0ff3SThierry Escande nfcsim_set_polling_mode(dev); 4017cbe0ff3SThierry Escande 4027cbe0ff3SThierry Escande if (dev->curr_polling_mode == NFCSIM_POLL_NONE) { 403b4834839SJoe Perches DEV_DBG(dev, "Not polling\n"); 4047cbe0ff3SThierry Escande goto unlock; 4057cbe0ff3SThierry Escande } 4067cbe0ff3SThierry Escande 4077cbe0ff3SThierry Escande DEV_DBG(dev, "Polling as %s", 4087cbe0ff3SThierry Escande dev->curr_polling_mode == NFCSIM_POLL_INITIATOR ? 409b4834839SJoe Perches "initiator\n" : "target\n"); 4107cbe0ff3SThierry Escande 4117cbe0ff3SThierry Escande if (dev->curr_polling_mode == NFCSIM_POLL_TARGET) 4127cbe0ff3SThierry Escande goto sched_work; 4137cbe0ff3SThierry Escande 4147cbe0ff3SThierry Escande if (peer->curr_polling_mode == NFCSIM_POLL_TARGET) { 4157cbe0ff3SThierry Escande peer->polling_mode = NFCSIM_POLL_NONE; 4167cbe0ff3SThierry Escande dev->polling_mode = NFCSIM_POLL_NONE; 4177cbe0ff3SThierry Escande 4187cbe0ff3SThierry Escande dev->initiator = 1; 4197cbe0ff3SThierry Escande 4207cbe0ff3SThierry Escande nfcsim_target_found(dev); 4217cbe0ff3SThierry Escande 4227cbe0ff3SThierry Escande goto unlock; 4237cbe0ff3SThierry Escande } 4247cbe0ff3SThierry Escande 4257cbe0ff3SThierry Escande sched_work: 4267cbe0ff3SThierry Escande /* This defines the delay for an initiator to check if the other device 4277cbe0ff3SThierry Escande * is polling in target mode. 4287cbe0ff3SThierry Escande * If the device starts in dual mode polling, it switches between 4297cbe0ff3SThierry Escande * initiator and target at every round. 4307cbe0ff3SThierry Escande * Because the wq is ordered and only 1 work item is executed at a time, 4317cbe0ff3SThierry Escande * we'll always have one device polling as initiator and the other as 4327cbe0ff3SThierry Escande * target at some point, even if both are started in dual mode. 4337cbe0ff3SThierry Escande */ 4347cbe0ff3SThierry Escande queue_delayed_work(wq, &dev->poll_work, msecs_to_jiffies(200)); 4357cbe0ff3SThierry Escande 4367cbe0ff3SThierry Escande unlock: 4377cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 4387cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 4397cbe0ff3SThierry Escande } 4407cbe0ff3SThierry Escande 4417cbe0ff3SThierry Escande static struct nfcsim *nfcsim_init_dev(void) 4427cbe0ff3SThierry Escande { 4437cbe0ff3SThierry Escande struct nfcsim *dev; 4447cbe0ff3SThierry Escande int rc = -ENOMEM; 4457cbe0ff3SThierry Escande 4467cbe0ff3SThierry Escande dev = kzalloc(sizeof(*dev), GFP_KERNEL); 4477cbe0ff3SThierry Escande if (dev == NULL) 4487cbe0ff3SThierry Escande return ERR_PTR(-ENOMEM); 4497cbe0ff3SThierry Escande 4507cbe0ff3SThierry Escande mutex_init(&dev->lock); 4517cbe0ff3SThierry Escande 4527cbe0ff3SThierry Escande INIT_DELAYED_WORK(&dev->recv_work, nfcsim_wq_recv); 4537cbe0ff3SThierry Escande INIT_DELAYED_WORK(&dev->poll_work, nfcsim_wq_poll); 4547cbe0ff3SThierry Escande 4557cbe0ff3SThierry Escande dev->nfc_dev = nfc_allocate_device(&nfcsim_nfc_ops, 4567cbe0ff3SThierry Escande NFC_PROTO_NFC_DEP_MASK, 4577cbe0ff3SThierry Escande 0, 0); 4587cbe0ff3SThierry Escande if (!dev->nfc_dev) 4597cbe0ff3SThierry Escande goto error; 4607cbe0ff3SThierry Escande 4617cbe0ff3SThierry Escande nfc_set_drvdata(dev->nfc_dev, dev); 4627cbe0ff3SThierry Escande 4637cbe0ff3SThierry Escande rc = nfc_register_device(dev->nfc_dev); 4647cbe0ff3SThierry Escande if (rc) 4657cbe0ff3SThierry Escande goto free_nfc_dev; 4667cbe0ff3SThierry Escande 467*a440f1aaSSaurabh Sengar dev->rx_delay = RX_DEFAULT_DELAY; 4687cbe0ff3SThierry Escande return dev; 4697cbe0ff3SThierry Escande 4707cbe0ff3SThierry Escande free_nfc_dev: 4717cbe0ff3SThierry Escande nfc_free_device(dev->nfc_dev); 4727cbe0ff3SThierry Escande 4737cbe0ff3SThierry Escande error: 4747cbe0ff3SThierry Escande kfree(dev); 4757cbe0ff3SThierry Escande 4767cbe0ff3SThierry Escande return ERR_PTR(rc); 4777cbe0ff3SThierry Escande } 4787cbe0ff3SThierry Escande 4797cbe0ff3SThierry Escande static void nfcsim_free_device(struct nfcsim *dev) 4807cbe0ff3SThierry Escande { 4817cbe0ff3SThierry Escande nfc_unregister_device(dev->nfc_dev); 4827cbe0ff3SThierry Escande 4837cbe0ff3SThierry Escande nfc_free_device(dev->nfc_dev); 4847cbe0ff3SThierry Escande 4857cbe0ff3SThierry Escande kfree(dev); 4867cbe0ff3SThierry Escande } 4877cbe0ff3SThierry Escande 48840dac370SThierry Escande static int __init nfcsim_init(void) 4897cbe0ff3SThierry Escande { 4907cbe0ff3SThierry Escande int rc; 4917cbe0ff3SThierry Escande 4927cbe0ff3SThierry Escande /* We need an ordered wq to ensure that poll_work items are executed 4937cbe0ff3SThierry Escande * one at a time. 4947cbe0ff3SThierry Escande */ 4957cbe0ff3SThierry Escande wq = alloc_ordered_workqueue("nfcsim", 0); 4967cbe0ff3SThierry Escande if (!wq) { 4977cbe0ff3SThierry Escande rc = -ENOMEM; 4987cbe0ff3SThierry Escande goto exit; 4997cbe0ff3SThierry Escande } 5007cbe0ff3SThierry Escande 5017cbe0ff3SThierry Escande dev0 = nfcsim_init_dev(); 5027cbe0ff3SThierry Escande if (IS_ERR(dev0)) { 5037cbe0ff3SThierry Escande rc = PTR_ERR(dev0); 5047cbe0ff3SThierry Escande goto exit; 5057cbe0ff3SThierry Escande } 5067cbe0ff3SThierry Escande 5077cbe0ff3SThierry Escande dev1 = nfcsim_init_dev(); 5087cbe0ff3SThierry Escande if (IS_ERR(dev1)) { 5097cbe0ff3SThierry Escande kfree(dev0); 5107cbe0ff3SThierry Escande 5117cbe0ff3SThierry Escande rc = PTR_ERR(dev1); 5127cbe0ff3SThierry Escande goto exit; 5137cbe0ff3SThierry Escande } 5147cbe0ff3SThierry Escande 5157cbe0ff3SThierry Escande dev0->peer_dev = dev1; 5167cbe0ff3SThierry Escande dev1->peer_dev = dev0; 5177cbe0ff3SThierry Escande 5187cbe0ff3SThierry Escande pr_debug("NFCsim " NFCSIM_VERSION " initialized\n"); 5197cbe0ff3SThierry Escande 5207cbe0ff3SThierry Escande rc = 0; 5217cbe0ff3SThierry Escande exit: 5227cbe0ff3SThierry Escande if (rc) 5237cbe0ff3SThierry Escande pr_err("Failed to initialize nfcsim driver (%d)\n", 5247cbe0ff3SThierry Escande rc); 5257cbe0ff3SThierry Escande 5267cbe0ff3SThierry Escande return rc; 5277cbe0ff3SThierry Escande } 5287cbe0ff3SThierry Escande 52940dac370SThierry Escande static void __exit nfcsim_exit(void) 5307cbe0ff3SThierry Escande { 5317cbe0ff3SThierry Escande nfcsim_cleanup_dev(dev0, 1); 5327cbe0ff3SThierry Escande nfcsim_cleanup_dev(dev1, 1); 5337cbe0ff3SThierry Escande 5347cbe0ff3SThierry Escande nfcsim_free_device(dev0); 5357cbe0ff3SThierry Escande nfcsim_free_device(dev1); 5367cbe0ff3SThierry Escande 5377cbe0ff3SThierry Escande destroy_workqueue(wq); 5387cbe0ff3SThierry Escande } 5397cbe0ff3SThierry Escande 5407cbe0ff3SThierry Escande module_init(nfcsim_init); 5417cbe0ff3SThierry Escande module_exit(nfcsim_exit); 5427cbe0ff3SThierry Escande 5437cbe0ff3SThierry Escande MODULE_DESCRIPTION("NFCSim driver ver " NFCSIM_VERSION); 5447cbe0ff3SThierry Escande MODULE_VERSION(NFCSIM_VERSION); 5457cbe0ff3SThierry Escande MODULE_LICENSE("GPL"); 546