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>
This commit is contained in:
Waldemar Rymarkiewicz 2012-09-07 11:08:29 +02:00 committed by Samuel Ortiz
parent 52da2449e1
commit ade672082d
2 changed files with 32 additions and 27 deletions

View File

@ -128,6 +128,8 @@ static struct nfc_hci_gate pn544_gates[] = {
/* Largest headroom needed for outgoing custom commands */ /* Largest headroom needed for outgoing custom commands */
#define PN544_CMDS_HEADROOM 2 #define PN544_CMDS_HEADROOM 2
#define PN544_FRAME_HEADROOM 1
#define PN544_FRAME_TAILROOM 2
struct pn544_hci_info { struct pn544_hci_info {
struct i2c_client *i2c_dev; struct i2c_client *i2c_dev;
@ -576,15 +578,40 @@ static int pn544_hci_ready(struct nfc_shdlc *shdlc)
return 0; 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) static int pn544_hci_xmit(struct nfc_shdlc *shdlc, struct sk_buff *skb)
{ {
struct pn544_hci_info *info = nfc_shdlc_get_clientdata(shdlc); struct pn544_hci_info *info = nfc_shdlc_get_clientdata(shdlc);
struct i2c_client *client = info->i2c_dev; struct i2c_client *client = info->i2c_dev;
int r;
if (info->hard_fault != 0) if (info->hard_fault != 0)
return info->hard_fault; 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, 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, info->shdlc = nfc_shdlc_allocate(&pn544_shdlc_ops,
&init_data, protocols, &init_data, protocols,
PN544_CMDS_HEADROOM, 0, PN544_FRAME_HEADROOM + PN544_CMDS_HEADROOM,
PN544_FRAME_TAILROOM,
PN544_HCI_LLC_MAX_PAYLOAD, PN544_HCI_LLC_MAX_PAYLOAD,
dev_name(&client->dev)); dev_name(&client->dev));
if (!info->shdlc) { if (!info->shdlc) {

View File

@ -22,7 +22,6 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/crc-ccitt.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
@ -30,7 +29,6 @@
#include <net/nfc/shdlc.h> #include <net/nfc/shdlc.h>
#define SHDLC_LLC_HEAD_ROOM 2 #define SHDLC_LLC_HEAD_ROOM 2
#define SHDLC_LLC_TAIL_ROOM 2
#define SHDLC_MAX_WINDOW 4 #define SHDLC_MAX_WINDOW 4
#define SHDLC_SREJ_SUPPORT false #define SHDLC_SREJ_SUPPORT false
@ -94,28 +92,13 @@ static struct sk_buff *nfc_shdlc_alloc_skb(struct nfc_shdlc *shdlc,
struct sk_buff *skb; struct sk_buff *skb;
skb = alloc_skb(shdlc->client_headroom + SHDLC_LLC_HEAD_ROOM + skb = alloc_skb(shdlc->client_headroom + SHDLC_LLC_HEAD_ROOM +
shdlc->client_tailroom + SHDLC_LLC_TAIL_ROOM + shdlc->client_tailroom + payload_len, GFP_KERNEL);
payload_len, GFP_KERNEL);
if (skb) if (skb)
skb_reserve(skb, shdlc->client_headroom + SHDLC_LLC_HEAD_ROOM); skb_reserve(skb, shdlc->client_headroom + SHDLC_LLC_HEAD_ROOM);
return skb; return skb;
} }
static void nfc_shdlc_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;
}
/* immediately sends an S frame. */ /* immediately sends an S frame. */
static int nfc_shdlc_send_s_frame(struct nfc_shdlc *shdlc, static int nfc_shdlc_send_s_frame(struct nfc_shdlc *shdlc,
enum sframe_type sframe_type, int nr) enum sframe_type sframe_type, int nr)
@ -131,8 +114,6 @@ static int nfc_shdlc_send_s_frame(struct nfc_shdlc *shdlc,
*skb_push(skb, 1) = SHDLC_CONTROL_HEAD_S | (sframe_type << 3) | nr; *skb_push(skb, 1) = SHDLC_CONTROL_HEAD_S | (sframe_type << 3) | nr;
nfc_shdlc_add_len_crc(skb);
r = shdlc->ops->xmit(shdlc, skb); r = shdlc->ops->xmit(shdlc, skb);
kfree_skb(skb); kfree_skb(skb);
@ -151,8 +132,6 @@ static int nfc_shdlc_send_u_frame(struct nfc_shdlc *shdlc,
*skb_push(skb, 1) = SHDLC_CONTROL_HEAD_U | uframe_modifier; *skb_push(skb, 1) = SHDLC_CONTROL_HEAD_U | uframe_modifier;
nfc_shdlc_add_len_crc(skb);
r = shdlc->ops->xmit(shdlc, skb); r = shdlc->ops->xmit(shdlc, skb);
kfree_skb(skb); kfree_skb(skb);
@ -509,8 +488,6 @@ static void nfc_shdlc_handle_send_queue(struct nfc_shdlc *shdlc)
shdlc->nr); shdlc->nr);
/* SHDLC_DUMP_SKB("shdlc frame written", skb); */ /* SHDLC_DUMP_SKB("shdlc frame written", skb); */
nfc_shdlc_add_len_crc(skb);
r = shdlc->ops->xmit(shdlc, skb); r = shdlc->ops->xmit(shdlc, skb);
if (r < 0) { if (r < 0) {
shdlc->hard_fault = r; shdlc->hard_fault = r;
@ -880,7 +857,7 @@ struct nfc_shdlc *nfc_shdlc_allocate(struct nfc_shdlc_ops *ops,
shdlc->hdev = nfc_hci_allocate_device(&shdlc_ops, init_data, protocols, shdlc->hdev = nfc_hci_allocate_device(&shdlc_ops, init_data, protocols,
tx_headroom + SHDLC_LLC_HEAD_ROOM, tx_headroom + SHDLC_LLC_HEAD_ROOM,
tx_tailroom + SHDLC_LLC_TAIL_ROOM, tx_tailroom,
max_link_payload); max_link_payload);
if (shdlc->hdev == NULL) if (shdlc->hdev == NULL)
goto err_allocdev; goto err_allocdev;