Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
mac802154
tx.c
Go to the documentation of this file.
1
/*
2
* Copyright 2007-2012 Siemens AG
3
*
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.
7
*
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.
12
*
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.
16
*
17
* Written by:
18
* Dmitry Eremin-Solenikov <
[email protected]
>
19
* Sergey Lapin <
[email protected]
>
20
* Maxim Gorbachyov <
[email protected]
>
21
* Alexander Smirnov <
[email protected]
>
22
*/
23
24
#include <linux/netdevice.h>
25
#include <linux/if_arp.h>
26
#include <
linux/crc-ccitt.h
>
27
28
#include <
net/mac802154.h
>
29
#include <
net/wpan-phy.h
>
30
31
#include "
mac802154.h
"
32
33
/* IEEE 802.15.4 transceivers can sleep during the xmit session, so process
34
* packets through the workqueue.
35
*/
36
struct
xmit_work
{
37
struct
sk_buff
*
skb
;
38
struct
work_struct
work
;
39
struct
mac802154_priv
*
priv
;
40
u8
chan
;
41
u8
page
;
42
u8
xmit_attempts
;
43
};
44
45
static
void
mac802154_xmit_worker(
struct
work_struct
*
work
)
46
{
47
struct
xmit_work
*xw =
container_of
(work,
struct
xmit_work
, work);
48
int
res
;
49
50
mutex_lock
(&xw->
priv
->phy->pib_lock);
51
if
(xw->
priv
->phy->current_channel != xw->
chan
||
52
xw->
priv
->phy->current_page != xw->
page
) {
53
res = xw->
priv
->ops->set_channel(&xw->
priv
->hw,
54
xw->
page
,
55
xw->
chan
);
56
if
(res) {
57
pr_debug
(
"set_channel failed\n"
);
58
goto
out
;
59
}
60
}
61
62
res = xw->
priv
->ops->xmit(&xw->
priv
->hw, xw->
skb
);
63
64
out
:
65
mutex_unlock
(&xw->
priv
->phy->pib_lock);
66
67
if
(res) {
68
if
(xw->
xmit_attempts
++ <
MAC802154_MAX_XMIT_ATTEMPTS
) {
69
queue_work
(xw->
priv
->dev_workqueue, &xw->
work
);
70
return
;
71
}
else
72
pr_debug
(
"transmission failed for %d times"
,
73
MAC802154_MAX_XMIT_ATTEMPTS
);
74
}
75
76
dev_kfree_skb(xw->
skb
);
77
78
kfree
(xw);
79
}
80
81
netdev_tx_t
mac802154_tx
(
struct
mac802154_priv
*
priv
,
struct
sk_buff
*
skb
,
82
u8
page
,
u8
chan
)
83
{
84
struct
xmit_work
*
work
;
85
86
if
(!(priv->
phy
->channels_supported[page] & (1 << chan))) {
87
WARN_ON
(1);
88
return
NETDEV_TX_OK
;
89
}
90
91
mac802154_monitors_rx
(
mac802154_to_priv
(&priv->
hw
), skb);
92
93
if
(!(priv->
hw
.flags &
IEEE802154_HW_OMIT_CKSUM
)) {
94
u16
crc
=
crc_ccitt
(0, skb->
data
, skb->
len
);
95
u8
*
data
=
skb_put
(skb, 2);
96
data[0] = crc & 0xff;
97
data[1] = crc >> 8;
98
}
99
100
if
(skb_cow_head(skb, priv->
hw
.extra_tx_headroom)) {
101
dev_kfree_skb(skb);
102
return
NETDEV_TX_OK
;
103
}
104
105
work = kzalloc(
sizeof
(
struct
xmit_work
),
GFP_ATOMIC
);
106
if
(!work)
107
return
NETDEV_TX_BUSY
;
108
109
INIT_WORK
(&work->
work
, mac802154_xmit_worker);
110
work->
skb
=
skb
;
111
work->
priv
=
priv
;
112
work->
page
=
page
;
113
work->
chan
=
chan
;
114
work->
xmit_attempts
= 0;
115
116
queue_work
(priv->
dev_workqueue
, &work->
work
);
117
118
return
NETDEV_TX_OK
;
119
}
Generated on Thu Jan 10 2013 14:05:13 for Linux Kernel by
1.8.2