Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2013  Intel Corporation. All rights reserved.
0004  */
0005 
0006 #define pr_fmt(fmt) "nci_spi: %s: " fmt, __func__
0007 
0008 #include <linux/module.h>
0009 
0010 #include <linux/export.h>
0011 #include <linux/spi/spi.h>
0012 #include <linux/crc-ccitt.h>
0013 #include <net/nfc/nci_core.h>
0014 
0015 #define NCI_SPI_ACK_SHIFT       6
0016 #define NCI_SPI_MSB_PAYLOAD_MASK    0x3F
0017 
0018 #define NCI_SPI_SEND_TIMEOUT    (NCI_CMD_TIMEOUT > NCI_DATA_TIMEOUT ? \
0019                     NCI_CMD_TIMEOUT : NCI_DATA_TIMEOUT)
0020 
0021 #define NCI_SPI_DIRECT_WRITE    0x01
0022 #define NCI_SPI_DIRECT_READ 0x02
0023 
0024 #define ACKNOWLEDGE_NONE    0
0025 #define ACKNOWLEDGE_ACK     1
0026 #define ACKNOWLEDGE_NACK    2
0027 
0028 #define CRC_INIT        0xFFFF
0029 
0030 static int __nci_spi_send(struct nci_spi *nspi, const struct sk_buff *skb,
0031               int cs_change)
0032 {
0033     struct spi_message m;
0034     struct spi_transfer t;
0035 
0036     memset(&t, 0, sizeof(struct spi_transfer));
0037     /* a NULL skb means we just want the SPI chip select line to raise */
0038     if (skb) {
0039         t.tx_buf = skb->data;
0040         t.len = skb->len;
0041     } else {
0042         /* still set tx_buf non NULL to make the driver happy */
0043         t.tx_buf = &t;
0044         t.len = 0;
0045     }
0046     t.cs_change = cs_change;
0047     t.delay.value = nspi->xfer_udelay;
0048     t.delay.unit = SPI_DELAY_UNIT_USECS;
0049     t.speed_hz = nspi->xfer_speed_hz;
0050 
0051     spi_message_init(&m);
0052     spi_message_add_tail(&t, &m);
0053 
0054     return spi_sync(nspi->spi, &m);
0055 }
0056 
0057 int nci_spi_send(struct nci_spi *nspi,
0058          struct completion *write_handshake_completion,
0059          struct sk_buff *skb)
0060 {
0061     unsigned int payload_len = skb->len;
0062     unsigned char *hdr;
0063     int ret;
0064     long completion_rc;
0065 
0066     /* add the NCI SPI header to the start of the buffer */
0067     hdr = skb_push(skb, NCI_SPI_HDR_LEN);
0068     hdr[0] = NCI_SPI_DIRECT_WRITE;
0069     hdr[1] = nspi->acknowledge_mode;
0070     hdr[2] = payload_len >> 8;
0071     hdr[3] = payload_len & 0xFF;
0072 
0073     if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
0074         u16 crc;
0075 
0076         crc = crc_ccitt(CRC_INIT, skb->data, skb->len);
0077         skb_put_u8(skb, crc >> 8);
0078         skb_put_u8(skb, crc & 0xFF);
0079     }
0080 
0081     if (write_handshake_completion) {
0082         /* Trick SPI driver to raise chip select */
0083         ret = __nci_spi_send(nspi, NULL, 1);
0084         if (ret)
0085             goto done;
0086 
0087         /* wait for NFC chip hardware handshake to complete */
0088         if (wait_for_completion_timeout(write_handshake_completion,
0089                         msecs_to_jiffies(1000)) == 0) {
0090             ret = -ETIME;
0091             goto done;
0092         }
0093     }
0094 
0095     ret = __nci_spi_send(nspi, skb, 0);
0096     if (ret != 0 || nspi->acknowledge_mode == NCI_SPI_CRC_DISABLED)
0097         goto done;
0098 
0099     reinit_completion(&nspi->req_completion);
0100     completion_rc = wait_for_completion_interruptible_timeout(
0101                             &nspi->req_completion,
0102                             NCI_SPI_SEND_TIMEOUT);
0103 
0104     if (completion_rc <= 0 || nspi->req_result == ACKNOWLEDGE_NACK)
0105         ret = -EIO;
0106 
0107 done:
0108     kfree_skb(skb);
0109 
0110     return ret;
0111 }
0112 EXPORT_SYMBOL_GPL(nci_spi_send);
0113 
0114 /* ---- Interface to NCI SPI drivers ---- */
0115 
0116 /**
0117  * nci_spi_allocate_spi - allocate a new nci spi
0118  *
0119  * @spi: SPI device
0120  * @acknowledge_mode: Acknowledge mode used by the NFC device
0121  * @delay: delay between transactions in us
0122  * @ndev: nci dev to send incoming nci frames to
0123  */
0124 struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
0125                      u8 acknowledge_mode, unsigned int delay,
0126                      struct nci_dev *ndev)
0127 {
0128     struct nci_spi *nspi;
0129 
0130     nspi = devm_kzalloc(&spi->dev, sizeof(struct nci_spi), GFP_KERNEL);
0131     if (!nspi)
0132         return NULL;
0133 
0134     nspi->acknowledge_mode = acknowledge_mode;
0135     nspi->xfer_udelay = delay;
0136     /* Use controller max SPI speed by default */
0137     nspi->xfer_speed_hz = 0;
0138     nspi->spi = spi;
0139     nspi->ndev = ndev;
0140     init_completion(&nspi->req_completion);
0141 
0142     return nspi;
0143 }
0144 EXPORT_SYMBOL_GPL(nci_spi_allocate_spi);
0145 
0146 static int send_acknowledge(struct nci_spi *nspi, u8 acknowledge)
0147 {
0148     struct sk_buff *skb;
0149     unsigned char *hdr;
0150     u16 crc;
0151     int ret;
0152 
0153     skb = nci_skb_alloc(nspi->ndev, 0, GFP_KERNEL);
0154 
0155     /* add the NCI SPI header to the start of the buffer */
0156     hdr = skb_push(skb, NCI_SPI_HDR_LEN);
0157     hdr[0] = NCI_SPI_DIRECT_WRITE;
0158     hdr[1] = NCI_SPI_CRC_ENABLED;
0159     hdr[2] = acknowledge << NCI_SPI_ACK_SHIFT;
0160     hdr[3] = 0;
0161 
0162     crc = crc_ccitt(CRC_INIT, skb->data, skb->len);
0163     skb_put_u8(skb, crc >> 8);
0164     skb_put_u8(skb, crc & 0xFF);
0165 
0166     ret = __nci_spi_send(nspi, skb, 0);
0167 
0168     kfree_skb(skb);
0169 
0170     return ret;
0171 }
0172 
0173 static struct sk_buff *__nci_spi_read(struct nci_spi *nspi)
0174 {
0175     struct sk_buff *skb;
0176     struct spi_message m;
0177     unsigned char req[2], resp_hdr[2];
0178     struct spi_transfer tx, rx;
0179     unsigned short rx_len = 0;
0180     int ret;
0181 
0182     spi_message_init(&m);
0183 
0184     memset(&tx, 0, sizeof(struct spi_transfer));
0185     req[0] = NCI_SPI_DIRECT_READ;
0186     req[1] = nspi->acknowledge_mode;
0187     tx.tx_buf = req;
0188     tx.len = 2;
0189     tx.cs_change = 0;
0190     tx.speed_hz = nspi->xfer_speed_hz;
0191     spi_message_add_tail(&tx, &m);
0192 
0193     memset(&rx, 0, sizeof(struct spi_transfer));
0194     rx.rx_buf = resp_hdr;
0195     rx.len = 2;
0196     rx.cs_change = 1;
0197     rx.speed_hz = nspi->xfer_speed_hz;
0198     spi_message_add_tail(&rx, &m);
0199 
0200     ret = spi_sync(nspi->spi, &m);
0201     if (ret)
0202         return NULL;
0203 
0204     if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED)
0205         rx_len = ((resp_hdr[0] & NCI_SPI_MSB_PAYLOAD_MASK) << 8) +
0206                 resp_hdr[1] + NCI_SPI_CRC_LEN;
0207     else
0208         rx_len = (resp_hdr[0] << 8) | resp_hdr[1];
0209 
0210     skb = nci_skb_alloc(nspi->ndev, rx_len, GFP_KERNEL);
0211     if (!skb)
0212         return NULL;
0213 
0214     spi_message_init(&m);
0215 
0216     memset(&rx, 0, sizeof(struct spi_transfer));
0217     rx.rx_buf = skb_put(skb, rx_len);
0218     rx.len = rx_len;
0219     rx.cs_change = 0;
0220     rx.delay.value = nspi->xfer_udelay;
0221     rx.delay.unit = SPI_DELAY_UNIT_USECS;
0222     rx.speed_hz = nspi->xfer_speed_hz;
0223     spi_message_add_tail(&rx, &m);
0224 
0225     ret = spi_sync(nspi->spi, &m);
0226     if (ret)
0227         goto receive_error;
0228 
0229     if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
0230         *(u8 *)skb_push(skb, 1) = resp_hdr[1];
0231         *(u8 *)skb_push(skb, 1) = resp_hdr[0];
0232     }
0233 
0234     return skb;
0235 
0236 receive_error:
0237     kfree_skb(skb);
0238 
0239     return NULL;
0240 }
0241 
0242 static int nci_spi_check_crc(struct sk_buff *skb)
0243 {
0244     u16 crc_data = (skb->data[skb->len - 2] << 8) |
0245             skb->data[skb->len - 1];
0246     int ret;
0247 
0248     ret = (crc_ccitt(CRC_INIT, skb->data, skb->len - NCI_SPI_CRC_LEN)
0249             == crc_data);
0250 
0251     skb_trim(skb, skb->len - NCI_SPI_CRC_LEN);
0252 
0253     return ret;
0254 }
0255 
0256 static u8 nci_spi_get_ack(struct sk_buff *skb)
0257 {
0258     u8 ret;
0259 
0260     ret = skb->data[0] >> NCI_SPI_ACK_SHIFT;
0261 
0262     /* Remove NFCC part of the header: ACK, NACK and MSB payload len */
0263     skb_pull(skb, 2);
0264 
0265     return ret;
0266 }
0267 
0268 /**
0269  * nci_spi_read - read frame from NCI SPI drivers
0270  *
0271  * @nspi: The nci spi
0272  * Context: can sleep
0273  *
0274  * This call may only be used from a context that may sleep.  The sleep
0275  * is non-interruptible, and has no timeout.
0276  *
0277  * It returns an allocated skb containing the frame on success, or NULL.
0278  */
0279 struct sk_buff *nci_spi_read(struct nci_spi *nspi)
0280 {
0281     struct sk_buff *skb;
0282 
0283     /* Retrieve frame from SPI */
0284     skb = __nci_spi_read(nspi);
0285     if (!skb)
0286         goto done;
0287 
0288     if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED) {
0289         if (!nci_spi_check_crc(skb)) {
0290             send_acknowledge(nspi, ACKNOWLEDGE_NACK);
0291             goto done;
0292         }
0293 
0294         /* In case of acknowledged mode: if ACK or NACK received,
0295          * unblock completion of latest frame sent.
0296          */
0297         nspi->req_result = nci_spi_get_ack(skb);
0298         if (nspi->req_result)
0299             complete(&nspi->req_completion);
0300     }
0301 
0302     /* If there is no payload (ACK/NACK only frame),
0303      * free the socket buffer
0304      */
0305     if (!skb->len) {
0306         kfree_skb(skb);
0307         skb = NULL;
0308         goto done;
0309     }
0310 
0311     if (nspi->acknowledge_mode == NCI_SPI_CRC_ENABLED)
0312         send_acknowledge(nspi, ACKNOWLEDGE_ACK);
0313 
0314 done:
0315 
0316     return skb;
0317 }
0318 EXPORT_SYMBOL_GPL(nci_spi_read);
0319 
0320 MODULE_LICENSE("GPL");