Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7889497 authored by Alexander Aring's avatar Alexander Aring Committed by Marcel Holtmann
Browse files

mac802154: rx: simplify crc receive handling



This patch change the actual crc handling while receive. Currently the
IEEE802154_HW_RX_OMIT_CKSUM flag is used to filter a frame with a bad crc.
This patch changes the behaviour of IEEE802154_HW_RX_OMIT_CKSUM to add a
crc while receiving for the monitor interface. After monitor receiving
we remove the crc for frame parsing. This affect the driver layer
because all drivers sets IEEE802154_HW_RX_OMIT_CKSUM and deliver without
checksum.

Signed-off-by: default avatarAlexander Aring <alex.aring@gmail.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 08c511a7
Loading
Loading
Loading
Loading
+12 −22
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/crc-ccitt.h>
#include <asm/unaligned.h>

#include <net/mac802154.h>
#include <net/ieee802154_netdev.h>
@@ -225,8 +226,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)
{
	struct sk_buff *skb2;
	struct ieee802154_sub_if_data *sdata;
	u16 crc = crc_ccitt(0, skb->data, skb->len);
	u8 *data;

	skb_reset_mac_header(skb);
	skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -241,9 +240,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, 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);
	}
@@ -255,32 +251,26 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)

	WARN_ON_ONCE(softirq_count() == 0);

	if (!(local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM)) {
		u16 crc;
	/* TODO: When a transceiver omits the checksum here, we
	 * add an own calculated one. This is currently an ugly
	 * solution because the monitor needs a crc here.
	 */
	if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) {
		u16 crc = crc_ccitt(0, skb->data, skb->len);

		if (skb->len < 2) {
			pr_debug("got invalid frame\n");
			goto fail;
		}
		crc = crc_ccitt(0, skb->data, skb->len);
		if (crc) {
			pr_debug("CRC mismatch\n");
			goto fail;
		}
		skb_trim(skb, skb->len - 2); /* CRC */
		put_unaligned_le16(crc, skb_put(skb, 2));
	}

	rcu_read_lock();

	ieee802154_monitors_rx(local, skb);
	__ieee802154_rx_handle_packet(local, skb);

	rcu_read_unlock();
	/* remove crc */
	skb_trim(skb, skb->len - 2);

	return;
	__ieee802154_rx_handle_packet(local, skb);

fail:
	kfree_skb(skb);
	rcu_read_unlock();
}
EXPORT_SYMBOL(ieee802154_rx);