GNU Linux-libre 4.14.332-gnu1
[releases.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/module.h>
22
23 #include <linux/export.h>
24 #include <linux/spi/spi.h>
25 #include <linux/crc-ccitt.h>
26 #include <net/nfc/nci_core.h>
27
28 #define NCI_SPI_ACK_SHIFT               6
29 #define NCI_SPI_MSB_PAYLOAD_MASK        0x3F
30
31 #define NCI_SPI_SEND_TIMEOUT    (NCI_CMD_TIMEOUT > NCI_DATA_TIMEOUT ? \
32                                         NCI_CMD_TIMEOUT : NCI_DATA_TIMEOUT)
33
34 #define NCI_SPI_DIRECT_WRITE    0x01
35 #define NCI_SPI_DIRECT_READ     0x02
36
37 #define ACKNOWLEDGE_NONE        0
38 #define ACKNOWLEDGE_ACK         1
39 #define ACKNOWLEDGE_NACK        2
40
41 #define CRC_INIT                0xFFFF
42
43 static int __nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb,
44                           int cs_change)
45 {
46         struct spi_message m;
47         struct spi_transfer t;
48
49         memset(&t, 0, sizeof(struct spi_transfer));
50         /* a NULL skb means we just want the SPI chip select line to raise */
51         if (skb) {
52                 t.tx_buf = skb->data;
53                 t.len = skb->len;
54         } else {
55                 /* still set tx_buf non NULL to make the driver happy */
56                 t.tx_buf = &t;
57                 t.len = 0;
58         }
59         t.cs_change = cs_change;
60         t.delay_usecs = nspi->xfer_udelay;
61         t.speed_hz = nspi->xfer_speed_hz;
62
63         spi_message_init(&m);
64         spi_message_add_tail(&t, &m);
65
66         return spi_sync(nspi->spi, &m);
67 }
68
69 int nci_spi_send(struct nci_spi *nspi,
70                  struct completion *write_handshake_completion,
71                  struct sk_buff *skb)
72 {
73         unsigned int payload_len = skb->len;
74         unsigned char *hdr;
75         int ret;
76         long completion_rc;
77
78         /* add the NCI SPI header to the start of the buffer */
79         hdr = skb_push(skb, NCI_SPI_HDR_LEN);
80         hdr[0] = NCI_SPI_DIRECT_WRITE;
81         hdr[1] = nspi->acknowledge_mode;
82         hdr[2] = payload_len >> 8;
83         hdr[3] = payload_len & 0xFF;
84
85         if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
86                 u16 crc;
87
88                 crc = crc_ccitt(CRC_INIT, skb->data, skb->len);
89                 skb_put_u8(skb, crc >> 8);
90                 skb_put_u8(skb, crc & 0xFF);
91         }
92
93         if (write_handshake_completion) {
94                 /* Trick SPI driver to raise chip select */
95                 ret = __nci_spi_send(nspi, NULL, 1);
96                 if (ret)
97                         goto done;
98
99                 /* wait for NFC chip hardware handshake to complete */
100                 if (wait_for_completion_timeout(write_handshake_completion,
101                                                 msecs_to_jiffies(1000)) == 0) {
102                         ret = -ETIME;
103                         goto done;
104                 }
105         }
106
107         ret = __nci_spi_send(nspi, skb, 0);
108         if (ret != 0 || nspi->acknowledge_mode == NCI_SPI_CRC_DISABLED)
109                 goto done;
110
111         reinit_completion(&nspi->req_completion);
112         completion_rc = wait_for_completion_interruptible_timeout(
113                                                         &nspi->req_completion,
114                                                         NCI_SPI_SEND_TIMEOUT);
115
116         if (completion_rc <= 0 || nspi->req_result == ACKNOWLEDGE_NACK)
117                 ret = -EIO;
118
119 done:
120         kfree_skb(skb);
121
122         return ret;
123 }
124 EXPORT_SYMBOL_GPL(nci_spi_send);
125
126 /* ---- Interface to NCI SPI drivers ---- */
127
128 /**
129  * nci_spi_allocate_spi - allocate a new nci spi
130  *
131  * @spi: SPI device
132  * @acknowledge_mode: Acknowledge mode used by the NFC device
133  * @delay: delay between transactions in us
134  * @ndev: nci dev to send incoming nci frames to
135  */
136 struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
137                                      u8 acknowledge_mode, unsigned int delay,
138                                      struct nci_dev *ndev)
139 {
140         struct nci_spi *nspi;
141
142         nspi = devm_kzalloc(&spi->dev, sizeof(struct nci_spi), GFP_KERNEL);
143         if (!nspi)
144                 return NULL;
145
146         nspi->acknowledge_mode = acknowledge_mode;
147         nspi->xfer_udelay = delay;
148         /* Use controller max SPI speed by default */
149         nspi->xfer_speed_hz = 0;
150         nspi->spi = spi;
151         nspi->ndev = ndev;
152         init_completion(&nspi->req_completion);
153
154         return nspi;
155 }
156 EXPORT_SYMBOL_GPL(nci_spi_allocate_spi);
157
158 static int send_acknowledge(struct nci_spi *nspi, u8 acknowledge)
159 {
160         struct sk_buff *skb;
161         unsigned char *hdr;
162         u16 crc;
163         int ret;
164
165         skb = nci_skb_alloc(nspi->ndev, 0, GFP_KERNEL);
166         if (!skb)
167                 return -ENOMEM;
168
169         /* add the NCI SPI header to the start of the buffer */
170         hdr = skb_push(skb, NCI_SPI_HDR_LEN);
171         hdr[0] = NCI_SPI_DIRECT_WRITE;
172         hdr[1] = NCI_SPI_CRC_ENABLED;
173         hdr[2] = acknowledge << NCI_SPI_ACK_SHIFT;
174         hdr[3] = 0;
175
176         crc = crc_ccitt(CRC_INIT, skb->data, skb->len);
177         skb_put_u8(skb, crc >> 8);
178         skb_put_u8(skb, crc & 0xFF);
179
180         ret = __nci_spi_send(nspi, skb, 0);
181
182         kfree_skb(skb);
183
184         return ret;
185 }
186
187 static struct sk_buff *__nci_spi_read(struct nci_spi *nspi)
188 {
189         struct sk_buff *skb;
190         struct spi_message m;
191         unsigned char req[2], resp_hdr[2];
192         struct spi_transfer tx, rx;
193         unsigned short rx_len = 0;
194         int ret;
195
196         spi_message_init(&m);
197
198         memset(&tx, 0, sizeof(struct spi_transfer));
199         req[0] = NCI_SPI_DIRECT_READ;
200         req[1] = nspi->acknowledge_mode;
201         tx.tx_buf = req;
202         tx.len = 2;
203         tx.cs_change = 0;
204         tx.speed_hz = nspi->xfer_speed_hz;
205         spi_message_add_tail(&tx, &m);
206
207         memset(&rx, 0, sizeof(struct spi_transfer));
208         rx.rx_buf = resp_hdr;
209         rx.len = 2;
210         rx.cs_change = 1;
211         rx.speed_hz = nspi->xfer_speed_hz;
212         spi_message_add_tail(&rx, &m);
213
214         ret = spi_sync(nspi->spi, &m);
215         if (ret)
216                 return NULL;
217
218         if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED)
219                 rx_len = ((resp_hdr[0] & NCI_SPI_MSB_PAYLOAD_MASK) << 8) +
220                                 resp_hdr[1] + NCI_SPI_CRC_LEN;
221         else
222                 rx_len = (resp_hdr[0] << 8) | resp_hdr[1];
223
224         skb = nci_skb_alloc(nspi->ndev, rx_len, GFP_KERNEL);
225         if (!skb)
226                 return NULL;
227
228         spi_message_init(&m);
229
230         memset(&rx, 0, sizeof(struct spi_transfer));
231         rx.rx_buf = skb_put(skb, rx_len);
232         rx.len = rx_len;
233         rx.cs_change = 0;
234         rx.delay_usecs = nspi->xfer_udelay;
235         rx.speed_hz = nspi->xfer_speed_hz;
236         spi_message_add_tail(&rx, &m);
237
238         ret = spi_sync(nspi->spi, &m);
239         if (ret)
240                 goto receive_error;
241
242         if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
243                 *(u8 *)skb_push(skb, 1) = resp_hdr[1];
244                 *(u8 *)skb_push(skb, 1) = resp_hdr[0];
245         }
246
247         return skb;
248
249 receive_error:
250         kfree_skb(skb);
251
252         return NULL;
253 }
254
255 static int nci_spi_check_crc(struct sk_buff *skb)
256 {
257         u16 crc_data = (skb->data[skb->len - 2] << 8) |
258                         skb->data[skb->len - 1];
259         int ret;
260
261         ret = (crc_ccitt(CRC_INIT, skb->data, skb->len - NCI_SPI_CRC_LEN)
262                         == crc_data);
263
264         skb_trim(skb, skb->len - NCI_SPI_CRC_LEN);
265
266         return ret;
267 }
268
269 static u8 nci_spi_get_ack(struct sk_buff *skb)
270 {
271         u8 ret;
272
273         ret = skb->data[0] >> NCI_SPI_ACK_SHIFT;
274
275         /* Remove NFCC part of the header: ACK, NACK and MSB payload len */
276         skb_pull(skb, 2);
277
278         return ret;
279 }
280
281 /**
282  * nci_spi_read - read frame from NCI SPI drivers
283  *
284  * @nspi: The nci spi
285  * Context: can sleep
286  *
287  * This call may only be used from a context that may sleep.  The sleep
288  * is non-interruptible, and has no timeout.
289  *
290  * It returns an allocated skb containing the frame on success, or NULL.
291  */
292 struct sk_buff *nci_spi_read(struct nci_spi *nspi)
293 {
294         struct sk_buff *skb;
295
296         /* Retrieve frame from SPI */
297         skb = __nci_spi_read(nspi);
298         if (!skb)
299                 goto done;
300
301         if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
302                 if (!nci_spi_check_crc(skb)) {
303                         send_acknowledge(nspi, ACKNOWLEDGE_NACK);
304                         goto done;
305                 }
306
307                 /* In case of acknowledged mode: if ACK or NACK received,
308                  * unblock completion of latest frame sent.
309                  */
310                 nspi->req_result = nci_spi_get_ack(skb);
311                 if (nspi->req_result)
312                         complete(&nspi->req_completion);
313         }
314
315         /* If there is no payload (ACK/NACK only frame),
316          * free the socket buffer
317          */
318         if (!skb->len) {
319                 kfree_skb(skb);
320                 skb = NULL;
321                 goto done;
322         }
323
324         if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED)
325                 send_acknowledge(nspi, ACKNOWLEDGE_ACK);
326
327 done:
328
329         return skb;
330 }
331 EXPORT_SYMBOL_GPL(nci_spi_read);
332
333 MODULE_LICENSE("GPL");