diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ieee802154/fakehard.c | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c index 262536fae90..c1c9697f9fd 100644 --- a/drivers/ieee802154/fakehard.c +++ b/drivers/ieee802154/fakehard.c @@ -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; } |