---
include/linux/if_arp.h | 1
include/linux/nl802154.h | 1
net/mac802154/Makefile | 2 -
net/mac802154/mac802154.h | 3 +
net/mac802154/main.c | 4 +
net/mac802154/mib.c | 3 +
net/mac802154/rx.c | 1
net/mac802154/smac.c | 127 +++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 140 insertions(+), 2 deletions(-)
create mode 100644 net/mac802154/smac.c
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
index 9cf4974..47a57d8 100644
--- a/include/linux/if_arp.h
+++ b/include/linux/if_arp.h
@@ -88,6 +88,7 @@
#define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
#define ARPHRD_IEEE802154 804
#define ARPHRD_IEEE802154_MONITOR 805
+#define ARPHRD_SMAC 806 /* Freescale Simple MAC */
#define ARPHRD_PHONET 820 /* PhoNet media type */
#define ARPHRD_PHONET_PIPE 821 /* PhoNet pipe header */
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
index a367738..a379fc7 100644
--- a/include/linux/nl802154.h
+++ b/include/linux/nl802154.h
@@ -128,6 +128,7 @@ enum {
enum {
IEEE802154_DEV_WPAN,
IEEE802154_DEV_MONITOR,
+ IEEE802154_DEV_SMAC,
__IEEE802154_DEV_MAX,
};
diff --git a/net/mac802154/Makefile b/net/mac802154/Makefile
index b0bc4f7..790b97f 100644
--- a/net/mac802154/Makefile
+++ b/net/mac802154/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_MAC802154) += mac802154.o
mac802154-objs := rx.o tx.o main.o monitor.o wpan.o mac_cmd.o scan.o
mib.o \
- beacon.o beacon_hash.o
+ beacon.o beacon_hash.o smac.o
EXTRA_CFLAGS += -Wall -DDEBUG
diff --git a/net/mac802154/mac802154.h b/net/mac802154/mac802154.h
index e86c8ee..f35245d 100644
--- a/net/mac802154/mac802154.h
+++ b/net/mac802154/mac802154.h
@@ -112,6 +112,9 @@ struct mac802154_priv *mac802154_slave_get_priv(struct
net_device *dev);
void mac802154_monitors_rx(struct mac802154_priv *priv, struct sk_buff *skb);
void mac802154_monitor_setup(struct net_device *dev);
+void mac802154_smacs_rx(struct mac802154_priv *priv, struct sk_buff *skb);
+void mac802154_smac_setup(struct net_device *dev);
+
void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb);
void mac802154_wpan_setup(struct net_device *dev);
diff --git a/net/mac802154/main.c b/net/mac802154/main.c
index dfa314f..b108df0 100644
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -141,6 +141,10 @@ static struct net_device *mac802154_add_iface(struct
wpan_phy *phy,
dev = alloc_netdev(sizeof(struct mac802154_sub_if_data),
name, mac802154_monitor_setup);
break;
+ case IEEE802154_DEV_SMAC:
+ dev = alloc_netdev(sizeof(struct mac802154_sub_if_data),
+ name, mac802154_smac_setup);
+ break;
default:
dev = NULL;
err = -EINVAL;
diff --git a/net/mac802154/mib.c b/net/mac802154/mib.c
index ee8cfa0..23871df 100644
--- a/net/mac802154/mib.c
+++ b/net/mac802154/mib.c
@@ -242,7 +242,8 @@ struct wpan_phy *mac802154_get_phy(const struct net_device
*dev)
{
struct mac802154_sub_if_data *priv = netdev_priv(dev);
BUG_ON(dev->type != ARPHRD_IEEE802154
- && dev->type != ARPHRD_IEEE802154_MONITOR);
+ && dev->type != ARPHRD_IEEE802154_MONITOR
+ && dev->type != ARPHRD_SMAC);
return to_phy(get_device(&priv->hw->phy->dev));
}
diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
index be05d6c..0e9d5d4 100644
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -54,6 +54,7 @@ static void mac802154_subif_rx(struct ieee802154_dev *hw,
struct sk_buff *skb)
}
mac802154_monitors_rx(priv, skb);
+ mac802154_smacs_rx(priv, skb);
mac802154_wpans_rx(priv, skb);
out:
diff --git a/net/mac802154/smac.c b/net/mac802154/smac.c
new file mode 100644
index 0000000..b11f0ec
--- /dev/null
+++ b/net/mac802154/smac.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2010 Siemens AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Dmitry Eremin-Solenikov <[email protected]>
+ */
+
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/nl802154.h>
+
+#include <net/mac802154.h>
+#include <net/wpan-phy.h>
+
+#include "mac802154.h"
+
+static const u8 smac_header[] = {0x7E, 0xFF};
+
+static netdev_tx_t mac802154_smac_xmit(struct sk_buff *skb, struct net_device
*dev)
+{
+ struct mac802154_sub_if_data *priv;
+ u8 chan, page;
+
+ priv = netdev_priv(dev);
+
+ /* FIXME: locking */
+ chan = priv->hw->phy->current_channel;
+ page = priv->hw->phy->current_page;
+
+ if (chan == (u8)-1) /* not init */
+ return NETDEV_TX_OK;
+
+ BUG_ON(page >= WPAN_NUM_PAGES);
+ BUG_ON(chan >= 27);
+
+ memcpy(skb_push(skb, sizeof(smac_header)), smac_header,
sizeof(smac_header));
+
+ skb->skb_iif = dev->ifindex;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
+
+ return mac802154_tx(priv->hw, skb, page, chan);
+}
+
+void mac802154_smacs_rx(struct mac802154_priv *priv, struct sk_buff *skb)
+{
+ struct mac802154_sub_if_data *sdata;
+
+ if (skb->len < sizeof(smac_header))
+ return;
+
+ if (memcmp(skb->data, smac_header, sizeof(smac_header)))
+ return;
+
+ /*
+ * Currently we are the owner of the skb.
+ * We can change it's data pointers, provided we change them
+ * back at the end.
+ */
+
+ skb_pull(skb, sizeof(smac_header));
+
+ list_for_each_entry_rcu(sdata, &priv->slaves, list) {
+ struct sk_buff *skb2;
+
+ if (sdata->type != IEEE802154_DEV_SMAC)
+ continue;
+
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ skb2->dev = sdata->dev;
+ skb2->pkt_type = PACKET_HOST;
+
+ if (in_interrupt())
+ netif_rx(skb2);
+ else
+ netif_rx_ni(skb2);
+ }
+ rcu_read_unlock();
+
+ skb_push(skb, sizeof(smac_header));
+}
+
+static const struct net_device_ops mac802154_smac_ops = {
+ .ndo_open = mac802154_slave_open,
+ .ndo_stop = mac802154_slave_close,
+ .ndo_start_xmit = mac802154_smac_xmit,
+};
+
+void mac802154_smac_setup(struct net_device *dev)
+{
+ struct mac802154_sub_if_data *priv;
+
+ dev->addr_len = 0;
+ dev->features = NETIF_F_NO_CSUM;
+ dev->hard_header_len = 2;
+ dev->needed_tailroom = 2; /* FCS */
+ dev->mtu = 123; /* 127 - 2 (FCS) - 2 (header) */
+ dev->tx_queue_len = 10;
+ dev->type = ARPHRD_SMAC;
+ dev->flags = IFF_NOARP | IFF_BROADCAST;
+ dev->watchdog_timeo = 0;
+
+ dev->destructor = free_netdev;
+ dev->netdev_ops = &mac802154_smac_ops;
+ dev->ml_priv = &mac802154_mlme_simple;
+
+ priv = netdev_priv(dev);
+ priv->type = IEEE802154_DEV_SMAC;
+
+ priv->chan = -1; /* not initialized */
+ priv->page = 0; /* for compat */
+}
+
------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
Linux-zigbee-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel