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/ieee802154_netdev.h>
25 #include <net/mac802154.h>
26 #include <net/cfg802154.h>
28 #include "ieee802154_i.h"
30 /* IEEE 802.15.4 transceivers can sleep during the xmit session, so process
31 * packets through the workqueue.
35 struct work_struct work
;
36 struct ieee802154_local
*local
;
41 static inline struct wpan_xmit_cb
*wpan_xmit_cb(const struct sk_buff
*skb
)
43 BUILD_BUG_ON(sizeof(skb
->cb
) < sizeof(struct wpan_xmit_cb
));
45 return (struct wpan_xmit_cb
*)skb
->cb
;
48 static void mac802154_xmit_worker(struct work_struct
*work
)
50 struct wpan_xmit_cb
*cb
= container_of(work
, struct wpan_xmit_cb
, work
);
51 struct ieee802154_local
*local
= cb
->local
;
52 struct ieee802154_sub_if_data
*sdata
;
53 struct sk_buff
*skb
= cb
->skb
;
56 mutex_lock(&local
->phy
->pib_lock
);
57 if (local
->phy
->current_channel
!= cb
->chan
||
58 local
->phy
->current_page
!= cb
->page
) {
59 res
= local
->ops
->set_channel(&local
->hw
, cb
->page
, cb
->chan
);
61 pr_debug("set_channel failed\n");
65 local
->phy
->current_channel
= cb
->chan
;
66 local
->phy
->current_page
= cb
->page
;
69 res
= local
->ops
->xmit(&local
->hw
, skb
);
71 pr_debug("transmission failed\n");
74 mutex_unlock(&local
->phy
->pib_lock
);
76 /* Restart the netif queue on each sub_if_data object. */
78 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
)
79 netif_wake_queue(sdata
->dev
);
85 static netdev_tx_t
mac802154_tx(struct ieee802154_local
*local
,
86 struct sk_buff
*skb
, u8 page
, u8 chan
)
88 struct ieee802154_sub_if_data
*sdata
;
89 struct wpan_xmit_cb
*cb
= wpan_xmit_cb(skb
);
91 if (!(local
->phy
->channels_supported
[page
] & (1 << chan
))) {
96 mac802154_monitors_rx(local
, skb
);
98 if (!(local
->hw
.flags
& IEEE802154_HW_OMIT_CKSUM
)) {
99 u16 crc
= crc_ccitt(0, skb
->data
, skb
->len
);
100 u8
*data
= skb_put(skb
, 2);
102 data
[0] = crc
& 0xff;
106 if (skb_cow_head(skb
, local
->hw
.extra_tx_headroom
))
109 /* Stop the netif queue on each sub_if_data object. */
111 list_for_each_entry_rcu(sdata
, &local
->interfaces
, list
)
112 netif_stop_queue(sdata
->dev
);
115 INIT_WORK(&cb
->work
, mac802154_xmit_worker
);
121 queue_work(local
->workqueue
, &cb
->work
);
130 netdev_tx_t
mac802154_monitor_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
132 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
136 chan
= sdata
->local
->phy
->current_channel
;
137 page
= sdata
->local
->phy
->current_page
;
139 if (chan
== MAC802154_CHAN_NONE
) /* not initialized */
142 if (WARN_ON(page
>= WPAN_NUM_PAGES
) ||
143 WARN_ON(chan
>= WPAN_NUM_CHANNELS
))
146 skb
->skb_iif
= dev
->ifindex
;
147 dev
->stats
.tx_packets
++;
148 dev
->stats
.tx_bytes
+= skb
->len
;
150 return mac802154_tx(sdata
->local
, skb
, page
, chan
);
153 netdev_tx_t
mac802154_wpan_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
155 struct ieee802154_sub_if_data
*sdata
= IEEE802154_DEV_TO_SUB_IF(dev
);
159 spin_lock_bh(&sdata
->mib_lock
);
162 spin_unlock_bh(&sdata
->mib_lock
);
164 if (chan
== MAC802154_CHAN_NONE
||
165 page
>= WPAN_NUM_PAGES
||
166 chan
>= WPAN_NUM_CHANNELS
) {
171 rc
= mac802154_llsec_encrypt(&sdata
->sec
, skb
);
173 pr_warn("encryption failed: %i\n", rc
);
178 skb
->skb_iif
= dev
->ifindex
;
179 dev
->stats
.tx_packets
++;
180 dev
->stats
.tx_bytes
+= skb
->len
;
182 return mac802154_tx(sdata
->local
, skb
, page
, chan
);
This page took 0.060772 seconds and 6 git commands to generate.