2 * Copyright 2007, 2008, 2009 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 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
19 * Sergey Lapin <slapin@ossfans.org>
20 * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
21 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
24 #include <linux/netdevice.h>
25 #include <linux/skbuff.h>
26 #include <linux/if_arp.h>
27 #include <linux/crc-ccitt.h>
29 #include <net/ieee802154.h>
30 #include <net/mac802154.h>
31 #include <net/netlink.h>
32 #include <net/wpan-phy.h>
33 #include <linux/nl802154.h>
35 #include "mac802154.h"
37 static netdev_tx_t
mac802154_monitor_xmit(struct sk_buff
*skb
,
38 struct net_device
*dev
)
40 struct mac802154_sub_if_data
*priv
;
43 priv
= netdev_priv(dev
);
46 chan
= priv
->hw
->phy
->current_channel
;
47 page
= priv
->hw
->phy
->current_page
;
49 if (chan
== MAC802154_CHAN_NONE
) /* not initialized */
52 if (WARN_ON(page
>= WPAN_NUM_PAGES
) ||
53 WARN_ON(chan
>= WPAN_NUM_CHANNELS
))
56 skb
->skb_iif
= dev
->ifindex
;
57 dev
->stats
.tx_packets
++;
58 dev
->stats
.tx_bytes
+= skb
->len
;
60 return mac802154_tx(priv
->hw
, skb
, page
, chan
);
64 void mac802154_monitors_rx(struct mac802154_priv
*priv
, struct sk_buff
*skb
)
67 struct mac802154_sub_if_data
*sdata
;
68 u16 crc
= crc_ccitt(0, skb
->data
, skb
->len
);
72 list_for_each_entry_rcu(sdata
, &priv
->slaves
, list
) {
73 if (sdata
->type
!= IEEE802154_DEV_MONITOR
)
76 skb2
= skb_clone(skb
, GFP_ATOMIC
);
77 skb2
->dev
= sdata
->dev
;
78 skb2
->pkt_type
= PACKET_HOST
;
79 data
= skb_put(skb2
, 2);
88 static const struct net_device_ops mac802154_monitor_ops
= {
89 .ndo_open
= mac802154_slave_open
,
90 .ndo_stop
= mac802154_slave_close
,
91 .ndo_start_xmit
= mac802154_monitor_xmit
,
94 void mac802154_monitor_setup(struct net_device
*dev
)
96 struct mac802154_sub_if_data
*priv
;
99 dev
->hard_header_len
= 0;
100 dev
->needed_tailroom
= 2; /* room for FCS */
101 dev
->mtu
= IEEE802154_MTU
;
102 dev
->tx_queue_len
= 10;
103 dev
->type
= ARPHRD_IEEE802154_MONITOR
;
104 dev
->flags
= IFF_NOARP
| IFF_BROADCAST
;
105 dev
->watchdog_timeo
= 0;
107 dev
->destructor
= free_netdev
;
108 dev
->netdev_ops
= &mac802154_monitor_ops
;
109 dev
->ml_priv
= &mac802154_mlme_reduced
;
111 priv
= netdev_priv(dev
);
112 priv
->type
= IEEE802154_DEV_MONITOR
;
114 priv
->chan
= MAC802154_CHAN_NONE
; /* not initialized */