Don't discard checksums from received packets at the first possible
moment to do so. This saves a crc calculation in mac802154_monitors_rx
for all frames coming in from the phy. In TX, calculate the checksum,
append it, and possibly remove it if the PHY supports elided checksums.
This gives a total reduction in CRC calculations of one per RX on smart
hardware.

Also, drop packets with incorrect checksums in the at86rf230 driver
instead of passing them up the stack. IEEE 802.15.4 requires that
packets with incorrect CRC be dropped immediatly, and the stack also
makes the assumption that they are dropped. The mrf24j40 driver needs no
change in that respect, since the chip drops bad packets by default.

Signed-off-by: Phoebe Buckheister <phoebe.buckheis...@itwm.fraunhofer.de>
---
 drivers/net/ieee802154/at86rf230.c |   18 ++++++++++++------
 drivers/net/ieee802154/mrf24j40.c  |    3 +--
 net/mac802154/monitor.c            |    5 -----
 net/mac802154/rx.c                 |    3 ++-
 net/mac802154/tx.c                 |   15 +++++++++------
 5 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ieee802154/at86rf230.c 
b/drivers/net/ieee802154/at86rf230.c
index 68d3d9c..1addfcf 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -31,6 +31,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/at86rf230.h>
 #include <linux/skbuff.h>
+#include <linux/crc-ccitt.h>
 
 #include <net/mac802154.h>
 #include <net/wpan-phy.h>
@@ -709,21 +710,26 @@ static int at86rf230_rx(struct at86rf230_local *lp)
                return -ENOMEM;
 
        if (at86rf230_read_fbuf(lp, skb_put(skb, len), &len, &lqi))
-               goto err;
+               goto out;
 
-       if (len < 2)
-               goto err;
+       if (len < 2) {
+               pr_debug("received frame is too small\n");
+               goto out;
+       }
 
-       skb_trim(skb, len - 2); /* We do not put CRC into the frame */
+       skb_trim(skb, len);
+       if (crc_ccitt(0, skb->data, skb->len)) {
+               pr_debug("received frame with incorrect CRC\n");
+               goto out;
+       }
 
        ieee802154_rx_irqsafe(lp->dev, skb, lqi);
 
        dev_dbg(&lp->spi->dev, "READ_FBUF: %d %x\n", len, lqi);
 
        return 0;
-err:
-       pr_debug("received frame is too small\n");
 
+out:
        kfree_skb(skb);
        return -EINVAL;
 }
diff --git a/drivers/net/ieee802154/mrf24j40.c 
b/drivers/net/ieee802154/mrf24j40.c
index c6e46d6..53a8968 100644
--- a/drivers/net/ieee802154/mrf24j40.c
+++ b/drivers/net/ieee802154/mrf24j40.c
@@ -555,8 +555,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
                goto out;
        }
 
-       /* Cut off the checksum */
-       skb_trim(skb, len-2);
+       skb_trim(skb, len);
 
        /* TODO: Other drivers call ieee20154_rx_irqsafe() here (eg: cc2040,
         * also from a workqueue).  I think irqsafe is not necessary here.
diff --git a/net/mac802154/monitor.c b/net/mac802154/monitor.c
index 434a26f..ea34bf7 100644
--- a/net/mac802154/monitor.c
+++ b/net/mac802154/monitor.c
@@ -65,8 +65,6 @@ void mac802154_monitors_rx(struct mac802154_priv *priv, 
struct sk_buff *skb)
 {
        struct sk_buff *skb2;
        struct mac802154_sub_if_data *sdata;
-       u16 crc = crc_ccitt(0, skb->data, skb->len);
-       u8 *data;
 
        rcu_read_lock();
        list_for_each_entry_rcu(sdata, &priv->slaves, list) {
@@ -76,9 +74,6 @@ void mac802154_monitors_rx(struct mac802154_priv *priv, 
struct sk_buff *skb)
                skb2 = skb_clone(skb, GFP_ATOMIC);
                skb2->dev = sdata->dev;
                skb2->pkt_type = PACKET_HOST;
-               data = skb_put(skb2, 2);
-               data[0] = crc & 0xff;
-               data[1] = crc >> 8;
 
                netif_rx_ni(skb2);
        }
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index 38548ec..8f4aafa 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -73,10 +73,11 @@ mac802154_subif_rx(struct ieee802154_dev *hw, struct 
sk_buff *skb, u8 lqi)
                        pr_debug("CRC mismatch\n");
                        goto out;
                }
-               skb_trim(skb, skb->len - 2); /* CRC */
        }
 
+       /* monitor devices expect the CRC to be there, wpans don't */
        mac802154_monitors_rx(priv, skb);
+       skb_trim(skb, skb->len - 2);
        mac802154_wpans_rx(priv, skb);
 out:
        dev_kfree_skb(skb);
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 6d16473..1f1407a 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -86,6 +86,8 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct 
sk_buff *skb,
 {
        struct xmit_work *work;
        struct mac802154_sub_if_data *sdata;
+       u16 crc;
+       u8 *data;
 
        if (!(priv->phy->channels_supported[page] & (1 << chan))) {
                WARN_ON(1);
@@ -93,14 +95,15 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, 
struct sk_buff *skb,
                return NETDEV_TX_OK;
        }
 
+       crc = crc_ccitt(0, skb->data, skb->len);
+       data = skb_put(skb, 2);
+       data[0] = crc & 0xff;
+       data[1] = crc >> 8;
+
        mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb);
 
-       if (!(priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)) {
-               u16 crc = crc_ccitt(0, skb->data, skb->len);
-               u8 *data = skb_put(skb, 2);
-               data[0] = crc & 0xff;
-               data[1] = crc >> 8;
-       }
+       if (priv->hw.flags & IEEE802154_HW_OMIT_CKSUM)
+               skb_trim(skb, skb->len - 2);
 
        if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) {
                kfree_skb(skb);
-- 
1.7.9.5


------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk
_______________________________________________
Linux-zigbee-devel mailing list
Linux-zigbee-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel

Reply via email to