NFC: NCI: Fix wrong allocation size in nci_spi_allocate_device()
[cascardo/linux.git] / net / nfc / nci / spi.c
1 /*
2  * Copyright (C) 2013  Intel Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16  *
17  */
18
19 #define pr_fmt(fmt) "nci_spi: %s: " fmt, __func__
20
21 #include <linux/export.h>
22 #include <linux/spi/spi.h>
23 #include <linux/crc-ccitt.h>
24 #include <linux/nfc.h>
25 #include <net/nfc/nci_core.h>
26
27 #define NCI_SPI_HDR_LEN                 4
28 #define NCI_SPI_CRC_LEN                 2
29 #define NCI_SPI_ACK_SHIFT               6
30 #define NCI_SPI_MSB_PAYLOAD_MASK        0x3F
31
32 #define NCI_SPI_SEND_TIMEOUT    (NCI_CMD_TIMEOUT > NCI_DATA_TIMEOUT ? \
33                                         NCI_CMD_TIMEOUT : NCI_DATA_TIMEOUT)
34
35 #define NCI_SPI_DIRECT_WRITE    0x01
36 #define NCI_SPI_DIRECT_READ     0x02
37
38 #define ACKNOWLEDGE_NONE        0
39 #define ACKNOWLEDGE_ACK         1
40 #define ACKNOWLEDGE_NACK        2
41
42 #define CRC_INIT                0xFFFF
43
44 static int nci_spi_open(struct nci_dev *nci_dev)
45 {
46         struct nci_spi_dev *ndev = nci_get_drvdata(nci_dev);
47
48         return ndev->ops->open(ndev);
49 }
50
51 static int nci_spi_close(struct nci_dev *nci_dev)
52 {
53         struct nci_spi_dev *ndev = nci_get_drvdata(nci_dev);
54
55         return ndev->ops->close(ndev);
56 }
57
58 static int __nci_spi_send(struct nci_spi_dev *ndev, struct sk_buff *skb)
59 {
60         struct spi_message m;
61         struct spi_transfer t;
62
63         t.tx_buf = skb->data;
64         t.len = skb->len;
65         t.cs_change = 0;
66         t.delay_usecs = ndev->xfer_udelay;
67
68         spi_message_init(&m);
69         spi_message_add_tail(&t, &m);
70
71         return spi_sync(ndev->spi, &m);
72 }
73
74 static int nci_spi_send(struct nci_dev *nci_dev, struct sk_buff *skb)
75 {
76         struct nci_spi_dev *ndev = nci_get_drvdata(nci_dev);
77         unsigned int payload_len = skb->len;
78         unsigned char *hdr;
79         int ret;
80         long completion_rc;
81
82         ndev->ops->deassert_int(ndev);
83
84         /* add the NCI SPI header to the start of the buffer */
85         hdr = skb_push(skb, NCI_SPI_HDR_LEN);
86         hdr[0] = NCI_SPI_DIRECT_WRITE;
87         hdr[1] = ndev->acknowledge_mode;
88         hdr[2] = payload_len >> 8;
89         hdr[3] = payload_len & 0xFF;
90
91         if (ndev->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
92                 u16 crc;
93
94                 crc = crc_ccitt(CRC_INIT, skb->data, skb->len);
95                 *skb_put(skb, 1) = crc >> 8;
96                 *skb_put(skb, 1) = crc & 0xFF;
97         }
98
99         ret = __nci_spi_send(ndev, skb);
100
101         kfree_skb(skb);
102         ndev->ops->assert_int(ndev);
103
104         if (ret != 0 || ndev->acknowledge_mode == NCI_SPI_CRC_DISABLED)
105                 goto done;
106
107         init_completion(&ndev->req_completion);
108         completion_rc =
109                 wait_for_completion_interruptible_timeout(&ndev->req_completion,
110                                                           NCI_SPI_SEND_TIMEOUT);
111
112         if (completion_rc <= 0 || ndev->req_result == ACKNOWLEDGE_NACK)
113                 ret = -EIO;
114
115 done:
116         return ret;
117 }
118
119 static struct nci_ops nci_spi_ops = {
120         .open = nci_spi_open,
121         .close = nci_spi_close,
122         .send = nci_spi_send,
123 };
124
125 /* ---- Interface to NCI SPI drivers ---- */
126
127 /**
128  * nci_spi_allocate_device - allocate a new nci spi device
129  *
130  * @spi: SPI device
131  * @ops: device operations
132  * @supported_protocols: NFC protocols supported by the 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
136  */
137 struct nci_spi_dev *nci_spi_allocate_device(struct spi_device *spi,
138                                                 struct nci_spi_ops *ops,
139                                                 u32 supported_protocols,
140                                                 u32 supported_se,
141                                                 u8 acknowledge_mode,
142                                                 unsigned int delay)
143 {
144         struct nci_spi_dev *ndev;
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
153         ndev = devm_kzalloc(&spi->dev, sizeof(struct nci_spi_dev), GFP_KERNEL);
154         if (!ndev)
155                 return NULL;
156
157         ndev->ops = ops;
158         ndev->acknowledge_mode = acknowledge_mode;
159         ndev->xfer_udelay = delay;
160
161         if (acknowledge_mode == NCI_SPI_CRC_ENABLED)
162                 tailroom += NCI_SPI_CRC_LEN;
163
164         ndev->nci_dev = nci_allocate_device(&nci_spi_ops, supported_protocols,
165                                             NCI_SPI_HDR_LEN, tailroom);
166         if (!ndev->nci_dev)
167                 return NULL;
168
169         nci_set_drvdata(ndev->nci_dev, ndev);
170
171         return ndev;
172 }
173 EXPORT_SYMBOL_GPL(nci_spi_allocate_device);
174
175 /**
176  * nci_spi_free_device - deallocate nci spi device
177  *
178  * @ndev: The nci spi device to deallocate
179  */
180 void nci_spi_free_device(struct nci_spi_dev *ndev)
181 {
182         nci_free_device(ndev->nci_dev);
183 }
184 EXPORT_SYMBOL_GPL(nci_spi_free_device);
185
186 /**
187  * nci_spi_register_device - register a nci spi device in the nfc subsystem
188  *
189  * @pdev: The nci spi device to register
190  */
191 int nci_spi_register_device(struct nci_spi_dev *ndev)
192 {
193         return nci_register_device(ndev->nci_dev);
194 }
195 EXPORT_SYMBOL_GPL(nci_spi_register_device);
196
197 /**
198  * nci_spi_unregister_device - unregister a nci spi device in the nfc subsystem
199  *
200  * @dev: The nci spi device to unregister
201  */
202 void nci_spi_unregister_device(struct nci_spi_dev *ndev)
203 {
204         nci_unregister_device(ndev->nci_dev);
205 }
206 EXPORT_SYMBOL_GPL(nci_spi_unregister_device);
207
208 static int send_acknowledge(struct nci_spi_dev *ndev, u8 acknowledge)
209 {
210         struct sk_buff *skb;
211         unsigned char *hdr;
212         u16 crc;
213         int ret;
214
215         skb = nci_skb_alloc(ndev->nci_dev, 0, GFP_KERNEL);
216
217         /* add the NCI SPI header to the start of the buffer */
218         hdr = skb_push(skb, NCI_SPI_HDR_LEN);
219         hdr[0] = NCI_SPI_DIRECT_WRITE;
220         hdr[1] = NCI_SPI_CRC_ENABLED;
221         hdr[2] = acknowledge << NCI_SPI_ACK_SHIFT;
222         hdr[3] = 0;
223
224         crc = crc_ccitt(CRC_INIT, skb->data, skb->len);
225         *skb_put(skb, 1) = crc >> 8;
226         *skb_put(skb, 1) = crc & 0xFF;
227
228         ret = __nci_spi_send(ndev, skb);
229
230         kfree_skb(skb);
231
232         return ret;
233 }
234
235 static struct sk_buff *__nci_spi_recv_frame(struct nci_spi_dev *ndev)
236 {
237         struct sk_buff *skb;
238         struct spi_message m;
239         unsigned char req[2], resp_hdr[2];
240         struct spi_transfer tx, rx;
241         unsigned short rx_len = 0;
242         int ret;
243
244         spi_message_init(&m);
245         req[0] = NCI_SPI_DIRECT_READ;
246         req[1] = ndev->acknowledge_mode;
247         tx.tx_buf = req;
248         tx.len = 2;
249         tx.cs_change = 0;
250         spi_message_add_tail(&tx, &m);
251         rx.rx_buf = resp_hdr;
252         rx.len = 2;
253         rx.cs_change = 1;
254         spi_message_add_tail(&rx, &m);
255         ret = spi_sync(ndev->spi, &m);
256
257         if (ret)
258                 return NULL;
259
260         if (ndev->acknowledge_mode == NCI_SPI_CRC_ENABLED)
261                 rx_len = ((resp_hdr[0] & NCI_SPI_MSB_PAYLOAD_MASK) << 8) +
262                                 resp_hdr[1] + NCI_SPI_CRC_LEN;
263         else
264                 rx_len = (resp_hdr[0] << 8) | resp_hdr[1];
265
266         skb = nci_skb_alloc(ndev->nci_dev, rx_len, GFP_KERNEL);
267         if (!skb)
268                 return NULL;
269
270         spi_message_init(&m);
271         rx.rx_buf = skb_put(skb, rx_len);
272         rx.len = rx_len;
273         rx.cs_change = 0;
274         rx.delay_usecs = ndev->xfer_udelay;
275         spi_message_add_tail(&rx, &m);
276         ret = spi_sync(ndev->spi, &m);
277
278         if (ret)
279                 goto receive_error;
280
281         if (ndev->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
282                 *skb_push(skb, 1) = resp_hdr[1];
283                 *skb_push(skb, 1) = resp_hdr[0];
284         }
285
286         return skb;
287
288 receive_error:
289         kfree_skb(skb);
290
291         return NULL;
292 }
293
294 static int nci_spi_check_crc(struct sk_buff *skb)
295 {
296         u16 crc_data = (skb->data[skb->len - 2] << 8) |
297                         skb->data[skb->len - 1];
298         int ret;
299
300         ret = (crc_ccitt(CRC_INIT, skb->data, skb->len - NCI_SPI_CRC_LEN)
301                         == crc_data);
302
303         skb_trim(skb, skb->len - NCI_SPI_CRC_LEN);
304
305         return ret;
306 }
307
308 static u8 nci_spi_get_ack(struct sk_buff *skb)
309 {
310         u8 ret;
311
312         ret = skb->data[0] >> NCI_SPI_ACK_SHIFT;
313
314         /* Remove NFCC part of the header: ACK, NACK and MSB payload len */
315         skb_pull(skb, 2);
316
317         return ret;
318 }
319
320 /**
321  * nci_spi_recv_frame - receive frame from NCI SPI drivers
322  *
323  * @ndev: The nci spi device
324  * Context: can sleep
325  *
326  * This call may only be used from a context that may sleep.  The sleep
327  * is non-interruptible, and has no timeout.
328  *
329  * It returns zero on success, else a negative error code.
330  */
331 int nci_spi_recv_frame(struct nci_spi_dev *ndev)
332 {
333         struct sk_buff *skb;
334         int ret = 0;
335
336         ndev->ops->deassert_int(ndev);
337
338         /* Retrieve frame from SPI */
339         skb = __nci_spi_recv_frame(ndev);
340         if (!skb) {
341                 ret = -EIO;
342                 goto done;
343         }
344
345         if (ndev->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
346                 if (!nci_spi_check_crc(skb)) {
347                         send_acknowledge(ndev, ACKNOWLEDGE_NACK);
348                         goto done;
349                 }
350
351                 /* In case of acknowledged mode: if ACK or NACK received,
352                  * unblock completion of latest frame sent.
353                  */
354                 ndev->req_result = nci_spi_get_ack(skb);
355                 if (ndev->req_result)
356                         complete(&ndev->req_completion);
357         }
358
359         /* If there is no payload (ACK/NACK only frame),
360          * free the socket buffer
361          */
362         if (skb->len == 0) {
363                 kfree_skb(skb);
364                 goto done;
365         }
366
367         if (ndev->acknowledge_mode == NCI_SPI_CRC_ENABLED)
368                 send_acknowledge(ndev, ACKNOWLEDGE_ACK);
369
370         /* Forward skb to NCI core layer */
371         ret = nci_recv_frame(ndev->nci_dev, skb);
372
373 done:
374         ndev->ops->assert_int(ndev);
375
376         return ret;
377 }
378 EXPORT_SYMBOL_GPL(nci_spi_recv_frame);