/* 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;
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,
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) {
#include <linux/sched.h>
#include <linux/export.h>
#include <linux/wait.h>
-#include <linux/crc-ccitt.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <net/nfc/shdlc.h>
#define SHDLC_LLC_HEAD_ROOM 2
-#define SHDLC_LLC_TAIL_ROOM 2
#define SHDLC_MAX_WINDOW 4
#define SHDLC_SREJ_SUPPORT false
struct sk_buff *skb;
skb = alloc_skb(shdlc->client_headroom + SHDLC_LLC_HEAD_ROOM +
- shdlc->client_tailroom + SHDLC_LLC_TAIL_ROOM +
- payload_len, GFP_KERNEL);
+ shdlc->client_tailroom + payload_len, GFP_KERNEL);
if (skb)
skb_reserve(skb, shdlc->client_headroom + SHDLC_LLC_HEAD_ROOM);
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. */
static int nfc_shdlc_send_s_frame(struct nfc_shdlc *shdlc,
enum sframe_type sframe_type, int 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);
kfree_skb(skb);
*skb_push(skb, 1) = SHDLC_CONTROL_HEAD_U | uframe_modifier;
- nfc_shdlc_add_len_crc(skb);
-
r = shdlc->ops->xmit(shdlc, skb);
kfree_skb(skb);
shdlc->nr);
/* SHDLC_DUMP_SKB("shdlc frame written", skb); */
- nfc_shdlc_add_len_crc(skb);
-
r = shdlc->ops->xmit(shdlc, skb);
if (r < 0) {
shdlc->hard_fault = r;
shdlc->hdev = nfc_hci_allocate_device(&shdlc_ops, init_data, protocols,
tx_headroom + SHDLC_LLC_HEAD_ROOM,
- tx_tailroom + SHDLC_LLC_TAIL_ROOM,
+ tx_tailroom,
max_link_payload);
if (shdlc->hdev == NULL)
goto err_allocdev;