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>
23 #include <asm/unaligned.h>
25 #include <net/rtnetlink.h>
26 #include <net/ieee802154_netdev.h>
27 #include <net/mac802154.h>
28 #include <net/cfg802154.h>
30 #include "ieee802154_i.h"
31 #include "driver-ops.h"
33 /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process
34 * packets through the workqueue.
36 struct ieee802154_xmit_cb
{
38 struct work_struct work
;
39 struct ieee802154_local
*local
;
42 static struct ieee802154_xmit_cb ieee802154_xmit_cb
;
44 static void ieee802154_xmit_worker(struct work_struct
*work
)
46 struct ieee802154_xmit_cb
*cb
=
47 container_of(work
, struct ieee802154_xmit_cb
, work
);
48 struct ieee802154_local
*local
= cb
->local
;
49 struct sk_buff
*skb
= cb
->skb
;
50 struct net_device
*dev
= skb
->dev
;
55 /* check if ifdown occurred while schedule */
56 if (!netif_running(dev
))
59 res
= drv_xmit_sync(local
, skb
);
63 ieee802154_xmit_complete(&local
->hw
, skb
, false);
65 dev
->stats
.tx_packets
++;
66 dev
->stats
.tx_bytes
+= skb
->len
;
73 /* Restart the netif queue on each sub_if_data object. */
74 ieee802154_wake_queue(&local
->hw
);
77 netdev_dbg(dev
, "transmission failed\n");
81 ieee802154_tx(struct ieee802154_local
*local
, struct sk_buff
*skb
)
83 struct net_device
*dev
= skb
->dev
;
86 if (!(local
->hw
.flags
& IEEE802154_HW_TX_OMIT_CKSUM
)) {
87 u16 crc
= crc_ccitt(0, skb
->data
, skb
->len
);
89 put_unaligned_le16(crc
, skb_put(skb
, 2));
92 if (skb_cow_head(skb
, local
->hw
.extra_tx_headroom
))
95 /* Stop the netif queue on each sub_if_data object. */
96 ieee802154_stop_queue(&local
->hw
);
98 /* async is priority, otherwise sync is fallback */
99 if (local
->ops
->xmit_async
) {
100 ret
= drv_xmit_async(local
, skb
);
102 ieee802154_wake_queue(&local
->hw
);
106 dev
->stats
.tx_packets
++;
107 dev
->stats
.tx_bytes
+= skb
->len
;
109 INIT_WORK(&ieee802154_xmit_cb
.work
, ieee802154_xmit_worker
);
110 ieee802154_xmit_cb
.skb
= skb
;
111 ieee802154_xmit_cb
.local
= local
;
113 queue_work(local
->workqueue
, &ieee802154_xmit_cb
.work
);
124 ieee802154_monitor_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
126 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
128 skb
->skb_iif
= dev
->ifindex
;
130 return ieee802154_tx(sdata
->local
, skb
);
134 ieee802154_subif_start_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
136 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
139 rc
= mac802154_llsec_encrypt(&sdata
->sec
, skb
);
141 netdev_warn(dev
, "encryption failed: %i\n", rc
);
146 skb
->skb_iif
= dev
->ifindex
;
148 return ieee802154_tx(sdata
->local
, skb
);