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

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
...@@ -96,6 +96,8 @@ struct ieee802154_hw { ...@@ -96,6 +96,8 @@ struct ieee802154_hw {
#define IEEE802154_HW_PROMISCUOUS 0x00000200 #define IEEE802154_HW_PROMISCUOUS 0x00000200
/* Indicates that receiver omits FCS. */ /* Indicates that receiver omits FCS. */
#define IEEE802154_HW_RX_OMIT_CKSUM 0x00000400 #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. */ /* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */
#define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \ #define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \
......
...@@ -248,6 +248,7 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) ...@@ -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) void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
{ {
struct ieee802154_local *local = hw_to_local(hw); struct ieee802154_local *local = hw_to_local(hw);
u16 crc;
WARN_ON_ONCE(softirq_count() == 0); WARN_ON_ONCE(softirq_count() == 0);
...@@ -256,8 +257,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) ...@@ -256,8 +257,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
* solution because the monitor needs a crc here. * solution because the monitor needs a crc here.
*/ */
if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) { 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)); put_unaligned_le16(crc, skb_put(skb, 2));
} }
...@@ -265,6 +265,17 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) ...@@ -265,6 +265,17 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb)
ieee802154_monitors_rx(local, 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 */ /* remove crc */
skb_trim(skb, skb->len - 2); skb_trim(skb, skb->len - 2);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment