diff options
Diffstat (limited to 'net/nfc/nci/data.c')
-rw-r--r-- | net/nfc/nci/data.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c index 427ef2c7ab68..a2de2a8cb00e 100644 --- a/net/nfc/nci/data.c +++ b/net/nfc/nci/data.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * NFC Controller (NFCC) and a Device Host (DH). | 3 | * NFC Controller (NFCC) and a Device Host (DH). |
4 | * | 4 | * |
5 | * Copyright (C) 2011 Texas Instruments, Inc. | 5 | * Copyright (C) 2011 Texas Instruments, Inc. |
6 | * Copyright (C) 2014 Marvell International Ltd. | ||
6 | * | 7 | * |
7 | * Written by Ilan Elias <ilane@ti.com> | 8 | * Written by Ilan Elias <ilane@ti.com> |
8 | * | 9 | * |
@@ -184,11 +185,16 @@ exit: | |||
184 | 185 | ||
185 | static void nci_add_rx_data_frag(struct nci_dev *ndev, | 186 | static void nci_add_rx_data_frag(struct nci_dev *ndev, |
186 | struct sk_buff *skb, | 187 | struct sk_buff *skb, |
187 | __u8 pbf) | 188 | __u8 pbf, __u8 status) |
188 | { | 189 | { |
189 | int reassembly_len; | 190 | int reassembly_len; |
190 | int err = 0; | 191 | int err = 0; |
191 | 192 | ||
193 | if (status) { | ||
194 | err = status; | ||
195 | goto exit; | ||
196 | } | ||
197 | |||
192 | if (ndev->rx_data_reassembly) { | 198 | if (ndev->rx_data_reassembly) { |
193 | reassembly_len = ndev->rx_data_reassembly->len; | 199 | reassembly_len = ndev->rx_data_reassembly->len; |
194 | 200 | ||
@@ -223,13 +229,24 @@ static void nci_add_rx_data_frag(struct nci_dev *ndev, | |||
223 | } | 229 | } |
224 | 230 | ||
225 | exit: | 231 | exit: |
226 | nci_data_exchange_complete(ndev, skb, err); | 232 | if (ndev->nfc_dev->rf_mode == NFC_RF_INITIATOR) { |
233 | nci_data_exchange_complete(ndev, skb, err); | ||
234 | } else if (ndev->nfc_dev->rf_mode == NFC_RF_TARGET) { | ||
235 | /* Data received in Target mode, forward to nfc core */ | ||
236 | err = nfc_tm_data_received(ndev->nfc_dev, skb); | ||
237 | if (err) | ||
238 | pr_err("unable to handle received data\n"); | ||
239 | } else { | ||
240 | pr_err("rf mode unknown\n"); | ||
241 | kfree_skb(skb); | ||
242 | } | ||
227 | } | 243 | } |
228 | 244 | ||
229 | /* Rx Data packet */ | 245 | /* Rx Data packet */ |
230 | void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb) | 246 | void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb) |
231 | { | 247 | { |
232 | __u8 pbf = nci_pbf(skb->data); | 248 | __u8 pbf = nci_pbf(skb->data); |
249 | __u8 status = 0; | ||
233 | 250 | ||
234 | pr_debug("len %d\n", skb->len); | 251 | pr_debug("len %d\n", skb->len); |
235 | 252 | ||
@@ -247,8 +264,9 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb) | |||
247 | ndev->target_active_prot == NFC_PROTO_ISO15693) { | 264 | ndev->target_active_prot == NFC_PROTO_ISO15693) { |
248 | /* frame I/F => remove the status byte */ | 265 | /* frame I/F => remove the status byte */ |
249 | pr_debug("frame I/F => remove the status byte\n"); | 266 | pr_debug("frame I/F => remove the status byte\n"); |
267 | status = skb->data[skb->len - 1]; | ||
250 | skb_trim(skb, (skb->len - 1)); | 268 | skb_trim(skb, (skb->len - 1)); |
251 | } | 269 | } |
252 | 270 | ||
253 | nci_add_rx_data_frag(ndev, skb, pbf); | 271 | nci_add_rx_data_frag(ndev, skb, pbf, nci_to_errno(status)); |
254 | } | 272 | } |