^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * The NFC Controller Interface is the communication protocol between an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * NFC Controller (NFCC) and a Device Host (DH).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2011 Texas Instruments, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2014 Marvell International Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Written by Ilan Elias <ilane@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "../nfc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <net/nfc/nci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <net/nfc/nci_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/nfc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* Complete data exchange transaction and forward skb to nfc core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) __u8 conn_id, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct nci_conn_info *conn_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) data_exchange_cb_t cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) void *cb_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (!conn_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) cb = conn_info->data_exchange_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) cb_context = conn_info->data_exchange_cb_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) pr_debug("len %d, err %d\n", skb ? skb->len : 0, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* data exchange is complete, stop the data timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) del_timer_sync(&ndev->data_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (cb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* forward skb to nfc core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) cb(cb_context, skb, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) } else if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) pr_err("no rx callback, dropping rx data...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* no waiting callback, free skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) clear_bit(NCI_DATA_EXCHANGE, &ndev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* ----------------- NCI TX Data ----------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static inline void nci_push_data_hdr(struct nci_dev *ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) __u8 conn_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) __u8 pbf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct nci_data_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int plen = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) hdr = skb_push(skb, NCI_DATA_HDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) hdr->conn_id = conn_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) hdr->rfu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) hdr->plen = plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) nci_mt_set((__u8 *)hdr, NCI_MT_DATA_PKT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) nci_pbf_set((__u8 *)hdr, pbf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int nci_conn_max_data_pkt_payload_size(struct nci_dev *ndev, __u8 conn_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct nci_conn_info *conn_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (!conn_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return conn_info->max_pkt_payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) EXPORT_SYMBOL(nci_conn_max_data_pkt_payload_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int nci_queue_tx_data_frags(struct nci_dev *ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) __u8 conn_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct sk_buff *skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct nci_conn_info *conn_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int total_len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned char *data = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct sk_buff_head frags_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct sk_buff *skb_frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int frag_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) pr_debug("conn_id 0x%x, total_len %d\n", conn_id, total_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!conn_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) rc = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) __skb_queue_head_init(&frags_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) while (total_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) frag_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) min_t(int, total_len, conn_info->max_pkt_payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) skb_frag = nci_skb_alloc(ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) (NCI_DATA_HDR_SIZE + frag_len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (skb_frag == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) goto free_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) skb_reserve(skb_frag, NCI_DATA_HDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* first, copy the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) skb_put_data(skb_frag, data, frag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* second, set the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) nci_push_data_hdr(ndev, conn_id, skb_frag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ((total_len == frag_len) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) (NCI_PBF_LAST) : (NCI_PBF_CONT)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __skb_queue_tail(&frags_q, skb_frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) data += frag_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) total_len -= frag_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) pr_debug("frag_len %d, remaining total_len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) frag_len, total_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* queue all fragments atomically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) spin_lock_irqsave(&ndev->tx_q.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) while ((skb_frag = __skb_dequeue(&frags_q)) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) __skb_queue_tail(&ndev->tx_q, skb_frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) spin_unlock_irqrestore(&ndev->tx_q.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* free the original skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) free_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) while ((skb_frag = __skb_dequeue(&frags_q)) != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) kfree_skb(skb_frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Send NCI data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct nci_conn_info *conn_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) pr_debug("conn_id 0x%x, plen %d\n", conn_id, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (!conn_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) rc = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) goto free_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* check if the packet need to be fragmented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (skb->len <= conn_info->max_pkt_payload_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* no need to fragment packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) skb_queue_tail(&ndev->tx_q, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* fragment packet and queue the fragments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) rc = nci_queue_tx_data_frags(ndev, conn_id, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) pr_err("failed to fragment tx data packet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) goto free_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ndev->cur_conn_id = conn_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) queue_work(ndev->tx_wq, &ndev->tx_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) free_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) EXPORT_SYMBOL(nci_send_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* ----------------- NCI RX Data ----------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static void nci_add_rx_data_frag(struct nci_dev *ndev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) __u8 pbf, __u8 conn_id, __u8 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int reassembly_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) err = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (ndev->rx_data_reassembly) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) reassembly_len = ndev->rx_data_reassembly->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* first, make enough room for the already accumulated data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (skb_cow_head(skb, reassembly_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) pr_err("error adding room for accumulated rx data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) kfree_skb(ndev->rx_data_reassembly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ndev->rx_data_reassembly = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* second, combine the two fragments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) memcpy(skb_push(skb, reassembly_len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ndev->rx_data_reassembly->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) reassembly_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* third, free old reassembly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) kfree_skb(ndev->rx_data_reassembly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ndev->rx_data_reassembly = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (pbf == NCI_PBF_CONT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* need to wait for next fragment, store skb and exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ndev->rx_data_reassembly = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (ndev->nfc_dev->rf_mode == NFC_RF_TARGET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Data received in Target mode, forward to nfc core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) err = nfc_tm_data_received(ndev->nfc_dev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) pr_err("unable to handle received data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) nci_data_exchange_complete(ndev, skb, conn_id, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* Rx Data packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) __u8 pbf = nci_pbf(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) __u8 status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) __u8 conn_id = nci_conn_id(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct nci_conn_info *conn_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) pr_debug("len %d\n", skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) pr_debug("NCI RX: MT=data, PBF=%d, conn_id=%d, plen=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) nci_pbf(skb->data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) nci_conn_id(skb->data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) nci_plen(skb->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) conn_info = nci_get_conn_info_by_conn_id(ndev, nci_conn_id(skb->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!conn_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* strip the nci data header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) skb_pull(skb, NCI_DATA_HDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (ndev->target_active_prot == NFC_PROTO_MIFARE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ndev->target_active_prot == NFC_PROTO_JEWEL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ndev->target_active_prot == NFC_PROTO_FELICA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ndev->target_active_prot == NFC_PROTO_ISO15693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* frame I/F => remove the status byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) pr_debug("frame I/F => remove the status byte\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) status = skb->data[skb->len - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) skb_trim(skb, (skb->len - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) nci_add_rx_data_frag(ndev, skb, pbf, conn_id, nci_to_errno(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }