]> Pileus Git - ~andy/linux/commitdiff
NFC: NCI: Simplify NCI SPI to become a simple framing/checking layer
authorEric Lapuyade <eric.lapuyade@linux.intel.com>
Thu, 5 Sep 2013 09:02:21 +0000 (11:02 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Tue, 24 Sep 2013 23:35:41 +0000 (01:35 +0200)
NCI SPI layer should not manage the nci dev, this is the job of the nci
chipset driver. This layer should be limited to frame/deframe nci
packets, and optionnaly check integrity (crc) and manage the ack/nak
protocol.

The NCI SPI must not be mixed up with an NCI dev. spi_[dev|device] are
therefore renamed to a simple spi for more clarity.
The header and crc sizes are moved to nci.h so that drivers can use
them to reserve space in outgoing skbs.
nci_spi_send() is exported to be accessible by drivers.

Signed-off-by: Eric Lapuyade <eric.lapuyade@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
include/net/nfc/nci.h
include/net/nfc/nci_core.h
net/nfc/nci/spi.c

index 88785e5c6b2cf6d2c32a8af553259a9d21678025..e5aa5acafea0e0e176e83ce50d58d33529be4669 100644 (file)
 #define NCI_GID_NFCEE_MGMT                                     0x2
 #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 ---- */
 #define NCI_CTRL_HDR_SIZE                                      3
 #define NCI_DATA_HDR_SIZE                                      3
index c08399621c8b220f94941d533e686e60734aec7a..37ba06f2dfa9e00a7f81912ded1748f5cc6823b6 100644 (file)
@@ -207,16 +207,14 @@ int nci_to_errno(__u8 code);
 #define NCI_SPI_CRC_ENABLED    0x01
 
 /* ----- NCI SPI structures ----- */
-struct nci_spi_dev;
+struct nci_spi;
 
 struct nci_spi_ops {
-       int (*open)(struct nci_spi_dev *nsdev);
-       int (*close)(struct nci_spi_dev *nsdev);
-       void (*assert_int)(struct nci_spi_dev *nsdev);
-       void (*deassert_int)(struct nci_spi_dev *nsdev);
+       void (*assert_int)(struct nci_spi *nspi);
+       void (*deassert_int)(struct nci_spi *nspi);
 };
 
-struct nci_spi_dev {
+struct nci_spi {
        struct nci_dev          *ndev;
        struct spi_device       *spi;
        struct nci_spi_ops      *ops;
@@ -227,31 +225,14 @@ struct nci_spi_dev {
 
        struct completion       req_completion;
        u8                      req_result;
-
-       void                    *driver_data;
 };
 
-/* ----- NCI SPI Devices ----- */
-struct nci_spi_dev *nci_spi_allocate_device(struct spi_device *spi,
-                                               struct nci_spi_ops *ops,
-                                               u32 supported_protocols,
-                                               u32 supported_se,
-                                               u8 acknowledge_mode,
-                                               unsigned int delay);
-void nci_spi_free_device(struct nci_spi_dev *nsdev);
-int nci_spi_register_device(struct nci_spi_dev *nsdev);
-void nci_spi_unregister_device(struct nci_spi_dev *nsdev);
-int nci_spi_recv_frame(struct nci_spi_dev *nsdev);
-
-static inline void nci_spi_set_drvdata(struct nci_spi_dev *nsdev,
-                                           void *data)
-{
-       nsdev->driver_data = data;
-}
-
-static inline void *nci_spi_get_drvdata(struct nci_spi_dev *nsdev)
-{
-       return nsdev->driver_data;
-}
+/* ----- NCI SPI ----- */
+struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
+                                    struct nci_spi_ops *ops,
+                                    u8 acknowledge_mode, unsigned int delay,
+                                    struct nci_dev *ndev);
+int nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb);
+int nci_spi_recv_frame(struct nci_spi *nspi);
 
 #endif /* __NCI_CORE_H */
index e66fda4d9edeba3b1f1c9ef030be23069fead37d..910dfd8015f41294331383648e42d0fb38304add 100644 (file)
@@ -24,8 +24,6 @@
 #include <linux/nfc.h>
 #include <net/nfc/nci_core.h>
 
-#define NCI_SPI_HDR_LEN                        4
-#define NCI_SPI_CRC_LEN                        2
 #define NCI_SPI_ACK_SHIFT              6
 #define NCI_SPI_MSB_PAYLOAD_MASK       0x3F
 
 
 #define CRC_INIT               0xFFFF
 
-static int nci_spi_open(struct nci_dev *ndev)
-{
-       struct nci_spi_dev *nsdev = nci_get_drvdata(ndev);
-
-       return nsdev->ops->open(nsdev);
-}
-
-static int nci_spi_close(struct nci_dev *ndev)
-{
-       struct nci_spi_dev *nsdev = nci_get_drvdata(ndev);
-
-       return nsdev->ops->close(nsdev);
-}
-
-static int __nci_spi_send(struct nci_spi_dev *nsdev, struct sk_buff *skb)
+static int __nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb)
 {
        struct spi_message m;
        struct spi_transfer t;
@@ -63,32 +47,31 @@ static int __nci_spi_send(struct nci_spi_dev *nsdev, struct sk_buff *skb)
        t.tx_buf = skb->data;
        t.len = skb->len;
        t.cs_change = 0;
-       t.delay_usecs = nsdev->xfer_udelay;
+       t.delay_usecs = nspi->xfer_udelay;
 
        spi_message_init(&m);
        spi_message_add_tail(&t, &m);
 
-       return spi_sync(nsdev->spi, &m);
+       return spi_sync(nspi->spi, &m);
 }
 
-static int nci_spi_send(struct nci_dev *ndev, struct sk_buff *skb)
+int nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb)
 {
-       struct nci_spi_dev *nsdev = nci_get_drvdata(ndev);
        unsigned int payload_len = skb->len;
        unsigned char *hdr;
        int ret;
        long completion_rc;
 
-       nsdev->ops->deassert_int(nsdev);
+       nspi->ops->deassert_int(nspi);
 
        /* add the NCI SPI header to the start of the buffer */
        hdr = skb_push(skb, NCI_SPI_HDR_LEN);
        hdr[0] = NCI_SPI_DIRECT_WRITE;
-       hdr[1] = nsdev->acknowledge_mode;
+       hdr[1] = nspi->acknowledge_mode;
        hdr[2] = payload_len >> 8;
        hdr[3] = payload_len & 0xFF;
 
-       if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
+       if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
                u16 crc;
 
                crc = crc_ccitt(CRC_INIT, skb->data, skb->len);
@@ -96,123 +79,70 @@ static int nci_spi_send(struct nci_dev *ndev, struct sk_buff *skb)
                *skb_put(skb, 1) = crc & 0xFF;
        }
 
-       ret = __nci_spi_send(nsdev, skb);
+       ret = __nci_spi_send(nspi, skb);
 
        kfree_skb(skb);
-       nsdev->ops->assert_int(nsdev);
+       nspi->ops->assert_int(nspi);
 
-       if (ret != 0 || nsdev->acknowledge_mode == NCI_SPI_CRC_DISABLED)
+       if (ret != 0 || nspi->acknowledge_mode == NCI_SPI_CRC_DISABLED)
                goto done;
 
-       init_completion(&nsdev->req_completion);
+       init_completion(&nspi->req_completion);
        completion_rc = wait_for_completion_interruptible_timeout(
-                                                       &nsdev->req_completion,
+                                                       &nspi->req_completion,
                                                        NCI_SPI_SEND_TIMEOUT);
 
-       if (completion_rc <= 0 || nsdev->req_result == ACKNOWLEDGE_NACK)
+       if (completion_rc <= 0 || nspi->req_result == ACKNOWLEDGE_NACK)
                ret = -EIO;
 
 done:
        return ret;
 }
-
-static struct nci_ops nci_spi_ops = {
-       .open = nci_spi_open,
-       .close = nci_spi_close,
-       .send = nci_spi_send,
-};
+EXPORT_SYMBOL_GPL(nci_spi_send);
 
 /* ---- Interface to NCI SPI drivers ---- */
 
 /**
- * nci_spi_allocate_device - allocate a new nci spi device
+ * nci_spi_allocate_spi - allocate a new nci spi
  *
  * @spi: SPI device
  * @ops: device operations
- * @supported_protocols: NFC protocols supported by the device
- * @supported_se: NFC Secure Elements supported by the device
- * @acknowledge_mode: Acknowledge mode used by the device
+ * @acknowledge_mode: Acknowledge mode used by the NFC device
  * @delay: delay between transactions in us
+ * @ndev: nci dev to send incoming nci frames to
  */
-struct nci_spi_dev *nci_spi_allocate_device(struct spi_device *spi,
-                                               struct nci_spi_ops *ops,
-                                               u32 supported_protocols,
-                                               u32 supported_se,
-                                               u8 acknowledge_mode,
-                                               unsigned int delay)
+struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
+                                    struct nci_spi_ops *ops,
+                                    u8 acknowledge_mode, unsigned int delay,
+                                    struct nci_dev *ndev)
 {
-       struct nci_spi_dev *nsdev;
-       int tailroom = 0;
-
-       if (!ops->open || !ops->close || !ops->assert_int || !ops->deassert_int)
-               return NULL;
-
-       if (!supported_protocols)
-               return NULL;
+       struct nci_spi *nspi;
 
-       nsdev = devm_kzalloc(&spi->dev, sizeof(struct nci_spi_dev), GFP_KERNEL);
-       if (!nsdev)
+       if (!ops->assert_int || !ops->deassert_int)
                return NULL;
 
-       nsdev->ops = ops;
-       nsdev->acknowledge_mode = acknowledge_mode;
-       nsdev->xfer_udelay = delay;
-
-       if (acknowledge_mode == NCI_SPI_CRC_ENABLED)
-               tailroom += NCI_SPI_CRC_LEN;
-
-       nsdev->ndev = nci_allocate_device(&nci_spi_ops, supported_protocols,
-                                         NCI_SPI_HDR_LEN, tailroom);
-       if (!nsdev->ndev)
+       nspi = devm_kzalloc(&spi->dev, sizeof(struct nci_spi), GFP_KERNEL);
+       if (!nspi)
                return NULL;
 
-       nci_set_drvdata(nsdev->ndev, nsdev);
-
-       return nsdev;
-}
-EXPORT_SYMBOL_GPL(nci_spi_allocate_device);
-
-/**
- * nci_spi_free_device - deallocate nci spi device
- *
- * @nsdev: The nci spi device to deallocate
- */
-void nci_spi_free_device(struct nci_spi_dev *nsdev)
-{
-       nci_free_device(nsdev->ndev);
-}
-EXPORT_SYMBOL_GPL(nci_spi_free_device);
+       nspi->ops = ops;
+       nspi->acknowledge_mode = acknowledge_mode;
+       nspi->xfer_udelay = delay;
 
-/**
- * nci_spi_register_device - register a nci spi device in the nfc subsystem
- *
- * @pdev: The nci spi device to register
- */
-int nci_spi_register_device(struct nci_spi_dev *nsdev)
-{
-       return nci_register_device(nsdev->ndev);
-}
-EXPORT_SYMBOL_GPL(nci_spi_register_device);
+       nspi->ndev = ndev;
 
-/**
- * nci_spi_unregister_device - unregister a nci spi device in the nfc subsystem
- *
- * @dev: The nci spi device to unregister
- */
-void nci_spi_unregister_device(struct nci_spi_dev *nsdev)
-{
-       nci_unregister_device(nsdev->ndev);
+       return nspi;
 }
-EXPORT_SYMBOL_GPL(nci_spi_unregister_device);
+EXPORT_SYMBOL_GPL(nci_spi_allocate_spi);
 
-static int send_acknowledge(struct nci_spi_dev *nsdev, u8 acknowledge)
+static int send_acknowledge(struct nci_spi *nspi, u8 acknowledge)
 {
        struct sk_buff *skb;
        unsigned char *hdr;
        u16 crc;
        int ret;
 
-       skb = nci_skb_alloc(nsdev->ndev, 0, GFP_KERNEL);
+       skb = nci_skb_alloc(nspi->ndev, 0, GFP_KERNEL);
 
        /* add the NCI SPI header to the start of the buffer */
        hdr = skb_push(skb, NCI_SPI_HDR_LEN);
@@ -225,14 +155,14 @@ static int send_acknowledge(struct nci_spi_dev *nsdev, u8 acknowledge)
        *skb_put(skb, 1) = crc >> 8;
        *skb_put(skb, 1) = crc & 0xFF;
 
-       ret = __nci_spi_send(nsdev, skb);
+       ret = __nci_spi_send(nspi, skb);
 
        kfree_skb(skb);
 
        return ret;
 }
 
-static struct sk_buff *__nci_spi_recv_frame(struct nci_spi_dev *nsdev)
+static struct sk_buff *__nci_spi_recv_frame(struct nci_spi *nspi)
 {
        struct sk_buff *skb;
        struct spi_message m;
@@ -243,7 +173,7 @@ static struct sk_buff *__nci_spi_recv_frame(struct nci_spi_dev *nsdev)
 
        spi_message_init(&m);
        req[0] = NCI_SPI_DIRECT_READ;
-       req[1] = nsdev->acknowledge_mode;
+       req[1] = nspi->acknowledge_mode;
        tx.tx_buf = req;
        tx.len = 2;
        tx.cs_change = 0;
@@ -252,18 +182,18 @@ static struct sk_buff *__nci_spi_recv_frame(struct nci_spi_dev *nsdev)
        rx.len = 2;
        rx.cs_change = 1;
        spi_message_add_tail(&rx, &m);
-       ret = spi_sync(nsdev->spi, &m);
+       ret = spi_sync(nspi->spi, &m);
 
        if (ret)
                return NULL;
 
-       if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED)
+       if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED)
                rx_len = ((resp_hdr[0] & NCI_SPI_MSB_PAYLOAD_MASK) << 8) +
                                resp_hdr[1] + NCI_SPI_CRC_LEN;
        else
                rx_len = (resp_hdr[0] << 8) | resp_hdr[1];
 
-       skb = nci_skb_alloc(nsdev->ndev, rx_len, GFP_KERNEL);
+       skb = nci_skb_alloc(nspi->ndev, rx_len, GFP_KERNEL);
        if (!skb)
                return NULL;
 
@@ -271,14 +201,14 @@ static struct sk_buff *__nci_spi_recv_frame(struct nci_spi_dev *nsdev)
        rx.rx_buf = skb_put(skb, rx_len);
        rx.len = rx_len;
        rx.cs_change = 0;
-       rx.delay_usecs = nsdev->xfer_udelay;
+       rx.delay_usecs = nspi->xfer_udelay;
        spi_message_add_tail(&rx, &m);
-       ret = spi_sync(nsdev->spi, &m);
+       ret = spi_sync(nspi->spi, &m);
 
        if (ret)
                goto receive_error;
 
-       if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
+       if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
                *skb_push(skb, 1) = resp_hdr[1];
                *skb_push(skb, 1) = resp_hdr[0];
        }
@@ -320,7 +250,7 @@ static u8 nci_spi_get_ack(struct sk_buff *skb)
 /**
  * nci_spi_recv_frame - receive frame from NCI SPI drivers
  *
- * @nsdev: The nci spi device
+ * @nspi: The nci spi
  * Context: can sleep
  *
  * This call may only be used from a context that may sleep.  The sleep
@@ -328,32 +258,32 @@ static u8 nci_spi_get_ack(struct sk_buff *skb)
  *
  * It returns zero on success, else a negative error code.
  */
-int nci_spi_recv_frame(struct nci_spi_dev *nsdev)
+int nci_spi_recv_frame(struct nci_spi *nspi)
 {
        struct sk_buff *skb;
        int ret = 0;
 
-       nsdev->ops->deassert_int(nsdev);
+       nspi->ops->deassert_int(nspi);
 
        /* Retrieve frame from SPI */
-       skb = __nci_spi_recv_frame(nsdev);
+       skb = __nci_spi_recv_frame(nspi);
        if (!skb) {
                ret = -EIO;
                goto done;
        }
 
-       if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
+       if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
                if (!nci_spi_check_crc(skb)) {
-                       send_acknowledge(nsdev, ACKNOWLEDGE_NACK);
+                       send_acknowledge(nspi, ACKNOWLEDGE_NACK);
                        goto done;
                }
 
                /* In case of acknowledged mode: if ACK or NACK received,
                 * unblock completion of latest frame sent.
                 */
-               nsdev->req_result = nci_spi_get_ack(skb);
-               if (nsdev->req_result)
-                       complete(&nsdev->req_completion);
+               nspi->req_result = nci_spi_get_ack(skb);
+               if (nspi->req_result)
+                       complete(&nspi->req_completion);
        }
 
        /* If there is no payload (ACK/NACK only frame),
@@ -364,14 +294,14 @@ int nci_spi_recv_frame(struct nci_spi_dev *nsdev)
                goto done;
        }
 
-       if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED)
-               send_acknowledge(nsdev, ACKNOWLEDGE_ACK);
+       if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED)
+               send_acknowledge(nspi, ACKNOWLEDGE_ACK);
 
        /* Forward skb to NCI core layer */
-       ret = nci_recv_frame(nsdev->ndev, skb);
+       ret = nci_recv_frame(nspi->ndev, skb);
 
 done:
-       nsdev->ops->assert_int(nsdev);
+       nspi->ops->assert_int(nspi);
 
        return ret;
 }