aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Lapuyade <eric.lapuyade@linux.intel.com>2013-09-05 05:02:21 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2013-09-24 19:35:41 -0400
commitfa544fff62aeeb0cf8008c61077aae10fb1407a9 (patch)
tree42e24efbcaca24ad48bde91259696649388483d3
parent08f13acff960d6c95a371f67ab98785aa9969179 (diff)
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>
-rw-r--r--include/net/nfc/nci.h4
-rw-r--r--include/net/nfc/nci_core.h41
-rw-r--r--net/nfc/nci/spi.c180
3 files changed, 70 insertions, 155 deletions
diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h
index 88785e5c6b2c..e5aa5acafea0 100644
--- a/include/net/nfc/nci.h
+++ b/include/net/nfc/nci.h
@@ -166,6 +166,10 @@
166#define NCI_GID_NFCEE_MGMT 0x2 166#define NCI_GID_NFCEE_MGMT 0x2
167#define NCI_GID_PROPRIETARY 0xf 167#define NCI_GID_PROPRIETARY 0xf
168 168
169/* ----- NCI over SPI head/crc(tail) room needed for outgoing frames ----- */
170#define NCI_SPI_HDR_LEN 4
171#define NCI_SPI_CRC_LEN 2
172
169/* ---- NCI Packet structures ---- */ 173/* ---- NCI Packet structures ---- */
170#define NCI_CTRL_HDR_SIZE 3 174#define NCI_CTRL_HDR_SIZE 3
171#define NCI_DATA_HDR_SIZE 3 175#define NCI_DATA_HDR_SIZE 3
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h
index c08399621c8b..37ba06f2dfa9 100644
--- a/include/net/nfc/nci_core.h
+++ b/include/net/nfc/nci_core.h
@@ -207,16 +207,14 @@ int nci_to_errno(__u8 code);
207#define NCI_SPI_CRC_ENABLED 0x01 207#define NCI_SPI_CRC_ENABLED 0x01
208 208
209/* ----- NCI SPI structures ----- */ 209/* ----- NCI SPI structures ----- */
210struct nci_spi_dev; 210struct nci_spi;
211 211
212struct nci_spi_ops { 212struct nci_spi_ops {
213 int (*open)(struct nci_spi_dev *nsdev); 213 void (*assert_int)(struct nci_spi *nspi);
214 int (*close)(struct nci_spi_dev *nsdev); 214 void (*deassert_int)(struct nci_spi *nspi);
215 void (*assert_int)(struct nci_spi_dev *nsdev);
216 void (*deassert_int)(struct nci_spi_dev *nsdev);
217}; 215};
218 216
219struct nci_spi_dev { 217struct nci_spi {
220 struct nci_dev *ndev; 218 struct nci_dev *ndev;
221 struct spi_device *spi; 219 struct spi_device *spi;
222 struct nci_spi_ops *ops; 220 struct nci_spi_ops *ops;
@@ -227,31 +225,14 @@ struct nci_spi_dev {
227 225
228 struct completion req_completion; 226 struct completion req_completion;
229 u8 req_result; 227 u8 req_result;
230
231 void *driver_data;
232}; 228};
233 229
234/* ----- NCI SPI Devices ----- */ 230/* ----- NCI SPI ----- */
235struct nci_spi_dev *nci_spi_allocate_device(struct spi_device *spi, 231struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
236 struct nci_spi_ops *ops, 232 struct nci_spi_ops *ops,
237 u32 supported_protocols, 233 u8 acknowledge_mode, unsigned int delay,
238 u32 supported_se, 234 struct nci_dev *ndev);
239 u8 acknowledge_mode, 235int nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb);
240 unsigned int delay); 236int nci_spi_recv_frame(struct nci_spi *nspi);
241void nci_spi_free_device(struct nci_spi_dev *nsdev);
242int nci_spi_register_device(struct nci_spi_dev *nsdev);
243void nci_spi_unregister_device(struct nci_spi_dev *nsdev);
244int nci_spi_recv_frame(struct nci_spi_dev *nsdev);
245
246static inline void nci_spi_set_drvdata(struct nci_spi_dev *nsdev,
247 void *data)
248{
249 nsdev->driver_data = data;
250}
251
252static inline void *nci_spi_get_drvdata(struct nci_spi_dev *nsdev)
253{
254 return nsdev->driver_data;
255}
256 237
257#endif /* __NCI_CORE_H */ 238#endif /* __NCI_CORE_H */
diff --git a/net/nfc/nci/spi.c b/net/nfc/nci/spi.c
index e66fda4d9ede..910dfd8015f4 100644
--- a/net/nfc/nci/spi.c
+++ b/net/nfc/nci/spi.c
@@ -24,8 +24,6 @@
24#include <linux/nfc.h> 24#include <linux/nfc.h>
25#include <net/nfc/nci_core.h> 25#include <net/nfc/nci_core.h>
26 26
27#define NCI_SPI_HDR_LEN 4
28#define NCI_SPI_CRC_LEN 2
29#define NCI_SPI_ACK_SHIFT 6 27#define NCI_SPI_ACK_SHIFT 6
30#define NCI_SPI_MSB_PAYLOAD_MASK 0x3F 28#define NCI_SPI_MSB_PAYLOAD_MASK 0x3F
31 29
@@ -41,21 +39,7 @@
41 39
42#define CRC_INIT 0xFFFF 40#define CRC_INIT 0xFFFF
43 41
44static int nci_spi_open(struct nci_dev *ndev) 42static int __nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb)
45{
46 struct nci_spi_dev *nsdev = nci_get_drvdata(ndev);
47
48 return nsdev->ops->open(nsdev);
49}
50
51static int nci_spi_close(struct nci_dev *ndev)
52{
53 struct nci_spi_dev *nsdev = nci_get_drvdata(ndev);
54
55 return nsdev->ops->close(nsdev);
56}
57
58static int __nci_spi_send(struct nci_spi_dev *nsdev, struct sk_buff *skb)
59{ 43{
60 struct spi_message m; 44 struct spi_message m;
61 struct spi_transfer t; 45 struct spi_transfer t;
@@ -63,32 +47,31 @@ static int __nci_spi_send(struct nci_spi_dev *nsdev, struct sk_buff *skb)
63 t.tx_buf = skb->data; 47 t.tx_buf = skb->data;
64 t.len = skb->len; 48 t.len = skb->len;
65 t.cs_change = 0; 49 t.cs_change = 0;
66 t.delay_usecs = nsdev->xfer_udelay; 50 t.delay_usecs = nspi->xfer_udelay;
67 51
68 spi_message_init(&m); 52 spi_message_init(&m);
69 spi_message_add_tail(&t, &m); 53 spi_message_add_tail(&t, &m);
70 54
71 return spi_sync(nsdev->spi, &m); 55 return spi_sync(nspi->spi, &m);
72} 56}
73 57
74static int nci_spi_send(struct nci_dev *ndev, struct sk_buff *skb) 58int nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb)
75{ 59{
76 struct nci_spi_dev *nsdev = nci_get_drvdata(ndev);
77 unsigned int payload_len = skb->len; 60 unsigned int payload_len = skb->len;
78 unsigned char *hdr; 61 unsigned char *hdr;
79 int ret; 62 int ret;
80 long completion_rc; 63 long completion_rc;
81 64
82 nsdev->ops->deassert_int(nsdev); 65 nspi->ops->deassert_int(nspi);
83 66
84 /* add the NCI SPI header to the start of the buffer */ 67 /* add the NCI SPI header to the start of the buffer */
85 hdr = skb_push(skb, NCI_SPI_HDR_LEN); 68 hdr = skb_push(skb, NCI_SPI_HDR_LEN);
86 hdr[0] = NCI_SPI_DIRECT_WRITE; 69 hdr[0] = NCI_SPI_DIRECT_WRITE;
87 hdr[1] = nsdev->acknowledge_mode; 70 hdr[1] = nspi->acknowledge_mode;
88 hdr[2] = payload_len >> 8; 71 hdr[2] = payload_len >> 8;
89 hdr[3] = payload_len & 0xFF; 72 hdr[3] = payload_len & 0xFF;
90 73
91 if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED) { 74 if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
92 u16 crc; 75 u16 crc;
93 76
94 crc = crc_ccitt(CRC_INIT, skb->data, skb->len); 77 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)
96 *skb_put(skb, 1) = crc & 0xFF; 79 *skb_put(skb, 1) = crc & 0xFF;
97 } 80 }
98 81
99 ret = __nci_spi_send(nsdev, skb); 82 ret = __nci_spi_send(nspi, skb);
100 83
101 kfree_skb(skb); 84 kfree_skb(skb);
102 nsdev->ops->assert_int(nsdev); 85 nspi->ops->assert_int(nspi);
103 86
104 if (ret != 0 || nsdev->acknowledge_mode == NCI_SPI_CRC_DISABLED) 87 if (ret != 0 || nspi->acknowledge_mode == NCI_SPI_CRC_DISABLED)
105 goto done; 88 goto done;
106 89
107 init_completion(&nsdev->req_completion); 90 init_completion(&nspi->req_completion);
108 completion_rc = wait_for_completion_interruptible_timeout( 91 completion_rc = wait_for_completion_interruptible_timeout(
109 &nsdev->req_completion, 92 &nspi->req_completion,
110 NCI_SPI_SEND_TIMEOUT); 93 NCI_SPI_SEND_TIMEOUT);
111 94