NFC: NCI: Simplify NCI SPI to become a simple framing/checking layer

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>
diff --git a/net/nfc/nci/spi.c b/net/nfc/nci/spi.c
index e66fda4..910dfd8 100644
--- a/net/nfc/nci/spi.c
+++ b/net/nfc/nci/spi.c
@@ -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
 
@@ -41,21 +39,7 @@
 
 #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 @@
 	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 @@
 		*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;
+	struct nci_spi *nspi;
 
-	if (!ops->open || !ops->close || !ops->assert_int || !ops->deassert_int)
+	if (!ops->assert_int || !ops->deassert_int)
 		return NULL;
 
-	if (!supported_protocols)
+	nspi = devm_kzalloc(&spi->dev, sizeof(struct nci_spi), GFP_KERNEL);
+	if (!nspi)
 		return NULL;
 
-	nsdev = devm_kzalloc(&spi->dev, sizeof(struct nci_spi_dev), GFP_KERNEL);
-	if (!nsdev)
-		return NULL;
+	nspi->ops = ops;
+	nspi->acknowledge_mode = acknowledge_mode;
+	nspi->xfer_udelay = delay;
 
-	nsdev->ops = ops;
-	nsdev->acknowledge_mode = acknowledge_mode;
-	nsdev->xfer_udelay = delay;
+	nspi->ndev = ndev;
 
-	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)
-		return NULL;
-
-	nci_set_drvdata(nsdev->ndev, nsdev);
-
-	return nsdev;
+	return nspi;
 }
-EXPORT_SYMBOL_GPL(nci_spi_allocate_device);
+EXPORT_SYMBOL_GPL(nci_spi_allocate_spi);
 
-/**
- * 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);
-
-/**
- * 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);
-
-/**
- * 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);
-}
-EXPORT_SYMBOL_GPL(nci_spi_unregister_device);
-
-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 @@
 	*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 @@
 
 	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 @@
 	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 @@
 	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 @@
 /**
  * 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 @@
  *
  * 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 @@
 		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;
 }