Skip to content

Commit f1f1a7d

Browse files
Vincent CuissardSamuel Ortiz
authored andcommitted
NFC: nfcmrvl: add support of HCI-based transport
In some configuration NCI packet can be encapsulated in HCI packets. This patch had the support of this. Signed-off-by: Vincent Cuissard <[email protected]> Signed-off-by: Samuel Ortiz <[email protected]>
1 parent d18ee5a commit f1f1a7d

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

drivers/nfc/nfcmrvl/main.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ static int nfcmrvl_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
6363
if (!test_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
6464
return -EBUSY;
6565

66+
if (priv->hci_muxed) {
67+
unsigned char *hdr;
68+
unsigned char len = skb->len;
69+
70+
hdr = (char *) skb_push(skb, NFCMRVL_HCI_EVENT_HEADER_SIZE);
71+
hdr[0] = NFCMRVL_HCI_COMMAND_CODE;
72+
hdr[1] = NFCMRVL_HCI_OGF;
73+
hdr[2] = NFCMRVL_HCI_OCF;
74+
hdr[3] = len;
75+
}
76+
6677
return priv->if_ops->nci_send(priv, skb);
6778
}
6879

@@ -80,10 +91,12 @@ static struct nci_ops nfcmrvl_nci_ops = {
8091

8192
struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
8293
struct nfcmrvl_if_ops *ops,
83-
struct device *dev)
94+
struct device *dev,
95+
unsigned int flags)
8496
{
8597
struct nfcmrvl_private *priv;
8698
int rc;
99+
int headroom = 0;
87100
u32 protocols;
88101

89102
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
@@ -93,14 +106,19 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
93106
priv->drv_data = drv_data;
94107
priv->if_ops = ops;
95108
priv->dev = dev;
109+
priv->hci_muxed = (flags & NFCMRVL_DEV_FLAG_HCI_MUXED) ? 1 : 0;
110+
111+
if (priv->hci_muxed)
112+
headroom = NFCMRVL_HCI_EVENT_HEADER_SIZE;
96113

97114
protocols = NFC_PROTO_JEWEL_MASK
98115
| NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK
99116
| NFC_PROTO_ISO14443_MASK
100117
| NFC_PROTO_ISO14443_B_MASK
101118
| NFC_PROTO_NFC_DEP_MASK;
102119

103-
priv->ndev = nci_allocate_device(&nfcmrvl_nci_ops, protocols, 0, 0);
120+
priv->ndev = nci_allocate_device(&nfcmrvl_nci_ops, protocols,
121+
headroom, 0);
104122
if (!priv->ndev) {
105123
nfc_err(dev, "nci_allocate_device failed\n");
106124
rc = -ENOMEM;
@@ -144,6 +162,19 @@ int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, void *data, int count)
144162
return -ENOMEM;
145163

146164
memcpy(skb_put(skb, count), data, count);
165+
166+
if (priv->hci_muxed) {
167+
if (skb->data[0] == NFCMRVL_HCI_EVENT_CODE &&
168+
skb->data[1] == NFCMRVL_HCI_NFC_EVENT_CODE) {
169+
/* Data packet, let's extract NCI payload */
170+
skb_pull(skb, NFCMRVL_HCI_EVENT_HEADER_SIZE);
171+
} else {
172+
/* Skip this packet */
173+
kfree_skb(skb);
174+
return 0;
175+
}
176+
}
177+
147178
nci_recv_frame(priv->ndev, skb);
148179

149180
return count;

drivers/nfc/nfcmrvl/nfcmrvl.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,23 @@
2727
#define NFCMRVL_GPIO_PIN_NFC_ACTIVE 0xB
2828
#define NFCMRVL_NCI_MAX_EVENT_SIZE 260
2929

30+
/*
31+
** HCI defines
32+
*/
33+
34+
#define NFCMRVL_HCI_EVENT_HEADER_SIZE 0x04
35+
#define NFCMRVL_HCI_EVENT_CODE 0x04
36+
#define NFCMRVL_HCI_NFC_EVENT_CODE 0xFF
37+
#define NFCMRVL_HCI_COMMAND_CODE 0x01
38+
#define NFCMRVL_HCI_OGF 0x81
39+
#define NFCMRVL_HCI_OCF 0xFE
40+
41+
#define NFCMRVL_DEV_FLAG_HCI_MUXED (1 << 0)
42+
3043
struct nfcmrvl_private {
44+
45+
/* Tell if NCI packets are encapsulated in HCI ones */
46+
int hci_muxed;
3147
struct nci_dev *ndev;
3248
unsigned long flags;
3349
void *drv_data;
@@ -45,4 +61,5 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv);
4561
int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, void *data, int count);
4662
struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
4763
struct nfcmrvl_if_ops *ops,
48-
struct device *dev);
64+
struct device *dev,
65+
unsigned int flags);

drivers/nfc/nfcmrvl/usb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ static int nfcmrvl_probe(struct usb_interface *intf,
329329
init_usb_anchor(&drv_data->deferred);
330330

331331
priv = nfcmrvl_nci_register_dev(drv_data, &usb_ops,
332-
&drv_data->udev->dev);
332+
&drv_data->udev->dev, 0);
333333
if (IS_ERR(priv))
334334
return PTR_ERR(priv);
335335

0 commit comments

Comments
 (0)