]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - net/mac802154/rx.c
2 * Copyright (C) 2007-2012 Siemens AG
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
19 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
20 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
21 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/workqueue.h>
27 #include <linux/netdevice.h>
28 #include <linux/crc-ccitt.h>
30 #include <net/mac802154.h>
31 #include <net/ieee802154_netdev.h>
33 #include "mac802154.h"
35 /* The IEEE 802.15.4 standard defines 4 MAC packet types:
38 * - acknowledgement frame
41 * and only the data frame should be pushed to the upper layers, other types
42 * are just internal MAC layer management information. So only data packets
43 * are going to be sent to the networking queue, all other will be processed
44 * right here by using the device workqueue.
48 struct work_struct work
;
49 struct ieee802154_dev
*dev
;
54 mac802154_subif_rx(struct ieee802154_dev
*hw
, struct sk_buff
*skb
, u8 lqi
)
56 struct mac802154_priv
*priv
= mac802154_to_priv(hw
);
58 mac_cb(skb
)->lqi
= lqi
;
59 skb
->protocol
= htons(ETH_P_IEEE802154
);
60 skb_reset_mac_header(skb
);
62 BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb
) > sizeof(skb
->cb
));
64 if (!(priv
->hw
.flags
& IEEE802154_HW_OMIT_CKSUM
)) {
68 pr_debug("got invalid frame\n");
71 crc
= crc_ccitt(0, skb
->data
, skb
->len
);
73 pr_debug("CRC mismatch\n");
76 skb_trim(skb
, skb
->len
- 2); /* CRC */
79 mac802154_monitors_rx(priv
, skb
);
80 mac802154_wpans_rx(priv
, skb
);
86 static void mac802154_rx_worker(struct work_struct
*work
)
88 struct rx_work
*rw
= container_of(work
, struct rx_work
, work
);
89 struct sk_buff
*skb
= rw
->skb
;
91 mac802154_subif_rx(rw
->dev
, skb
, rw
->lqi
);
96 ieee802154_rx_irqsafe(struct ieee802154_dev
*dev
, struct sk_buff
*skb
, u8 lqi
)
98 struct mac802154_priv
*priv
= mac802154_to_priv(dev
);
104 work
= kzalloc(sizeof(struct rx_work
), GFP_ATOMIC
);
108 INIT_WORK(&work
->work
, mac802154_rx_worker
);
113 queue_work(priv
->dev_workqueue
, &work
->work
);
115 EXPORT_SYMBOL(ieee802154_rx_irqsafe
);