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

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

mac802154: rx: add software checksum filtering check



This patch adds a new hardware flag which indicate that the transceiver
doesn't support check for bad checksum via hardware. Also add a handling of
this while receive.

Signed-off-by: default avatarAlexander Aring <alex.aring@gmail.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent b7889497
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -96,6 +96,8 @@ struct ieee802154_hw {
#define IEEE802154_HW_PROMISCUOUS	0x00000200
/* Indicates that receiver omits FCS. */
#define IEEE802154_HW_RX_OMIT_CKSUM	0x00000400
/* Indicates that receiver will not filter frames with bad checksum. */
#define IEEE802154_HW_RX_DROP_BAD_CKSUM	0x00000800

/* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */
#define IEEE802154_HW_OMIT_CKSUM	(IEEE802154_HW_TX_OMIT_CKSUM | \
+13 −2
Original line number Diff line number Diff line
@@ -248,6 +248,7 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb)
void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
{
	struct ieee802154_local *local = hw_to_local(hw);
	u16 crc;

	WARN_ON_ONCE(softirq_count() == 0);

@@ -256,8 +257,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
	 * 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);

		crc = crc_ccitt(0, skb->data, skb->len);
		put_unaligned_le16(crc, skb_put(skb, 2));
	}

@@ -265,6 +265,17 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)

	ieee802154_monitors_rx(local, skb);

	/* Check if transceiver doesn't validate the checksum.
	 * If not we validate the checksum here.
	 */
	if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) {
		crc = crc_ccitt(0, skb->data, skb->len);
		if (crc) {
			rcu_read_unlock();
			kfree_skb(skb);
			return;
		}
	}
	/* remove crc */
	skb_trim(skb, skb->len - 2);