Re: [PATCH net-next] nfc: Add a virtual nci device driver
by Bongsu Jeon
On Tue, Dec 29, 2020 at 6:16 AM Jakub Kicinski <kuba(a)kernel.org> wrote:
>
> On Mon, 28 Dec 2020 18:45:07 +0900 Bongsu Jeon wrote:
> > From: Bongsu Jeon <bongsu.jeon(a)samsung.com>
> >
> > A NCI virtual device can be made to simulate a NCI device in user space.
> > Using the virtual NCI device, The NCI module and application can be
> > validated. This driver supports to communicate between the virtual NCI
> > device and NCI module.
> >
> > Signed-off-by: Bongsu Jeon <bongsu.jeon(a)samsung.com>
>
> net-next is still closed:
>
> http://vger.kernel.org/~davem/net-next.html
>
> Please repost in a few days.
>
> As far as the patch goes - please include some tests for the NCI/NFC
> subsystem based on this virtual device, best if they live in tree under
> tools/testing/selftest.
thank you for your answer.
I think that neard(NFC deamon) is necessary to test the NCI subsystem
meaningfully.
The NCI virtual device in user space can communicate with neard
through this driver.
Is it enough to make NCI virtual device at tools/nfc for some test?
1 year, 5 months
[PATCH net-next v2] net: nfc: nci: Change the NCI close sequence
by Bongsu Jeon
From: Bongsu Jeon <bongsu.jeon(a)samsung.com>
If there is a NCI command in work queue after closing the NCI device at
nci_unregister_device, The NCI command timer starts at flush_workqueue
function and then NCI command timeout handler would be called 5 second
after flushing the NCI command work queue and destroying the queue.
At that time, the timeout handler would try to use NCI command work queue
that is destroyed already. it will causes the problem. To avoid this
abnormal situation, change the sequence to prevent the NCI command timeout
handler from being called after destroying the NCI command work queue.
Signed-off-by: Bongsu Jeon <bongsu.jeon(a)samsung.com>
---
Changes in v2:
- Change the commit message.
net/nfc/nci/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index e64727e1a72f..79bebf4b0796 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -579,11 +579,11 @@ static int nci_close_device(struct nci_dev *ndev)
clear_bit(NCI_INIT, &ndev->flags);
- del_timer_sync(&ndev->cmd_timer);
-
/* Flush cmd wq */
flush_workqueue(ndev->cmd_wq);
+ del_timer_sync(&ndev->cmd_timer);
+
/* Clear flags */
ndev->flags = 0;
--
2.17.1
1 year, 5 months
[PATCH net-next] nfc: Add a virtual nci device driver
by Bongsu Jeon
From: Bongsu Jeon <bongsu.jeon(a)samsung.com>
A NCI virtual device can be made to simulate a NCI device in user space.
Using the virtual NCI device, The NCI module and application can be
validated. This driver supports to communicate between the virtual NCI
device and NCI module.
Signed-off-by: Bongsu Jeon <bongsu.jeon(a)samsung.com>
---
MAINTAINERS | 7 ++
drivers/nfc/Kconfig | 11 ++
drivers/nfc/Makefile | 1 +
drivers/nfc/virtual_ncidev.c | 216 +++++++++++++++++++++++++++++++++++
4 files changed, 235 insertions(+)
create mode 100644 drivers/nfc/virtual_ncidev.c
diff --git a/MAINTAINERS b/MAINTAINERS
index a355db292486..6479a4754a1e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12431,6 +12431,13 @@ F: include/net/nfc/
F: include/uapi/linux/nfc.h
F: net/nfc/
+NFC VIRTUAL NCI DEVICE DRIVER
+M: Bongsu Jeon <bongsu.jeon(a)samsung.com>
+L: netdev(a)vger.kernel.org
+L: linux-nfc(a)lists.01.org (moderated for non-subscribers)
+S: Supported
+F: drivers/nfc/virtual_ncidev.c
+
NFS, SUNRPC, AND LOCKD CLIENTS
M: Trond Myklebust <trond.myklebust(a)hammerspace.com>
M: Anna Schumaker <anna.schumaker(a)netapp.com>
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 75c65d339018..d32c3a8937ed 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -49,6 +49,17 @@ config NFC_PORT100
If unsure, say N.
+config NFC_VIRTUAL_NCI
+ tristate "NCI device simulator driver"
+ depends on NFC_NCI
+ help
+ A NCI virtual device can be made to simulate a NCI device in user
+ level. Using the virtual NCI device, The NCI module and application
+ can be validated. This driver supports to communicate between the
+ virtual NCI device and NCI module.
+
+ If unsure, say N.
+
source "drivers/nfc/fdp/Kconfig"
source "drivers/nfc/pn544/Kconfig"
source "drivers/nfc/pn533/Kconfig"
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index 5393ba59b17d..7b1bfde1d971 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_NFC_ST_NCI) += st-nci/
obj-$(CONFIG_NFC_NXP_NCI) += nxp-nci/
obj-$(CONFIG_NFC_S3FWRN5) += s3fwrn5/
obj-$(CONFIG_NFC_ST95HF) += st95hf/
+obj-$(CONFIG_NFC_VIRTUAL_NCI) += virtual_ncidev.o
diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c
new file mode 100644
index 000000000000..163d0b2dda2e
--- /dev/null
+++ b/drivers/nfc/virtual_ncidev.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Virtual NCI device simulation driver
+ *
+ * Copyright (C) 2020 Samsung Electrnoics
+ * Bongsu Jeon <bongsu.jeon(a)samsung.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/mutex.h>
+#include <net/nfc/nci_core.h>
+
+enum virtual_ncidev_mode {
+ virtual_ncidev_enabled,
+ virtual_ncidev_disabled,
+ virtual_ncidev_disabling,
+};
+
+#define VIRTUAL_NFC_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
+ NFC_PROTO_MIFARE_MASK | \
+ NFC_PROTO_FELICA_MASK | \
+ NFC_PROTO_ISO14443_MASK | \
+ NFC_PROTO_ISO14443_B_MASK | \
+ NFC_PROTO_ISO15693_MASK)
+
+static enum virtual_ncidev_mode state;
+static struct mutex nci_send_mutex;
+static struct miscdevice miscdev;
+static struct sk_buff *send_buff;
+static struct mutex nci_mutex;
+static struct nci_dev *ndev;
+static bool full_txbuff;
+
+static bool virtual_ncidev_check_enabled(void)
+{
+ bool ret = true;
+
+ mutex_lock(&nci_mutex);
+ if (state != virtual_ncidev_enabled)
+ ret = false;
+ mutex_unlock(&nci_mutex);
+
+ return ret;
+}
+
+static int virtual_nci_open(struct nci_dev *ndev)
+{
+ return 0;
+}
+
+static int virtual_nci_close(struct nci_dev *ndev)
+{
+ mutex_lock(&nci_send_mutex);
+ if (full_txbuff)
+ kfree_skb(send_buff);
+ full_txbuff = false;
+ mutex_unlock(&nci_send_mutex);
+
+ return 0;
+}
+
+static int virtual_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+{
+ if (virtual_ncidev_check_enabled() == false)
+ return 0;
+
+ mutex_lock(&nci_send_mutex);
+ if (full_txbuff) {
+ mutex_unlock(&nci_send_mutex);
+ return -1;
+ }
+ send_buff = skb_copy(skb, GFP_KERNEL);
+ full_txbuff = true;
+ mutex_unlock(&nci_send_mutex);
+
+ return 0;
+}
+
+static struct nci_ops virtual_nci_ops = {
+ .open = virtual_nci_open,
+ .close = virtual_nci_close,
+ .send = virtual_nci_send
+};
+
+static ssize_t virtual_ncidev_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ size_t actual_len;
+
+ mutex_lock(&nci_send_mutex);
+ if (!full_txbuff) {
+ mutex_unlock(&nci_send_mutex);
+ return 0;
+ }
+
+ actual_len = count > send_buff->len ? send_buff->len : count;
+
+ if (copy_to_user(buf, send_buff->data, actual_len)) {
+ mutex_unlock(&nci_send_mutex);
+ return -EFAULT;
+ }
+
+ skb_pull(send_buff, actual_len);
+ if (send_buff->len == 0) {
+ kfree_skb(send_buff);
+ full_txbuff = false;
+ }
+ mutex_unlock(&nci_send_mutex);
+
+ return actual_len;
+}
+
+static ssize_t virtual_ncidev_write(struct file *file,
+ const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct sk_buff *skb;
+
+ skb = alloc_skb(count, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ if (copy_from_user(skb_put(skb, count), buf, count))
+ return -EFAULT;
+
+ nci_recv_frame(ndev, skb);
+
+ return count;
+}
+
+static int virtual_ncidev_open(struct inode *inode, struct file *file)
+{
+ int ret = 0;
+
+ mutex_lock(&nci_mutex);
+ if (state != virtual_ncidev_disabled) {
+ mutex_unlock(&nci_mutex);
+ return -EBUSY;
+ }
+
+ mutex_init(&nci_send_mutex);
+
+ ndev = nci_allocate_device(&virtual_nci_ops, VIRTUAL_NFC_PROTOCOLS,
+ 0, 0);
+ if (!ndev) {
+ mutex_unlock(&nci_mutex);
+ return -ENOMEM;
+ }
+
+ ret = nci_register_device(ndev);
+ if (ret < 0) {
+ nci_free_device(ndev);
+ mutex_unlock(&nci_mutex);
+ return ret;
+ }
+ state = virtual_ncidev_enabled;
+ mutex_unlock(&nci_mutex);
+
+ return 0;
+}
+
+static int virtual_ncidev_close(struct inode *inode, struct file *file)
+{
+ mutex_lock(&nci_mutex);
+
+ if (state == virtual_ncidev_enabled) {
+ state = virtual_ncidev_disabling;
+ mutex_unlock(&nci_mutex);
+
+ nci_unregister_device(ndev);
+ nci_free_device(ndev);
+
+ mutex_lock(&nci_mutex);
+ }
+
+ state = virtual_ncidev_disabled;
+ mutex_unlock(&nci_mutex);
+
+ return 0;
+}
+
+static const struct file_operations virtual_ncidev_fops = {
+ .owner = THIS_MODULE,
+ .read = virtual_ncidev_read,
+ .write = virtual_ncidev_write,
+ .open = virtual_ncidev_open,
+ .release = virtual_ncidev_close,
+};
+
+static int __init virtual_ncidev_init(void)
+{
+ int ret;
+
+ mutex_init(&nci_mutex);
+ state = virtual_ncidev_disabled;
+ miscdev.minor = MISC_DYNAMIC_MINOR;
+ miscdev.name = "virtual_nci";
+ miscdev.fops = &virtual_ncidev_fops;
+ ret = misc_register(&miscdev);
+
+ return ret;
+}
+
+static void __exit virtual_ncidev_exit(void)
+{
+ misc_deregister(&miscdev);
+}
+
+module_init(virtual_ncidev_init);
+module_exit(virtual_ncidev_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Virtual NCI device simulation driver");
+MODULE_AUTHOR("Bongsu Jeon <bongsu.jeon(a)samsung.com>");
--
2.17.1
1 year, 5 months
[PATCH net-next] net: nfc: nci: Change the NCI close sequence
by Bongsu Jeon
From: Bongsu Jeon <bongsu.jeon(a)samsung.com>
Change the NCI close sequence because the NCI Command timer should be
deleted after flushing the NCI command work queue.
Signed-off-by: Bongsu Jeon <bongsu.jeon(a)samsung.com>
---
net/nfc/nci/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index e64727e1a72f..79bebf4b0796 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -579,11 +579,11 @@ static int nci_close_device(struct nci_dev *ndev)
clear_bit(NCI_INIT, &ndev->flags);
- del_timer_sync(&ndev->cmd_timer);
-
/* Flush cmd wq */
flush_workqueue(ndev->cmd_wq);
+ del_timer_sync(&ndev->cmd_timer);
+
/* Clear flags */
ndev->flags = 0;
--
2.17.1
1 year, 5 months
[PATCH v2 net-next 0/2] nfc: s3fwrn5: Refactor the s3fwrn5 module
by Bongsu Jeon
From: Bongsu Jeon <bongsu.jeon(a)samsung.com>
Refactor the s3fwrn5 module.
1/2 is to remove the unneeded delay for NFC sleep.
2/2 is to remove the unused NCI prop commands.
ChangeLog:
v2:
- Update the commit messages.
Bongsu Jeon (2):
nfc: s3fwrn5: Remove the delay for NFC sleep
nfc: s3fwrn5: Remove unused NCI prop commands
drivers/nfc/s3fwrn5/nci.c | 25 -------------------------
drivers/nfc/s3fwrn5/nci.h | 22 ----------------------
drivers/nfc/s3fwrn5/phy_common.c | 3 ++-
3 files changed, 2 insertions(+), 48 deletions(-)
--
2.17.1
1 year, 6 months
[PATCH net-next] nfc: s3fwrn5: Remove unused nci prop commands
by Bongsu Jeon
From: Bongsu Jeon <bongsu.jeon(a)samsung.com>
remove the unused nci prop commands that samsung driver doesn't use.
Signed-off-by: Bongsu Jeon <bongsu.jeon(a)samsung.com>
---
drivers/nfc/s3fwrn5/nci.c | 25 -------------------------
drivers/nfc/s3fwrn5/nci.h | 22 ----------------------
2 files changed, 47 deletions(-)
diff --git a/drivers/nfc/s3fwrn5/nci.c b/drivers/nfc/s3fwrn5/nci.c
index 103bf5c92bdc..f042d3eaf8f6 100644
--- a/drivers/nfc/s3fwrn5/nci.c
+++ b/drivers/nfc/s3fwrn5/nci.c
@@ -21,31 +21,11 @@ static int s3fwrn5_nci_prop_rsp(struct nci_dev *ndev, struct sk_buff *skb)
}
static struct nci_driver_ops s3fwrn5_nci_prop_ops[] = {
- {
- .opcode = nci_opcode_pack(NCI_GID_PROPRIETARY,
- NCI_PROP_AGAIN),
- .rsp = s3fwrn5_nci_prop_rsp,
- },
- {
- .opcode = nci_opcode_pack(NCI_GID_PROPRIETARY,
- NCI_PROP_GET_RFREG),
- .rsp = s3fwrn5_nci_prop_rsp,
- },
{
.opcode = nci_opcode_pack(NCI_GID_PROPRIETARY,
NCI_PROP_SET_RFREG),
.rsp = s3fwrn5_nci_prop_rsp,
},
- {
- .opcode = nci_opcode_pack(NCI_GID_PROPRIETARY,
- NCI_PROP_GET_RFREG_VER),
- .rsp = s3fwrn5_nci_prop_rsp,
- },
- {
- .opcode = nci_opcode_pack(NCI_GID_PROPRIETARY,
- NCI_PROP_SET_RFREG_VER),
- .rsp = s3fwrn5_nci_prop_rsp,
- },
{
.opcode = nci_opcode_pack(NCI_GID_PROPRIETARY,
NCI_PROP_START_RFREG),
@@ -61,11 +41,6 @@ static struct nci_driver_ops s3fwrn5_nci_prop_ops[] = {
NCI_PROP_FW_CFG),
.rsp = s3fwrn5_nci_prop_rsp,
},
- {
- .opcode = nci_opcode_pack(NCI_GID_PROPRIETARY,
- NCI_PROP_WR_RESET),
- .rsp = s3fwrn5_nci_prop_rsp,
- },
};
void s3fwrn5_nci_get_prop_ops(struct nci_driver_ops **ops, size_t *n)
diff --git a/drivers/nfc/s3fwrn5/nci.h b/drivers/nfc/s3fwrn5/nci.h
index 23c0b28f247a..a80f0fb082a8 100644
--- a/drivers/nfc/s3fwrn5/nci.h
+++ b/drivers/nfc/s3fwrn5/nci.h
@@ -11,9 +11,6 @@
#include "s3fwrn5.h"
-#define NCI_PROP_AGAIN 0x01
-
-#define NCI_PROP_GET_RFREG 0x21
#define NCI_PROP_SET_RFREG 0x22
struct nci_prop_set_rfreg_cmd {
@@ -25,23 +22,6 @@ struct nci_prop_set_rfreg_rsp {
__u8 status;
};
-#define NCI_PROP_GET_RFREG_VER 0x24
-
-struct nci_prop_get_rfreg_ver_rsp {
- __u8 status;
- __u8 data[8];
-};
-
-#define NCI_PROP_SET_RFREG_VER 0x25
-
-struct nci_prop_set_rfreg_ver_cmd {
- __u8 data[8];
-};
-
-struct nci_prop_set_rfreg_ver_rsp {
- __u8 status;
-};
-
#define NCI_PROP_START_RFREG 0x26
struct nci_prop_start_rfreg_rsp {
@@ -70,8 +50,6 @@ struct nci_prop_fw_cfg_rsp {
__u8 status;
};
-#define NCI_PROP_WR_RESET 0x2f
-
void s3fwrn5_nci_get_prop_ops(struct nci_driver_ops **ops, size_t *n);
int s3fwrn5_nci_rf_configure(struct s3fwrn5_info *info, const char *fw_name);
--
2.17.1
1 year, 6 months
[PATCH net-next] MAINTAINERS: Update maintainer for SAMSUNG S3FWRN5 NFC
by Bongsu Jeon
From: Bongsu Jeon <bongsu.jeon(a)samsung.com>
add an email to look after the SAMSUNG NFC driver.
Signed-off-by: Bongsu Jeon <bongsu.jeon(a)samsung.com>
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 5c1a6ba5ef26..cb1634eb010d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15425,6 +15425,7 @@ F: include/media/drv-intf/s3c_camif.h
SAMSUNG S3FWRN5 NFC DRIVER
M: Krzysztof Kozlowski <krzk(a)kernel.org>
M: Krzysztof Opasiak <k.opasiak(a)samsung.com>
+M: Bongsu Jeon <bongsu.jeon(a)samsung.com>
L: linux-nfc(a)lists.01.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/net/nfc/samsung,s3fwrn5.yaml
--
2.17.1
1 year, 6 months
[PATCH net-next] nfc: s3fwrn5: Remove the delay for nfc sleep
by Bongsu Jeon
From: Bongsu Jeon <bongsu.jeon(a)samsung.com>
remove the delay for nfc sleep because nfc doesn't need the sleep delay.
Signed-off-by: Bongsu Jeon <bongsu.jeon(a)samsung.com>
---
drivers/nfc/s3fwrn5/phy_common.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nfc/s3fwrn5/phy_common.c b/drivers/nfc/s3fwrn5/phy_common.c
index 497b02b30ae7..81318478d5fd 100644
--- a/drivers/nfc/s3fwrn5/phy_common.c
+++ b/drivers/nfc/s3fwrn5/phy_common.c
@@ -20,7 +20,8 @@ void s3fwrn5_phy_set_wake(void *phy_id, bool wake)
mutex_lock(&phy->mutex);
gpio_set_value(phy->gpio_fw_wake, wake);
- msleep(S3FWRN5_EN_WAIT_TIME);
+ if (wake)
+ msleep(S3FWRN5_EN_WAIT_TIME);
mutex_unlock(&phy->mutex);
}
EXPORT_SYMBOL(s3fwrn5_phy_set_wake);
--
2.17.1
1 year, 6 months
[PATCH net-next] nfc: s3fwrn5: Release the nfc firmware
by Bongsu Jeon
From: Bongsu Jeon <bongsu.jeon(a)samsung.com>
add the code to release the nfc firmware when the firmware image size is
wrong.
Signed-off-by: Bongsu Jeon <bongsu.jeon(a)samsung.com>
---
drivers/nfc/s3fwrn5/firmware.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/nfc/s3fwrn5/firmware.c b/drivers/nfc/s3fwrn5/firmware.c
index 4b5352e2b915..b70737b3070e 100644
--- a/drivers/nfc/s3fwrn5/firmware.c
+++ b/drivers/nfc/s3fwrn5/firmware.c
@@ -293,8 +293,10 @@ int s3fwrn5_fw_request_firmware(struct s3fwrn5_fw_info *fw_info)
if (ret < 0)
return ret;
- if (fw->fw->size < S3FWRN5_FW_IMAGE_HEADER_SIZE)
+ if (fw->fw->size < S3FWRN5_FW_IMAGE_HEADER_SIZE) {
+ release_firmware(fw->fw);
return -EINVAL;
+ }
memcpy(fw->date, fw->fw->data + 0x00, 12);
fw->date[12] = '\0';
--
2.17.1
1 year, 6 months
[PATCH] nfc: s3fwrn5: let core configure the interrupt trigger
by Krzysztof Kozlowski
If interrupt trigger is not set when requesting the interrupt, the core
will take care of reading trigger type from Devicetree. There is no
point to do it in the driver.
Signed-off-by: Krzysztof Kozlowski <krzk(a)kernel.org>
---
drivers/nfc/s3fwrn5/i2c.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/nfc/s3fwrn5/i2c.c b/drivers/nfc/s3fwrn5/i2c.c
index 42f1f610ac2c..897394167522 100644
--- a/drivers/nfc/s3fwrn5/i2c.c
+++ b/drivers/nfc/s3fwrn5/i2c.c
@@ -179,8 +179,6 @@ static int s3fwrn5_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct s3fwrn5_i2c_phy *phy;
- struct irq_data *irq_data;
- unsigned long irqflags;
int ret;
phy = devm_kzalloc(&client->dev, sizeof(*phy), GFP_KERNEL);
@@ -214,11 +212,8 @@ static int s3fwrn5_i2c_probe(struct i2c_client *client,
if (ret < 0)
return ret;
- irq_data = irq_get_irq_data(client->irq);
- irqflags = irqd_get_trigger_type(irq_data) | IRQF_ONESHOT;
-
ret = devm_request_threaded_irq(&client->dev, phy->i2c_dev->irq, NULL,
- s3fwrn5_i2c_irq_thread_fn, irqflags,
+ s3fwrn5_i2c_irq_thread_fn, IRQF_ONESHOT,
S3FWRN5_I2C_DRIVER_NAME, phy);
if (ret)
s3fwrn5_remove(phy->common.ndev);
--
2.25.1
1 year, 6 months