2 * Copyright 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.
14 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
15 * Sergey Lapin <slapin@ossfans.org>
16 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
17 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
20 #include <linux/netdevice.h>
21 #include <linux/if_arp.h>
22 #include <linux/crc-ccitt.h>
24 #include <net/rtnetlink.h>
25 #include <net/ieee802154_netdev.h>
26 #include <net/mac802154.h>
27 #include <net/cfg802154.h>
29 #include "ieee802154_i.h"
31 /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process
32 * packets through the workqueue.
36 struct work_struct work
;
37 struct ieee802154_local
*local
;
40 static inline struct wpan_xmit_cb
*wpan_xmit_cb(const struct sk_buff
*skb
)
42 BUILD_BUG_ON(sizeof(skb
->cb
) < sizeof(struct wpan_xmit_cb
));
44 return (struct wpan_xmit_cb
*)skb
->cb
;
47 static void mac802154_xmit_worker(struct work_struct
*work
)
49 struct wpan_xmit_cb
*cb
= container_of(work
, struct wpan_xmit_cb
, work
);
50 struct ieee802154_local
*local
= cb
->local
;
51 struct sk_buff
*skb
= cb
->skb
;
56 /* check if ifdown occurred while schedule */
57 if (!netif_running(skb
->dev
))
60 res
= local
->ops
->xmit_sync(&local
->hw
, skb
);
64 ieee802154_xmit_complete(&local
->hw
, skb
);
71 /* Restart the netif queue on each sub_if_data object. */
72 ieee802154_wake_queue(&local
->hw
);
75 netdev_dbg(skb
->dev
, "transmission failed\n");
79 mac802154_tx(struct ieee802154_local
*local
, struct sk_buff
*skb
)
81 struct wpan_xmit_cb
*cb
= wpan_xmit_cb(skb
);
84 mac802154_monitors_rx(local
, skb
);
86 if (!(local
->hw
.flags
& IEEE802154_HW_OMIT_CKSUM
)) {
87 u16 crc
= crc_ccitt(0, skb
->data
, skb
->len
);
88 u8
*data
= skb_put(skb
, 2);
94 if (skb_cow_head(skb
, local
->hw
.extra_tx_headroom
))
97 /* Stop the netif queue on each sub_if_data object. */
98 ieee802154_stop_queue(&local
->hw
);
100 /* async is priority, otherwise sync is fallback */
101 if (local
->ops
->xmit_async
) {
102 ret
= local
->ops
->xmit_async(&local
->hw
, skb
);
104 ieee802154_wake_queue(&local
->hw
);
108 INIT_WORK(&cb
->work
, mac802154_xmit_worker
);
112 queue_work(local
->workqueue
, &cb
->work
);
122 netdev_tx_t
mac802154_monitor_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
124 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
126 skb
->skb_iif
= dev
->ifindex
;
127 dev
->stats
.tx_packets
++;
128 dev
->stats
.tx_bytes
+= skb
->len
;
130 return mac802154_tx(sdata
->local
, skb
);
133 netdev_tx_t
mac802154_wpan_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
135 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
138 rc
= mac802154_llsec_encrypt(&sdata
->sec
, skb
);
140 netdev_warn(dev
, "encryption failed: %i\n", rc
);
145 skb
->skb_iif
= dev
->ifindex
;
146 dev
->stats
.tx_packets
++;
147 dev
->stats
.tx_bytes
+= skb
->len
;
149 return mac802154_tx(sdata
->local
, skb
);
This page took 0.117646 seconds and 6 git commands to generate.