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