1*7cbe0ff3SThierry Escande /* 2*7cbe0ff3SThierry Escande * NFC hardware simulation driver 3*7cbe0ff3SThierry Escande * Copyright (c) 2013, Intel Corporation. 4*7cbe0ff3SThierry Escande * 5*7cbe0ff3SThierry Escande * This program is free software; you can redistribute it and/or modify it 6*7cbe0ff3SThierry Escande * under the terms and conditions of the GNU General Public License, 7*7cbe0ff3SThierry Escande * version 2, as published by the Free Software Foundation. 8*7cbe0ff3SThierry Escande * 9*7cbe0ff3SThierry Escande * This program is distributed in the hope it will be useful, but WITHOUT 10*7cbe0ff3SThierry Escande * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11*7cbe0ff3SThierry Escande * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12*7cbe0ff3SThierry Escande * more details. 13*7cbe0ff3SThierry Escande * 14*7cbe0ff3SThierry Escande */ 15*7cbe0ff3SThierry Escande 16*7cbe0ff3SThierry Escande #include <linux/device.h> 17*7cbe0ff3SThierry Escande #include <linux/kernel.h> 18*7cbe0ff3SThierry Escande #include <linux/module.h> 19*7cbe0ff3SThierry Escande #include <linux/nfc.h> 20*7cbe0ff3SThierry Escande #include <net/nfc/nfc.h> 21*7cbe0ff3SThierry Escande 22*7cbe0ff3SThierry Escande #define DEV_ERR(_dev, fmt, args...) nfc_dev_err(&_dev->nfc_dev->dev, \ 23*7cbe0ff3SThierry Escande "%s: " fmt, __func__, ## args) 24*7cbe0ff3SThierry Escande 25*7cbe0ff3SThierry Escande #define DEV_DBG(_dev, fmt, args...) nfc_dev_dbg(&_dev->nfc_dev->dev, \ 26*7cbe0ff3SThierry Escande "%s: " fmt, __func__, ## args) 27*7cbe0ff3SThierry Escande 28*7cbe0ff3SThierry Escande #define NFCSIM_VERSION "0.1" 29*7cbe0ff3SThierry Escande 30*7cbe0ff3SThierry Escande #define NFCSIM_POLL_NONE 0 31*7cbe0ff3SThierry Escande #define NFCSIM_POLL_INITIATOR 1 32*7cbe0ff3SThierry Escande #define NFCSIM_POLL_TARGET 2 33*7cbe0ff3SThierry Escande #define NFCSIM_POLL_DUAL (NFCSIM_POLL_INITIATOR | NFCSIM_POLL_TARGET) 34*7cbe0ff3SThierry Escande 35*7cbe0ff3SThierry Escande struct nfcsim { 36*7cbe0ff3SThierry Escande struct nfc_dev *nfc_dev; 37*7cbe0ff3SThierry Escande 38*7cbe0ff3SThierry Escande struct mutex lock; 39*7cbe0ff3SThierry Escande 40*7cbe0ff3SThierry Escande struct delayed_work recv_work; 41*7cbe0ff3SThierry Escande 42*7cbe0ff3SThierry Escande struct sk_buff *clone_skb; 43*7cbe0ff3SThierry Escande 44*7cbe0ff3SThierry Escande struct delayed_work poll_work; 45*7cbe0ff3SThierry Escande u8 polling_mode; 46*7cbe0ff3SThierry Escande u8 curr_polling_mode; 47*7cbe0ff3SThierry Escande 48*7cbe0ff3SThierry Escande u8 shutting_down; 49*7cbe0ff3SThierry Escande 50*7cbe0ff3SThierry Escande u8 up; 51*7cbe0ff3SThierry Escande 52*7cbe0ff3SThierry Escande u8 initiator; 53*7cbe0ff3SThierry Escande 54*7cbe0ff3SThierry Escande data_exchange_cb_t cb; 55*7cbe0ff3SThierry Escande void *cb_context; 56*7cbe0ff3SThierry Escande 57*7cbe0ff3SThierry Escande struct nfcsim *peer_dev; 58*7cbe0ff3SThierry Escande }; 59*7cbe0ff3SThierry Escande 60*7cbe0ff3SThierry Escande static struct nfcsim *dev0; 61*7cbe0ff3SThierry Escande static struct nfcsim *dev1; 62*7cbe0ff3SThierry Escande 63*7cbe0ff3SThierry Escande struct workqueue_struct *wq; 64*7cbe0ff3SThierry Escande 65*7cbe0ff3SThierry Escande static void nfcsim_cleanup_dev(struct nfcsim *dev, u8 shutdown) 66*7cbe0ff3SThierry Escande { 67*7cbe0ff3SThierry Escande DEV_DBG(dev, "shutdown=%d", shutdown); 68*7cbe0ff3SThierry Escande 69*7cbe0ff3SThierry Escande mutex_lock(&dev->lock); 70*7cbe0ff3SThierry Escande 71*7cbe0ff3SThierry Escande dev->polling_mode = NFCSIM_POLL_NONE; 72*7cbe0ff3SThierry Escande dev->shutting_down = shutdown; 73*7cbe0ff3SThierry Escande dev->cb = NULL; 74*7cbe0ff3SThierry Escande dev_kfree_skb(dev->clone_skb); 75*7cbe0ff3SThierry Escande dev->clone_skb = NULL; 76*7cbe0ff3SThierry Escande 77*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 78*7cbe0ff3SThierry Escande 79*7cbe0ff3SThierry Escande cancel_delayed_work_sync(&dev->poll_work); 80*7cbe0ff3SThierry Escande cancel_delayed_work_sync(&dev->recv_work); 81*7cbe0ff3SThierry Escande } 82*7cbe0ff3SThierry Escande 83*7cbe0ff3SThierry Escande static int nfcsim_target_found(struct nfcsim *dev) 84*7cbe0ff3SThierry Escande { 85*7cbe0ff3SThierry Escande struct nfc_target nfc_tgt; 86*7cbe0ff3SThierry Escande 87*7cbe0ff3SThierry Escande DEV_DBG(dev, ""); 88*7cbe0ff3SThierry Escande 89*7cbe0ff3SThierry Escande memset(&nfc_tgt, 0, sizeof(struct nfc_target)); 90*7cbe0ff3SThierry Escande 91*7cbe0ff3SThierry Escande nfc_tgt.supported_protocols = NFC_PROTO_NFC_DEP_MASK; 92*7cbe0ff3SThierry Escande nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1); 93*7cbe0ff3SThierry Escande 94*7cbe0ff3SThierry Escande return 0; 95*7cbe0ff3SThierry Escande } 96*7cbe0ff3SThierry Escande 97*7cbe0ff3SThierry Escande static int nfcsim_dev_up(struct nfc_dev *nfc_dev) 98*7cbe0ff3SThierry Escande { 99*7cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 100*7cbe0ff3SThierry Escande 101*7cbe0ff3SThierry Escande DEV_DBG(dev, ""); 102*7cbe0ff3SThierry Escande 103*7cbe0ff3SThierry Escande mutex_lock(&dev->lock); 104*7cbe0ff3SThierry Escande 105*7cbe0ff3SThierry Escande dev->up = 1; 106*7cbe0ff3SThierry Escande 107*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 108*7cbe0ff3SThierry Escande 109*7cbe0ff3SThierry Escande return 0; 110*7cbe0ff3SThierry Escande } 111*7cbe0ff3SThierry Escande 112*7cbe0ff3SThierry Escande static int nfcsim_dev_down(struct nfc_dev *nfc_dev) 113*7cbe0ff3SThierry Escande { 114*7cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 115*7cbe0ff3SThierry Escande 116*7cbe0ff3SThierry Escande DEV_DBG(dev, ""); 117*7cbe0ff3SThierry Escande 118*7cbe0ff3SThierry Escande mutex_lock(&dev->lock); 119*7cbe0ff3SThierry Escande 120*7cbe0ff3SThierry Escande dev->up = 0; 121*7cbe0ff3SThierry Escande 122*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 123*7cbe0ff3SThierry Escande 124*7cbe0ff3SThierry Escande return 0; 125*7cbe0ff3SThierry Escande } 126*7cbe0ff3SThierry Escande 127*7cbe0ff3SThierry Escande static int nfcsim_dep_link_up(struct nfc_dev *nfc_dev, 128*7cbe0ff3SThierry Escande struct nfc_target *target, 129*7cbe0ff3SThierry Escande u8 comm_mode, u8 *gb, size_t gb_len) 130*7cbe0ff3SThierry Escande { 131*7cbe0ff3SThierry Escande int rc; 132*7cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 133*7cbe0ff3SThierry Escande struct nfcsim *peer = dev->peer_dev; 134*7cbe0ff3SThierry Escande u8 *remote_gb; 135*7cbe0ff3SThierry Escande size_t remote_gb_len; 136*7cbe0ff3SThierry Escande 137*7cbe0ff3SThierry Escande DEV_DBG(dev, "target_idx: %d, comm_mode: %d\n", target->idx, comm_mode); 138*7cbe0ff3SThierry Escande 139*7cbe0ff3SThierry Escande mutex_lock(&peer->lock); 140*7cbe0ff3SThierry Escande 141*7cbe0ff3SThierry Escande nfc_tm_activated(peer->nfc_dev, NFC_PROTO_NFC_DEP_MASK, 142*7cbe0ff3SThierry Escande NFC_COMM_ACTIVE, gb, gb_len); 143*7cbe0ff3SThierry Escande 144*7cbe0ff3SThierry Escande remote_gb = nfc_get_local_general_bytes(peer->nfc_dev, &remote_gb_len); 145*7cbe0ff3SThierry Escande if (!remote_gb) { 146*7cbe0ff3SThierry Escande DEV_ERR(peer, "Can't get remote general bytes"); 147*7cbe0ff3SThierry Escande 148*7cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 149*7cbe0ff3SThierry Escande return -EINVAL; 150*7cbe0ff3SThierry Escande } 151*7cbe0ff3SThierry Escande 152*7cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 153*7cbe0ff3SThierry Escande 154*7cbe0ff3SThierry Escande mutex_lock(&dev->lock); 155*7cbe0ff3SThierry Escande 156*7cbe0ff3SThierry Escande rc = nfc_set_remote_general_bytes(nfc_dev, remote_gb, remote_gb_len); 157*7cbe0ff3SThierry Escande if (rc) { 158*7cbe0ff3SThierry Escande DEV_ERR(dev, "Can't set remote general bytes"); 159*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 160*7cbe0ff3SThierry Escande return rc; 161*7cbe0ff3SThierry Escande } 162*7cbe0ff3SThierry Escande 163*7cbe0ff3SThierry Escande rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_ACTIVE, 164*7cbe0ff3SThierry Escande NFC_RF_INITIATOR); 165*7cbe0ff3SThierry Escande 166*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 167*7cbe0ff3SThierry Escande 168*7cbe0ff3SThierry Escande return rc; 169*7cbe0ff3SThierry Escande } 170*7cbe0ff3SThierry Escande 171*7cbe0ff3SThierry Escande static int nfcsim_dep_link_down(struct nfc_dev *nfc_dev) 172*7cbe0ff3SThierry Escande { 173*7cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 174*7cbe0ff3SThierry Escande 175*7cbe0ff3SThierry Escande DEV_DBG(dev, ""); 176*7cbe0ff3SThierry Escande 177*7cbe0ff3SThierry Escande nfcsim_cleanup_dev(dev, 0); 178*7cbe0ff3SThierry Escande 179*7cbe0ff3SThierry Escande return 0; 180*7cbe0ff3SThierry Escande } 181*7cbe0ff3SThierry Escande 182*7cbe0ff3SThierry Escande static int nfcsim_start_poll(struct nfc_dev *nfc_dev, 183*7cbe0ff3SThierry Escande u32 im_protocols, u32 tm_protocols) 184*7cbe0ff3SThierry Escande { 185*7cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 186*7cbe0ff3SThierry Escande int rc; 187*7cbe0ff3SThierry Escande 188*7cbe0ff3SThierry Escande mutex_lock(&dev->lock); 189*7cbe0ff3SThierry Escande 190*7cbe0ff3SThierry Escande if (dev->polling_mode != NFCSIM_POLL_NONE) { 191*7cbe0ff3SThierry Escande DEV_ERR(dev, "Already in polling mode"); 192*7cbe0ff3SThierry Escande rc = -EBUSY; 193*7cbe0ff3SThierry Escande goto exit; 194*7cbe0ff3SThierry Escande } 195*7cbe0ff3SThierry Escande 196*7cbe0ff3SThierry Escande if (im_protocols & NFC_PROTO_NFC_DEP_MASK) 197*7cbe0ff3SThierry Escande dev->polling_mode |= NFCSIM_POLL_INITIATOR; 198*7cbe0ff3SThierry Escande 199*7cbe0ff3SThierry Escande if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) 200*7cbe0ff3SThierry Escande dev->polling_mode |= NFCSIM_POLL_TARGET; 201*7cbe0ff3SThierry Escande 202*7cbe0ff3SThierry Escande if (dev->polling_mode == NFCSIM_POLL_NONE) { 203*7cbe0ff3SThierry Escande DEV_ERR(dev, "Unsupported polling mode"); 204*7cbe0ff3SThierry Escande rc = -EINVAL; 205*7cbe0ff3SThierry Escande goto exit; 206*7cbe0ff3SThierry Escande } 207*7cbe0ff3SThierry Escande 208*7cbe0ff3SThierry Escande dev->initiator = 0; 209*7cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_NONE; 210*7cbe0ff3SThierry Escande 211*7cbe0ff3SThierry Escande queue_delayed_work(wq, &dev->poll_work, 0); 212*7cbe0ff3SThierry Escande 213*7cbe0ff3SThierry Escande DEV_DBG(dev, "Start polling: im: 0x%X, tm: 0x%X", im_protocols, 214*7cbe0ff3SThierry Escande tm_protocols); 215*7cbe0ff3SThierry Escande 216*7cbe0ff3SThierry Escande rc = 0; 217*7cbe0ff3SThierry Escande exit: 218*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 219*7cbe0ff3SThierry Escande 220*7cbe0ff3SThierry Escande return rc; 221*7cbe0ff3SThierry Escande } 222*7cbe0ff3SThierry Escande 223*7cbe0ff3SThierry Escande static void nfcsim_stop_poll(struct nfc_dev *nfc_dev) 224*7cbe0ff3SThierry Escande { 225*7cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 226*7cbe0ff3SThierry Escande 227*7cbe0ff3SThierry Escande DEV_DBG(dev, "Stop poll"); 228*7cbe0ff3SThierry Escande 229*7cbe0ff3SThierry Escande mutex_lock(&dev->lock); 230*7cbe0ff3SThierry Escande 231*7cbe0ff3SThierry Escande dev->polling_mode = NFCSIM_POLL_NONE; 232*7cbe0ff3SThierry Escande 233*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 234*7cbe0ff3SThierry Escande 235*7cbe0ff3SThierry Escande cancel_delayed_work_sync(&dev->poll_work); 236*7cbe0ff3SThierry Escande } 237*7cbe0ff3SThierry Escande 238*7cbe0ff3SThierry Escande static int nfcsim_activate_target(struct nfc_dev *nfc_dev, 239*7cbe0ff3SThierry Escande struct nfc_target *target, u32 protocol) 240*7cbe0ff3SThierry Escande { 241*7cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 242*7cbe0ff3SThierry Escande 243*7cbe0ff3SThierry Escande DEV_DBG(dev, ""); 244*7cbe0ff3SThierry Escande 245*7cbe0ff3SThierry Escande return -ENOTSUPP; 246*7cbe0ff3SThierry Escande } 247*7cbe0ff3SThierry Escande 248*7cbe0ff3SThierry Escande static void nfcsim_deactivate_target(struct nfc_dev *nfc_dev, 249*7cbe0ff3SThierry Escande struct nfc_target *target) 250*7cbe0ff3SThierry Escande { 251*7cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 252*7cbe0ff3SThierry Escande 253*7cbe0ff3SThierry Escande DEV_DBG(dev, ""); 254*7cbe0ff3SThierry Escande } 255*7cbe0ff3SThierry Escande 256*7cbe0ff3SThierry Escande static void nfcsim_wq_recv(struct work_struct *work) 257*7cbe0ff3SThierry Escande { 258*7cbe0ff3SThierry Escande struct nfcsim *dev = container_of(work, struct nfcsim, 259*7cbe0ff3SThierry Escande recv_work.work); 260*7cbe0ff3SThierry Escande 261*7cbe0ff3SThierry Escande mutex_lock(&dev->lock); 262*7cbe0ff3SThierry Escande 263*7cbe0ff3SThierry Escande if (dev->shutting_down || !dev->up || !dev->clone_skb) { 264*7cbe0ff3SThierry Escande dev_kfree_skb(dev->clone_skb); 265*7cbe0ff3SThierry Escande goto exit; 266*7cbe0ff3SThierry Escande } 267*7cbe0ff3SThierry Escande 268*7cbe0ff3SThierry Escande if (dev->initiator) { 269*7cbe0ff3SThierry Escande if (!dev->cb) { 270*7cbe0ff3SThierry Escande DEV_ERR(dev, "Null recv callback"); 271*7cbe0ff3SThierry Escande dev_kfree_skb(dev->clone_skb); 272*7cbe0ff3SThierry Escande goto exit; 273*7cbe0ff3SThierry Escande } 274*7cbe0ff3SThierry Escande 275*7cbe0ff3SThierry Escande dev->cb(dev->cb_context, dev->clone_skb, 0); 276*7cbe0ff3SThierry Escande dev->cb = NULL; 277*7cbe0ff3SThierry Escande } else { 278*7cbe0ff3SThierry Escande nfc_tm_data_received(dev->nfc_dev, dev->clone_skb); 279*7cbe0ff3SThierry Escande } 280*7cbe0ff3SThierry Escande 281*7cbe0ff3SThierry Escande exit: 282*7cbe0ff3SThierry Escande dev->clone_skb = NULL; 283*7cbe0ff3SThierry Escande 284*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 285*7cbe0ff3SThierry Escande } 286*7cbe0ff3SThierry Escande 287*7cbe0ff3SThierry Escande static int nfcsim_tx(struct nfc_dev *nfc_dev, struct nfc_target *target, 288*7cbe0ff3SThierry Escande struct sk_buff *skb, data_exchange_cb_t cb, 289*7cbe0ff3SThierry Escande void *cb_context) 290*7cbe0ff3SThierry Escande { 291*7cbe0ff3SThierry Escande struct nfcsim *dev = nfc_get_drvdata(nfc_dev); 292*7cbe0ff3SThierry Escande struct nfcsim *peer = dev->peer_dev; 293*7cbe0ff3SThierry Escande int err; 294*7cbe0ff3SThierry Escande 295*7cbe0ff3SThierry Escande mutex_lock(&dev->lock); 296*7cbe0ff3SThierry Escande 297*7cbe0ff3SThierry Escande if (dev->shutting_down || !dev->up) { 298*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 299*7cbe0ff3SThierry Escande err = -ENODEV; 300*7cbe0ff3SThierry Escande goto exit; 301*7cbe0ff3SThierry Escande } 302*7cbe0ff3SThierry Escande 303*7cbe0ff3SThierry Escande dev->cb = cb; 304*7cbe0ff3SThierry Escande dev->cb_context = cb_context; 305*7cbe0ff3SThierry Escande 306*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 307*7cbe0ff3SThierry Escande 308*7cbe0ff3SThierry Escande mutex_lock(&peer->lock); 309*7cbe0ff3SThierry Escande 310*7cbe0ff3SThierry Escande peer->clone_skb = skb_clone(skb, GFP_KERNEL); 311*7cbe0ff3SThierry Escande 312*7cbe0ff3SThierry Escande if (!peer->clone_skb) { 313*7cbe0ff3SThierry Escande DEV_ERR(dev, "skb_clone failed"); 314*7cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 315*7cbe0ff3SThierry Escande err = -ENOMEM; 316*7cbe0ff3SThierry Escande goto exit; 317*7cbe0ff3SThierry Escande } 318*7cbe0ff3SThierry Escande 319*7cbe0ff3SThierry Escande /* This simulates an arbitrary transmission delay between the 2 devices. 320*7cbe0ff3SThierry Escande * If packet transmission occurs immediately between them, we have a 321*7cbe0ff3SThierry Escande * non-stop flow of several tens of thousands SYMM packets per second 322*7cbe0ff3SThierry Escande * and a burning cpu. 323*7cbe0ff3SThierry Escande * 324*7cbe0ff3SThierry Escande * TODO: Add support for a sysfs entry to control this delay. 325*7cbe0ff3SThierry Escande */ 326*7cbe0ff3SThierry Escande queue_delayed_work(wq, &peer->recv_work, msecs_to_jiffies(5)); 327*7cbe0ff3SThierry Escande 328*7cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 329*7cbe0ff3SThierry Escande 330*7cbe0ff3SThierry Escande err = 0; 331*7cbe0ff3SThierry Escande exit: 332*7cbe0ff3SThierry Escande dev_kfree_skb(skb); 333*7cbe0ff3SThierry Escande 334*7cbe0ff3SThierry Escande return err; 335*7cbe0ff3SThierry Escande } 336*7cbe0ff3SThierry Escande 337*7cbe0ff3SThierry Escande static int nfcsim_im_transceive(struct nfc_dev *nfc_dev, 338*7cbe0ff3SThierry Escande struct nfc_target *target, struct sk_buff *skb, 339*7cbe0ff3SThierry Escande data_exchange_cb_t cb, void *cb_context) 340*7cbe0ff3SThierry Escande { 341*7cbe0ff3SThierry Escande return nfcsim_tx(nfc_dev, target, skb, cb, cb_context); 342*7cbe0ff3SThierry Escande } 343*7cbe0ff3SThierry Escande 344*7cbe0ff3SThierry Escande static int nfcsim_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) 345*7cbe0ff3SThierry Escande { 346*7cbe0ff3SThierry Escande return nfcsim_tx(nfc_dev, NULL, skb, NULL, NULL); 347*7cbe0ff3SThierry Escande } 348*7cbe0ff3SThierry Escande 349*7cbe0ff3SThierry Escande static struct nfc_ops nfcsim_nfc_ops = { 350*7cbe0ff3SThierry Escande .dev_up = nfcsim_dev_up, 351*7cbe0ff3SThierry Escande .dev_down = nfcsim_dev_down, 352*7cbe0ff3SThierry Escande .dep_link_up = nfcsim_dep_link_up, 353*7cbe0ff3SThierry Escande .dep_link_down = nfcsim_dep_link_down, 354*7cbe0ff3SThierry Escande .start_poll = nfcsim_start_poll, 355*7cbe0ff3SThierry Escande .stop_poll = nfcsim_stop_poll, 356*7cbe0ff3SThierry Escande .activate_target = nfcsim_activate_target, 357*7cbe0ff3SThierry Escande .deactivate_target = nfcsim_deactivate_target, 358*7cbe0ff3SThierry Escande .im_transceive = nfcsim_im_transceive, 359*7cbe0ff3SThierry Escande .tm_send = nfcsim_tm_send, 360*7cbe0ff3SThierry Escande }; 361*7cbe0ff3SThierry Escande 362*7cbe0ff3SThierry Escande static void nfcsim_set_polling_mode(struct nfcsim *dev) 363*7cbe0ff3SThierry Escande { 364*7cbe0ff3SThierry Escande if (dev->polling_mode == NFCSIM_POLL_NONE) { 365*7cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_NONE; 366*7cbe0ff3SThierry Escande return; 367*7cbe0ff3SThierry Escande } 368*7cbe0ff3SThierry Escande 369*7cbe0ff3SThierry Escande if (dev->curr_polling_mode == NFCSIM_POLL_NONE) { 370*7cbe0ff3SThierry Escande if (dev->polling_mode & NFCSIM_POLL_INITIATOR) 371*7cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_INITIATOR; 372*7cbe0ff3SThierry Escande else 373*7cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_TARGET; 374*7cbe0ff3SThierry Escande 375*7cbe0ff3SThierry Escande return; 376*7cbe0ff3SThierry Escande } 377*7cbe0ff3SThierry Escande 378*7cbe0ff3SThierry Escande if (dev->polling_mode == NFCSIM_POLL_DUAL) { 379*7cbe0ff3SThierry Escande if (dev->curr_polling_mode == NFCSIM_POLL_TARGET) 380*7cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_INITIATOR; 381*7cbe0ff3SThierry Escande else 382*7cbe0ff3SThierry Escande dev->curr_polling_mode = NFCSIM_POLL_TARGET; 383*7cbe0ff3SThierry Escande } 384*7cbe0ff3SThierry Escande } 385*7cbe0ff3SThierry Escande 386*7cbe0ff3SThierry Escande static void nfcsim_wq_poll(struct work_struct *work) 387*7cbe0ff3SThierry Escande { 388*7cbe0ff3SThierry Escande struct nfcsim *dev = container_of(work, struct nfcsim, poll_work.work); 389*7cbe0ff3SThierry Escande struct nfcsim *peer = dev->peer_dev; 390*7cbe0ff3SThierry Escande 391*7cbe0ff3SThierry Escande /* These work items run on an ordered workqueue and are therefore 392*7cbe0ff3SThierry Escande * serialized. So we can take both mutexes without being dead locked. 393*7cbe0ff3SThierry Escande */ 394*7cbe0ff3SThierry Escande mutex_lock(&dev->lock); 395*7cbe0ff3SThierry Escande mutex_lock(&peer->lock); 396*7cbe0ff3SThierry Escande 397*7cbe0ff3SThierry Escande nfcsim_set_polling_mode(dev); 398*7cbe0ff3SThierry Escande 399*7cbe0ff3SThierry Escande if (dev->curr_polling_mode == NFCSIM_POLL_NONE) { 400*7cbe0ff3SThierry Escande DEV_DBG(dev, "Not polling"); 401*7cbe0ff3SThierry Escande goto unlock; 402*7cbe0ff3SThierry Escande } 403*7cbe0ff3SThierry Escande 404*7cbe0ff3SThierry Escande DEV_DBG(dev, "Polling as %s", 405*7cbe0ff3SThierry Escande dev->curr_polling_mode == NFCSIM_POLL_INITIATOR ? 406*7cbe0ff3SThierry Escande "initiator" : "target"); 407*7cbe0ff3SThierry Escande 408*7cbe0ff3SThierry Escande if (dev->curr_polling_mode == NFCSIM_POLL_TARGET) 409*7cbe0ff3SThierry Escande goto sched_work; 410*7cbe0ff3SThierry Escande 411*7cbe0ff3SThierry Escande if (peer->curr_polling_mode == NFCSIM_POLL_TARGET) { 412*7cbe0ff3SThierry Escande peer->polling_mode = NFCSIM_POLL_NONE; 413*7cbe0ff3SThierry Escande dev->polling_mode = NFCSIM_POLL_NONE; 414*7cbe0ff3SThierry Escande 415*7cbe0ff3SThierry Escande dev->initiator = 1; 416*7cbe0ff3SThierry Escande 417*7cbe0ff3SThierry Escande nfcsim_target_found(dev); 418*7cbe0ff3SThierry Escande 419*7cbe0ff3SThierry Escande goto unlock; 420*7cbe0ff3SThierry Escande } 421*7cbe0ff3SThierry Escande 422*7cbe0ff3SThierry Escande sched_work: 423*7cbe0ff3SThierry Escande /* This defines the delay for an initiator to check if the other device 424*7cbe0ff3SThierry Escande * is polling in target mode. 425*7cbe0ff3SThierry Escande * If the device starts in dual mode polling, it switches between 426*7cbe0ff3SThierry Escande * initiator and target at every round. 427*7cbe0ff3SThierry Escande * Because the wq is ordered and only 1 work item is executed at a time, 428*7cbe0ff3SThierry Escande * we'll always have one device polling as initiator and the other as 429*7cbe0ff3SThierry Escande * target at some point, even if both are started in dual mode. 430*7cbe0ff3SThierry Escande */ 431*7cbe0ff3SThierry Escande queue_delayed_work(wq, &dev->poll_work, msecs_to_jiffies(200)); 432*7cbe0ff3SThierry Escande 433*7cbe0ff3SThierry Escande unlock: 434*7cbe0ff3SThierry Escande mutex_unlock(&peer->lock); 435*7cbe0ff3SThierry Escande mutex_unlock(&dev->lock); 436*7cbe0ff3SThierry Escande } 437*7cbe0ff3SThierry Escande 438*7cbe0ff3SThierry Escande static struct nfcsim *nfcsim_init_dev(void) 439*7cbe0ff3SThierry Escande { 440*7cbe0ff3SThierry Escande struct nfcsim *dev; 441*7cbe0ff3SThierry Escande int rc = -ENOMEM; 442*7cbe0ff3SThierry Escande 443*7cbe0ff3SThierry Escande dev = kzalloc(sizeof(*dev), GFP_KERNEL); 444*7cbe0ff3SThierry Escande if (dev == NULL) 445*7cbe0ff3SThierry Escande return ERR_PTR(-ENOMEM); 446*7cbe0ff3SThierry Escande 447*7cbe0ff3SThierry Escande mutex_init(&dev->lock); 448*7cbe0ff3SThierry Escande 449*7cbe0ff3SThierry Escande INIT_DELAYED_WORK(&dev->recv_work, nfcsim_wq_recv); 450*7cbe0ff3SThierry Escande INIT_DELAYED_WORK(&dev->poll_work, nfcsim_wq_poll); 451*7cbe0ff3SThierry Escande 452*7cbe0ff3SThierry Escande dev->nfc_dev = nfc_allocate_device(&nfcsim_nfc_ops, 453*7cbe0ff3SThierry Escande NFC_PROTO_NFC_DEP_MASK, 454*7cbe0ff3SThierry Escande 0, 0); 455*7cbe0ff3SThierry Escande if (!dev->nfc_dev) 456*7cbe0ff3SThierry Escande goto error; 457*7cbe0ff3SThierry Escande 458*7cbe0ff3SThierry Escande nfc_set_drvdata(dev->nfc_dev, dev); 459*7cbe0ff3SThierry Escande 460*7cbe0ff3SThierry Escande rc = nfc_register_device(dev->nfc_dev); 461*7cbe0ff3SThierry Escande if (rc) 462*7cbe0ff3SThierry Escande goto free_nfc_dev; 463*7cbe0ff3SThierry Escande 464*7cbe0ff3SThierry Escande return dev; 465*7cbe0ff3SThierry Escande 466*7cbe0ff3SThierry Escande free_nfc_dev: 467*7cbe0ff3SThierry Escande nfc_free_device(dev->nfc_dev); 468*7cbe0ff3SThierry Escande 469*7cbe0ff3SThierry Escande error: 470*7cbe0ff3SThierry Escande kfree(dev); 471*7cbe0ff3SThierry Escande 472*7cbe0ff3SThierry Escande return ERR_PTR(rc); 473*7cbe0ff3SThierry Escande } 474*7cbe0ff3SThierry Escande 475*7cbe0ff3SThierry Escande static void nfcsim_free_device(struct nfcsim *dev) 476*7cbe0ff3SThierry Escande { 477*7cbe0ff3SThierry Escande nfc_unregister_device(dev->nfc_dev); 478*7cbe0ff3SThierry Escande 479*7cbe0ff3SThierry Escande nfc_free_device(dev->nfc_dev); 480*7cbe0ff3SThierry Escande 481*7cbe0ff3SThierry Escande kfree(dev); 482*7cbe0ff3SThierry Escande } 483*7cbe0ff3SThierry Escande 484*7cbe0ff3SThierry Escande int __init nfcsim_init(void) 485*7cbe0ff3SThierry Escande { 486*7cbe0ff3SThierry Escande int rc; 487*7cbe0ff3SThierry Escande 488*7cbe0ff3SThierry Escande /* We need an ordered wq to ensure that poll_work items are executed 489*7cbe0ff3SThierry Escande * one at a time. 490*7cbe0ff3SThierry Escande */ 491*7cbe0ff3SThierry Escande wq = alloc_ordered_workqueue("nfcsim", 0); 492*7cbe0ff3SThierry Escande if (!wq) { 493*7cbe0ff3SThierry Escande rc = -ENOMEM; 494*7cbe0ff3SThierry Escande goto exit; 495*7cbe0ff3SThierry Escande } 496*7cbe0ff3SThierry Escande 497*7cbe0ff3SThierry Escande dev0 = nfcsim_init_dev(); 498*7cbe0ff3SThierry Escande if (IS_ERR(dev0)) { 499*7cbe0ff3SThierry Escande rc = PTR_ERR(dev0); 500*7cbe0ff3SThierry Escande goto exit; 501*7cbe0ff3SThierry Escande } 502*7cbe0ff3SThierry Escande 503*7cbe0ff3SThierry Escande dev1 = nfcsim_init_dev(); 504*7cbe0ff3SThierry Escande if (IS_ERR(dev1)) { 505*7cbe0ff3SThierry Escande kfree(dev0); 506*7cbe0ff3SThierry Escande 507*7cbe0ff3SThierry Escande rc = PTR_ERR(dev1); 508*7cbe0ff3SThierry Escande goto exit; 509*7cbe0ff3SThierry Escande } 510*7cbe0ff3SThierry Escande 511*7cbe0ff3SThierry Escande dev0->peer_dev = dev1; 512*7cbe0ff3SThierry Escande dev1->peer_dev = dev0; 513*7cbe0ff3SThierry Escande 514*7cbe0ff3SThierry Escande pr_debug("NFCsim " NFCSIM_VERSION " initialized\n"); 515*7cbe0ff3SThierry Escande 516*7cbe0ff3SThierry Escande rc = 0; 517*7cbe0ff3SThierry Escande exit: 518*7cbe0ff3SThierry Escande if (rc) 519*7cbe0ff3SThierry Escande pr_err("Failed to initialize nfcsim driver (%d)\n", 520*7cbe0ff3SThierry Escande rc); 521*7cbe0ff3SThierry Escande 522*7cbe0ff3SThierry Escande return rc; 523*7cbe0ff3SThierry Escande } 524*7cbe0ff3SThierry Escande 525*7cbe0ff3SThierry Escande void __exit nfcsim_exit(void) 526*7cbe0ff3SThierry Escande { 527*7cbe0ff3SThierry Escande nfcsim_cleanup_dev(dev0, 1); 528*7cbe0ff3SThierry Escande nfcsim_cleanup_dev(dev1, 1); 529*7cbe0ff3SThierry Escande 530*7cbe0ff3SThierry Escande nfcsim_free_device(dev0); 531*7cbe0ff3SThierry Escande nfcsim_free_device(dev1); 532*7cbe0ff3SThierry Escande 533*7cbe0ff3SThierry Escande destroy_workqueue(wq); 534*7cbe0ff3SThierry Escande } 535*7cbe0ff3SThierry Escande 536*7cbe0ff3SThierry Escande module_init(nfcsim_init); 537*7cbe0ff3SThierry Escande module_exit(nfcsim_exit); 538*7cbe0ff3SThierry Escande 539*7cbe0ff3SThierry Escande MODULE_DESCRIPTION("NFCSim driver ver " NFCSIM_VERSION); 540*7cbe0ff3SThierry Escande MODULE_VERSION(NFCSIM_VERSION); 541*7cbe0ff3SThierry Escande MODULE_LICENSE("GPL"); 542