Commit df3c2ade authored by John W. Linville's avatar John W. Linville

Merge tag 'nfc-next-3.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-next

Samuel Ortiz <sameo@linux.intel.com> says:

"This is the first NFC pull request for the 3.13 kernel.
It's a fairly big one, with the following highlights:

- NFC digital layer implementation: Most NFC chipsets implement the NFC
  digital layer in firmware, but others have more basic functionalities
  and expect the host to implement the digital layer. This layer sits
  below the NFC core.

- Sony's port100 support: This is "soft" NFC USB dongle that expects the
  digital layer to be implemented on the host. This is the first user of
  our NFC digital stack implementation.

- Secure element API: We now provide a netlink API for enabling,
  disabling and discovering NFC attached (embedded or UICC ones) secure
  elements. With some userspace help, this allows us to support NFC
  payments.
  Only the pn544 driver currently supports that API.

- NCI SPI fixes and improvements: In order to support NCI devices over
  SPI, we fixed and improved our NCI/SPI implementation. The currently
  most deployed NFC NCI chipset, Broadcom's bcm2079x, supports that mode
  and we're planning to use our NCI/SPI framework to implement a
  driver for it.

- pn533 fragmentation support in target mode: This was the only missing
  feature from our pn533 impementation. We now support fragmentation in
  both Tx and Rx modes, in target mode."
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parents 444474dd ddc1a70b
...@@ -46,6 +46,16 @@ config NFC_SIM ...@@ -46,6 +46,16 @@ config NFC_SIM
If unsure, say N. If unsure, say N.
config NFC_PORT100
tristate "Sony NFC Port-100 Series USB device support"
depends on USB
depends on NFC_DIGITAL
help
This adds support for Sony Port-100 chip based USB devices such as the
RC-S380 dongle.
If unsure, say N.
source "drivers/nfc/pn544/Kconfig" source "drivers/nfc/pn544/Kconfig"
source "drivers/nfc/microread/Kconfig" source "drivers/nfc/microread/Kconfig"
......
...@@ -8,5 +8,6 @@ obj-$(CONFIG_NFC_PN533) += pn533.o ...@@ -8,5 +8,6 @@ obj-$(CONFIG_NFC_PN533) += pn533.o
obj-$(CONFIG_NFC_WILINK) += nfcwilink.o obj-$(CONFIG_NFC_WILINK) += nfcwilink.o
obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o
obj-$(CONFIG_NFC_SIM) += nfcsim.o obj-$(CONFIG_NFC_SIM) += nfcsim.o
obj-$(CONFIG_NFC_PORT100) += port100.o
ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/nfc.h> #include <linux/nfc.h>
...@@ -60,13 +62,13 @@ int nfc_mei_phy_enable(void *phy_id) ...@@ -60,13 +62,13 @@ int nfc_mei_phy_enable(void *phy_id)
r = mei_cl_enable_device(phy->device); r = mei_cl_enable_device(phy->device);
if (r < 0) { if (r < 0) {
pr_err("MEI_PHY: Could not enable device\n"); pr_err("Could not enable device\n");
return r; return r;
} }
r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy); r = mei_cl_register_event_cb(phy->device, nfc_mei_event_cb, phy);
if (r) { if (r) {
pr_err("MEY_PHY: Event cb registration failed\n"); pr_err("Event cb registration failed\n");
mei_cl_disable_device(phy->device); mei_cl_disable_device(phy->device);
phy->powered = 0; phy->powered = 0;
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -95,12 +97,8 @@ static int check_crc(struct sk_buff *skb) ...@@ -95,12 +97,8 @@ static int check_crc(struct sk_buff *skb)
crc = crc ^ skb->data[i]; crc = crc ^ skb->data[i];
if (crc != skb->data[skb->len-1]) { if (crc != skb->data[skb->len-1]) {
pr_err(MICROREAD_I2C_DRIVER_NAME pr_err("CRC error 0x%x != 0x%x\n", crc, skb->data[skb->len-1]);
": CRC error 0x%x != 0x%x\n", pr_info("%s: BAD CRC\n", __func__);
crc, skb->data[skb->len-1]);
pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__);
return -EPERM; return -EPERM;
} }
...@@ -160,18 +158,15 @@ static int microread_i2c_read(struct microread_i2c_phy *phy, ...@@ -160,18 +158,15 @@ static int microread_i2c_read(struct microread_i2c_phy *phy,
u8 tmp[MICROREAD_I2C_LLC_MAX_SIZE - 1]; u8 tmp[MICROREAD_I2C_LLC_MAX_SIZE - 1];
struct i2c_client *client = phy->i2c_dev; struct i2c_client *client = phy->i2c_dev;
pr_debug("%s\n", __func__);
r = i2c_master_recv(client, &len, 1); r = i2c_master_recv(client, &len, 1);
if (r != 1) { if (r != 1) {
dev_err(&client->dev, "cannot read len byte\n"); nfc_err(&client->dev, "cannot read len byte\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
if ((len < MICROREAD_I2C_LLC_MIN_SIZE) || if ((len < MICROREAD_I2C_LLC_MIN_SIZE) ||
(len > MICROREAD_I2C_LLC_MAX_SIZE)) { (len > MICROREAD_I2C_LLC_MAX_SIZE)) {
dev_err(&client->dev, "invalid len byte\n"); nfc_err(&client->dev, "invalid len byte\n");
pr_err("invalid len byte\n");
r = -EBADMSG; r = -EBADMSG;
goto flush; goto flush;
} }
...@@ -228,7 +223,6 @@ static irqreturn_t microread_i2c_irq_thread_fn(int irq, void *phy_id) ...@@ -228,7 +223,6 @@ static irqreturn_t microread_i2c_irq_thread_fn(int irq, void *phy_id)
} }
client = phy->i2c_dev; client = phy->i2c_dev;
dev_dbg(&client->dev, "IRQ\n");
if (phy->hard_fault != 0) if (phy->hard_fault != 0)
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -263,20 +257,18 @@ static int microread_i2c_probe(struct i2c_client *client, ...@@ -263,20 +257,18 @@ static int microread_i2c_probe(struct i2c_client *client,
dev_get_platdata(&client->dev); dev_get_platdata(&client->dev);
int r; int r;
dev_dbg(&client->dev, "client %p", client); dev_dbg(&client->dev, "client %p\n", client);
if (!pdata) { if (!pdata) {
dev_err(&client->dev, "client %p: missing platform data", nfc_err(&client->dev, "client %p: missing platform data\n",
client); client);
return -EINVAL; return -EINVAL;
} }
phy = devm_kzalloc(&client->dev, sizeof(struct microread_i2c_phy), phy = devm_kzalloc(&client->dev, sizeof(struct microread_i2c_phy),
GFP_KERNEL); GFP_KERNEL);
if (!phy) { if (!phy)
dev_err(&client->dev, "Can't allocate microread phy");
return -ENOMEM; return -ENOMEM;
}
i2c_set_clientdata(client, phy); i2c_set_clientdata(client, phy);
phy->i2c_dev = client; phy->i2c_dev = client;
...@@ -285,7 +277,7 @@ static int microread_i2c_probe(struct i2c_client *client, ...@@ -285,7 +277,7 @@ static int microread_i2c_probe(struct i2c_client *client,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
MICROREAD_I2C_DRIVER_NAME, phy); MICROREAD_I2C_DRIVER_NAME, phy);
if (r) { if (r) {
dev_err(&client->dev, "Unable to register IRQ handler"); nfc_err(&client->dev, "Unable to register IRQ handler\n");
return r; return r;
} }
...@@ -296,7 +288,7 @@ static int microread_i2c_probe(struct i2c_client *client, ...@@ -296,7 +288,7 @@ static int microread_i2c_probe(struct i2c_client *client,
if (r < 0) if (r < 0)
goto err_irq; goto err_irq;
dev_info(&client->dev, "Probed"); nfc_info(&client->dev, "Probed");
return 0; return 0;
...@@ -310,8 +302,6 @@ static int microread_i2c_remove(struct i2c_client *client) ...@@ -310,8 +302,6 @@ static int microread_i2c_remove(struct i2c_client *client)
{ {
struct microread_i2c_phy *phy = i2c_get_clientdata(client); struct microread_i2c_phy *phy = i2c_get_clientdata(client);
dev_dbg(&client->dev, "%s\n", __func__);
microread_remove(phy->hdev); microread_remove(phy->hdev);
free_irq(client->irq, phy); free_irq(client->irq, phy);
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/nfc.h> #include <linux/nfc.h>
...@@ -59,8 +61,6 @@ static int microread_mei_remove(struct mei_cl_device *device) ...@@ -59,8 +61,6 @@ static int microread_mei_remove(struct mei_cl_device *device)
{ {
struct nfc_mei_phy *phy = mei_cl_get_drvdata(device); struct nfc_mei_phy *phy = mei_cl_get_drvdata(device);
pr_info("Removing microread\n");
microread_remove(phy->hdev); microread_remove(phy->hdev);
nfc_mei_phy_free(phy); nfc_mei_phy_free(phy);
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -546,7 +548,7 @@ static void microread_target_discovered(struct nfc_hci_dev *hdev, u8 gate, ...@@ -546,7 +548,7 @@ static void microread_target_discovered(struct nfc_hci_dev *hdev, u8 gate,
kfree_skb(skb); kfree_skb(skb);
if (r) if (r)
pr_err("Failed to handle discovered target err=%d", r); pr_err("Failed to handle discovered target err=%d\n", r);
} }
static int microread_event_received(struct nfc_hci_dev *hdev, u8 gate, static int microread_event_received(struct nfc_hci_dev *hdev, u8 gate,
...@@ -656,7 +658,6 @@ int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, ...@@ -656,7 +658,6 @@ int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
info = kzalloc(sizeof(struct microread_info), GFP_KERNEL); info = kzalloc(sizeof(struct microread_info), GFP_KERNEL);
if (!info) { if (!info) {
pr_err("Cannot allocate memory for microread_info.\n");
r = -ENOMEM; r = -ENOMEM;
goto err_info_alloc; goto err_info_alloc;
} }
...@@ -686,7 +687,7 @@ int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, ...@@ -686,7 +687,7 @@ int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
MICROREAD_CMD_TAILROOM, MICROREAD_CMD_TAILROOM,
phy_payload); phy_payload);
if (!info->hdev) { if (!info->hdev) {
pr_err("Cannot allocate nfc hdev.\n"); pr_err("Cannot allocate nfc hdev\n");
r = -ENOMEM; r = -ENOMEM;
goto err_alloc_hdev; goto err_alloc_hdev;
} }
......
...@@ -19,10 +19,10 @@ ...@@ -19,10 +19,10 @@
#include <linux/nfc.h> #include <linux/nfc.h>
#include <net/nfc/nfc.h> #include <net/nfc/nfc.h>
#define DEV_ERR(_dev, fmt, args...) nfc_dev_err(&_dev->nfc_dev->dev, \ #define DEV_ERR(_dev, fmt, args...) nfc_err(&_dev->nfc_dev->dev, \
"%s: " fmt, __func__, ## args) "%s: " fmt, __func__, ## args)
#define DEV_DBG(_dev, fmt, args...) nfc_dev_dbg(&_dev->nfc_dev->dev, \ #define DEV_DBG(_dev, fmt, args...) dev_dbg(&_dev->nfc_dev->dev, \
"%s: " fmt, __func__, ## args) "%s: " fmt, __func__, ## args)
#define NFCSIM_VERSION "0.1" #define NFCSIM_VERSION "0.1"
...@@ -64,7 +64,7 @@ static struct workqueue_struct *wq; ...@@ -64,7 +64,7 @@ static struct workqueue_struct *wq;
static void nfcsim_cleanup_dev(struct nfcsim *dev, u8 shutdown) static void nfcsim_cleanup_dev(struct nfcsim *dev, u8 shutdown)
{ {
DEV_DBG(dev, "shutdown=%d", shutdown); DEV_DBG(dev, "shutdown=%d\n", shutdown);
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
...@@ -84,7 +84,7 @@ static int nfcsim_target_found(struct nfcsim *dev) ...@@ -84,7 +84,7 @@ static int nfcsim_target_found(struct nfcsim *dev)
{ {
struct nfc_target nfc_tgt; struct nfc_target nfc_tgt;
DEV_DBG(dev, ""); DEV_DBG(dev, "\n");
memset(&nfc_tgt, 0, sizeof(struct nfc_target)); memset(&nfc_tgt, 0, sizeof(struct nfc_target));
...@@ -98,7 +98,7 @@ static int nfcsim_dev_up(struct nfc_dev *nfc_dev) ...@@ -98,7 +98,7 @@ static int nfcsim_dev_up(struct nfc_dev *nfc_dev)
{ {
struct nfcsim *dev = nfc_get_drvdata(nfc_dev); struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
DEV_DBG(dev, ""); DEV_DBG(dev, "\n");
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
...@@ -113,7 +113,7 @@ static int nfcsim_dev_down(struct nfc_dev *nfc_dev) ...@@ -113,7 +113,7 @@ static int nfcsim_dev_down(struct nfc_dev *nfc_dev)
{ {
struct nfcsim *dev = nfc_get_drvdata(nfc_dev); struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
DEV_DBG(dev, ""); DEV_DBG(dev, "\n");
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
...@@ -143,7 +143,7 @@ static int nfcsim_dep_link_up(struct nfc_dev *nfc_dev, ...@@ -143,7 +143,7 @@ static int nfcsim_dep_link_up(struct nfc_dev *nfc_dev,
remote_gb = nfc_get_local_general_bytes(peer->nfc_dev, &remote_gb_len); remote_gb = nfc_get_local_general_bytes(peer->nfc_dev, &remote_gb_len);
if (!remote_gb) { if (!remote_gb) {
DEV_ERR(peer, "Can't get remote general bytes"); DEV_ERR(peer, "Can't get remote general bytes\n");
mutex_unlock(&peer->lock); mutex_unlock(&peer->lock);
return -EINVAL; return -EINVAL;
...@@ -155,7 +155,7 @@ static int nfcsim_dep_link_up(struct nfc_dev *nfc_dev, ...@@ -155,7 +155,7 @@ static int nfcsim_dep_link_up(struct nfc_dev *nfc_dev,
rc = nfc_set_remote_general_bytes(nfc_dev, remote_gb, remote_gb_len); rc = nfc_set_remote_general_bytes(nfc_dev, remote_gb, remote_gb_len);
if (rc) { if (rc) {
DEV_ERR(dev, "Can't set remote general bytes"); DEV_ERR(dev, "Can't set remote general bytes\n");
mutex_unlock(&dev->lock); mutex_unlock(&dev->lock);
return rc; return rc;
} }
...@@ -172,7 +172,7 @@ static int nfcsim_dep_link_down(struct nfc_dev *nfc_dev) ...@@ -172,7 +172,7 @@ static int nfcsim_dep_link_down(struct nfc_dev *nfc_dev)
{ {
struct nfcsim *dev = nfc_get_drvdata(nfc_dev); struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
DEV_DBG(dev, ""); DEV_DBG(dev, "\n");
nfcsim_cleanup_dev(dev, 0); nfcsim_cleanup_dev(dev, 0);
...@@ -188,7 +188,7 @@ static int nfcsim_start_poll(struct nfc_dev *nfc_dev, ...@@ -188,7 +188,7 @@ static int nfcsim_start_poll(struct nfc_dev *nfc_dev,
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
if (dev->polling_mode != NFCSIM_POLL_NONE) { if (dev->polling_mode != NFCSIM_POLL_NONE) {
DEV_ERR(dev, "Already in polling mode"); DEV_ERR(dev, "Already in polling mode\n");
rc = -EBUSY; rc = -EBUSY;
goto exit; goto exit;
} }
...@@ -200,7 +200,7 @@ static int nfcsim_start_poll(struct nfc_dev *nfc_dev, ...@@ -200,7 +200,7 @@ static int nfcsim_start_poll(struct nfc_dev *nfc_dev,
dev->polling_mode |= NFCSIM_POLL_TARGET; dev->polling_mode |= NFCSIM_POLL_TARGET;
if (dev->polling_mode == NFCSIM_POLL_NONE) { if (dev->polling_mode == NFCSIM_POLL_NONE) {
DEV_ERR(dev, "Unsupported polling mode"); DEV_ERR(dev, "Unsupported polling mode\n");
rc = -EINVAL; rc = -EINVAL;
goto exit; goto exit;
} }
...@@ -210,7 +210,7 @@ static int nfcsim_start_poll(struct nfc_dev *nfc_dev, ...@@ -210,7 +210,7 @@ static int nfcsim_start_poll(struct nfc_dev *nfc_dev,
queue_delayed_work(wq, &dev->poll_work, 0); queue_delayed_work(wq, &dev->poll_work, 0);
DEV_DBG(dev, "Start polling: im: 0x%X, tm: 0x%X", im_protocols, DEV_DBG(dev, "Start polling: im: 0x%X, tm: 0x%X\n", im_protocols,
tm_protocols); tm_protocols);
rc = 0; rc = 0;
...@@ -224,7 +224,7 @@ static void nfcsim_stop_poll(struct nfc_dev *nfc_dev) ...@@ -224,7 +224,7 @@ static void nfcsim_stop_poll(struct nfc_dev *nfc_dev)
{ {
struct nfcsim *dev = nfc_get_drvdata(nfc_dev); struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
DEV_DBG(dev, "Stop poll"); DEV_DBG(dev, "Stop poll\n");
mutex_lock(&dev->lock); mutex_lock(&dev->lock);
...@@ -240,7 +240,7 @@ static int nfcsim_activate_target(struct nfc_dev *nfc_dev, ...@@ -240,7 +240,7 @@ static int nfcsim_activate_target(struct nfc_dev *nfc_dev,
{ {
struct nfcsim *dev = nfc_get_drvdata(nfc_dev); struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
DEV_DBG(dev, ""); DEV_DBG(dev, "\n");
return -ENOTSUPP; return -ENOTSUPP;
} }
...@@ -250,7 +250,7 @@ static void nfcsim_deactivate_target(struct nfc_dev *nfc_dev, ...@@ -250,7 +250,7 @@ static void nfcsim_deactivate_target(struct nfc_dev *nfc_dev,
{ {
struct nfcsim *dev = nfc_get_drvdata(nfc_dev); struct nfcsim *dev = nfc_get_drvdata(nfc_dev);
DEV_DBG(dev, ""); DEV_DBG(dev, "\n");
} }
static void nfcsim_wq_recv(struct work_struct *work) static void nfcsim_wq_recv(struct work_struct *work)
...@@ -267,7 +267,7 @@ static void nfcsim_wq_recv(struct work_struct *work) ...@@ -267,7 +267,7 @@ static void nfcsim_wq_recv(struct work_struct *work)
if (dev->initiator) { if (dev->initiator) {
if (!dev->cb) { if (!dev->cb) {
DEV_ERR(dev, "Null recv callback"); DEV_ERR(dev, "Null recv callback\n");
dev_kfree_skb(dev->clone_skb); dev_kfree_skb(dev->clone_skb);
goto exit; goto exit;
} }
...@@ -310,7 +310,7 @@ static int nfcsim_tx(struct nfc_dev *nfc_dev, struct nfc_target *target, ...@@ -310,7 +310,7 @@ static int nfcsim_tx(struct nfc_dev *nfc_dev, struct nfc_target *target,
peer->clone_skb = skb_clone(skb, GFP_KERNEL); peer->clone_skb = skb_clone(skb, GFP_KERNEL);
if (!peer->clone_skb) { if (!peer->clone_skb) {
DEV_ERR(dev, "skb_clone failed"); DEV_ERR(dev, "skb_clone failed\n");
mutex_unlock(&peer->lock); mutex_unlock(&peer->lock);
err = -ENOMEM; err = -ENOMEM;
goto exit; goto exit;
...@@ -397,13 +397,13 @@ static void nfcsim_wq_poll(struct work_struct *work) ...@@ -397,13 +397,13 @@ static void nfcsim_wq_poll(struct work_struct *work)
nfcsim_set_polling_mode(dev); nfcsim_set_polling_mode(dev);
if (dev->curr_polling_mode == NFCSIM_POLL_NONE) { if (dev->curr_polling_mode == NFCSIM_POLL_NONE) {
DEV_DBG(dev, "Not polling"); DEV_DBG(dev, "Not polling\n");
goto unlock; goto unlock;
} }
DEV_DBG(dev, "Polling as %s", DEV_DBG(dev, "Polling as %s",
dev->curr_polling_mode == NFCSIM_POLL_INITIATOR ? dev->curr_polling_mode == NFCSIM_POLL_INITIATOR ?
"initiator" : "target"); "initiator\n" : "target\n");
if (dev->curr_polling_mode == NFCSIM_POLL_TARGET) if (dev->curr_polling_mode == NFCSIM_POLL_TARGET)
goto sched_work; goto sched_work;
......
...@@ -146,13 +146,11 @@ static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name) ...@@ -146,13 +146,11 @@ static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name)
unsigned long comp_ret; unsigned long comp_ret;
int rc; int rc;
nfc_dev_dbg(&drv->pdev->dev, "get_bts_file_name entry");
skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd), skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd),
GFP_KERNEL); GFP_KERNEL);
if (!skb) { if (!skb) {
nfc_dev_err(&drv->pdev->dev, nfc_err(&drv->pdev->dev,
"no memory for nci_vs_nfcc_info_cmd"); "no memory for nci_vs_nfcc_info_cmd\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -170,21 +168,19 @@ static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name) ...@@ -170,21 +168,19 @@ static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name)
comp_ret = wait_for_completion_timeout(&drv->completed, comp_ret = wait_for_completion_timeout(&drv->completed,
msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld", dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n",
comp_ret); comp_ret);
if (comp_ret == 0) { if (comp_ret == 0) {
nfc_dev_err(&drv->pdev->dev, nfc_err(&drv->pdev->dev,
"timeout on wait_for_completion_timeout"); "timeout on wait_for_completion_timeout\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
nfc_dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d", dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d\n",
drv->nfcc_info.plen, drv->nfcc_info.plen, drv->nfcc_info.status);
drv->nfcc_info.status);
if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) { if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) {
nfc_dev_err(&drv->pdev->dev, nfc_err(&drv->pdev->dev, "invalid nci_vs_nfcc_info_rsp\n");
"invalid nci_vs_nfcc_info_rsp");
return -EINVAL; return -EINVAL;
} }
...@@ -195,7 +191,7 @@ static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name) ...@@ -195,7 +191,7 @@ static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name)
drv->nfcc_info.sw_ver_z, drv->nfcc_info.sw_ver_z,
drv->nfcc_info.patch_id); drv->nfcc_info.patch_id);
nfc_dev_info(&drv->pdev->dev, "nfcwilink FW file name: %s", file_name); nfc_info(&drv->pdev->dev, "nfcwilink FW file name: %s\n", file_name);
return 0; return 0;
} }
...@@ -207,15 +203,13 @@ static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len) ...@@ -207,15 +203,13 @@ static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len)
unsigned long comp_ret; unsigned long comp_ret;
int rc; int rc;
nfc_dev_dbg(&drv->pdev->dev, "send_bts_cmd entry");
/* verify valid cmd for the NFC channel */ /* verify valid cmd for the NFC channel */
if ((len <= sizeof(struct nfcwilink_hdr)) || if ((len <= sizeof(struct nfcwilink_hdr)) ||
(len > BTS_FILE_CMD_MAX_LEN) || (len > BTS_FILE_CMD_MAX_LEN) ||
(hdr->chnl != NFCWILINK_CHNL) || (hdr->chnl != NFCWILINK_CHNL) ||
(hdr->opcode != NFCWILINK_OPCODE)) { (hdr->opcode != NFCWILINK_OPCODE)) {
nfc_dev_err(&drv->pdev->dev, nfc_err(&drv->pdev->dev,
"ignoring invalid bts cmd, len %d, chnl %d, opcode %d", "ignoring invalid bts cmd, len %d, chnl %d, opcode %d\n",
len, hdr->chnl, hdr->opcode); len, hdr->chnl, hdr->opcode);
return 0; return 0;
} }
...@@ -226,7 +220,7 @@ static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len) ...@@ -226,7 +220,7 @@ static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len)
skb = nfcwilink_skb_alloc(len, GFP_KERNEL); skb = nfcwilink_skb_alloc(len, GFP_KERNEL);
if (!skb) { if (!skb) {
nfc_dev_err(&drv->pdev->dev, "no memory for bts cmd"); nfc_err(&drv->pdev->dev, "no memory for bts cmd\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -238,11 +232,11 @@ static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len) ...@@ -238,11 +232,11 @@ static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len)
comp_ret = wait_for_completion_timeout(&drv->completed, comp_ret = wait_for_completion_timeout(&drv->completed,
msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld", dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n",
comp_ret); comp_ret);
if (comp_ret == 0) { if (comp_ret == 0) {
nfc_dev_err(&drv->pdev->dev, nfc_err(&drv->pdev->dev,
"timeout on wait_for_completion_timeout"); "timeout on wait_for_completion_timeout\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
...@@ -257,8 +251,6 @@ static int nfcwilink_download_fw(struct nfcwilink *drv) ...@@ -257,8 +251,6 @@ static int nfcwilink_download_fw(struct nfcwilink *drv)
__u8 *ptr; __u8 *ptr;
int len, rc; int len, rc;
nfc_dev_dbg(&drv->pdev->dev, "download_fw entry");
set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags); set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags);
rc = nfcwilink_get_bts_file_name(drv, file_name); rc = nfcwilink_get_bts_file_name(drv, file_name);
...@@ -267,7 +259,7 @@ static int nfcwilink_download_fw(struct nfcwilink *drv) ...@@ -267,7 +259,7 @@ static int nfcwilink_download_fw(struct nfcwilink *drv)
rc = request_firmware(&fw, file_name, &drv->pdev->dev); rc = request_firmware(&fw, file_name, &drv->pdev->dev);
if (rc) { if (rc) {
nfc_dev_err(&drv->pdev->dev, "request_firmware failed %d", rc); nfc_err(&drv->pdev->dev, "request_firmware failed %d\n", rc);
/* if the file is not found, don't exit with failure */ /* if the file is not found, don't exit with failure */
if (rc == -ENOENT) if (rc == -ENOENT)
...@@ -280,14 +272,14 @@ static int nfcwilink_download_fw(struct nfcwilink *drv) ...@@ -280,14 +272,14 @@ static int nfcwilink_download_fw(struct nfcwilink *drv)
ptr = (__u8 *)fw->data; ptr = (__u8 *)fw->data;
if ((len == 0) || (ptr == NULL)) { if ((len == 0) || (ptr == NULL)) {
nfc_dev_dbg(&drv->pdev->dev, dev_dbg(&drv->pdev->dev,
"request_firmware returned size %d", len); "request_firmware returned size %d\n", len);
goto release_fw; goto release_fw;
} }
if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) != if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) !=
BTS_FILE_HDR_MAGIC) { BTS_FILE_HDR_MAGIC) {
nfc_dev_err(&drv->pdev->dev, "wrong bts magic number"); nfc_err(&drv->pdev->dev, "wrong bts magic number\n");
rc = -EINVAL; rc = -EINVAL;
goto release_fw; goto release_fw;
} }
...@@ -302,8 +294,8 @@ static int nfcwilink_download_fw(struct nfcwilink *drv) ...@@ -302,8 +294,8 @@ static int nfcwilink_download_fw(struct nfcwilink *drv)
action_len = action_len =
__le16_to_cpu(((struct bts_file_action *)ptr)->len); __le16_to_cpu(((struct bts_file_action *)ptr)->len);
nfc_dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d", dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d\n",
action_type, action_len); action_type, action_len);
switch (action_type) { switch (action_type) {
case BTS_FILE_ACTION_TYPE_SEND_CMD: case BTS_FILE_ACTION_TYPE_SEND_CMD:
...@@ -333,8 +325,6 @@ static void nfcwilink_register_complete(void *priv_data, char data) ...@@ -333,8 +325,6 @@ static void nfcwilink_register_complete(void *priv_data, char data)
{ {
struct nfcwilink *drv = priv_data; struct nfcwilink *drv = priv_data;
nfc_dev_dbg(&drv->pdev->dev, "register_complete entry");
/* store ST registration status */ /* store ST registration status */
drv->st_register_cb_status = data; drv->st_register_cb_status = data;
...@@ -356,7 +346,7 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb) ...@@ -356,7 +346,7 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb)
return -EFAULT; return -EFAULT;
} }
nfc_dev_dbg(&drv->pdev->dev, "receive entry, len %d", skb->len); dev_dbg(&drv->pdev->dev, "receive entry, len %d\n", skb->len);
/* strip the ST header /* strip the ST header
(apart for the chnl byte, which is not received in the hdr) */ (apart for the chnl byte, which is not received in the hdr) */
...@@ -370,7 +360,7 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb) ...@@ -370,7 +360,7 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb)
/* Forward skb to NCI core layer */ /* Forward skb to NCI core layer */
rc = nci_recv_frame(drv->ndev, skb); rc = nci_recv_frame(drv->ndev, skb);
if (rc < 0) { if (rc < 0) {
nfc_dev_err(&drv->pdev->dev, "nci_recv_frame failed %d", rc); nfc_err(&drv->pdev->dev, "nci_recv_frame failed %d\n", rc);
return rc; return rc;
} }
...@@ -396,8 +386,6 @@ static int nfcwilink_open(struct nci_dev *ndev) ...@@ -396,8 +386,6 @@ static int nfcwilink_open(struct nci_dev *ndev)
unsigned long comp_ret; unsigned long comp_ret;
int rc; int rc;
nfc_dev_dbg(&drv->pdev->dev, "open entry");
if (test_and_set_bit(NFCWILINK_RUNNING, &drv->flags)) { if (test_and_set_bit(NFCWILINK_RUNNING, &drv->flags)) {
rc = -EBUSY; rc = -EBUSY;
goto exit; goto exit;
...@@ -415,9 +403,9 @@ static int nfcwilink_open(struct nci_dev *ndev) ...@@ -415,9 +403,9 @@ static int nfcwilink_open(struct nci_dev *ndev)
&drv->completed, &drv->completed,
msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT)); msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT));
nfc_dev_dbg(&drv->pdev->dev, dev_dbg(&drv->pdev->dev,
"wait_for_completion_timeout returned %ld", "wait_for_completion_timeout returned %ld\n",
comp_ret); comp_ret);
if (comp_ret == 0) { if (comp_ret == 0) {
/* timeout */ /* timeout */
...@@ -425,13 +413,12 @@ static int nfcwilink_open(struct nci_dev *ndev) ...@@ -425,13 +413,12 @@ static int nfcwilink_open(struct nci_dev *ndev)
goto clear_exit; goto clear_exit;
} else if (drv->st_register_cb_status != 0) { } else if (drv->st_register_cb_status != 0) {
rc = drv->st_register_cb_status; rc = drv->st_register_cb_status;
nfc_dev_err(&drv->pdev->dev, nfc_err(&drv->pdev->dev,
"st_register_cb failed %d", rc); "st_register_cb failed %d\n", rc);
goto clear_exit; goto clear_exit;
} }
} else { } else {
nfc_dev_err(&drv->pdev->dev, nfc_err(&drv->pdev->dev, "st_register failed %d\n", rc);
"st_register failed %d", rc);
goto clear_exit; goto clear_exit;
} }
} }
...@@ -441,8 +428,8 @@ static int nfcwilink_open(struct nci_dev *ndev) ...@@ -441,8 +428,8 @@ static int nfcwilink_open(struct nci_dev *ndev)
drv->st_write = nfcwilink_proto.write; drv->st_write = nfcwilink_proto.write;
if (nfcwilink_download_fw(drv)) { if (nfcwilink_download_fw(drv)) {
nfc_dev_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d", nfc_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d\n",
rc); rc);
/* open should succeed, even if the FW download failed */ /* open should succeed, even if the FW download failed */
} }
...@@ -460,14 +447,12 @@ static int nfcwilink_close(struct nci_dev *ndev) ...@@ -460,14 +447,12 @@ static int nfcwilink_close(struct nci_dev *ndev)
struct nfcwilink *drv = nci_get_drvdata(ndev); struct nfcwilink *drv = nci_get_drvdata(ndev);
int rc; int rc;
nfc_dev_dbg(&drv->pdev->dev, "close entry");
if (!test_and_clear_bit(NFCWILINK_RUNNING, &drv->flags)) if (!test_and_clear_bit(NFCWILINK_RUNNING, &drv->flags))
return 0; return 0;
rc = st_unregister(&nfcwilink_proto); rc = st_unregister(&nfcwilink_proto);
if (rc) if (rc)
nfc_dev_err(&drv->pdev->dev, "st_unregister failed %d", rc); nfc_err(&drv->pdev->dev, "st_unregister failed %d\n", rc);
drv->st_write = NULL; drv->st_write = NULL;
...@@ -480,7 +465,7 @@ static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb) ...@@ -480,7 +465,7 @@ static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb)
struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000}; struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000};
long len; long len;
nfc_dev_dbg(&drv->pdev->dev, "send entry, len %d", skb->len); dev_dbg(&drv->pdev->dev, "send entry, len %d\n", skb->len);
if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) { if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) {
kfree_skb(skb); kfree_skb(skb);
...@@ -498,7 +483,7 @@ static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb) ...@@ -498,7 +483,7 @@ static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb)
len = drv->st_write(skb); len = drv->st_write(skb);
if (len < 0) { if (len < 0) {
kfree_skb(skb); kfree_skb(skb);
nfc_dev_err(&drv->pdev->dev, "st_write failed %ld", len); nfc_err(&drv->pdev->dev, "st_write failed %ld\n", len);
return -EFAULT; return -EFAULT;
} }
...@@ -517,8 +502,6 @@ static int nfcwilink_probe(struct platform_device *pdev) ...@@ -517,8 +502,6 @@ static int nfcwilink_probe(struct platform_device *pdev)
int rc; int rc;
__u32 protocols; __u32 protocols;
nfc_dev_dbg(&pdev->dev, "probe entry");
drv = devm_kzalloc(&pdev->dev, sizeof(struct nfcwilink), GFP_KERNEL); drv = devm_kzalloc(&pdev->dev, sizeof(struct nfcwilink), GFP_KERNEL);
if (!drv) { if (!drv) {
rc = -ENOMEM; rc = -ENOMEM;
...@@ -538,7 +521,7 @@ static int nfcwilink_probe(struct platform_device *pdev) ...@@ -538,7 +521,7 @@ static int nfcwilink_probe(struct platform_device *pdev)
NFCWILINK_HDR_LEN, NFCWILINK_HDR_LEN,
0); 0);
if (!drv->ndev) { if (!drv->ndev) {
nfc_dev_err(&pdev->dev, "nci_allocate_device failed"); nfc_err(&pdev->dev, "nci_allocate_device failed\n");
rc = -ENOMEM; rc = -ENOMEM;
goto exit; goto exit;
} }
...@@ -548,7 +531,7 @@ static int nfcwilink_probe(struct platform_device *pdev) ...@@ -548,7 +531,7 @@ static int nfcwilink_probe(struct platform_device *pdev)
rc = nci_register_device(drv->ndev); rc = nci_register_device(drv->ndev);
if (rc < 0) { if (rc < 0) {
nfc_dev_err(&pdev->dev, "nci_register_device failed %d", rc); nfc_err(&pdev->dev, "nci_register_device failed %d\n", rc);
goto free_dev_exit; goto free_dev_exit;
} }
...@@ -568,8 +551,6 @@ static int nfcwilink_remove(struct platform_device *pdev) ...@@ -568,8 +551,6 @@ static int nfcwilink_remove(struct platform_device *pdev)
struct nfcwilink *drv = dev_get_drvdata(&pdev->dev); struct nfcwilink *drv = dev_get_drvdata(&pdev->dev);
struct nci_dev *ndev; struct nci_dev *ndev;
nfc_dev_dbg(&pdev->dev, "remove entry");
if (!drv) if (!drv)
return -EFAULT; return -EFAULT;
...@@ -578,8 +559,6 @@ static int nfcwilink_remove(struct platform_device *pdev) ...@@ -578,8 +559,6 @@ static int nfcwilink_remove(struct platform_device *pdev)
nci_unregister_device(ndev); nci_unregister_device(ndev);
nci_free_device(ndev); nci_free_device(ndev);
dev_set_drvdata(&pdev->dev, NULL);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/crc-ccitt.h> #include <linux/crc-ccitt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -151,8 +153,7 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) ...@@ -151,8 +153,7 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy)
char rset_cmd[] = { 0x05, 0xF9, 0x04, 0x00, 0xC3, 0xE5 }; char rset_cmd[] = { 0x05, 0xF9, 0x04, 0x00, 0xC3, 0xE5 };
int count = sizeof(rset_cmd); int count = sizeof(rset_cmd);
pr_info(DRIVER_DESC ": %s\n", __func__); nfc_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n");
dev_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n");
/* Disable fw download */ /* Disable fw download */
gpio_set_value(phy->gpio_fw, 0); gpio_set_value(phy->gpio_fw, 0);
...@@ -173,7 +174,7 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) ...@@ -173,7 +174,7 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy)
dev_dbg(&phy->i2c_dev->dev, "Sending reset cmd\n"); dev_dbg(&phy->i2c_dev->dev, "Sending reset cmd\n");
ret = i2c_master_send(phy->i2c_dev, rset_cmd, count); ret = i2c_master_send(phy->i2c_dev, rset_cmd, count);
if (ret == count) { if (ret == count) {
dev_info(&phy->i2c_dev->dev, nfc_info(&phy->i2c_dev->dev,
"nfc_en polarity : active %s\n", "nfc_en polarity : active %s\n",
(polarity == 0 ? "low" : "high")); (polarity == 0 ? "low" : "high"));
goto out; goto out;
...@@ -181,7 +182,7 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) ...@@ -181,7 +182,7 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy)
} }
} }
dev_err(&phy->i2c_dev->dev, nfc_err(&phy->i2c_dev->dev,
"Could not detect nfc_en polarity, fallback to active high\n"); "Could not detect nfc_en polarity, fallback to active high\n");
out: out:
...@@ -201,7 +202,7 @@ static int pn544_hci_i2c_enable(void *phy_id) ...@@ -201,7 +202,7 @@ static int pn544_hci_i2c_enable(void *phy_id)
{ {
struct pn544_i2c_phy *phy = phy_id; struct pn544_i2c_phy *phy = phy_id;
pr_info(DRIVER_DESC ": %s\n", __func__); pr_info("%s\n", __func__);
pn544_hci_i2c_enable_mode(phy, PN544_HCI_MODE); pn544_hci_i2c_enable_mode(phy, PN544_HCI_MODE);
...@@ -214,8 +215,6 @@ static void pn544_hci_i2c_disable(void *phy_id) ...@@ -214,8 +215,6 @@ static void pn544_hci_i2c_disable(void *phy_id)
{ {
struct pn544_i2c_phy *phy = phy_id; struct pn544_i2c_phy *phy = phy_id;
pr_info(DRIVER_DESC ": %s\n", __func__);
gpio_set_value(phy->gpio_fw, 0); gpio_set_value(phy->gpio_fw, 0);
gpio_set_value(phy->gpio_en, !phy->en_polarity); gpio_set_value(phy->gpio_en, !phy->en_polarity);
usleep_range(10000, 15000); usleep_range(10000, 15000);
...@@ -298,11 +297,9 @@ static int check_crc(u8 *buf, int buflen) ...@@ -298,11 +297,9 @@ static int check_crc(u8 *buf, int buflen)
crc = ~crc; crc = ~crc;
if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) { if (buf[len - 2] != (crc & 0xff) || buf[len - 1] != (crc >> 8)) {
pr_err(PN544_HCI_I2C_DRIVER_NAME pr_err("CRC error 0x%x != 0x%x 0x%x\n",
": CRC error 0x%x != 0x%x 0x%x\n",
crc, buf[len - 1], buf[len - 2]); crc, buf[len - 1], buf[len - 2]);
pr_info("%s: BAD CRC\n", __func__);
pr_info(DRIVER_DESC ": %s : BAD CRC\n", __func__);
print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE, print_hex_dump(KERN_DEBUG, "crc: ", DUMP_PREFIX_NONE,
16, 2, buf, buflen, false); 16, 2, buf, buflen, false);
return -EPERM; return -EPERM;
...@@ -328,13 +325,13 @@ static int pn544_hci_i2c_read(struct pn544_i2c_phy *phy, struct sk_buff **skb) ...@@ -328,13 +325,13 @@ static int pn544_hci_i2c_read(struct pn544_i2c_phy *phy, struct sk_buff **skb)
r = i2c_master_recv(client, &len, 1); r = i2c_master_recv(client, &len, 1);
if (r != 1) { if (r != 1) {
dev_err(&client->dev, "cannot read len byte\n"); nfc_err(&client->dev, "cannot read len byte\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
if ((len < (PN544_HCI_I2C_LLC_MIN_SIZE - 1)) || if ((len < (PN544_HCI_I2C_LLC_MIN_SIZE - 1)) ||
(len > (PN544_HCI_I2C_LLC_MAX_SIZE - 1))) { (len > (PN544_HCI_I2C_LLC_MAX_SIZE - 1))) {
dev_err(&client->dev, "invalid len byte\n"); nfc_err(&client->dev, "invalid len byte\n");
r = -EBADMSG; r = -EBADMSG;
goto flush; goto flush;
} }
...@@ -386,7 +383,7 @@ static int pn544_hci_i2c_fw_read_status(struct pn544_i2c_phy *phy) ...@@ -386,7 +383,7 @@ static int pn544_hci_i2c_fw_read_status(struct pn544_i2c_phy *phy)
r = i2c_master_recv(client, (char *) &response, sizeof(response)); r = i2c_master_recv(client, (char *) &response, sizeof(response));
if (r != sizeof(response)) { if (r != sizeof(response)) {
dev_err(&client->dev, "cannot read fw status\n"); nfc_err(&client->dev, "cannot read fw status\n");
return -EIO; return -EIO;
} }
...@@ -478,8 +475,7 @@ static int pn544_hci_i2c_fw_download(void *phy_id, const char *firmware_name) ...@@ -478,8 +475,7 @@ static int pn544_hci_i2c_fw_download(void *phy_id, const char *firmware_name)
{ {
struct pn544_i2c_phy *phy = phy_id; struct pn544_i2c_phy *phy = phy_id;
pr_info(DRIVER_DESC ": Starting Firmware Download (%s)\n", pr_info("Starting Firmware Download (%s)\n", firmware_name);
firmware_name);
strcpy(phy->firmware_name, firmware_name); strcpy(phy->firmware_name, firmware_name);
...@@ -493,7 +489,7 @@ static int pn544_hci_i2c_fw_download(void *phy_id, const char *firmware_name) ...@@ -493,7 +489,7 @@ static int pn544_hci_i2c_fw_download(void *phy_id, const char *firmware_name)
static void pn544_hci_i2c_fw_work_complete(struct pn544_i2c_phy *phy, static void pn544_hci_i2c_fw_work_complete(struct pn544_i2c_phy *phy,
int result) int result)
{ {
pr_info(DRIVER_DESC ": Firmware Download Complete, result=%d\n", result); pr_info("Firmware Download Complete, result=%d\n", result);
pn544_hci_i2c_disable(phy); pn544_hci_i2c_disable(phy);
...@@ -694,14 +690,14 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, ...@@ -694,14 +690,14 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
dev_dbg(&client->dev, "IRQ: %d\n", client->irq); dev_dbg(&client->dev, "IRQ: %d\n", client->irq);
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_err(&client->dev, "Need I2C_FUNC_I2C\n"); nfc_err(&client->dev, "Need I2C_FUNC_I2C\n");
return -ENODEV; return -ENODEV;
} }
phy = devm_kzalloc(&client->dev, sizeof(struct pn544_i2c_phy), phy = devm_kzalloc(&client->dev, sizeof(struct pn544_i2c_phy),
GFP_KERNEL); GFP_KERNEL);
if (!phy) { if (!phy) {
dev_err(&client->dev, nfc_err(&client->dev,
"Cannot allocate memory for pn544 i2c phy.\n"); "Cannot allocate memory for pn544 i2c phy.\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -714,18 +710,18 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, ...@@ -714,18 +710,18 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
pdata = client->dev.platform_data; pdata = client->dev.platform_data;
if (pdata == NULL) { if (pdata == NULL) {
dev_err(&client->dev, "No platform data\n"); nfc_err(&client->dev, "No platform data\n");
return -EINVAL; return -EINVAL;
} }
if (pdata->request_resources == NULL) { if (pdata->request_resources == NULL) {
dev_err(&client->dev, "request_resources() missing\n"); nfc_err(&client->dev, "request_resources() missing\n");
return -EINVAL; return -EINVAL;
} }
r = pdata->request_resources(client); r = pdata->request_resources(client);
if (r) { if (r) {
dev_err(&client->dev, "Cannot get platform resources\n"); nfc_err(&client->dev, "Cannot get platform resources\n");
return r; return r;
} }
...@@ -739,7 +735,7 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, ...@@ -739,7 +735,7 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
PN544_HCI_I2C_DRIVER_NAME, phy); PN544_HCI_I2C_DRIVER_NAME, phy);
if (r < 0) { if (r < 0) {
dev_err(&client->dev, "Unable to register IRQ handler\n"); nfc_err(&client->dev, "Unable to register IRQ handler\n");
goto err_rti; goto err_rti;
} }
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -41,6 +43,7 @@ enum pn544_state { ...@@ -41,6 +43,7 @@ enum pn544_state {
/* Proprietary commands */ /* Proprietary commands */
#define PN544_WRITE 0x3f #define PN544_WRITE 0x3f
#define PN544_TEST_SWP 0x21
/* Proprietary gates, events, commands and registers */ /* Proprietary gates, events, commands and registers */
...@@ -81,14 +84,17 @@ enum pn544_state { ...@@ -81,14 +84,17 @@ enum pn544_state {
#define PN544_PL_NFCT_DEACTIVATED 0x09 #define PN544_PL_NFCT_DEACTIVATED 0x09
#define PN544_SWP_MGMT_GATE 0xA0 #define PN544_SWP_MGMT_GATE 0xA0
#define PN544_SWP_DEFAULT_MODE 0x01
#define PN544_NFC_WI_MGMT_GATE 0xA1 #define PN544_NFC_WI_MGMT_GATE 0xA1
#define PN544_NFC_ESE_DEFAULT_MODE 0x01
#define PN544_HCI_EVT_SND_DATA 0x01 #define PN544_HCI_EVT_SND_DATA 0x01
#define PN544_HCI_EVT_ACTIVATED 0x02 #define PN544_HCI_EVT_ACTIVATED 0x02
#define PN544_HCI_EVT_DEACTIVATED 0x03 #define PN544_HCI_EVT_DEACTIVATED 0x03
#define PN544_HCI_EVT_RCV_DATA 0x04 #define PN544_HCI_EVT_RCV_DATA 0x04
#define PN544_HCI_EVT_CONTINUE_MI 0x05 #define PN544_HCI_EVT_CONTINUE_MI 0x05
#define PN544_HCI_EVT_SWITCH_MODE 0x03
#define PN544_HCI_CMD_ATTREQUEST 0x12 #define PN544_HCI_CMD_ATTREQUEST 0x12
#define PN544_HCI_CMD_CONTINUE_ACTIVATION 0x13 #define PN544_HCI_CMD_CONTINUE_ACTIVATION 0x13
...@@ -187,13 +193,6 @@ static int pn544_hci_ready(struct nfc_hci_dev *hdev) ...@@ -187,13 +193,6 @@ static int pn544_hci_ready(struct nfc_hci_dev *hdev)
{{0x9e, 0xb4}, 0x00}, {{0x9e, 0xb4}, 0x00},
{{0x9e, 0xd9}, 0xff},
{{0x9e, 0xda}, 0xff},
{{0x9e, 0xdb}, 0x23},
{{0x9e, 0xdc}, 0x21},
{{0x9e, 0xdd}, 0x22},
{{0x9e, 0xde}, 0x24},
{{0x9c, 0x01}, 0x08}, {{0x9c, 0x01}, 0x08},
{{0x9e, 0xaa}, 0x01}, {{0x9e, 0xaa}, 0x01},
...@@ -394,7 +393,7 @@ static int pn544_hci_start_poll(struct nfc_hci_dev *hdev, ...@@ -394,7 +393,7 @@ static int pn544_hci_start_poll(struct nfc_hci_dev *hdev,
if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) { if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
hdev->gb = nfc_get_local_general_bytes(hdev->ndev, hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
&hdev->gb_len); &hdev->gb_len);
pr_debug("generate local bytes %p", hdev->gb); pr_debug("generate local bytes %p\n", hdev->gb);
if (hdev->gb == NULL || hdev->gb_len == 0) { if (hdev->gb == NULL || hdev->gb_len == 0) {
im_protocols &= ~NFC_PROTO_NFC_DEP_MASK; im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK; tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
...@@ -696,7 +695,7 @@ static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb) ...@@ -696,7 +695,7 @@ static int pn544_hci_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
static int pn544_hci_check_presence(struct nfc_hci_dev *hdev, static int pn544_hci_check_presence(struct nfc_hci_dev *hdev,
struct nfc_target *target) struct nfc_target *target)
{ {
pr_debug("supported protocol %d", target->supported_protocols); pr_debug("supported protocol %d\b", target->supported_protocols);
if (target->supported_protocols & (NFC_PROTO_ISO14443_MASK | if (target->supported_protocols & (NFC_PROTO_ISO14443_MASK |
NFC_PROTO_ISO14443_B_MASK)) { NFC_PROTO_ISO14443_B_MASK)) {
return nfc_hci_send_cmd(hdev, target->hci_reader_gate, return nfc_hci_send_cmd(hdev, target->hci_reader_gate,
...@@ -733,7 +732,7 @@ static int pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event, ...@@ -733,7 +732,7 @@ static int pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event,
struct sk_buff *rgb_skb = NULL; struct sk_buff *rgb_skb = NULL;
int r; int r;
pr_debug("hci event %d", event); pr_debug("hci event %d\n", event);
switch (event) { switch (event) {
case PN544_HCI_EVT_ACTIVATED: case PN544_HCI_EVT_ACTIVATED:
if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) { if (gate == PN544_RF_READER_NFCIP1_INITIATOR_GATE) {
...@@ -764,7 +763,7 @@ static int pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event, ...@@ -764,7 +763,7 @@ static int pn544_hci_event_received(struct nfc_hci_dev *hdev, u8 gate, u8 event,
} }
if (skb->data[0] != 0) { if (skb->data[0] != 0) {
pr_debug("data0 %d", skb->data[0]); pr_debug("data0 %d\n", skb->data[0]);
r = -EPROTO; r = -EPROTO;
goto exit; goto exit;
} }
...@@ -792,6 +791,108 @@ static int pn544_hci_fw_download(struct nfc_hci_dev *hdev, ...@@ -792,6 +791,108 @@ static int pn544_hci_fw_download(struct nfc_hci_dev *hdev,
return info->fw_download(info->phy_id, firmware_name); return info->fw_download(info->phy_id, firmware_name);
} }
static int pn544_hci_discover_se(struct nfc_hci_dev *hdev)
{
u32 se_idx = 0;
u8 ese_mode = 0x01; /* Default mode */
struct sk_buff *res_skb;
int r;
r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE, PN544_TEST_SWP,
NULL, 0, &res_skb);
if (r == 0) {
if (res_skb->len == 2 && res_skb->data[0] == 0x00)
nfc_add_se(hdev->ndev, se_idx++, NFC_SE_UICC);
kfree_skb(res_skb);
}
r = nfc_hci_send_event(hdev, PN544_NFC_WI_MGMT_GATE,
PN544_HCI_EVT_SWITCH_MODE,
&ese_mode, 1);
if (r == 0)
nfc_add_se(hdev->ndev, se_idx++, NFC_SE_EMBEDDED);
return !se_idx;
}
#define PN544_SE_MODE_OFF 0x00
#define PN544_SE_MODE_ON 0x01
static int pn544_hci_enable_se(struct nfc_hci_dev *hdev, u32 se_idx)
{
struct nfc_se *se;
u8 enable = PN544_SE_MODE_ON;
static struct uicc_gatelist {
u8 head;
u8 adr[2];
u8 value;
} uicc_gatelist[] = {
{0x00, {0x9e, 0xd9}, 0x23},
{0x00, {0x9e, 0xda}, 0x21},
{0x00, {0x9e, 0xdb}, 0x22},
{0x00, {0x9e, 0xdc}, 0x24},
};
struct uicc_gatelist *p = uicc_gatelist;
int count = ARRAY_SIZE(uicc_gatelist);
struct sk_buff *res_skb;
int r;
se = nfc_find_se(hdev->ndev, se_idx);
switch (se->type) {
case NFC_SE_UICC:
while (count--) {
r = nfc_hci_send_cmd(hdev, PN544_SYS_MGMT_GATE,
PN544_WRITE, (u8 *)p, 4, &res_skb);
if (r < 0)
return r;
if (res_skb->len != 1) {
kfree_skb(res_skb);
return -EPROTO;
}
if (res_skb->data[0] != p->value) {
kfree_skb(res_skb);
return -EIO;
}
kfree_skb(res_skb);
p++;
}
return nfc_hci_set_param(hdev, PN544_SWP_MGMT_GATE,
PN544_SWP_DEFAULT_MODE, &enable, 1);
case NFC_SE_EMBEDDED:
return nfc_hci_set_param(hdev, PN544_NFC_WI_MGMT_GATE,
PN544_NFC_ESE_DEFAULT_MODE, &enable, 1);
default:
return -EINVAL;
}
}
static int pn544_hci_disable_se(struct nfc_hci_dev *hdev, u32 se_idx)
{
struct nfc_se *se;
u8 disable = PN544_SE_MODE_OFF;
se = nfc_find_se(hdev->ndev, se_idx);
switch (se->type) {
case NFC_SE_UICC:
return nfc_hci_set_param(hdev, PN544_SWP_MGMT_GATE,
PN544_SWP_DEFAULT_MODE, &disable, 1);
case NFC_SE_EMBEDDED:
return nfc_hci_set_param(hdev, PN544_NFC_WI_MGMT_GATE,
PN544_NFC_ESE_DEFAULT_MODE, &disable, 1);
default:
return -EINVAL;
}
}
static struct nfc_hci_ops pn544_hci_ops = { static struct nfc_hci_ops pn544_hci_ops = {
.open = pn544_hci_open, .open = pn544_hci_open,
.close = pn544_hci_close, .close = pn544_hci_close,
...@@ -807,6 +908,9 @@ static struct nfc_hci_ops pn544_hci_ops = { ...@@ -807,6 +908,9 @@ static struct nfc_hci_ops pn544_hci_ops = {
.check_presence = pn544_hci_check_presence, .check_presence = pn544_hci_check_presence,
.event_received = pn544_hci_event_received, .event_received = pn544_hci_event_received,
.fw_download = pn544_hci_fw_download, .fw_download = pn544_hci_fw_download,
.discover_se = pn544_hci_discover_se,
.enable_se = pn544_hci_enable_se,
.disable_se = pn544_hci_disable_se,
}; };
int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
...@@ -820,7 +924,6 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, ...@@ -820,7 +924,6 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL); info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL);
if (!info) { if (!info) {
pr_err("Cannot allocate memory for pn544_hci_info.\n");
r = -ENOMEM; r = -ENOMEM;
goto err_info_alloc; goto err_info_alloc;
} }
...@@ -853,7 +956,7 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name, ...@@ -853,7 +956,7 @@ int pn544_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
phy_headroom + PN544_CMDS_HEADROOM, phy_headroom + PN544_CMDS_HEADROOM,
phy_tailroom, phy_payload); phy_tailroom, phy_payload);
if (!info->hdev) { if (!info->hdev) {
pr_err("Cannot allocate nfc hdev.\n"); pr_err("Cannot allocate nfc hdev\n");
r = -ENOMEM; r = -ENOMEM;
goto err_alloc_hdev; goto err_alloc_hdev;
} }
......
This diff is collapsed.
/*
* NFC Digital Protocol stack
* Copyright (c) 2013, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef __NFC_DIGITAL_H
#define __NFC_DIGITAL_H
#include <linux/skbuff.h>
#include <net/nfc/nfc.h>
/**
* Configuration types for in_configure_hw and tg_configure_hw.
*/
enum {
NFC_DIGITAL_CONFIG_RF_TECH = 0,
NFC_DIGITAL_CONFIG_FRAMING,
};
/**
* RF technology values passed as param argument to in_configure_hw and
* tg_configure_hw for NFC_DIGITAL_CONFIG_RF_TECH configuration type.
*/
enum {
NFC_DIGITAL_RF_TECH_106A = 0,
NFC_DIGITAL_RF_TECH_212F,
NFC_DIGITAL_RF_TECH_424F,
NFC_DIGITAL_RF_TECH_LAST,
};
/**
* Framing configuration passed as param argument to in_configure_hw and
* tg_configure_hw for NFC_DIGITAL_CONFIG_FRAMING configuration type.
*/
enum {
NFC_DIGITAL_FRAMING_NFCA_SHORT = 0,
NFC_DIGITAL_FRAMING_NFCA_STANDARD,
NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A,
NFC_DIGITAL_FRAMING_NFCA_T1T,
NFC_DIGITAL_FRAMING_NFCA_T2T,
NFC_DIGITAL_FRAMING_NFCA_NFC_DEP,
NFC_DIGITAL_FRAMING_NFCF,
NFC_DIGITAL_FRAMING_NFCF_T3T,
NFC_DIGITAL_FRAMING_NFCF_NFC_DEP,
NFC_DIGITAL_FRAMING_NFC_DEP_ACTIVATED,
NFC_DIGITAL_FRAMING_LAST,
};
#define DIGITAL_MDAA_NFCID1_SIZE 3
struct digital_tg_mdaa_params {
u16 sens_res;
u8 nfcid1[DIGITAL_MDAA_NFCID1_SIZE];
u8 sel_res;
u8 nfcid2[NFC_NFCID2_MAXSIZE];
u16 sc;
};
struct nfc_digital_dev;
/**
* nfc_digital_cmd_complete_t - Definition of command result callback
*
* @ddev: nfc_digital_device ref
* @arg: user data
* @resp: response data
*
* resp pointer can be an error code and will be checked with IS_ERR() macro.
* The callback is responsible for freeing resp sk_buff.
*/
typedef void (*nfc_digital_cmd_complete_t)(struct nfc_digital_dev *ddev,
void *arg, struct sk_buff *resp);
/**
* Device side NFC Digital operations
*
* Initiator mode:
* @in_configure_hw: Hardware configuration for RF technology and communication
* framing in initiator mode. This is a synchronous function.
* @in_send_cmd: Initiator mode data exchange using RF technology and framing
* previously set with in_configure_hw. The peer response is returned
* through callback cb. If an io error occurs or the peer didn't reply
* within the specified timeout (ms), the error code is passed back through
* the resp pointer. This is an asynchronous function.
*
* Target mode: Only NFC-DEP protocol is supported in target mode.
* @tg_configure_hw: Hardware configuration for RF technology and communication
* framing in target mode. This is a synchronous function.
* @tg_send_cmd: Target mode data exchange using RF technology and framing
* previously set with tg_configure_hw. The peer next command is returned
* through callback cb. If an io error occurs or the peer didn't reply
* within the specified timeout (ms), the error code is passed back through
* the resp pointer. This is an asynchronous function.
* @tg_listen: Put the device in listen mode waiting for data from the peer
* device. This is an asynchronous function.
* @tg_listen_mdaa: If supported, put the device in automatic listen mode with
* mode detection and automatic anti-collision. In this mode, the device
* automatically detects the RF technology and executes the anti-collision
* detection using the command responses specified in mdaa_params. The
* mdaa_params structure contains SENS_RES, NFCID1, and SEL_RES for 106A RF
* tech. NFCID2 and system code (sc) for 212F and 424F. The driver returns
* the NFC-DEP ATR_REQ command through cb. The digital stack deducts the RF
* tech by analyzing the SoD of the frame containing the ATR_REQ command.
* This is an asynchronous function.
*
* @switch_rf: Turns device radio on or off. The stack does not call explicitly
* switch_rf to turn the radio on. A call to in|tg_configure_hw must turn
* the device radio on.
* @abort_cmd: Discard the last sent command.
*/
struct nfc_digital_ops {
int (*in_configure_hw)(struct nfc_digital_dev *ddev, int type,
int param);
int (*in_send_cmd)(struct nfc_digital_dev *ddev, struct sk_buff *skb,
u16 timeout, nfc_digital_cmd_complete_t cb,
void *arg);
int (*tg_configure_hw)(struct nfc_digital_dev *ddev, int type,
int param);
int (*tg_send_cmd)(struct nfc_digital_dev *ddev, struct sk_buff *skb,
u16 timeout, nfc_digital_cmd_complete_t cb,
void *arg);
int (*tg_listen)(struct nfc_digital_dev *ddev, u16 timeout,
nfc_digital_cmd_complete_t cb, void *arg);
int (*tg_listen_mdaa)(struct nfc_digital_dev *ddev,
struct digital_tg_mdaa_params *mdaa_params,
u16 timeout, nfc_digital_cmd_complete_t cb,
void *arg);
int (*switch_rf)(struct nfc_digital_dev *ddev, bool on);
void (*abort_cmd)(struct nfc_digital_dev *ddev);
};
#define NFC_DIGITAL_POLL_MODE_COUNT_MAX 6 /* 106A, 212F, and 424F in & tg */
typedef int (*digital_poll_t)(struct nfc_digital_dev *ddev, u8 rf_tech);
struct digital_poll_tech {
u8 rf_tech;
digital_poll_t poll_func;
};
/**
* Driver capabilities - bit mask made of the following values
*
* @NFC_DIGITAL_DRV_CAPS_IN_CRC: The driver handles CRC calculation in initiator
* mode.
* @NFC_DIGITAL_DRV_CAPS_TG_CRC: The driver handles CRC calculation in target
* mode.
*/
#define NFC_DIGITAL_DRV_CAPS_IN_CRC 0x0001
#define NFC_DIGITAL_DRV_CAPS_TG_CRC 0x0002
struct nfc_digital_dev {
struct nfc_dev *nfc_dev;
struct nfc_digital_ops *ops;
u32 protocols;
int tx_headroom;
int tx_tailroom;
u32 driver_capabilities;
void *driver_data;
struct digital_poll_tech poll_techs[NFC_DIGITAL_POLL_MODE_COUNT_MAX];
u8 poll_tech_count;
u8 poll_tech_index;
struct mutex poll_lock;
struct work_struct cmd_work;
struct work_struct cmd_complete_work;
struct list_head cmd_queue;
struct mutex cmd_lock;
struct work_struct poll_work;
u8 curr_protocol;
u8 curr_rf_tech;
u8 curr_nfc_dep_pni;
int (*skb_check_crc)(struct sk_buff *skb);
void (*skb_add_crc)(struct sk_buff *skb);
};
struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
__u32 supported_protocols,
__u32 driver_capabilities,
int tx_headroom,
int tx_tailroom);
void nfc_digital_free_device(struct nfc_digital_dev *ndev);
int nfc_digital_register_device(struct nfc_digital_dev *ndev);
void nfc_digital_unregister_device(struct nfc_digital_dev *ndev);
static inline void nfc_digital_set_parent_dev(struct nfc_digital_dev *ndev,
struct device *dev)
{
nfc_set_parent_dev(ndev->nfc_dev, dev);
}
static inline void nfc_digital_set_drvdata(struct nfc_digital_dev *dev,
void *data)
{
dev->driver_data = data;
}
static inline void *nfc_digital_get_drvdata(struct nfc_digital_dev *dev)
{
return dev->driver_data;
}
#endif /* __NFC_DIGITAL_H */
...@@ -24,12 +24,6 @@ ...@@ -24,12 +24,6 @@
#include <net/nfc/nfc.h> #include <net/nfc/nfc.h>
struct nfc_phy_ops {
int (*write)(void *dev_id, struct sk_buff *skb);
int (*enable)(void *dev_id);
void (*disable)(void *dev_id);
};
struct nfc_hci_dev; struct nfc_hci_dev;
struct nfc_hci_ops { struct nfc_hci_ops {
......
...@@ -166,6 +166,10 @@ ...@@ -166,6 +166,10 @@
#define NCI_GID_NFCEE_MGMT 0x2 #define NCI_GID_NFCEE_MGMT 0x2
#define NCI_GID_PROPRIETARY 0xf #define NCI_GID_PROPRIETARY 0xf
/* ----- NCI over SPI head/crc(tail) room needed for outgoing frames ----- */
#define NCI_SPI_HDR_LEN 4
#define NCI_SPI_CRC_LEN 2
/* ---- NCI Packet structures ---- */ /* ---- NCI Packet structures ---- */
#define NCI_CTRL_HDR_SIZE 3 #define NCI_CTRL_HDR_SIZE 3
#define NCI_DATA_HDR_SIZE 3 #define NCI_DATA_HDR_SIZE 3
......
...@@ -207,19 +207,9 @@ int nci_to_errno(__u8 code); ...@@ -207,19 +207,9 @@ int nci_to_errno(__u8 code);
#define NCI_SPI_CRC_ENABLED 0x01 #define NCI_SPI_CRC_ENABLED 0x01
/* ----- NCI SPI structures ----- */ /* ----- NCI SPI structures ----- */
struct nci_spi_dev; struct nci_spi {
struct nci_dev *ndev;
struct nci_spi_ops {
int (*open)(struct nci_spi_dev *ndev);
int (*close)(struct nci_spi_dev *ndev);
void (*assert_int)(struct nci_spi_dev *ndev);
void (*deassert_int)(struct nci_spi_dev *ndev);
};
struct nci_spi_dev {
struct nci_dev *nci_dev;
struct spi_device *spi; struct spi_device *spi;
struct nci_spi_ops *ops;
unsigned int xfer_udelay; /* microseconds delay between unsigned int xfer_udelay; /* microseconds delay between
transactions */ transactions */
...@@ -227,31 +217,15 @@ struct nci_spi_dev { ...@@ -227,31 +217,15 @@ struct nci_spi_dev {
struct completion req_completion; struct completion req_completion;
u8 req_result; u8 req_result;
void *driver_data;
}; };
/* ----- NCI SPI Devices ----- */ /* ----- NCI SPI ----- */
struct nci_spi_dev *nci_spi_allocate_device(struct spi_device *spi, struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
struct nci_spi_ops *ops, u8 acknowledge_mode, unsigned int delay,
u32 supported_protocols, struct nci_dev *ndev);
u32 supported_se, int nci_spi_send(struct nci_spi *nspi,
u8 acknowledge_mode, struct completion *write_handshake_completion,
unsigned int delay); struct sk_buff *skb);
void nci_spi_free_device(struct nci_spi_dev *ndev); struct sk_buff *nci_spi_read(struct nci_spi *nspi);
int nci_spi_register_device(struct nci_spi_dev *ndev);
void nci_spi_unregister_device(struct nci_spi_dev *ndev);
int nci_spi_recv_frame(struct nci_spi_dev *ndev);
static inline void nci_spi_set_drvdata(struct nci_spi_dev *ndev,
void *data)
{
ndev->driver_data = data;
}
static inline void *nci_spi_get_drvdata(struct nci_spi_dev *ndev)
{
return ndev->driver_data;
}
#endif /* __NCI_CORE_H */ #endif /* __NCI_CORE_H */
...@@ -28,9 +28,14 @@ ...@@ -28,9 +28,14 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#define nfc_dev_info(dev, fmt, arg...) dev_info((dev), "NFC: " fmt "\n", ## arg) #define nfc_info(dev, fmt, ...) dev_info((dev), "NFC: " fmt, ##__VA_ARGS__)
#define nfc_dev_err(dev, fmt, arg...) dev_err((dev), "NFC: " fmt "\n", ## arg) #define nfc_err(dev, fmt, ...) dev_err((dev), "NFC: " fmt, ##__VA_ARGS__)
#define nfc_dev_dbg(dev, fmt, arg...) dev_dbg((dev), fmt "\n", ## arg)
struct nfc_phy_ops {
int (*write)(void *dev_id, struct sk_buff *skb);
int (*enable)(void *dev_id);
void (*disable)(void *dev_id);
};
struct nfc_dev; struct nfc_dev;
...@@ -48,6 +53,8 @@ struct nfc_dev; ...@@ -48,6 +53,8 @@ struct nfc_dev;
typedef void (*data_exchange_cb_t)(void *context, struct sk_buff *skb, typedef void (*data_exchange_cb_t)(void *context, struct sk_buff *skb,
int err); int err);
typedef void (*se_io_cb_t)(void *context, u8 *apdu, size_t apdu_len, int err);
struct nfc_target; struct nfc_target;
struct nfc_ops { struct nfc_ops {
...@@ -74,12 +81,23 @@ struct nfc_ops { ...@@ -74,12 +81,23 @@ struct nfc_ops {
int (*discover_se)(struct nfc_dev *dev); int (*discover_se)(struct nfc_dev *dev);
int (*enable_se)(struct nfc_dev *dev, u32 se_idx); int (*enable_se)(struct nfc_dev *dev, u32 se_idx);
int (*disable_se)(struct nfc_dev *dev, u32 se_idx); int (*disable_se)(struct nfc_dev *dev, u32 se_idx);
int (*se_io) (struct nfc_dev *dev, u32 se_idx,
u8 *apdu, size_t apdu_length,
se_io_cb_t cb, void *cb_context);
}; };
#define NFC_TARGET_IDX_ANY -1 #define NFC_TARGET_IDX_ANY -1
#define NFC_MAX_GT_LEN 48 #define NFC_MAX_GT_LEN 48
#define NFC_ATR_RES_GT_OFFSET 15 #define NFC_ATR_RES_GT_OFFSET 15
/**
* struct nfc_target - NFC target descriptiom
*
* @sens_res: 2 bytes describing the target SENS_RES response, if the target
* is a type A one. The %sens_res most significant byte must be byte 2
* as described by the NFC Forum digital specification (i.e. the platform
* configuration one) while %sens_res least significant byte is byte 1.
*/
struct nfc_target { struct nfc_target {
u32 idx; u32 idx;
u32 supported_protocols; u32 supported_protocols;
...@@ -243,5 +261,6 @@ void nfc_driver_failure(struct nfc_dev *dev, int err); ...@@ -243,5 +261,6 @@ void nfc_driver_failure(struct nfc_dev *dev, int err);
int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type); int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type);
int nfc_remove_se(struct nfc_dev *dev, u32 se_idx); int nfc_remove_se(struct nfc_dev *dev, u32 se_idx);
struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx);
#endif /* __NET_NFC_H */ #endif /* __NET_NFC_H */
...@@ -85,6 +85,7 @@ ...@@ -85,6 +85,7 @@
* a specific SE notifies us about the end of a transaction. The parameter * a specific SE notifies us about the end of a transaction. The parameter
* for this event is the application ID (AID). * for this event is the application ID (AID).
* @NFC_CMD_GET_SE: Dump all discovered secure elements from an NFC controller. * @NFC_CMD_GET_SE: Dump all discovered secure elements from an NFC controller.
* @NFC_CMD_SE_IO: Send/Receive APDUs to/from the selected secure element.
*/ */
enum nfc_commands { enum nfc_commands {
NFC_CMD_UNSPEC, NFC_CMD_UNSPEC,
...@@ -114,6 +115,7 @@ enum nfc_commands { ...@@ -114,6 +115,7 @@ enum nfc_commands {
NFC_EVENT_SE_CONNECTIVITY, NFC_EVENT_SE_CONNECTIVITY,
NFC_EVENT_SE_TRANSACTION, NFC_EVENT_SE_TRANSACTION,
NFC_CMD_GET_SE, NFC_CMD_GET_SE,
NFC_CMD_SE_IO,
/* private: internal use only */ /* private: internal use only */
__NFC_CMD_AFTER_LAST __NFC_CMD_AFTER_LAST
}; };
...@@ -147,6 +149,7 @@ enum nfc_commands { ...@@ -147,6 +149,7 @@ enum nfc_commands {
* @NFC_ATTR_SE_INDEX: Secure element index * @NFC_ATTR_SE_INDEX: Secure element index
* @NFC_ATTR_SE_TYPE: Secure element type (UICC or EMBEDDED) * @NFC_ATTR_SE_TYPE: Secure element type (UICC or EMBEDDED)
* @NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS: Firmware download operation status * @NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS: Firmware download operation status
* @NFC_ATTR_APDU: Secure element APDU
*/ */
enum nfc_attrs { enum nfc_attrs {
NFC_ATTR_UNSPEC, NFC_ATTR_UNSPEC,
...@@ -174,6 +177,7 @@ enum nfc_attrs { ...@@ -174,6 +177,7 @@ enum nfc_attrs {
NFC_ATTR_SE_TYPE, NFC_ATTR_SE_TYPE,
NFC_ATTR_SE_AID, NFC_ATTR_SE_AID,
NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS, NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS,
NFC_ATTR_SE_APDU,
/* private: internal use only */ /* private: internal use only */
__NFC_ATTR_AFTER_LAST __NFC_ATTR_AFTER_LAST
}; };
......
...@@ -14,6 +14,20 @@ menuconfig NFC ...@@ -14,6 +14,20 @@ menuconfig NFC
To compile this support as a module, choose M here: the module will To compile this support as a module, choose M here: the module will
be called nfc. be called nfc.
config NFC_DIGITAL
depends on NFC
select CRC_CCITT
select CRC_ITU_T
tristate "NFC Digital Protocol stack support"
default n
help
Say Y if you want to build NFC digital protocol stack support.
This is needed by NFC chipsets whose firmware only implement
the NFC analog layer.
To compile this support as a module, choose M here: the module will
be called nfc_digital.
source "net/nfc/nci/Kconfig" source "net/nfc/nci/Kconfig"
source "net/nfc/hci/Kconfig" source "net/nfc/hci/Kconfig"
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
obj-$(CONFIG_NFC) += nfc.o obj-$(CONFIG_NFC) += nfc.o
obj-$(CONFIG_NFC_NCI) += nci/ obj-$(CONFIG_NFC_NCI) += nci/
obj-$(CONFIG_NFC_HCI) += hci/ obj-$(CONFIG_NFC_HCI) += hci/
obj-$(CONFIG_NFC_DIGITAL) += nfc_digital.o
nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \ nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \
llcp_sock.o llcp_sock.o
nfc_digital-objs := digital_core.o digital_technology.o digital_dep.o
...@@ -384,6 +384,19 @@ int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx, ...@@ -384,6 +384,19 @@ int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
{ {
dev->dep_link_up = true; dev->dep_link_up = true;
if (!dev->active_target) {
struct nfc_target *target;
target = nfc_find_target(dev, target_idx);
if (target == NULL)
return -ENOTCONN;
dev->active_target = target;
}
dev->polling = false;
dev->rf_mode = rf_mode;
nfc_llcp_mac_is_up(dev, target_idx, comm_mode, rf_mode); nfc_llcp_mac_is_up(dev, target_idx, comm_mode, rf_mode);
return nfc_genl_dep_link_up_event(dev, target_idx, comm_mode, rf_mode); return nfc_genl_dep_link_up_event(dev, target_idx, comm_mode, rf_mode);
...@@ -536,7 +549,7 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, ...@@ -536,7 +549,7 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb,
return rc; return rc;
} }
static struct nfc_se *find_se(struct nfc_dev *dev, u32 se_idx) struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx)
{ {
struct nfc_se *se, *n; struct nfc_se *se, *n;
...@@ -546,6 +559,7 @@ static struct nfc_se *find_se(struct nfc_dev *dev, u32 se_idx) ...@@ -546,6 +559,7 @@ static struct nfc_se *find_se(struct nfc_dev *dev, u32 se_idx)
return NULL; return NULL;
} }
EXPORT_SYMBOL(nfc_find_se);
int nfc_enable_se(struct nfc_dev *dev, u32 se_idx) int nfc_enable_se(struct nfc_dev *dev, u32 se_idx)
{ {
...@@ -577,7 +591,7 @@ int nfc_enable_se(struct nfc_dev *dev, u32 se_idx) ...@@ -577,7 +591,7 @@ int nfc_enable_se(struct nfc_dev *dev, u32 se_idx)
goto error; goto error;
} }
se = find_se(dev, se_idx); se = nfc_find_se(dev, se_idx);
if (!se) { if (!se) {
rc = -EINVAL; rc = -EINVAL;
goto error; goto error;
...@@ -622,7 +636,7 @@ int nfc_disable_se(struct nfc_dev *dev, u32 se_idx) ...@@ -622,7 +636,7 @@ int nfc_disable_se(struct nfc_dev *dev, u32 se_idx)
goto error; goto error;
} }
se = find_se(dev, se_idx); se = nfc_find_se(dev, se_idx);
if (!se) { if (!se) {
rc = -EINVAL; rc = -EINVAL;
goto error; goto error;
...@@ -881,7 +895,7 @@ int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type) ...@@ -881,7 +895,7 @@ int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type)
pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx); pr_debug("%s se index %d\n", dev_name(&dev->dev), se_idx);
se = find_se(dev, se_idx); se = nfc_find_se(dev, se_idx);
if (se) if (se)
return -EALREADY; return -EALREADY;
......
/*
* NFC Digital Protocol stack
* Copyright (c) 2013, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef __DIGITAL_H
#define __DIGITAL_H
#include <net/nfc/nfc.h>
#include <net/nfc/digital.h>
#include <linux/crc-ccitt.h>
#include <linux/crc-itu-t.h>
#define PROTOCOL_ERR(req) pr_err("%d: NFC Digital Protocol error: %s\n", \
__LINE__, req)
#define DIGITAL_CMD_IN_SEND 0
#define DIGITAL_CMD_TG_SEND 1
#define DIGITAL_CMD_TG_LISTEN 2
#define DIGITAL_CMD_TG_LISTEN_MDAA 3
#define DIGITAL_MAX_HEADER_LEN 7
#define DIGITAL_CRC_LEN 2
#define DIGITAL_SENSF_NFCID2_NFC_DEP_B1 0x01
#define DIGITAL_SENSF_NFCID2_NFC_DEP_B2 0xFE
#define DIGITAL_SENS_RES_NFC_DEP 0x0100
#define DIGITAL_SEL_RES_NFC_DEP 0x40
#define DIGITAL_SENSF_FELICA_SC 0xFFFF
#define DIGITAL_DRV_CAPS_IN_CRC(ddev) \
((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_IN_CRC)
#define DIGITAL_DRV_CAPS_TG_CRC(ddev) \
((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_TG_CRC)
struct digital_data_exch {
data_exchange_cb_t cb;
void *cb_context;
};
struct sk_buff *digital_skb_alloc(struct nfc_digital_dev *ddev,
unsigned int len);
int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type,
struct sk_buff *skb, struct digital_tg_mdaa_params *params,
u16 timeout, nfc_digital_cmd_complete_t cmd_cb,
void *cb_context);
int digital_in_configure_hw(struct nfc_digital_dev *ddev, int type, int param);
static inline int digital_in_send_cmd(struct nfc_digital_dev *ddev,
struct sk_buff *skb, u16 timeout,
nfc_digital_cmd_complete_t cmd_cb,
void *cb_context)
{
return digital_send_cmd(ddev, DIGITAL_CMD_IN_SEND, skb, NULL, timeout,
cmd_cb, cb_context);
}
void digital_poll_next_tech(struct nfc_digital_dev *ddev);
int digital_in_send_sens_req(struct nfc_digital_dev *ddev, u8 rf_tech);
int digital_in_send_sensf_req(struct nfc_digital_dev *ddev, u8 rf_tech);
int digital_target_found(struct nfc_digital_dev *ddev,
struct nfc_target *target, u8 protocol);
int digital_in_recv_mifare_res(struct sk_buff *resp);
int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
struct nfc_target *target, __u8 comm_mode, __u8 *gb,
size_t gb_len);
int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
struct nfc_target *target, struct sk_buff *skb,
struct digital_data_exch *data_exch);
int digital_tg_configure_hw(struct nfc_digital_dev *ddev, int type, int param);
static inline int digital_tg_send_cmd(struct nfc_digital_dev *ddev,
struct sk_buff *skb, u16 timeout,
nfc_digital_cmd_complete_t cmd_cb, void *cb_context)
{
return digital_send_cmd(ddev, DIGITAL_CMD_TG_SEND, skb, NULL, timeout,
cmd_cb, cb_context);
}
void digital_tg_recv_sens_req(struct nfc_digital_dev *ddev, void *arg,
struct sk_buff *resp);
void digital_tg_recv_sensf_req(struct nfc_digital_dev *ddev, void *arg,
struct sk_buff *resp);
static inline int digital_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
nfc_digital_cmd_complete_t cb, void *arg)
{
return digital_send_cmd(ddev, DIGITAL_CMD_TG_LISTEN, NULL, NULL,
timeout, cb, arg);
}
void digital_tg_recv_atr_req(struct nfc_digital_dev *ddev, void *arg,
struct sk_buff *resp);
int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb);
int digital_tg_listen_nfca(struct nfc_digital_dev *ddev, u8 rf_tech);
int digital_tg_listen_nfcf(struct nfc_digital_dev *ddev, u8 rf_tech);
typedef u16 (*crc_func_t)(u16, const u8 *, size_t);
#define CRC_A_INIT 0x6363
#define CRC_B_INIT 0xFFFF
#define CRC_F_INIT 0x0000
void digital_skb_add_crc(struct sk_buff *skb, crc_func_t crc_func, u16 init,
u8 bitwise_inv, u8 msb_first);
static inline void digital_skb_add_crc_a(struct sk_buff *skb)
{
digital_skb_add_crc(skb, crc_ccitt, CRC_A_INIT, 0, 0);
}
static inline void digital_skb_add_crc_b(struct sk_buff *skb)
{
digital_skb_add_crc(skb, crc_ccitt, CRC_B_INIT, 1, 0);
}
static inline void digital_skb_add_crc_f(struct sk_buff *skb)
{
digital_skb_add_crc(skb, crc_itu_t, CRC_F_INIT, 0, 1);
}
static inline void digital_skb_add_crc_none(struct sk_buff *skb)
{
return;
}
int digital_skb_check_crc(struct sk_buff *skb, crc_func_t crc_func,
u16 crc_init, u8 bitwise_inv, u8 msb_first);
static inline int digital_skb_check_crc_a(struct sk_buff *skb)
{
return digital_skb_check_crc(skb, crc_ccitt, CRC_A_INIT, 0, 0);
}
static inline int digital_skb_check_crc_b(struct sk_buff *skb)
{
return digital_skb_check_crc(skb, crc_ccitt, CRC_B_INIT, 1, 0);
}
static inline int digital_skb_check_crc_f(struct sk_buff *skb)
{
return digital_skb_check_crc(skb, crc_itu_t, CRC_F_INIT, 0, 1);
}
static inline int digital_skb_check_crc_none(struct sk_buff *skb)
{
return 0;
}
#endif /* __DIGITAL_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -58,6 +58,7 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = { ...@@ -58,6 +58,7 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 1] = {
[NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED }, [NFC_ATTR_LLC_SDP] = { .type = NLA_NESTED },
[NFC_ATTR_FIRMWARE_NAME] = { .type = NLA_STRING, [NFC_ATTR_FIRMWARE_NAME] = { .type = NLA_STRING,
.len = NFC_FIRMWARE_NAME_MAXSIZE }, .len = NFC_FIRMWARE_NAME_MAXSIZE },
[NFC_ATTR_SE_APDU] = { .type = NLA_BINARY },
}; };
static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = { static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = {
...@@ -1278,6 +1279,91 @@ static int nfc_genl_dump_ses_done(struct netlink_callback *cb) ...@@ -1278,6 +1279,91 @@ static int nfc_genl_dump_ses_done(struct netlink_callback *cb)
return 0; return 0;
} }
struct se_io_ctx {
u32 dev_idx;
u32 se_idx;
};
static void se_io_cb(void *context, u8 *apdu, size_t apdu_len, int err)
{
struct se_io_ctx *ctx = context;
struct sk_buff *msg;
void *hdr;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg) {
kfree(ctx);
return;
}
hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
NFC_CMD_SE_IO);
if (!hdr)
goto free_msg;
if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, ctx->dev_idx) ||
nla_put_u32(msg, NFC_ATTR_SE_INDEX, ctx->se_idx) ||
nla_put(msg, NFC_ATTR_SE_APDU, apdu_len, apdu))
goto nla_put_failure;
genlmsg_end(msg, hdr);
genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);
kfree(ctx);
return;
nla_put_failure:
genlmsg_cancel(msg, hdr);
free_msg:
nlmsg_free(msg);
kfree(ctx);
return;
}
static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
{
struct nfc_dev *dev;
struct se_io_ctx *ctx;
u32 dev_idx, se_idx;
u8 *apdu;
size_t apdu_len;
if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
!info->attrs[NFC_ATTR_SE_INDEX] ||
!info->attrs[NFC_ATTR_SE_APDU])
return -EINVAL;
dev_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);
se_idx = nla_get_u32(info->attrs[NFC_ATTR_SE_INDEX]);
dev = nfc_get_device(dev_idx);
if (!dev)
return -ENODEV;
if (!dev->ops || !dev->ops->se_io)
return -ENOTSUPP;
apdu_len = nla_len(info->attrs[NFC_ATTR_SE_APDU]);
if (apdu_len == 0)
return -EINVAL;
apdu = nla_data(info->attrs[NFC_ATTR_SE_APDU]);
if (!apdu)
return -EINVAL;
ctx = kzalloc(sizeof(struct se_io_ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
ctx->dev_idx = dev_idx;
ctx->se_idx = se_idx;
return dev->ops->se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
}
static struct genl_ops nfc_genl_ops[] = { static struct genl_ops nfc_genl_ops[] = {
{ {
.cmd = NFC_CMD_GET_DEVICE, .cmd = NFC_CMD_GET_DEVICE,
...@@ -1358,6 +1444,11 @@ static struct genl_ops nfc_genl_ops[] = { ...@@ -1358,6 +1444,11 @@ static struct genl_ops nfc_genl_ops[] = {
.done = nfc_genl_dump_ses_done, .done = nfc_genl_dump_ses_done,
.policy = nfc_genl_policy, .policy = nfc_genl_policy,
}, },
{
.cmd = NFC_CMD_SE_IO,
.doit = nfc_genl_se_io,
.policy = nfc_genl_policy,
},
}; };
......
...@@ -142,11 +142,11 @@ static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb, ...@@ -142,11 +142,11 @@ static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb,
err = rawsock_add_header(skb); err = rawsock_add_header(skb);
if (err) if (err)
goto error; goto error_skb;
err = sock_queue_rcv_skb(sk, skb); err = sock_queue_rcv_skb(sk, skb);
if (err) if (err)
goto error; goto error_skb;
spin_lock_bh(&sk->sk_write_queue.lock); spin_lock_bh(&sk->sk_write_queue.lock);
if (!skb_queue_empty(&sk->sk_write_queue)) if (!skb_queue_empty(&sk->sk_write_queue))
...@@ -158,6 +158,9 @@ static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb, ...@@ -158,6 +158,9 @@ static void rawsock_data_exchange_complete(void *context, struct sk_buff *skb,
sock_put(sk); sock_put(sk);
return; return;
error_skb:
kfree_skb(skb);
error: error:
rawsock_report_error(sk, err); rawsock_report_error(sk, err);
sock_put(sk); sock_put(sk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment