diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-10-29 16:34:37 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-10-29 18:07:45 -0400 |
commit | ec718f3db9b7968ca5dfb10c85c56ff27149df94 (patch) | |
tree | 55b01d80793110ba50facc1a6054130760aad150 | |
parent | b7889497d306df0be52300b3060ebc12b4194f9a (diff) |
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>
-rw-r--r-- | include/net/mac802154.h | 2 | ||||
-rw-r--r-- | net/mac802154/rx.c | 15 |
2 files changed, 15 insertions, 2 deletions
diff --git a/include/net/mac802154.h b/include/net/mac802154.h index bc1d40c826e3..8f1de6844cb0 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h | |||
@@ -96,6 +96,8 @@ struct ieee802154_hw { | |||
96 | #define IEEE802154_HW_PROMISCUOUS 0x00000200 | 96 | #define IEEE802154_HW_PROMISCUOUS 0x00000200 |
97 | /* Indicates that receiver omits FCS. */ | 97 | /* Indicates that receiver omits FCS. */ |
98 | #define IEEE802154_HW_RX_OMIT_CKSUM 0x00000400 | 98 | #define IEEE802154_HW_RX_OMIT_CKSUM 0x00000400 |
99 | /* Indicates that receiver will not filter frames with bad checksum. */ | ||
100 | #define IEEE802154_HW_RX_DROP_BAD_CKSUM 0x00000800 | ||
99 | 101 | ||
100 | /* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ | 102 | /* Indicates that receiver omits FCS and xmitter will add FCS on it's own. */ |
101 | #define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \ | 103 | #define IEEE802154_HW_OMIT_CKSUM (IEEE802154_HW_TX_OMIT_CKSUM | \ |
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) | |||
248 | void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) | 248 | void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) |
249 | { | 249 | { |
250 | struct ieee802154_local *local = hw_to_local(hw); | 250 | struct ieee802154_local *local = hw_to_local(hw); |
251 | u16 crc; | ||
251 | 252 | ||
252 | WARN_ON_ONCE(softirq_count() == 0); | 253 | WARN_ON_ONCE(softirq_count() == 0); |
253 | 254 | ||
@@ -256,8 +257,7 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) | |||
256 | * solution because the monitor needs a crc here. | 257 | * solution because the monitor needs a crc here. |
257 | */ | 258 | */ |
258 | if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) { | 259 | if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) { |
259 | u16 crc = crc_ccitt(0, skb->data, skb->len); | 260 | crc = crc_ccitt(0, skb->data, skb->len); |
260 | |||
261 | put_unaligned_le16(crc, skb_put(skb, 2)); | 261 | put_unaligned_le16(crc, skb_put(skb, 2)); |
262 | } | 262 | } |
263 | 263 | ||
@@ -265,6 +265,17 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) | |||
265 | 265 | ||
266 | ieee802154_monitors_rx(local, skb); | 266 | ieee802154_monitors_rx(local, skb); |
267 | 267 | ||
268 | /* Check if transceiver doesn't validate the checksum. | ||
269 | * If not we validate the checksum here. | ||
270 | */ | ||
271 | if (local->hw.flags & IEEE802154_HW_RX_DROP_BAD_CKSUM) { | ||
272 | crc = crc_ccitt(0, skb->data, skb->len); | ||
273 | if (crc) { | ||
274 | rcu_read_unlock(); | ||
275 | kfree_skb(skb); | ||
276 | return; | ||
277 | } | ||
278 | } | ||
268 | /* remove crc */ | 279 | /* remove crc */ |
269 | skb_trim(skb, skb->len - 2); | 280 | skb_trim(skb, skb->len - 2); |
270 | 281 | ||