diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-10-29 16:34:36 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-10-29 18:07:45 -0400 |
commit | b7889497d306df0be52300b3060ebc12b4194f9a (patch) | |
tree | ee2f0a995b2e5579f63960a47f2f519dbffa326e /net/mac802154/rx.c | |
parent | 08c511a7331cf6edb28895d7f46c3039180b30cb (diff) |
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: 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 | 34 |
1 files changed, 12 insertions, 22 deletions
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 51a55d9200cb..b6a4bbfdbf90 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
23 | #include <linux/crc-ccitt.h> | 23 | #include <linux/crc-ccitt.h> |
24 | #include <asm/unaligned.h> | ||
24 | 25 | ||
25 | #include <net/mac802154.h> | 26 | #include <net/mac802154.h> |
26 | #include <net/ieee802154_netdev.h> | 27 | #include <net/ieee802154_netdev.h> |
@@ -225,8 +226,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) | |||
225 | { | 226 | { |
226 | struct sk_buff *skb2; | 227 | struct sk_buff *skb2; |
227 | struct ieee802154_sub_if_data *sdata; | 228 | struct ieee802154_sub_if_data *sdata; |
228 | u16 crc = crc_ccitt(0, skb->data, skb->len); | ||
229 | u8 *data; | ||
230 | 229 | ||
231 | skb_reset_mac_header(skb); | 230 | skb_reset_mac_header(skb); |
232 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 231 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -241,9 +240,6 @@ ieee802154_monitors_rx(struct ieee802154_local *local, struct sk_buff *skb) | |||
241 | skb2 = skb_clone(skb, GFP_ATOMIC); | 240 | skb2 = skb_clone(skb, GFP_ATOMIC); |
242 | skb2->dev = sdata->dev; | 241 | skb2->dev = sdata->dev; |
243 | skb2->pkt_type = PACKET_HOST; | 242 | skb2->pkt_type = PACKET_HOST; |
244 | data = skb_put(skb2, 2); | ||
245 | data[0] = crc & 0xff; | ||
246 | data[1] = crc >> 8; | ||
247 | 243 | ||
248 | netif_rx_ni(skb2); | 244 | netif_rx_ni(skb2); |
249 | } | 245 | } |
@@ -255,32 +251,26 @@ void ieee802154_rx(struct ieee802154_hw *hw, struct sk_buff *skb) | |||
255 | 251 | ||
256 | WARN_ON_ONCE(softirq_count() == 0); | 252 | WARN_ON_ONCE(softirq_count() == 0); |
257 | 253 | ||
258 | if (!(local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM)) { | 254 | /* TODO: When a transceiver omits the checksum here, we |
259 | u16 crc; | 255 | * add an own calculated one. This is currently an ugly |
256 | * solution because the monitor needs a crc here. | ||
257 | */ | ||
258 | if (local->hw.flags & IEEE802154_HW_RX_OMIT_CKSUM) { | ||
259 | u16 crc = crc_ccitt(0, skb->data, skb->len); | ||
260 | 260 | ||
261 | if (skb->len < 2) { | 261 | put_unaligned_le16(crc, skb_put(skb, 2)); |
262 | pr_debug("got invalid frame\n"); | ||
263 | goto fail; | ||
264 | } | ||
265 | crc = crc_ccitt(0, skb->data, skb->len); | ||
266 | if (crc) { | ||
267 | pr_debug("CRC mismatch\n"); | ||
268 | goto fail; | ||
269 | } | ||
270 | skb_trim(skb, skb->len - 2); /* CRC */ | ||
271 | } | 262 | } |
272 | 263 | ||
273 | rcu_read_lock(); | 264 | rcu_read_lock(); |
274 | 265 | ||
275 | ieee802154_monitors_rx(local, skb); | 266 | ieee802154_monitors_rx(local, skb); |
276 | __ieee802154_rx_handle_packet(local, skb); | ||
277 | 267 | ||
278 | rcu_read_unlock(); | 268 | /* remove crc */ |
269 | skb_trim(skb, skb->len - 2); | ||
279 | 270 | ||
280 | return; | 271 | __ieee802154_rx_handle_packet(local, skb); |
281 | 272 | ||
282 | fail: | 273 | rcu_read_unlock(); |
283 | kfree_skb(skb); | ||
284 | } | 274 | } |
285 | EXPORT_SYMBOL(ieee802154_rx); | 275 | EXPORT_SYMBOL(ieee802154_rx); |
286 | 276 | ||