Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * NFC hardware simulation driver
0004  * Copyright (c) 2013, Intel Corporation.
0005  */
0006 
0007 #include <linux/device.h>
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/ctype.h>
0011 #include <linux/debugfs.h>
0012 #include <linux/nfc.h>
0013 #include <net/nfc/nfc.h>
0014 #include <net/nfc/digital.h>
0015 
0016 #define NFCSIM_ERR(d, fmt, args...) nfc_err(&d->nfc_digital_dev->nfc_dev->dev, \
0017                         "%s: " fmt, __func__, ## args)
0018 
0019 #define NFCSIM_DBG(d, fmt, args...) dev_dbg(&d->nfc_digital_dev->nfc_dev->dev, \
0020                         "%s: " fmt, __func__, ## args)
0021 
0022 #define NFCSIM_VERSION "0.2"
0023 
0024 #define NFCSIM_MODE_NONE    0
0025 #define NFCSIM_MODE_INITIATOR   1
0026 #define NFCSIM_MODE_TARGET  2
0027 
0028 #define NFCSIM_CAPABILITIES (NFC_DIGITAL_DRV_CAPS_IN_CRC   | \
0029                  NFC_DIGITAL_DRV_CAPS_TG_CRC)
0030 
0031 struct nfcsim {
0032     struct nfc_digital_dev *nfc_digital_dev;
0033 
0034     struct work_struct recv_work;
0035     struct delayed_work send_work;
0036 
0037     struct nfcsim_link *link_in;
0038     struct nfcsim_link *link_out;
0039 
0040     bool up;
0041     u8 mode;
0042     u8 rf_tech;
0043 
0044     u16 recv_timeout;
0045 
0046     nfc_digital_cmd_complete_t cb;
0047     void *arg;
0048 
0049     u8 dropframe;
0050 };
0051 
0052 struct nfcsim_link {
0053     struct mutex lock;
0054 
0055     u8 rf_tech;
0056     u8 mode;
0057 
0058     u8 shutdown;
0059 
0060     struct sk_buff *skb;
0061     wait_queue_head_t recv_wait;
0062     u8 cond;
0063 };
0064 
0065 static struct nfcsim_link *nfcsim_link_new(void)
0066 {
0067     struct nfcsim_link *link;
0068 
0069     link = kzalloc(sizeof(struct nfcsim_link), GFP_KERNEL);
0070     if (!link)
0071         return NULL;
0072 
0073     mutex_init(&link->lock);
0074     init_waitqueue_head(&link->recv_wait);
0075 
0076     return link;
0077 }
0078 
0079 static void nfcsim_link_free(struct nfcsim_link *link)
0080 {
0081     dev_kfree_skb(link->skb);
0082     kfree(link);
0083 }
0084 
0085 static void nfcsim_link_recv_wake(struct nfcsim_link *link)
0086 {
0087     link->cond = 1;
0088     wake_up_interruptible(&link->recv_wait);
0089 }
0090 
0091 static void nfcsim_link_set_skb(struct nfcsim_link *link, struct sk_buff *skb,
0092                 u8 rf_tech, u8 mode)
0093 {
0094     mutex_lock(&link->lock);
0095 
0096     dev_kfree_skb(link->skb);
0097     link->skb = skb;
0098     link->rf_tech = rf_tech;
0099     link->mode = mode;
0100 
0101     mutex_unlock(&link->lock);
0102 }
0103 
0104 static void nfcsim_link_recv_cancel(struct nfcsim_link *link)
0105 {
0106     mutex_lock(&link->lock);
0107 
0108     link->mode = NFCSIM_MODE_NONE;
0109 
0110     mutex_unlock(&link->lock);
0111 
0112     nfcsim_link_recv_wake(link);
0113 }
0114 
0115 static void nfcsim_link_shutdown(struct nfcsim_link *link)
0116 {
0117     mutex_lock(&link->lock);
0118 
0119     link->shutdown = 1;
0120     link->mode = NFCSIM_MODE_NONE;
0121 
0122     mutex_unlock(&link->lock);
0123 
0124     nfcsim_link_recv_wake(link);
0125 }
0126 
0127 static struct sk_buff *nfcsim_link_recv_skb(struct nfcsim_link *link,
0128                         int timeout, u8 rf_tech, u8 mode)
0129 {
0130     int rc;
0131     struct sk_buff *skb;
0132 
0133     rc = wait_event_interruptible_timeout(link->recv_wait,
0134                           link->cond,
0135                           msecs_to_jiffies(timeout));
0136 
0137     mutex_lock(&link->lock);
0138 
0139     skb = link->skb;
0140     link->skb = NULL;
0141 
0142     if (!rc) {
0143         rc = -ETIMEDOUT;
0144         goto done;
0145     }
0146 
0147     if (!skb || link->rf_tech != rf_tech || link->mode == mode) {
0148         rc = -EINVAL;
0149         goto done;
0150     }
0151 
0152     if (link->shutdown) {
0153         rc = -ENODEV;
0154         goto done;
0155     }
0156 
0157 done:
0158     mutex_unlock(&link->lock);
0159 
0160     if (rc < 0) {
0161         dev_kfree_skb(skb);
0162         skb = ERR_PTR(rc);
0163     }
0164 
0165     link->cond = 0;
0166 
0167     return skb;
0168 }
0169 
0170 static void nfcsim_send_wq(struct work_struct *work)
0171 {
0172     struct nfcsim *dev = container_of(work, struct nfcsim, send_work.work);
0173 
0174     /*
0175      * To effectively send data, the device just wake up its link_out which
0176      * is the link_in of the peer device. The exchanged skb has already been
0177      * stored in the dev->link_out through nfcsim_link_set_skb().
0178      */
0179     nfcsim_link_recv_wake(dev->link_out);
0180 }
0181 
0182 static void nfcsim_recv_wq(struct work_struct *work)
0183 {
0184     struct nfcsim *dev = container_of(work, struct nfcsim, recv_work);
0185     struct sk_buff *skb;
0186 
0187     skb = nfcsim_link_recv_skb(dev->link_in, dev->recv_timeout,
0188                    dev->rf_tech, dev->mode);
0189 
0190     if (!dev->up) {
0191         NFCSIM_ERR(dev, "Device is down\n");
0192 
0193         if (!IS_ERR(skb))
0194             dev_kfree_skb(skb);
0195         return;
0196     }
0197 
0198     dev->cb(dev->nfc_digital_dev, dev->arg, skb);
0199 }
0200 
0201 static int nfcsim_send(struct nfc_digital_dev *ddev, struct sk_buff *skb,
0202                u16 timeout, nfc_digital_cmd_complete_t cb, void *arg)
0203 {
0204     struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
0205     u8 delay;
0206 
0207     if (!dev->up) {
0208         NFCSIM_ERR(dev, "Device is down\n");
0209         return -ENODEV;
0210     }
0211 
0212     dev->recv_timeout = timeout;
0213     dev->cb = cb;
0214     dev->arg = arg;
0215 
0216     schedule_work(&dev->recv_work);
0217 
0218     if (dev->dropframe) {
0219         NFCSIM_DBG(dev, "dropping frame (out of %d)\n", dev->dropframe);
0220         dev_kfree_skb(skb);
0221         dev->dropframe--;
0222 
0223         return 0;
0224     }
0225 
0226     if (skb) {
0227         nfcsim_link_set_skb(dev->link_out, skb, dev->rf_tech,
0228                     dev->mode);
0229 
0230         /* Add random delay (between 3 and 10 ms) before sending data */
0231         get_random_bytes(&delay, 1);
0232         delay = 3 + (delay & 0x07);
0233 
0234         schedule_delayed_work(&dev->send_work, msecs_to_jiffies(delay));
0235     }
0236 
0237     return 0;
0238 }
0239 
0240 static void nfcsim_abort_cmd(struct nfc_digital_dev *ddev)
0241 {
0242     const struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
0243 
0244     nfcsim_link_recv_cancel(dev->link_in);
0245 }
0246 
0247 static int nfcsim_switch_rf(struct nfc_digital_dev *ddev, bool on)
0248 {
0249     struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
0250 
0251     dev->up = on;
0252 
0253     return 0;
0254 }
0255 
0256 static int nfcsim_in_configure_hw(struct nfc_digital_dev *ddev,
0257                       int type, int param)
0258 {
0259     struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
0260 
0261     switch (type) {
0262     case NFC_DIGITAL_CONFIG_RF_TECH:
0263         dev->up = true;
0264         dev->mode = NFCSIM_MODE_INITIATOR;
0265         dev->rf_tech = param;
0266         break;
0267 
0268     case NFC_DIGITAL_CONFIG_FRAMING:
0269         break;
0270 
0271     default:
0272         NFCSIM_ERR(dev, "Invalid configuration type: %d\n", type);
0273         return -EINVAL;
0274     }
0275 
0276     return 0;
0277 }
0278 
0279 static int nfcsim_in_send_cmd(struct nfc_digital_dev *ddev,
0280                    struct sk_buff *skb, u16 timeout,
0281                    nfc_digital_cmd_complete_t cb, void *arg)
0282 {
0283     return nfcsim_send(ddev, skb, timeout, cb, arg);
0284 }
0285 
0286 static int nfcsim_tg_configure_hw(struct nfc_digital_dev *ddev,
0287                       int type, int param)
0288 {
0289     struct nfcsim *dev = nfc_digital_get_drvdata(ddev);
0290 
0291     switch (type) {
0292     case NFC_DIGITAL_CONFIG_RF_TECH:
0293         dev->up = true;
0294         dev->mode = NFCSIM_MODE_TARGET;
0295         dev->rf_tech = param;
0296         break;
0297 
0298     case NFC_DIGITAL_CONFIG_FRAMING:
0299         break;
0300 
0301     default:
0302         NFCSIM_ERR(dev, "Invalid configuration type: %d\n", type);
0303         return -EINVAL;
0304     }
0305 
0306     return 0;
0307 }
0308 
0309 static int nfcsim_tg_send_cmd(struct nfc_digital_dev *ddev,
0310                    struct sk_buff *skb, u16 timeout,
0311                    nfc_digital_cmd_complete_t cb, void *arg)
0312 {
0313     return nfcsim_send(ddev, skb, timeout, cb, arg);
0314 }
0315 
0316 static int nfcsim_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
0317                 nfc_digital_cmd_complete_t cb, void *arg)
0318 {
0319     return nfcsim_send(ddev, NULL, timeout, cb, arg);
0320 }
0321 
0322 static const struct nfc_digital_ops nfcsim_digital_ops = {
0323     .in_configure_hw = nfcsim_in_configure_hw,
0324     .in_send_cmd = nfcsim_in_send_cmd,
0325 
0326     .tg_listen = nfcsim_tg_listen,
0327     .tg_configure_hw = nfcsim_tg_configure_hw,
0328     .tg_send_cmd = nfcsim_tg_send_cmd,
0329 
0330     .abort_cmd = nfcsim_abort_cmd,
0331     .switch_rf = nfcsim_switch_rf,
0332 };
0333 
0334 static struct dentry *nfcsim_debugfs_root;
0335 
0336 static void nfcsim_debugfs_init(void)
0337 {
0338     nfcsim_debugfs_root = debugfs_create_dir("nfcsim", NULL);
0339 
0340     if (!nfcsim_debugfs_root)
0341         pr_err("Could not create debugfs entry\n");
0342 
0343 }
0344 
0345 static void nfcsim_debugfs_remove(void)
0346 {
0347     debugfs_remove_recursive(nfcsim_debugfs_root);
0348 }
0349 
0350 static void nfcsim_debugfs_init_dev(struct nfcsim *dev)
0351 {
0352     struct dentry *dev_dir;
0353     char devname[5]; /* nfcX\0 */
0354     u32 idx;
0355     int n;
0356 
0357     if (!nfcsim_debugfs_root) {
0358         NFCSIM_ERR(dev, "nfcsim debugfs not initialized\n");
0359         return;
0360     }
0361 
0362     idx = dev->nfc_digital_dev->nfc_dev->idx;
0363     n = snprintf(devname, sizeof(devname), "nfc%d", idx);
0364     if (n >= sizeof(devname)) {
0365         NFCSIM_ERR(dev, "Could not compute dev name for dev %d\n", idx);
0366         return;
0367     }
0368 
0369     dev_dir = debugfs_create_dir(devname, nfcsim_debugfs_root);
0370     if (!dev_dir) {
0371         NFCSIM_ERR(dev, "Could not create debugfs entries for nfc%d\n",
0372                idx);
0373         return;
0374     }
0375 
0376     debugfs_create_u8("dropframe", 0664, dev_dir, &dev->dropframe);
0377 }
0378 
0379 static struct nfcsim *nfcsim_device_new(struct nfcsim_link *link_in,
0380                     struct nfcsim_link *link_out)
0381 {
0382     struct nfcsim *dev;
0383     int rc;
0384 
0385     dev = kzalloc(sizeof(struct nfcsim), GFP_KERNEL);
0386     if (!dev)
0387         return ERR_PTR(-ENOMEM);
0388 
0389     INIT_DELAYED_WORK(&dev->send_work, nfcsim_send_wq);
0390     INIT_WORK(&dev->recv_work, nfcsim_recv_wq);
0391 
0392     dev->nfc_digital_dev =
0393             nfc_digital_allocate_device(&nfcsim_digital_ops,
0394                             NFC_PROTO_NFC_DEP_MASK,
0395                             NFCSIM_CAPABILITIES,
0396                             0, 0);
0397     if (!dev->nfc_digital_dev) {
0398         kfree(dev);
0399         return ERR_PTR(-ENOMEM);
0400     }
0401 
0402     nfc_digital_set_drvdata(dev->nfc_digital_dev, dev);
0403 
0404     dev->link_in = link_in;
0405     dev->link_out = link_out;
0406 
0407     rc = nfc_digital_register_device(dev->nfc_digital_dev);
0408     if (rc) {
0409         pr_err("Could not register digital device (%d)\n", rc);
0410         nfc_digital_free_device(dev->nfc_digital_dev);
0411         kfree(dev);
0412 
0413         return ERR_PTR(rc);
0414     }
0415 
0416     nfcsim_debugfs_init_dev(dev);
0417 
0418     return dev;
0419 }
0420 
0421 static void nfcsim_device_free(struct nfcsim *dev)
0422 {
0423     nfc_digital_unregister_device(dev->nfc_digital_dev);
0424 
0425     dev->up = false;
0426 
0427     nfcsim_link_shutdown(dev->link_in);
0428 
0429     cancel_delayed_work_sync(&dev->send_work);
0430     cancel_work_sync(&dev->recv_work);
0431 
0432     nfc_digital_free_device(dev->nfc_digital_dev);
0433 
0434     kfree(dev);
0435 }
0436 
0437 static struct nfcsim *dev0;
0438 static struct nfcsim *dev1;
0439 
0440 static int __init nfcsim_init(void)
0441 {
0442     struct nfcsim_link *link0, *link1;
0443     int rc;
0444 
0445     link0 = nfcsim_link_new();
0446     link1 = nfcsim_link_new();
0447     if (!link0 || !link1) {
0448         rc = -ENOMEM;
0449         goto exit_err;
0450     }
0451 
0452     nfcsim_debugfs_init();
0453 
0454     dev0 = nfcsim_device_new(link0, link1);
0455     if (IS_ERR(dev0)) {
0456         rc = PTR_ERR(dev0);
0457         goto exit_err;
0458     }
0459 
0460     dev1 = nfcsim_device_new(link1, link0);
0461     if (IS_ERR(dev1)) {
0462         nfcsim_device_free(dev0);
0463 
0464         rc = PTR_ERR(dev1);
0465         goto exit_err;
0466     }
0467 
0468     pr_info("nfcsim " NFCSIM_VERSION " initialized\n");
0469 
0470     return 0;
0471 
0472 exit_err:
0473     pr_err("Failed to initialize nfcsim driver (%d)\n", rc);
0474 
0475     if (link0)
0476         nfcsim_link_free(link0);
0477     if (link1)
0478         nfcsim_link_free(link1);
0479 
0480     return rc;
0481 }
0482 
0483 static void __exit nfcsim_exit(void)
0484 {
0485     struct nfcsim_link *link0, *link1;
0486 
0487     link0 = dev0->link_in;
0488     link1 = dev0->link_out;
0489 
0490     nfcsim_device_free(dev0);
0491     nfcsim_device_free(dev1);
0492 
0493     nfcsim_link_free(link0);
0494     nfcsim_link_free(link1);
0495 
0496     nfcsim_debugfs_remove();
0497 }
0498 
0499 module_init(nfcsim_init);
0500 module_exit(nfcsim_exit);
0501 
0502 MODULE_DESCRIPTION("NFCSim driver ver " NFCSIM_VERSION);
0503 MODULE_VERSION(NFCSIM_VERSION);
0504 MODULE_LICENSE("GPL");