Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94091722 authored by David S. Miller's avatar David S. Miller
Browse files
parents 9818f660 929122cd
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -56,8 +56,12 @@ HardMAC

See the header include/net/ieee802154_netdev.h. You have to implement Linux
net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family
code via plain sk_buffs. The control block of sk_buffs will contain additional
info as described in the struct ieee802154_mac_cb.
code via plain sk_buffs. On skb reception skb->cb must contain additional
info as described in the struct ieee802154_mac_cb. During packet transmission
the skb->cb is used to provide additional data to device's header_ops->create
function. Be aware, that this data can be overriden later (when socket code
submits skb to qdisc), so if you need something from that cb later, you should
store info in the skb->data on your own.

To hook the MLME interface you have to populate the ml_priv field of your
net_device with a pointer to struct ieee802154_mlme_ops instance. All fields are
@@ -73,3 +77,4 @@ We are going to provide intermediate layer implementing IEEE 802.15.4 MAC
in software. This is currently WIP.

See header include/net/mac802154.h and several drivers in drivers/ieee802154/.
+52 −10
Original line number Diff line number Diff line
@@ -30,6 +30,12 @@
#include <net/ieee802154_netdev.h>
#include <net/ieee802154.h>
#include <net/nl802154.h>
#include <net/wpan-phy.h>

struct wpan_phy *net_to_phy(struct net_device *dev)
{
	return container_of(dev->dev.parent, struct wpan_phy, dev);
}

/**
 * fake_get_pan_id - Retrieve the PAN ID of the device.
@@ -113,8 +119,15 @@ static u8 fake_get_bsn(struct net_device *dev)
 *       802.15.4-2006 document.
 */
static int fake_assoc_req(struct net_device *dev,
		struct ieee802154_addr *addr, u8 channel, u8 cap)
		struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap)
{
	struct wpan_phy *phy = net_to_phy(dev);

	mutex_lock(&phy->pib_lock);
	phy->current_channel = channel;
	phy->current_page = page;
	mutex_unlock(&phy->pib_lock);

	/* We simply emulate it here */
	return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev),
			IEEE802154_SUCCESS);
@@ -179,10 +192,17 @@ static int fake_disassoc_req(struct net_device *dev,
 * document, with 7.3.8 describing coordinator realignment.
 */
static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr,
				u8 channel,
				u8 channel, u8 page,
				u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx,
				u8 coord_realign)
{
	struct wpan_phy *phy = net_to_phy(dev);

	mutex_lock(&phy->pib_lock);
	phy->current_channel = channel;
	phy->current_page = page;
	mutex_unlock(&phy->pib_lock);

	/* We don't emulate beacons here at all, so START should fail */
	ieee802154_nl_start_confirm(dev, IEEE802154_INVALID_PARAMETER);
	return 0;
@@ -204,11 +224,11 @@ static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr,
 * Note: This is in section 7.5.2.1 of the IEEE 802.15.4-2006 document.
 */
static int fake_scan_req(struct net_device *dev, u8 type, u32 channels,
		u8 duration)
		u8 page, u8 duration)
{
	u8 edl[27] = {};
	return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type,
			channels,
			channels, page,
			type == IEEE802154_MAC_SCAN_ED ? edl : NULL);
}

@@ -290,6 +310,14 @@ static const struct net_device_ops fake_ops = {
	.ndo_set_mac_address	= ieee802154_fake_mac_addr,
};

static void ieee802154_fake_destruct(struct net_device *dev)
{
	struct wpan_phy *phy = net_to_phy(dev);

	wpan_phy_unregister(phy);
	free_netdev(dev);
	wpan_phy_free(phy);
}

static void ieee802154_fake_setup(struct net_device *dev)
{
@@ -302,22 +330,34 @@ static void ieee802154_fake_setup(struct net_device *dev)
	dev->type		= ARPHRD_IEEE802154;
	dev->flags		= IFF_NOARP | IFF_BROADCAST;
	dev->watchdog_timeo	= 0;
	dev->destructor		= ieee802154_fake_destruct;
}


static int __devinit ieee802154fake_probe(struct platform_device *pdev)
{
	struct net_device *dev =
		alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup);
	struct net_device *dev;
	struct wpan_phy *phy = wpan_phy_alloc(0);
	int err;

	if (!dev)
	if (!phy)
		return -ENOMEM;

	dev = alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup);
	if (!dev) {
		wpan_phy_free(phy);
		return -ENOMEM;
	}

	phy->dev.platform_data = dev;

	memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef",
			dev->addr_len);
	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);

	phy->channels_supported = (1 << 27) - 1;
	phy->transmit_power = 0xbf;

	dev->netdev_ops = &fake_ops;
	dev->ml_priv = &fake_mlme;

@@ -331,15 +371,18 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
			goto out;
	}

	SET_NETDEV_DEV(dev, &pdev->dev);
	SET_NETDEV_DEV(dev, &phy->dev);

	platform_set_drvdata(pdev, dev);

	err = wpan_phy_register(&pdev->dev, phy);
	if (err)
		goto out;

	err = register_netdev(dev);
	if (err < 0)
		goto out;


	dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n");
	return 0;

@@ -352,7 +395,6 @@ static int __devexit ieee802154fake_remove(struct platform_device *pdev)
{
	struct net_device *dev = platform_get_drvdata(pdev);
	unregister_netdev(dev);
	free_netdev(dev);
	return 0;
}

+0 −1
Original line number Diff line number Diff line
@@ -87,7 +87,6 @@
#define ARPHRD_IEEE80211_PRISM 802	/* IEEE 802.11 + Prism2 header  */
#define ARPHRD_IEEE80211_RADIOTAP 803	/* IEEE 802.11 + radiotap header */
#define ARPHRD_IEEE802154	  804
#define ARPHRD_IEEE802154_PHY	  805

#define ARPHRD_PHONET	820		/* PhoNet media type		*/
#define ARPHRD_PHONET_PIPE 821		/* PhoNet pipe header		*/
+2 −0
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ enum {
	IEEE802154_ATTR_COORD_REALIGN,
	IEEE802154_ATTR_SEC,

	IEEE802154_ATTR_PAGE,

	__IEEE802154_ATTR_MAX,
};

+3 −3
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ static inline int mac_cb_type(struct sk_buff *skb)
struct ieee802154_mlme_ops {
	int (*assoc_req)(struct net_device *dev,
			struct ieee802154_addr *addr,
			u8 channel, u8 cap);
			u8 channel, u8 page, u8 cap);
	int (*assoc_resp)(struct net_device *dev,
			struct ieee802154_addr *addr,
			u16 short_addr, u8 status);
@@ -89,10 +89,10 @@ struct ieee802154_mlme_ops {
			u8 reason);
	int (*start_req)(struct net_device *dev,
			struct ieee802154_addr *addr,
			u8 channel, u8 bcn_ord, u8 sf_ord,
			u8 channel, u8 page, u8 bcn_ord, u8 sf_ord,
			u8 pan_coord, u8 blx, u8 coord_realign);
	int (*scan_req)(struct net_device *dev,
			u8 type, u32 channels, u8 duration);
			u8 type, u32 channels, u8 page, u8 duration);

	/*
	 * FIXME: these should become the part of PIB/MIB interface.
Loading