diff options
author | Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> | 2012-09-07 11:08:29 +0200 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-09-25 00:17:24 +0200 |
commit | ade672082dd35aaaf7c8630d16c9f795c30459c4 (patch) | |
tree | bd0c438012bbf4006f63b3f13faddf0d5803d357 /drivers/nfc | |
parent | 52da2449e10039d3bb04c598d24cb1a34530b716 (diff) |
NFC: Remove crc generation from shdlc layer
Checksum is specific for a chip spcification and it varies
(in size and type) between different hardware. It should be
handled in the driver then.
Moreover, shdlc spec doesn't mention crc as a part of the frame.
Update pn544_hci driver as well.
Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Acked-by: Eric Lapuyade <eric.lapuyade@intel.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/nfc')
-rw-r--r-- | drivers/nfc/pn544_hci.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/nfc/pn544_hci.c b/drivers/nfc/pn544_hci.c index 9458d53cdb5..d90aecfce73 100644 --- a/drivers/nfc/pn544_hci.c +++ b/drivers/nfc/pn544_hci.c @@ -128,6 +128,8 @@ static struct nfc_hci_gate pn544_gates[] = { /* Largest headroom needed for outgoing custom commands */ #define PN544_CMDS_HEADROOM 2 +#define PN544_FRAME_HEADROOM 1 +#define PN544_FRAME_TAILROOM 2 struct pn544_hci_info { struct i2c_client *i2c_dev; @@ -576,15 +578,40 @@ static int pn544_hci_ready(struct nfc_shdlc *shdlc) return 0; } +static void pn544_hci_add_len_crc(struct sk_buff *skb) +{ + u16 crc; + int len; + + len = skb->len + 2; + *skb_push(skb, 1) = len; + + crc = crc_ccitt(0xffff, skb->data, skb->len); + crc = ~crc; + *skb_put(skb, 1) = crc & 0xff; + *skb_put(skb, 1) = crc >> 8; +} + +static void pn544_hci_remove_len_crc(struct sk_buff *skb) +{ + skb_pull(skb, PN544_FRAME_HEADROOM); + skb_trim(skb, PN544_FRAME_TAILROOM); +} + static int pn544_hci_xmit(struct nfc_shdlc *shdlc, struct sk_buff *skb) { struct pn544_hci_info *info = nfc_shdlc_get_clientdata(shdlc); struct i2c_client *client = info->i2c_dev; + int r; if (info->hard_fault != 0) return info->hard_fault; - return pn544_hci_i2c_write(client, skb->data, skb->len); + pn544_hci_add_len_crc(skb); + r = pn544_hci_i2c_write(client, skb->data, skb->len); + pn544_hci_remove_len_crc(skb); + + return r; } static int pn544_hci_start_poll(struct nfc_shdlc *shdlc, @@ -874,7 +901,8 @@ static int __devinit pn544_hci_probe(struct i2c_client *client, info->shdlc = nfc_shdlc_allocate(&pn544_shdlc_ops, &init_data, protocols, - PN544_CMDS_HEADROOM, 0, + PN544_FRAME_HEADROOM + PN544_CMDS_HEADROOM, + PN544_FRAME_TAILROOM, PN544_HCI_LLC_MAX_PAYLOAD, dev_name(&client->dev)); if (!info->shdlc) { |