diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-10-29 21:34:37 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-10-29 23:07:45 +0100 |
commit | ec718f3db9b7968ca5dfb10c85c56ff27149df94 (patch) | |
tree | 55b01d80793110ba50facc1a6054130760aad150 /net/mac802154/rx.c | |
parent | b7889497d306df0be52300b3060ebc12b4194f9a (diff) | |
download | blackbird-op-linux-ec718f3db9b7968ca5dfb10c85c56ff27149df94.tar.gz blackbird-op-linux-ec718f3db9b7968ca5dfb10c85c56ff27149df94.zip |
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: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/mac802154/rx.c')
-rw-r--r-- | net/mac802154/rx.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index b6a4bbfdbf90..c9f1c72a1afc 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -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); |