aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
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 /net/nfc
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>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/nci/spi.c180
1 files changed, 55 insertions, 125 deletions
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
112 if (completion_rc <= 0 || nsdev->req_result == ACKNOWLEDGE_NACK) 95 if (completion_rc <= 0 || nspi->req_result == ACKNOWLEDGE_NACK)
113 ret = -EIO; 96 ret = -EIO;
114 97
115done: 98done:
116 return ret; 99 return ret;
117} 100}
118 101EXPORT_SYMBOL_GPL(nci_spi_send);
119static struct nci_ops nci_spi_ops = {
120 .open = nci_spi_open,
121 .close = nci_spi_close,
122 .send = nci_spi_send,
123};
124 102
125/* ---- Interface to NCI SPI drivers ---- */ 103/* ---- Interface to NCI SPI drivers ---- */
126 104
127/** 105/**
128 * nci_spi_allocate_device - allocate a new nci spi device 106 * nci_spi_allocate_spi - allocate a new nci spi
129 * 107 *
130 * @spi: SPI device 108 * @spi: SPI device
131 * @ops: device operations 109 * @ops: device operations
132 * @supported_protocols: NFC protocols supported by the device 110 * @acknowledge_mode: Acknowledge mode used by the NFC device
133 * @supported_se: NFC Secure Elements supported by the device
134 * @acknowledge_mode: Acknowledge mode used by the device
135 * @delay: delay between transactions in us 111 * @delay: delay between transactions in us
112 * @ndev: nci dev to send incoming nci frames to
136 */ 113 */
137struct nci_spi_dev *nci_spi_allocate_device(struct spi_device *spi, 114struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
138 struct nci_spi_ops *ops, 115 struct nci_spi_ops *ops,
139 u32 supported_protocols, 116 u8 acknowledge_mode, unsigned int delay,
140 u32 supported_se, 117 struct nci_dev *ndev)
141 u8 acknowledge_mode,
142 unsigned int delay)
143{ 118{
144 struct nci_spi_dev *nsdev; 119 struct nci_spi *nspi;
145 int tailroom = 0;
146
147 if (!ops->open || !ops->close || !ops->assert_int || !ops->deassert_int)
148 return NULL;
149
150 if (!supported_protocols)
151 return NULL;
152 120
153 nsdev = devm_kzalloc(&spi->dev, sizeof(struct nci_spi_dev), GFP_KERNEL); 121 if (!ops->assert_int || !ops->deassert_int)
154 if (!nsdev)
155 return NULL; 122 return NULL;
156 123
157 nsdev->ops = ops; 124 nspi = devm_kzalloc(&spi->dev, sizeof(struct nci_spi), GFP_KERNEL);
158 nsdev->acknowledge_mode = acknowledge_mode; 125 if (!nspi)
159 nsdev->xfer_udelay = delay;
160
161 if (acknowledge_mode == NCI_SPI_CRC_ENABLED)
162 tailroom += NCI_SPI_CRC_LEN;
163
164 nsdev->ndev = nci_allocate_device(&nci_spi_ops, supported_protocols,
165 NCI_SPI_HDR_LEN, tailroom);
166 if (!nsdev->ndev)
167 return NULL; 126 return NULL;
168 127
169 nci_set_drvdata(nsdev->ndev, nsdev); 128 nspi->ops = ops;
170 129 nspi->acknowledge_mode = acknowledge_mode;
171 return nsdev; 130 nspi->xfer_udelay = delay;
172}
173EXPORT_SYMBOL_GPL(nci_spi_allocate_device);
174
175/**
176 * nci_spi_free_device - deallocate nci spi device
177 *
178 * @nsdev: The nci spi device to deallocate
179 */
180void nci_spi_free_device(struct nci_spi_dev *nsdev)
181{
182 nci_free_device(nsdev->ndev);
183}
184EXPORT_SYMBOL_GPL(nci_spi_free_device);
185 131
186/** 132 nspi->ndev = ndev;
187 * nci_spi_register_device - register a nci spi device in the nfc subsystem
188 *
189 * @pdev: The nci spi device to register
190 */
191int nci_spi_register_device(struct nci_spi_dev *nsdev)
192{
193 return nci_register_device(nsdev->ndev);
194}
195EXPORT_SYMBOL_GPL(nci_spi_register_device);
196 133
197/** 134 return nspi;
198 * nci_spi_unregister_device - unregister a nci spi device in the nfc subsystem
199 *
200 * @dev: The nci spi device to unregister
201 */
202void nci_spi_unregister_device(struct nci_spi_dev *nsdev)
203{
204 nci_unregister_device(nsdev->ndev);
205} 135}
206EXPORT_SYMBOL_GPL(nci_spi_unregister_device); 136EXPORT_SYMBOL_GPL(nci_spi_allocate_spi);
207 137
208static int send_acknowledge(struct nci_spi_dev *nsdev, u8 acknowledge) 138static int send_acknowledge(struct nci_spi *nspi, u8 acknowledge)
209{ 139{
210 struct sk_buff *skb; 140 struct sk_buff *skb;
211 unsigned char *hdr; 141 unsigned char *hdr;
212 u16 crc; 142 u16 crc;
213 int ret; 143 int ret;
214 144
215 skb = nci_skb_alloc(nsdev->ndev, 0, GFP_KERNEL); 145 skb = nci_skb_alloc(nspi->ndev, 0, GFP_KERNEL);
216 146
217 /* add the NCI SPI header to the start of the buffer */ 147 /* add the NCI SPI header to the start of the buffer */
218 hdr = skb_push(skb, NCI_SPI_HDR_LEN); 148 hdr = skb_push(skb, NCI_SPI_HDR_LEN);
@@ -225,14 +155,14 @@ static int send_acknowledge(struct nci_spi_dev *nsdev, u8 acknowledge)
225 *skb_put(skb, 1) = crc >> 8; 155 *skb_put(skb, 1) = crc >> 8;
226 *skb_put(skb, 1) = crc & 0xFF; 156 *skb_put(skb, 1) = crc & 0xFF;
227 157
228 ret = __nci_spi_send(nsdev, skb); 158 ret = __nci_spi_send(nspi, skb);
229 159
230 kfree_skb(skb); 160 kfree_skb(skb);
231 161
232 return ret; 162 return ret;
233} 163}
234 164
235static struct sk_buff *__nci_spi_recv_frame(struct nci_spi_dev *nsdev) 165static struct sk_buff *__nci_spi_recv_frame(struct nci_spi *nspi)
236{ 166{
237 struct sk_buff *skb; 167 struct sk_buff *skb;
238 struct spi_message m; 168 struct spi_message m;
@@ -243,7 +173,7 @@ static struct sk_buff *__nci_spi_recv_frame(struct nci_spi_dev *nsdev)
243 173
244 spi_message_init(&m); 174 spi_message_init(&m);
245 req[0] = NCI_SPI_DIRECT_READ; 175 req[0] = NCI_SPI_DIRECT_READ;
246 req[1] = nsdev->acknowledge_mode; 176 req[1] = nspi->acknowledge_mode;
247 tx.tx_buf = req; 177 tx.tx_buf = req;
248 tx.len = 2; 178 tx.len = 2;
249 tx.cs_change = 0; 179 tx.cs_change = 0;
@@ -252,18 +182,18 @@ static struct sk_buff *__nci_spi_recv_frame(struct nci_spi_dev *nsdev)
252 rx.len = 2; 182 rx.len = 2;
253 rx.cs_change = 1; 183 rx.cs_change = 1;
254 spi_message_add_tail(&rx, &m); 184 spi_message_add_tail(&rx, &m);
255 ret = spi_sync(nsdev->spi, &m); 185 ret = spi_sync(nspi->spi, &m);
256 186
257 if (ret) 187 if (ret)
258 return NULL; 188 return NULL;
259 189
260 if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED) 190 if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED)
261 rx_len = ((resp_hdr[0] & NCI_SPI_MSB_PAYLOAD_MASK) << 8) + 191 rx_len = ((resp_hdr[0] & NCI_SPI_MSB_PAYLOAD_MASK) << 8) +
262 resp_hdr[1] + NCI_SPI_CRC_LEN; 192 resp_hdr[1] + NCI_SPI_CRC_LEN;
263 else 193 else
264 rx_len = (resp_hdr[0] << 8) | resp_hdr[1]; 194 rx_len = (resp_hdr[0] << 8) | resp_hdr[1];
265 195
266 skb = nci_skb_alloc(nsdev->ndev, rx_len, GFP_KERNEL); 196 skb = nci_skb_alloc(nspi->ndev, rx_len, GFP_KERNEL);
267 if (!skb) 197 if (!skb)
268 return NULL; 198 return NULL;
269 199
@@ -271,14 +201,14 @@ static struct sk_buff *__nci_spi_recv_frame(struct nci_spi_dev *nsdev)
271 rx.rx_buf = skb_put(skb, rx_len); 201 rx.rx_buf = skb_put(skb, rx_len);
272 rx.len = rx_len; 202 rx.len = rx_len;
273 rx.cs_change = 0; 203 rx.cs_change = 0;
274 rx.delay_usecs = nsdev->xfer_udelay; 204 rx.delay_usecs = nspi->xfer_udelay;
275 spi_message_add_tail(&rx, &m); 205 spi_message_add_tail(&rx, &m);
276 ret = spi_sync(nsdev->spi, &m); 206 ret = spi_sync(nspi->spi, &m);
277 207
278 if (ret) 208 if (ret)
279 goto receive_error; 209 goto receive_error;
280 210
281 if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED) { 211 if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
282 *skb_push(skb, 1) = resp_hdr[1]; 212 *skb_push(skb, 1) = resp_hdr[1];
283 *skb_push(skb, 1) = resp_hdr[0]; 213 *skb_push(skb, 1) = resp_hdr[0];
284 } 214 }
@@ -320,7 +250,7 @@ static u8 nci_spi_get_ack(struct sk_buff *skb)
320/** 250/**
321 * nci_spi_recv_frame - receive frame from NCI SPI drivers 251 * nci_spi_recv_frame - receive frame from NCI SPI drivers
322 * 252 *
323 * @nsdev: The nci spi device 253 * @nspi: The nci spi
324 * Context: can sleep 254 * Context: can sleep
325 * 255 *
326 * This call may only be used from a context that may sleep. The sleep 256 * 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)
328 * 258 *
329 * It returns zero on success, else a negative error code. 259 * It returns zero on success, else a negative error code.
330 */ 260 */
331int nci_spi_recv_frame(struct nci_spi_dev *nsdev) 261int nci_spi_recv_frame(struct nci_spi *nspi)
332{ 262{
333 struct sk_buff *skb; 263 struct sk_buff *skb;
334 int ret = 0; 264 int ret = 0;
335 265
336 nsdev->ops->deassert_int(nsdev); 266 nspi->ops->deassert_int(nspi);
337 267
338 /* Retrieve frame from SPI */ 268 /* Retrieve frame from SPI */
339 skb = __nci_spi_recv_frame(nsdev); 269 skb = __nci_spi_recv_frame(nspi);
340 if (!skb) { 270 if (!skb) {
341 ret = -EIO; 271 ret = -EIO;
342 goto done; 272 goto done;
343 } 273 }
344 274
345 if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED) { 275 if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
346 if (!nci_spi_check_crc(skb)) { 276 if (!nci_spi_check_crc(skb)) {
347 send_acknowledge(nsdev, ACKNOWLEDGE_NACK); 277 send_acknowledge(nspi, ACKNOWLEDGE_NACK);
348 goto done; 278 goto done;
349 } 279 }
350 280
351 /* In case of acknowledged mode: if ACK or NACK received, 281 /* In case of acknowledged mode: if ACK or NACK received,
352 * unblock completion of latest frame sent. 282 * unblock completion of latest frame sent.
353 */ 283 */
354 nsdev->req_result = nci_spi_get_ack(skb); 284 nspi->req_result = nci_spi_get_ack(skb);
355 if (nsdev->req_result) 285 if (nspi->req_result)
356 complete(&nsdev->req_completion); 286 complete(&nspi->req_completion);
357 } 287 }
358 288
359 /* If there is no payload (ACK/NACK only frame), 289 /* If there is no payload (ACK/NACK only frame),
@@ -364,14 +294,14 @@ int nci_spi_recv_frame(struct nci_spi_dev *nsdev)
364 goto done; 294 goto done;
365 } 295 }
366 296
367 if (nsdev->acknowledge_mode == NCI_SPI_CRC_ENABLED) 297 if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED)
368 send_acknowledge(nsdev, ACKNOWLEDGE_ACK); 298 send_acknowledge(nspi, ACKNOWLEDGE_ACK);
369 299
370 /* Forward skb to NCI core layer */ 300 /* Forward skb to NCI core layer */
371 ret = nci_recv_frame(nsdev->ndev, skb); 301 ret = nci_recv_frame(nspi->ndev, skb);
372 302
373done: 303done:
374 nsdev->ops->assert_int(nsdev); 304 nspi->ops->assert_int(nspi);
375 305
376 return ret; 306 return ret;
377} 307}