xref: /openbmc/linux/drivers/nfc/st21nfca/dep.c (revision 762f99f4f3cb41a775b5157dd761217beba65873)
146fe7771SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21c54795dSChristophe Ricard /*
31c54795dSChristophe Ricard  * Copyright (C) 2014  STMicroelectronics SAS. All rights reserved.
41c54795dSChristophe Ricard  */
51c54795dSChristophe Ricard 
61c54795dSChristophe Ricard #include <net/nfc/hci.h>
71c54795dSChristophe Ricard 
81c54795dSChristophe Ricard #include "st21nfca.h"
91c54795dSChristophe Ricard 
101c54795dSChristophe Ricard #define ST21NFCA_NFCIP1_INITIATOR 0x00
111c54795dSChristophe Ricard #define ST21NFCA_NFCIP1_REQ 0xd4
121c54795dSChristophe Ricard #define ST21NFCA_NFCIP1_RES 0xd5
131c54795dSChristophe Ricard #define ST21NFCA_NFCIP1_ATR_REQ 0x00
141c54795dSChristophe Ricard #define ST21NFCA_NFCIP1_ATR_RES 0x01
151c54795dSChristophe Ricard #define ST21NFCA_NFCIP1_PSL_REQ 0x04
161c54795dSChristophe Ricard #define ST21NFCA_NFCIP1_PSL_RES 0x05
171c54795dSChristophe Ricard #define ST21NFCA_NFCIP1_DEP_REQ 0x06
181c54795dSChristophe Ricard #define ST21NFCA_NFCIP1_DEP_RES 0x07
191c54795dSChristophe Ricard 
201c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_PFB_PNI(pfb)     ((pfb) & 0x03)
211c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_PFB_TYPE(pfb) ((pfb) & 0xE0)
221c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
231c54795dSChristophe Ricard 				((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
241c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_DID_BIT_SET(pfb) ((pfb) & 0x04)
251c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_NAD_BIT_SET(pfb) ((pfb) & 0x08)
261c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT 0x10
271c54795dSChristophe Ricard 
281c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_PFB_IS_TIMEOUT(pfb) \
291c54795dSChristophe Ricard 				((pfb) & ST21NFCA_NFC_DEP_PFB_TIMEOUT_BIT)
301c54795dSChristophe Ricard 
311c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_PFB_I_PDU          0x00
321c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU   0x40
331c54795dSChristophe Ricard #define ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU 0x80
341c54795dSChristophe Ricard 
351c54795dSChristophe Ricard #define ST21NFCA_ATR_REQ_MIN_SIZE 17
361c54795dSChristophe Ricard #define ST21NFCA_ATR_REQ_MAX_SIZE 65
371c54795dSChristophe Ricard #define ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B 0x30
381c54795dSChristophe Ricard #define ST21NFCA_GB_BIT  0x02
391c54795dSChristophe Ricard 
401c54795dSChristophe Ricard #define ST21NFCA_EVT_SEND_DATA		0x10
411c54795dSChristophe Ricard #define ST21NFCA_EVT_FIELD_ON           0x11
421c54795dSChristophe Ricard #define ST21NFCA_EVT_CARD_DEACTIVATED   0x12
431c54795dSChristophe Ricard #define ST21NFCA_EVT_CARD_ACTIVATED     0x13
441c54795dSChristophe Ricard #define ST21NFCA_EVT_FIELD_OFF          0x14
451c54795dSChristophe Ricard 
461c54795dSChristophe Ricard #define ST21NFCA_EVT_CARD_F_BITRATE 0x16
471c54795dSChristophe Ricard #define ST21NFCA_EVT_READER_F_BITRATE 0x13
481c54795dSChristophe Ricard #define	ST21NFCA_PSL_REQ_SEND_SPEED(brs) (brs & 0x38)
491c54795dSChristophe Ricard #define ST21NFCA_PSL_REQ_RECV_SPEED(brs) (brs & 0x07)
501c54795dSChristophe Ricard #define ST21NFCA_PP2LRI(pp) ((pp & 0x30) >> 4)
511c54795dSChristophe Ricard #define ST21NFCA_CARD_BITRATE_212 0x01
521c54795dSChristophe Ricard #define ST21NFCA_CARD_BITRATE_424 0x02
531c54795dSChristophe Ricard 
541c54795dSChristophe Ricard #define ST21NFCA_DEFAULT_TIMEOUT 0x0a
551c54795dSChristophe Ricard 
561c54795dSChristophe Ricard 
571c54795dSChristophe Ricard #define PROTOCOL_ERR(req) pr_err("%d: ST21NFCA Protocol error: %s\n", \
581c54795dSChristophe Ricard 				 __LINE__, req)
591c54795dSChristophe Ricard 
601c54795dSChristophe Ricard struct st21nfca_atr_req {
611c54795dSChristophe Ricard 	u8 length;
621c54795dSChristophe Ricard 	u8 cmd0;
631c54795dSChristophe Ricard 	u8 cmd1;
641c54795dSChristophe Ricard 	u8 nfcid3[NFC_NFCID3_MAXSIZE];
651c54795dSChristophe Ricard 	u8 did;
661c54795dSChristophe Ricard 	u8 bsi;
671c54795dSChristophe Ricard 	u8 bri;
681c54795dSChristophe Ricard 	u8 ppi;
69da60fbe7SGustavo A. R. Silva 	u8 gbi[];
701c54795dSChristophe Ricard } __packed;
711c54795dSChristophe Ricard 
721c54795dSChristophe Ricard struct st21nfca_atr_res {
731c54795dSChristophe Ricard 	u8 length;
741c54795dSChristophe Ricard 	u8 cmd0;
751c54795dSChristophe Ricard 	u8 cmd1;
761c54795dSChristophe Ricard 	u8 nfcid3[NFC_NFCID3_MAXSIZE];
771c54795dSChristophe Ricard 	u8 did;
781c54795dSChristophe Ricard 	u8 bsi;
791c54795dSChristophe Ricard 	u8 bri;
801c54795dSChristophe Ricard 	u8 to;
811c54795dSChristophe Ricard 	u8 ppi;
82da60fbe7SGustavo A. R. Silva 	u8 gbi[];
831c54795dSChristophe Ricard } __packed;
841c54795dSChristophe Ricard 
851c54795dSChristophe Ricard struct st21nfca_psl_req {
861c54795dSChristophe Ricard 	u8 length;
871c54795dSChristophe Ricard 	u8 cmd0;
881c54795dSChristophe Ricard 	u8 cmd1;
891c54795dSChristophe Ricard 	u8 did;
901c54795dSChristophe Ricard 	u8 brs;
911c54795dSChristophe Ricard 	u8 fsl;
921c54795dSChristophe Ricard } __packed;
931c54795dSChristophe Ricard 
941c54795dSChristophe Ricard struct st21nfca_psl_res {
951c54795dSChristophe Ricard 	u8 length;
961c54795dSChristophe Ricard 	u8 cmd0;
971c54795dSChristophe Ricard 	u8 cmd1;
981c54795dSChristophe Ricard 	u8 did;
991c54795dSChristophe Ricard } __packed;
1001c54795dSChristophe Ricard 
1011c54795dSChristophe Ricard struct st21nfca_dep_req_res {
1021c54795dSChristophe Ricard 	u8 length;
1031c54795dSChristophe Ricard 	u8 cmd0;
1041c54795dSChristophe Ricard 	u8 cmd1;
1051c54795dSChristophe Ricard 	u8 pfb;
1061c54795dSChristophe Ricard 	u8 did;
1071c54795dSChristophe Ricard 	u8 nad;
1081c54795dSChristophe Ricard } __packed;
1091c54795dSChristophe Ricard 
st21nfca_tx_work(struct work_struct * work)1101c54795dSChristophe Ricard static void st21nfca_tx_work(struct work_struct *work)
1111c54795dSChristophe Ricard {
1121c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = container_of(work,
1131c54795dSChristophe Ricard 						struct st21nfca_hci_info,
1141c54795dSChristophe Ricard 						dep_info.tx_work);
1151c54795dSChristophe Ricard 
1161c54795dSChristophe Ricard 	struct nfc_dev *dev;
1171c54795dSChristophe Ricard 	struct sk_buff *skb;
1181c54795dSChristophe Ricard 
1191c54795dSChristophe Ricard 	if (info) {
1201c54795dSChristophe Ricard 		dev = info->hdev->ndev;
1211c54795dSChristophe Ricard 		skb = info->dep_info.tx_pending;
1221c54795dSChristophe Ricard 
1231c54795dSChristophe Ricard 		device_lock(&dev->dev);
1241c54795dSChristophe Ricard 
1251c54795dSChristophe Ricard 		nfc_hci_send_cmd_async(info->hdev, ST21NFCA_RF_READER_F_GATE,
1261c54795dSChristophe Ricard 				ST21NFCA_WR_XCHG_DATA, skb->data, skb->len,
1271c54795dSChristophe Ricard 				info->async_cb, info);
1281c54795dSChristophe Ricard 		device_unlock(&dev->dev);
1291c54795dSChristophe Ricard 		kfree_skb(skb);
1301c54795dSChristophe Ricard 	}
1311c54795dSChristophe Ricard }
1321c54795dSChristophe Ricard 
st21nfca_im_send_pdu(struct st21nfca_hci_info * info,struct sk_buff * skb)1331c54795dSChristophe Ricard static void st21nfca_im_send_pdu(struct st21nfca_hci_info *info,
1341c54795dSChristophe Ricard 						struct sk_buff *skb)
1351c54795dSChristophe Ricard {
1361c54795dSChristophe Ricard 	info->dep_info.tx_pending = skb;
1371c54795dSChristophe Ricard 	schedule_work(&info->dep_info.tx_work);
1381c54795dSChristophe Ricard }
1391c54795dSChristophe Ricard 
st21nfca_tm_send_atr_res(struct nfc_hci_dev * hdev,struct st21nfca_atr_req * atr_req)1401c54795dSChristophe Ricard static int st21nfca_tm_send_atr_res(struct nfc_hci_dev *hdev,
1411c54795dSChristophe Ricard 				    struct st21nfca_atr_req *atr_req)
1421c54795dSChristophe Ricard {
1431c54795dSChristophe Ricard 	struct st21nfca_atr_res *atr_res;
1441c54795dSChristophe Ricard 	struct sk_buff *skb;
1451c54795dSChristophe Ricard 	size_t gb_len;
1461c54795dSChristophe Ricard 	int r;
1471c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
1481c54795dSChristophe Ricard 
1491c54795dSChristophe Ricard 	gb_len = atr_req->length - sizeof(struct st21nfca_atr_req);
1501c54795dSChristophe Ricard 	skb = alloc_skb(atr_req->length + 1, GFP_KERNEL);
1511c54795dSChristophe Ricard 	if (!skb)
1521c54795dSChristophe Ricard 		return -ENOMEM;
1531c54795dSChristophe Ricard 
1541c54795dSChristophe Ricard 	skb_put(skb, sizeof(struct st21nfca_atr_res));
1551c54795dSChristophe Ricard 
1561c54795dSChristophe Ricard 	atr_res = (struct st21nfca_atr_res *)skb->data;
1571c54795dSChristophe Ricard 	memset(atr_res, 0, sizeof(struct st21nfca_atr_res));
1581c54795dSChristophe Ricard 
1591c54795dSChristophe Ricard 	atr_res->length = atr_req->length + 1;
1601c54795dSChristophe Ricard 	atr_res->cmd0 = ST21NFCA_NFCIP1_RES;
1611c54795dSChristophe Ricard 	atr_res->cmd1 = ST21NFCA_NFCIP1_ATR_RES;
1621c54795dSChristophe Ricard 
1631c54795dSChristophe Ricard 	memcpy(atr_res->nfcid3, atr_req->nfcid3, 6);
1641c54795dSChristophe Ricard 	atr_res->bsi = 0x00;
1651c54795dSChristophe Ricard 	atr_res->bri = 0x00;
1661c54795dSChristophe Ricard 	atr_res->to = ST21NFCA_DEFAULT_TIMEOUT;
1671c54795dSChristophe Ricard 	atr_res->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
1681c54795dSChristophe Ricard 
1691c54795dSChristophe Ricard 	if (gb_len) {
1701c54795dSChristophe Ricard 		skb_put(skb, gb_len);
1711c54795dSChristophe Ricard 
1721c54795dSChristophe Ricard 		atr_res->ppi |= ST21NFCA_GB_BIT;
1731c54795dSChristophe Ricard 		memcpy(atr_res->gbi, atr_req->gbi, gb_len);
1741c54795dSChristophe Ricard 		r = nfc_set_remote_general_bytes(hdev->ndev, atr_res->gbi,
1751c54795dSChristophe Ricard 						  gb_len);
1763decabdcSChuhong Yuan 		if (r < 0) {
1773decabdcSChuhong Yuan 			kfree_skb(skb);
1781c54795dSChristophe Ricard 			return r;
1791c54795dSChristophe Ricard 		}
1803decabdcSChuhong Yuan 	}
1811c54795dSChristophe Ricard 
1821c54795dSChristophe Ricard 	info->dep_info.curr_nfc_dep_pni = 0;
1831c54795dSChristophe Ricard 
1841c54795dSChristophe Ricard 	r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
1851c54795dSChristophe Ricard 				ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
1861c54795dSChristophe Ricard 	kfree_skb(skb);
1871c54795dSChristophe Ricard 	return r;
1881c54795dSChristophe Ricard }
1891c54795dSChristophe Ricard 
st21nfca_tm_recv_atr_req(struct nfc_hci_dev * hdev,struct sk_buff * skb)1901c54795dSChristophe Ricard static int st21nfca_tm_recv_atr_req(struct nfc_hci_dev *hdev,
1911c54795dSChristophe Ricard 				    struct sk_buff *skb)
1921c54795dSChristophe Ricard {
1931c54795dSChristophe Ricard 	struct st21nfca_atr_req *atr_req;
1941c54795dSChristophe Ricard 	size_t gb_len;
1951c54795dSChristophe Ricard 	int r;
1961c54795dSChristophe Ricard 
1971c54795dSChristophe Ricard 	skb_trim(skb, skb->len - 1);
1981c54795dSChristophe Ricard 
199*4b99b749Swengjianfeng 	if (!skb->len)
200*4b99b749Swengjianfeng 		return -EIO;
2011c54795dSChristophe Ricard 
202*4b99b749Swengjianfeng 	if (skb->len < ST21NFCA_ATR_REQ_MIN_SIZE)
203*4b99b749Swengjianfeng 		return -EPROTO;
2041c54795dSChristophe Ricard 
2051c54795dSChristophe Ricard 	atr_req = (struct st21nfca_atr_req *)skb->data;
2061c54795dSChristophe Ricard 
207*4b99b749Swengjianfeng 	if (atr_req->length < sizeof(struct st21nfca_atr_req))
208*4b99b749Swengjianfeng 		return -EPROTO;
2091c54795dSChristophe Ricard 
2101c54795dSChristophe Ricard 	r = st21nfca_tm_send_atr_res(hdev, atr_req);
2111c54795dSChristophe Ricard 	if (r)
212*4b99b749Swengjianfeng 		return r;
2131c54795dSChristophe Ricard 
2141c54795dSChristophe Ricard 	gb_len = skb->len - sizeof(struct st21nfca_atr_req);
2151c54795dSChristophe Ricard 
2161c54795dSChristophe Ricard 	r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK,
2171c54795dSChristophe Ricard 			      NFC_COMM_PASSIVE, atr_req->gbi, gb_len);
2181c54795dSChristophe Ricard 	if (r)
2191c54795dSChristophe Ricard 		return r;
220*4b99b749Swengjianfeng 
221*4b99b749Swengjianfeng 	return 0;
2221c54795dSChristophe Ricard }
2231c54795dSChristophe Ricard 
st21nfca_tm_send_psl_res(struct nfc_hci_dev * hdev,struct st21nfca_psl_req * psl_req)2241c54795dSChristophe Ricard static int st21nfca_tm_send_psl_res(struct nfc_hci_dev *hdev,
2251c54795dSChristophe Ricard 				    struct st21nfca_psl_req *psl_req)
2261c54795dSChristophe Ricard {
2271c54795dSChristophe Ricard 	struct st21nfca_psl_res *psl_res;
2281c54795dSChristophe Ricard 	struct sk_buff *skb;
2291c54795dSChristophe Ricard 	u8 bitrate[2] = {0, 0};
2301c54795dSChristophe Ricard 	int r;
2311c54795dSChristophe Ricard 
2321c54795dSChristophe Ricard 	skb = alloc_skb(sizeof(struct st21nfca_psl_res), GFP_KERNEL);
2331c54795dSChristophe Ricard 	if (!skb)
2341c54795dSChristophe Ricard 		return -ENOMEM;
2351c54795dSChristophe Ricard 	skb_put(skb, sizeof(struct st21nfca_psl_res));
2361c54795dSChristophe Ricard 
2371c54795dSChristophe Ricard 	psl_res = (struct st21nfca_psl_res *)skb->data;
2381c54795dSChristophe Ricard 
2391c54795dSChristophe Ricard 	psl_res->length = sizeof(struct st21nfca_psl_res);
2401c54795dSChristophe Ricard 	psl_res->cmd0 = ST21NFCA_NFCIP1_RES;
2411c54795dSChristophe Ricard 	psl_res->cmd1 = ST21NFCA_NFCIP1_PSL_RES;
2421c54795dSChristophe Ricard 	psl_res->did = psl_req->did;
2431c54795dSChristophe Ricard 
2441c54795dSChristophe Ricard 	r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
2451c54795dSChristophe Ricard 				ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
2461c54795dSChristophe Ricard 	if (r < 0)
2471c54795dSChristophe Ricard 		goto error;
2481c54795dSChristophe Ricard 
2491c54795dSChristophe Ricard 	/*
2501c54795dSChristophe Ricard 	 * ST21NFCA only support P2P passive.
2511c54795dSChristophe Ricard 	 * PSL_REQ BRS value != 0 has only a meaning to
2521c54795dSChristophe Ricard 	 * change technology to type F.
2531c54795dSChristophe Ricard 	 * We change to BITRATE 424Kbits.
2541c54795dSChristophe Ricard 	 * In other case switch to BITRATE 106Kbits.
2551c54795dSChristophe Ricard 	 */
2561c54795dSChristophe Ricard 	if (ST21NFCA_PSL_REQ_SEND_SPEED(psl_req->brs) &&
2571c54795dSChristophe Ricard 	    ST21NFCA_PSL_REQ_RECV_SPEED(psl_req->brs)) {
2581c54795dSChristophe Ricard 		bitrate[0] = ST21NFCA_CARD_BITRATE_424;
2591c54795dSChristophe Ricard 		bitrate[1] = ST21NFCA_CARD_BITRATE_424;
2601c54795dSChristophe Ricard 	}
2611c54795dSChristophe Ricard 
2621c54795dSChristophe Ricard 	/* Send an event to change bitrate change event to card f */
2631c54795dSChristophe Ricard 	r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
2641c54795dSChristophe Ricard 			ST21NFCA_EVT_CARD_F_BITRATE, bitrate, 2);
2651c54795dSChristophe Ricard error:
2661c54795dSChristophe Ricard 	kfree_skb(skb);
2671c54795dSChristophe Ricard 	return r;
2681c54795dSChristophe Ricard }
2691c54795dSChristophe Ricard 
st21nfca_tm_recv_psl_req(struct nfc_hci_dev * hdev,struct sk_buff * skb)2701c54795dSChristophe Ricard static int st21nfca_tm_recv_psl_req(struct nfc_hci_dev *hdev,
2711c54795dSChristophe Ricard 				    struct sk_buff *skb)
2721c54795dSChristophe Ricard {
2731c54795dSChristophe Ricard 	struct st21nfca_psl_req *psl_req;
2741c54795dSChristophe Ricard 
2751c54795dSChristophe Ricard 	skb_trim(skb, skb->len - 1);
2761c54795dSChristophe Ricard 
277*4b99b749Swengjianfeng 	if (!skb->len)
278*4b99b749Swengjianfeng 		return -EIO;
2791c54795dSChristophe Ricard 
2801c54795dSChristophe Ricard 	psl_req = (struct st21nfca_psl_req *)skb->data;
2811c54795dSChristophe Ricard 
282*4b99b749Swengjianfeng 	if (skb->len < sizeof(struct st21nfca_psl_req))
283*4b99b749Swengjianfeng 		return -EIO;
2841c54795dSChristophe Ricard 
285*4b99b749Swengjianfeng 	return st21nfca_tm_send_psl_res(hdev, psl_req);
2861c54795dSChristophe Ricard }
2871c54795dSChristophe Ricard 
st21nfca_tm_send_dep_res(struct nfc_hci_dev * hdev,struct sk_buff * skb)2881c54795dSChristophe Ricard int st21nfca_tm_send_dep_res(struct nfc_hci_dev *hdev, struct sk_buff *skb)
2891c54795dSChristophe Ricard {
2901c54795dSChristophe Ricard 	int r;
2911c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
2921c54795dSChristophe Ricard 
293d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
294d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_RES;
295d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_RES;
296d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = skb->len;
2971c54795dSChristophe Ricard 
2981c54795dSChristophe Ricard 	r = nfc_hci_send_event(hdev, ST21NFCA_RF_CARD_F_GATE,
2991c54795dSChristophe Ricard 			ST21NFCA_EVT_SEND_DATA, skb->data, skb->len);
3001c54795dSChristophe Ricard 	kfree_skb(skb);
3011c54795dSChristophe Ricard 
3021c54795dSChristophe Ricard 	return r;
3031c54795dSChristophe Ricard }
3041c54795dSChristophe Ricard EXPORT_SYMBOL(st21nfca_tm_send_dep_res);
3051c54795dSChristophe Ricard 
st21nfca_tm_recv_dep_req(struct nfc_hci_dev * hdev,struct sk_buff * skb)3061c54795dSChristophe Ricard static int st21nfca_tm_recv_dep_req(struct nfc_hci_dev *hdev,
3071c54795dSChristophe Ricard 				    struct sk_buff *skb)
3081c54795dSChristophe Ricard {
3091c54795dSChristophe Ricard 	struct st21nfca_dep_req_res *dep_req;
3101c54795dSChristophe Ricard 	u8 size;
3111c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
3121c54795dSChristophe Ricard 
3131c54795dSChristophe Ricard 	skb_trim(skb, skb->len - 1);
3141c54795dSChristophe Ricard 
3151c54795dSChristophe Ricard 	size = 4;
3161c54795dSChristophe Ricard 
3171c54795dSChristophe Ricard 	dep_req = (struct st21nfca_dep_req_res *)skb->data;
318*4b99b749Swengjianfeng 	if (skb->len < size)
319*4b99b749Swengjianfeng 		return -EIO;
3201c54795dSChristophe Ricard 
3211c54795dSChristophe Ricard 	if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_req->pfb))
3221c54795dSChristophe Ricard 		size++;
3231c54795dSChristophe Ricard 	if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_req->pfb))
3241c54795dSChristophe Ricard 		size++;
3251c54795dSChristophe Ricard 
326*4b99b749Swengjianfeng 	if (skb->len < size)
327*4b99b749Swengjianfeng 		return -EIO;
3281c54795dSChristophe Ricard 
3291c54795dSChristophe Ricard 	/* Receiving DEP_REQ - Decoding */
3301c54795dSChristophe Ricard 	switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_req->pfb)) {
3311c54795dSChristophe Ricard 	case ST21NFCA_NFC_DEP_PFB_I_PDU:
3321c54795dSChristophe Ricard 		info->dep_info.curr_nfc_dep_pni =
3331c54795dSChristophe Ricard 				ST21NFCA_NFC_DEP_PFB_PNI(dep_req->pfb);
3341c54795dSChristophe Ricard 		break;
3351c54795dSChristophe Ricard 	case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
3361c54795dSChristophe Ricard 		pr_err("Received a ACK/NACK PDU\n");
3371c54795dSChristophe Ricard 		break;
3381c54795dSChristophe Ricard 	case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
3391c54795dSChristophe Ricard 		pr_err("Received a SUPERVISOR PDU\n");
3401c54795dSChristophe Ricard 		break;
3411c54795dSChristophe Ricard 	}
3421c54795dSChristophe Ricard 
3431c54795dSChristophe Ricard 	skb_pull(skb, size);
3441c54795dSChristophe Ricard 
3451c54795dSChristophe Ricard 	return nfc_tm_data_received(hdev->ndev, skb);
3461c54795dSChristophe Ricard }
3471c54795dSChristophe Ricard 
st21nfca_tm_event_send_data(struct nfc_hci_dev * hdev,struct sk_buff * skb)3481c54795dSChristophe Ricard static int st21nfca_tm_event_send_data(struct nfc_hci_dev *hdev,
3491c54795dSChristophe Ricard 				struct sk_buff *skb)
3501c54795dSChristophe Ricard {
3511c54795dSChristophe Ricard 	u8 cmd0, cmd1;
3521c54795dSChristophe Ricard 	int r;
3531c54795dSChristophe Ricard 
3541c54795dSChristophe Ricard 	cmd0 = skb->data[1];
3551c54795dSChristophe Ricard 	switch (cmd0) {
3561c54795dSChristophe Ricard 	case ST21NFCA_NFCIP1_REQ:
3571c54795dSChristophe Ricard 		cmd1 = skb->data[2];
3581c54795dSChristophe Ricard 		switch (cmd1) {
3591c54795dSChristophe Ricard 		case ST21NFCA_NFCIP1_ATR_REQ:
3601c54795dSChristophe Ricard 			r = st21nfca_tm_recv_atr_req(hdev, skb);
3611c54795dSChristophe Ricard 			break;
3621c54795dSChristophe Ricard 		case ST21NFCA_NFCIP1_PSL_REQ:
3631c54795dSChristophe Ricard 			r = st21nfca_tm_recv_psl_req(hdev, skb);
3641c54795dSChristophe Ricard 			break;
3651c54795dSChristophe Ricard 		case ST21NFCA_NFCIP1_DEP_REQ:
3661c54795dSChristophe Ricard 			r = st21nfca_tm_recv_dep_req(hdev, skb);
3671c54795dSChristophe Ricard 			break;
3681c54795dSChristophe Ricard 		default:
3691c54795dSChristophe Ricard 			return 1;
3701c54795dSChristophe Ricard 		}
371a01bcfd6SGustavo A. R. Silva 		break;
3721c54795dSChristophe Ricard 	default:
3731c54795dSChristophe Ricard 		return 1;
3741c54795dSChristophe Ricard 	}
3751c54795dSChristophe Ricard 	return r;
3761c54795dSChristophe Ricard }
3771c54795dSChristophe Ricard 
3781c54795dSChristophe Ricard /*
3791c54795dSChristophe Ricard  * Returns:
3801c54795dSChristophe Ricard  * <= 0: driver handled the event, skb consumed
3811c54795dSChristophe Ricard  *    1: driver does not handle the event, please do standard processing
3821c54795dSChristophe Ricard  */
st21nfca_dep_event_received(struct nfc_hci_dev * hdev,u8 event,struct sk_buff * skb)3831c54795dSChristophe Ricard int st21nfca_dep_event_received(struct nfc_hci_dev *hdev,
3841c54795dSChristophe Ricard 				u8 event, struct sk_buff *skb)
3851c54795dSChristophe Ricard {
3861c54795dSChristophe Ricard 	int r = 0;
3871c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
3881c54795dSChristophe Ricard 
3891c54795dSChristophe Ricard 	pr_debug("dep event: %d\n", event);
3901c54795dSChristophe Ricard 
3911c54795dSChristophe Ricard 	switch (event) {
3921c54795dSChristophe Ricard 	case ST21NFCA_EVT_CARD_ACTIVATED:
3931c54795dSChristophe Ricard 		info->dep_info.curr_nfc_dep_pni = 0;
3941c54795dSChristophe Ricard 		break;
3951c54795dSChristophe Ricard 	case ST21NFCA_EVT_CARD_DEACTIVATED:
3961c54795dSChristophe Ricard 		break;
3971c54795dSChristophe Ricard 	case ST21NFCA_EVT_FIELD_ON:
3981c54795dSChristophe Ricard 		break;
3991c54795dSChristophe Ricard 	case ST21NFCA_EVT_FIELD_OFF:
4001c54795dSChristophe Ricard 		break;
4011c54795dSChristophe Ricard 	case ST21NFCA_EVT_SEND_DATA:
4021c54795dSChristophe Ricard 		r = st21nfca_tm_event_send_data(hdev, skb);
4031c54795dSChristophe Ricard 		if (r < 0)
4041c54795dSChristophe Ricard 			return r;
4051c54795dSChristophe Ricard 		return 0;
4061c54795dSChristophe Ricard 	default:
407a9e062d0SChristophe Ricard 		nfc_err(&hdev->ndev->dev, "Unexpected event on card f gate\n");
4081c54795dSChristophe Ricard 		return 1;
4091c54795dSChristophe Ricard 	}
4101c54795dSChristophe Ricard 	kfree_skb(skb);
4111c54795dSChristophe Ricard 	return r;
4121c54795dSChristophe Ricard }
4131c54795dSChristophe Ricard EXPORT_SYMBOL(st21nfca_dep_event_received);
4141c54795dSChristophe Ricard 
st21nfca_im_send_psl_req(struct nfc_hci_dev * hdev,u8 did,u8 bsi,u8 bri,u8 lri)4151c54795dSChristophe Ricard static void st21nfca_im_send_psl_req(struct nfc_hci_dev *hdev, u8 did, u8 bsi,
4161c54795dSChristophe Ricard 				     u8 bri, u8 lri)
4171c54795dSChristophe Ricard {
4181c54795dSChristophe Ricard 	struct sk_buff *skb;
4191c54795dSChristophe Ricard 	struct st21nfca_psl_req *psl_req;
4201c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
4211c54795dSChristophe Ricard 
4221c54795dSChristophe Ricard 	skb =
4231c54795dSChristophe Ricard 	    alloc_skb(sizeof(struct st21nfca_psl_req) + 1, GFP_KERNEL);
4241c54795dSChristophe Ricard 	if (!skb)
4251c54795dSChristophe Ricard 		return;
4261c54795dSChristophe Ricard 	skb_reserve(skb, 1);
4271c54795dSChristophe Ricard 
4281c54795dSChristophe Ricard 	skb_put(skb, sizeof(struct st21nfca_psl_req));
4291c54795dSChristophe Ricard 	psl_req = (struct st21nfca_psl_req *) skb->data;
4301c54795dSChristophe Ricard 
4311c54795dSChristophe Ricard 	psl_req->length = sizeof(struct st21nfca_psl_req);
4321c54795dSChristophe Ricard 	psl_req->cmd0 = ST21NFCA_NFCIP1_REQ;
4331c54795dSChristophe Ricard 	psl_req->cmd1 = ST21NFCA_NFCIP1_PSL_REQ;
4341c54795dSChristophe Ricard 	psl_req->did = did;
4351c54795dSChristophe Ricard 	psl_req->brs = (0x30 & bsi << 4) | (bri & 0x03);
4361c54795dSChristophe Ricard 	psl_req->fsl = lri;
4371c54795dSChristophe Ricard 
438d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = info->dep_info.to | 0x10;
4391c54795dSChristophe Ricard 
4401c54795dSChristophe Ricard 	st21nfca_im_send_pdu(info, skb);
4411c54795dSChristophe Ricard }
4421c54795dSChristophe Ricard 
4431c54795dSChristophe Ricard #define ST21NFCA_CB_TYPE_READER_F 1
st21nfca_im_recv_atr_res_cb(void * context,struct sk_buff * skb,int err)4441c54795dSChristophe Ricard static void st21nfca_im_recv_atr_res_cb(void *context, struct sk_buff *skb,
4451c54795dSChristophe Ricard 					int err)
4461c54795dSChristophe Ricard {
4471c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = context;
4481c54795dSChristophe Ricard 	struct st21nfca_atr_res *atr_res;
4491c54795dSChristophe Ricard 	int r;
4501c54795dSChristophe Ricard 
4511c54795dSChristophe Ricard 	if (err != 0)
4521c54795dSChristophe Ricard 		return;
4531c54795dSChristophe Ricard 
4541c54795dSChristophe Ricard 	if (!skb)
4551c54795dSChristophe Ricard 		return;
4561c54795dSChristophe Ricard 
4571c54795dSChristophe Ricard 	switch (info->async_cb_type) {
4581c54795dSChristophe Ricard 	case ST21NFCA_CB_TYPE_READER_F:
4591c54795dSChristophe Ricard 		skb_trim(skb, skb->len - 1);
4601c54795dSChristophe Ricard 		atr_res = (struct st21nfca_atr_res *)skb->data;
4611c54795dSChristophe Ricard 		r = nfc_set_remote_general_bytes(info->hdev->ndev,
4621c54795dSChristophe Ricard 				atr_res->gbi,
4631c54795dSChristophe Ricard 				skb->len - sizeof(struct st21nfca_atr_res));
4641c54795dSChristophe Ricard 		if (r < 0)
4651c54795dSChristophe Ricard 			return;
4661c54795dSChristophe Ricard 
4671c54795dSChristophe Ricard 		if (atr_res->to >= 0x0e)
4681c54795dSChristophe Ricard 			info->dep_info.to = 0x0e;
4691c54795dSChristophe Ricard 		else
4701c54795dSChristophe Ricard 			info->dep_info.to = atr_res->to + 1;
4711c54795dSChristophe Ricard 
4721c54795dSChristophe Ricard 		info->dep_info.to |= 0x10;
4731c54795dSChristophe Ricard 
4741c54795dSChristophe Ricard 		r = nfc_dep_link_is_up(info->hdev->ndev, info->dep_info.idx,
4751c54795dSChristophe Ricard 					NFC_COMM_PASSIVE, NFC_RF_INITIATOR);
4761c54795dSChristophe Ricard 		if (r < 0)
4771c54795dSChristophe Ricard 			return;
4781c54795dSChristophe Ricard 
4791c54795dSChristophe Ricard 		info->dep_info.curr_nfc_dep_pni = 0;
4801c54795dSChristophe Ricard 		if (ST21NFCA_PP2LRI(atr_res->ppi) != info->dep_info.lri)
4811c54795dSChristophe Ricard 			st21nfca_im_send_psl_req(info->hdev, atr_res->did,
4821c54795dSChristophe Ricard 						atr_res->bsi, atr_res->bri,
4831c54795dSChristophe Ricard 						ST21NFCA_PP2LRI(atr_res->ppi));
4841c54795dSChristophe Ricard 		break;
4851c54795dSChristophe Ricard 	default:
4861c54795dSChristophe Ricard 		kfree_skb(skb);
4871c54795dSChristophe Ricard 		break;
4881c54795dSChristophe Ricard 	}
4891c54795dSChristophe Ricard }
4901c54795dSChristophe Ricard 
st21nfca_im_send_atr_req(struct nfc_hci_dev * hdev,u8 * gb,size_t gb_len)4911c54795dSChristophe Ricard int st21nfca_im_send_atr_req(struct nfc_hci_dev *hdev, u8 *gb, size_t gb_len)
4921c54795dSChristophe Ricard {
4931c54795dSChristophe Ricard 	struct sk_buff *skb;
4941c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
4951c54795dSChristophe Ricard 	struct st21nfca_atr_req *atr_req;
4961c54795dSChristophe Ricard 	struct nfc_target *target;
4971c54795dSChristophe Ricard 	uint size;
4981c54795dSChristophe Ricard 
4991c54795dSChristophe Ricard 	info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
5001c54795dSChristophe Ricard 	size = ST21NFCA_ATR_REQ_MIN_SIZE + gb_len;
5011c54795dSChristophe Ricard 	if (size > ST21NFCA_ATR_REQ_MAX_SIZE) {
5021c54795dSChristophe Ricard 		PROTOCOL_ERR("14.6.1.1");
5031c54795dSChristophe Ricard 		return -EINVAL;
5041c54795dSChristophe Ricard 	}
5051c54795dSChristophe Ricard 
5061c54795dSChristophe Ricard 	skb =
5071c54795dSChristophe Ricard 	    alloc_skb(sizeof(struct st21nfca_atr_req) + gb_len + 1, GFP_KERNEL);
5081c54795dSChristophe Ricard 	if (!skb)
5091c54795dSChristophe Ricard 		return -ENOMEM;
5101c54795dSChristophe Ricard 
5111c54795dSChristophe Ricard 	skb_reserve(skb, 1);
5121c54795dSChristophe Ricard 
5131c54795dSChristophe Ricard 	skb_put(skb, sizeof(struct st21nfca_atr_req));
5141c54795dSChristophe Ricard 
5151c54795dSChristophe Ricard 	atr_req = (struct st21nfca_atr_req *)skb->data;
5161c54795dSChristophe Ricard 	memset(atr_req, 0, sizeof(struct st21nfca_atr_req));
5171c54795dSChristophe Ricard 
5181c54795dSChristophe Ricard 	atr_req->cmd0 = ST21NFCA_NFCIP1_REQ;
5191c54795dSChristophe Ricard 	atr_req->cmd1 = ST21NFCA_NFCIP1_ATR_REQ;
5201c54795dSChristophe Ricard 	memset(atr_req->nfcid3, 0, NFC_NFCID3_MAXSIZE);
5211c54795dSChristophe Ricard 	target = hdev->ndev->targets;
5221c54795dSChristophe Ricard 
5231c54795dSChristophe Ricard 	if (target->sensf_res_len > 0)
5241c54795dSChristophe Ricard 		memcpy(atr_req->nfcid3, target->sensf_res,
5251c54795dSChristophe Ricard 				target->sensf_res_len);
5261c54795dSChristophe Ricard 	else
5271c54795dSChristophe Ricard 		get_random_bytes(atr_req->nfcid3, NFC_NFCID3_MAXSIZE);
5281c54795dSChristophe Ricard 
5291c54795dSChristophe Ricard 	atr_req->did = 0x0;
5301c54795dSChristophe Ricard 
5311c54795dSChristophe Ricard 	atr_req->bsi = 0x00;
5321c54795dSChristophe Ricard 	atr_req->bri = 0x00;
5331c54795dSChristophe Ricard 	atr_req->ppi = ST21NFCA_LR_BITS_PAYLOAD_SIZE_254B;
5341c54795dSChristophe Ricard 	if (gb_len) {
5351c54795dSChristophe Ricard 		atr_req->ppi |= ST21NFCA_GB_BIT;
53659ae1d12SJohannes Berg 		skb_put_data(skb, gb, gb_len);
5371c54795dSChristophe Ricard 	}
5381c54795dSChristophe Ricard 	atr_req->length = sizeof(struct st21nfca_atr_req) + hdev->gb_len;
5391c54795dSChristophe Ricard 
540d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = info->dep_info.to | 0x10; /* timeout */
5411c54795dSChristophe Ricard 
5421c54795dSChristophe Ricard 	info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
5431c54795dSChristophe Ricard 	info->async_cb_context = info;
5441c54795dSChristophe Ricard 	info->async_cb = st21nfca_im_recv_atr_res_cb;
5451c54795dSChristophe Ricard 	info->dep_info.bri = atr_req->bri;
5461c54795dSChristophe Ricard 	info->dep_info.bsi = atr_req->bsi;
5471c54795dSChristophe Ricard 	info->dep_info.lri = ST21NFCA_PP2LRI(atr_req->ppi);
5481c54795dSChristophe Ricard 
5491c54795dSChristophe Ricard 	return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
5501c54795dSChristophe Ricard 				ST21NFCA_WR_XCHG_DATA, skb->data,
5511c54795dSChristophe Ricard 				skb->len, info->async_cb, info);
5521c54795dSChristophe Ricard }
5531c54795dSChristophe Ricard EXPORT_SYMBOL(st21nfca_im_send_atr_req);
5541c54795dSChristophe Ricard 
st21nfca_im_recv_dep_res_cb(void * context,struct sk_buff * skb,int err)5551c54795dSChristophe Ricard static void st21nfca_im_recv_dep_res_cb(void *context, struct sk_buff *skb,
5561c54795dSChristophe Ricard 					int err)
5571c54795dSChristophe Ricard {
5581c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = context;
5591c54795dSChristophe Ricard 	struct st21nfca_dep_req_res *dep_res;
5601c54795dSChristophe Ricard 
5611c54795dSChristophe Ricard 	int size;
5621c54795dSChristophe Ricard 
5631c54795dSChristophe Ricard 	if (err != 0)
5641c54795dSChristophe Ricard 		return;
5651c54795dSChristophe Ricard 
5661c54795dSChristophe Ricard 	if (!skb)
5671c54795dSChristophe Ricard 		return;
5681c54795dSChristophe Ricard 
5691c54795dSChristophe Ricard 	switch (info->async_cb_type) {
5701c54795dSChristophe Ricard 	case ST21NFCA_CB_TYPE_READER_F:
5711c54795dSChristophe Ricard 		dep_res = (struct st21nfca_dep_req_res *)skb->data;
5721c54795dSChristophe Ricard 
5731c54795dSChristophe Ricard 		size = 3;
5741c54795dSChristophe Ricard 		if (skb->len < size)
5751c54795dSChristophe Ricard 			goto exit;
5761c54795dSChristophe Ricard 
5771c54795dSChristophe Ricard 		if (ST21NFCA_NFC_DEP_DID_BIT_SET(dep_res->pfb))
5781c54795dSChristophe Ricard 			size++;
5791c54795dSChristophe Ricard 		if (ST21NFCA_NFC_DEP_NAD_BIT_SET(dep_res->pfb))
5801c54795dSChristophe Ricard 			size++;
5811c54795dSChristophe Ricard 
5821c54795dSChristophe Ricard 		if (skb->len < size)
5831c54795dSChristophe Ricard 			goto exit;
5841c54795dSChristophe Ricard 
5851c54795dSChristophe Ricard 		skb_trim(skb, skb->len - 1);
5861c54795dSChristophe Ricard 
5871c54795dSChristophe Ricard 		/* Receiving DEP_REQ - Decoding */
5881c54795dSChristophe Ricard 		switch (ST21NFCA_NFC_DEP_PFB_TYPE(dep_res->pfb)) {
5891c54795dSChristophe Ricard 		case ST21NFCA_NFC_DEP_PFB_ACK_NACK_PDU:
5901c54795dSChristophe Ricard 			pr_err("Received a ACK/NACK PDU\n");
591df561f66SGustavo A. R. Silva 			fallthrough;
5921c54795dSChristophe Ricard 		case ST21NFCA_NFC_DEP_PFB_I_PDU:
5931c54795dSChristophe Ricard 			info->dep_info.curr_nfc_dep_pni =
5941c54795dSChristophe Ricard 			    ST21NFCA_NFC_DEP_PFB_PNI(dep_res->pfb + 1);
5951c54795dSChristophe Ricard 			size++;
5961c54795dSChristophe Ricard 			skb_pull(skb, size);
5971c54795dSChristophe Ricard 			nfc_tm_data_received(info->hdev->ndev, skb);
5981c54795dSChristophe Ricard 			break;
5991c54795dSChristophe Ricard 		case ST21NFCA_NFC_DEP_PFB_SUPERVISOR_PDU:
6001c54795dSChristophe Ricard 			pr_err("Received a SUPERVISOR PDU\n");
6011c54795dSChristophe Ricard 			skb_pull(skb, size);
602d58ff351SJohannes Berg 			*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
603d58ff351SJohannes Berg 			*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
604d58ff351SJohannes Berg 			*(u8 *)skb_push(skb, 1) = skb->len;
605d58ff351SJohannes Berg 			*(u8 *)skb_push(skb, 1) = info->dep_info.to | 0x10;
6061c54795dSChristophe Ricard 
6071c54795dSChristophe Ricard 			st21nfca_im_send_pdu(info, skb);
6081c54795dSChristophe Ricard 			break;
6091c54795dSChristophe Ricard 		}
6101c54795dSChristophe Ricard 
6111c54795dSChristophe Ricard 		return;
6121c54795dSChristophe Ricard 	default:
6131c54795dSChristophe Ricard 		break;
6141c54795dSChristophe Ricard 	}
6151c54795dSChristophe Ricard 
6161c54795dSChristophe Ricard exit:
6171c54795dSChristophe Ricard 	kfree_skb(skb);
6181c54795dSChristophe Ricard }
6191c54795dSChristophe Ricard 
st21nfca_im_send_dep_req(struct nfc_hci_dev * hdev,struct sk_buff * skb)6201c54795dSChristophe Ricard int st21nfca_im_send_dep_req(struct nfc_hci_dev *hdev, struct sk_buff *skb)
6211c54795dSChristophe Ricard {
6221c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
6231c54795dSChristophe Ricard 
6241c54795dSChristophe Ricard 	info->async_cb_type = ST21NFCA_CB_TYPE_READER_F;
6251c54795dSChristophe Ricard 	info->async_cb_context = info;
6261c54795dSChristophe Ricard 	info->async_cb = st21nfca_im_recv_dep_res_cb;
6271c54795dSChristophe Ricard 
628d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = info->dep_info.curr_nfc_dep_pni;
629d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_DEP_REQ;
630d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = ST21NFCA_NFCIP1_REQ;
631d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = skb->len;
6321c54795dSChristophe Ricard 
633d58ff351SJohannes Berg 	*(u8 *)skb_push(skb, 1) = info->dep_info.to | 0x10;
6341c54795dSChristophe Ricard 
6351c54795dSChristophe Ricard 	return nfc_hci_send_cmd_async(hdev, ST21NFCA_RF_READER_F_GATE,
6361c54795dSChristophe Ricard 				      ST21NFCA_WR_XCHG_DATA,
6371c54795dSChristophe Ricard 				      skb->data, skb->len,
6381c54795dSChristophe Ricard 				      info->async_cb, info);
6391c54795dSChristophe Ricard }
6401c54795dSChristophe Ricard EXPORT_SYMBOL(st21nfca_im_send_dep_req);
6411c54795dSChristophe Ricard 
st21nfca_dep_init(struct nfc_hci_dev * hdev)6421c54795dSChristophe Ricard void st21nfca_dep_init(struct nfc_hci_dev *hdev)
6431c54795dSChristophe Ricard {
6441c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
6451c54795dSChristophe Ricard 
6461c54795dSChristophe Ricard 	INIT_WORK(&info->dep_info.tx_work, st21nfca_tx_work);
6471c54795dSChristophe Ricard 	info->dep_info.curr_nfc_dep_pni = 0;
6481c54795dSChristophe Ricard 	info->dep_info.idx = 0;
6491c54795dSChristophe Ricard 	info->dep_info.to = ST21NFCA_DEFAULT_TIMEOUT;
6501c54795dSChristophe Ricard }
6511c54795dSChristophe Ricard EXPORT_SYMBOL(st21nfca_dep_init);
6521c54795dSChristophe Ricard 
st21nfca_dep_deinit(struct nfc_hci_dev * hdev)6531c54795dSChristophe Ricard void st21nfca_dep_deinit(struct nfc_hci_dev *hdev)
6541c54795dSChristophe Ricard {
6551c54795dSChristophe Ricard 	struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
6561c54795dSChristophe Ricard 
6571c54795dSChristophe Ricard 	cancel_work_sync(&info->dep_info.tx_work);
6581c54795dSChristophe Ricard }
6591c54795dSChristophe Ricard EXPORT_SYMBOL(st21nfca_dep_deinit);
660