ieee802154: rework interface registration
This patch meld mac802154_netdev_register into ieee802154_if_add function. Also we have now only one alloc_netdev call with one interface setup routine "ieee802154_if_setup" instead two different one for each interface type. This patch checks via runtime the interface type and do different handling now. Additional we add the wpan_dev struct in ieee802154_sub_if_data and set the new ieee802154_ptr while netdev registration. This behaviour is very similar the mac80211 netdev registration functionality. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
parent
12cb56c237
commit
d5ae67bacd
@ -65,6 +65,10 @@ struct wpan_phy {
|
|||||||
char priv[0] __aligned(NETDEV_ALIGN);
|
char priv[0] __aligned(NETDEV_ALIGN);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wpan_dev {
|
||||||
|
struct wpan_phy *wpan_phy;
|
||||||
|
};
|
||||||
|
|
||||||
#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev)
|
#define to_phy(_dev) container_of(_dev, struct wpan_phy, dev)
|
||||||
|
|
||||||
struct wpan_phy *
|
struct wpan_phy *
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* Based on: net/mac80211/cfg.c
|
* Based on: net/mac80211/cfg.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <net/rtnetlink.h>
|
||||||
#include <net/cfg802154.h>
|
#include <net/cfg802154.h>
|
||||||
|
|
||||||
#include "ieee802154_i.h"
|
#include "ieee802154_i.h"
|
||||||
@ -23,8 +24,13 @@ ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy,
|
|||||||
const char *name, int type)
|
const char *name, int type)
|
||||||
{
|
{
|
||||||
struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
|
struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
|
||||||
|
struct net_device *dev;
|
||||||
|
|
||||||
return ieee802154_if_add(local, name, NULL, type);
|
rtnl_lock();
|
||||||
|
dev = ieee802154_if_add(local, name, NULL, type);
|
||||||
|
rtnl_unlock();
|
||||||
|
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
|
static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define __IEEE802154_I_H
|
#define __IEEE802154_I_H
|
||||||
|
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
#include <net/cfg802154.h>
|
||||||
#include <net/mac802154.h>
|
#include <net/mac802154.h>
|
||||||
#include <net/ieee802154_netdev.h>
|
#include <net/ieee802154_netdev.h>
|
||||||
|
|
||||||
@ -73,11 +74,14 @@ enum ieee802154_sdata_state_bits {
|
|||||||
struct ieee802154_sub_if_data {
|
struct ieee802154_sub_if_data {
|
||||||
struct list_head list; /* the ieee802154_priv->slaves list */
|
struct list_head list; /* the ieee802154_priv->slaves list */
|
||||||
|
|
||||||
|
struct wpan_dev wpan_dev;
|
||||||
|
|
||||||
struct ieee802154_local *local;
|
struct ieee802154_local *local;
|
||||||
struct net_device *dev;
|
struct net_device *dev;
|
||||||
|
|
||||||
int type;
|
int type;
|
||||||
unsigned long state;
|
unsigned long state;
|
||||||
|
char name[IFNAMSIZ];
|
||||||
|
|
||||||
spinlock_t mib_lock;
|
spinlock_t mib_lock;
|
||||||
|
|
||||||
|
@ -381,30 +381,23 @@ static void mac802154_wpan_free(struct net_device *dev)
|
|||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mac802154_wpan_setup(struct net_device *dev)
|
static void ieee802154_if_setup(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ieee802154_sub_if_data *sdata;
|
|
||||||
|
|
||||||
dev->addr_len = IEEE802154_ADDR_LEN;
|
dev->addr_len = IEEE802154_ADDR_LEN;
|
||||||
memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
|
memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
|
||||||
|
|
||||||
dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN;
|
dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN;
|
||||||
dev->header_ops = &mac802154_header_ops;
|
|
||||||
dev->needed_tailroom = 2 + 16; /* FCS + MIC */
|
dev->needed_tailroom = 2 + 16; /* FCS + MIC */
|
||||||
dev->mtu = IEEE802154_MTU;
|
dev->mtu = IEEE802154_MTU;
|
||||||
dev->tx_queue_len = 300;
|
dev->tx_queue_len = 300;
|
||||||
dev->type = ARPHRD_IEEE802154;
|
|
||||||
dev->flags = IFF_NOARP | IFF_BROADCAST;
|
dev->flags = IFF_NOARP | IFF_BROADCAST;
|
||||||
|
}
|
||||||
|
|
||||||
dev->destructor = mac802154_wpan_free;
|
static int
|
||||||
dev->netdev_ops = &mac802154_wpan_ops;
|
ieee802154_setup_sdata(struct ieee802154_sub_if_data *sdata, int type)
|
||||||
dev->ml_priv = &mac802154_mlme_wpan;
|
{
|
||||||
|
/* set some type-dependent values */
|
||||||
sdata = IEEE802154_DEV_TO_SUB_IF(dev);
|
sdata->type = type;
|
||||||
sdata->type = IEEE802154_DEV_WPAN;
|
|
||||||
|
|
||||||
spin_lock_init(&sdata->mib_lock);
|
|
||||||
mutex_init(&sdata->sec_mtx);
|
|
||||||
|
|
||||||
get_random_bytes(&sdata->bsn, 1);
|
get_random_bytes(&sdata->bsn, 1);
|
||||||
get_random_bytes(&sdata->dsn, 1);
|
get_random_bytes(&sdata->dsn, 1);
|
||||||
@ -419,54 +412,28 @@ void mac802154_wpan_setup(struct net_device *dev)
|
|||||||
sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
|
sdata->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
|
||||||
sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
|
sdata->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
|
||||||
|
|
||||||
sdata->promisuous_mode = false;
|
switch (type) {
|
||||||
|
case IEEE802154_DEV_WPAN:
|
||||||
|
sdata->dev->header_ops = &mac802154_header_ops;
|
||||||
|
sdata->dev->destructor = mac802154_wpan_free;
|
||||||
|
sdata->dev->netdev_ops = &mac802154_wpan_ops;
|
||||||
|
sdata->dev->ml_priv = &mac802154_mlme_wpan;
|
||||||
|
sdata->promisuous_mode = false;
|
||||||
|
|
||||||
mac802154_llsec_init(&sdata->sec);
|
spin_lock_init(&sdata->mib_lock);
|
||||||
}
|
mutex_init(&sdata->sec_mtx);
|
||||||
|
|
||||||
void mac802154_monitor_setup(struct net_device *dev)
|
mac802154_llsec_init(&sdata->sec);
|
||||||
{
|
break;
|
||||||
struct ieee802154_sub_if_data *sdata;
|
case IEEE802154_DEV_MONITOR:
|
||||||
|
sdata->dev->destructor = free_netdev;
|
||||||
dev->needed_tailroom = 2; /* room for FCS */
|
sdata->dev->netdev_ops = &mac802154_monitor_ops;
|
||||||
dev->mtu = IEEE802154_MTU;
|
sdata->dev->ml_priv = &mac802154_mlme_reduced;
|
||||||
dev->tx_queue_len = 10;
|
sdata->promisuous_mode = true;
|
||||||
dev->type = ARPHRD_IEEE802154_MONITOR;
|
break;
|
||||||
dev->flags = IFF_NOARP | IFF_BROADCAST;
|
default:
|
||||||
|
BUG();
|
||||||
dev->destructor = free_netdev;
|
}
|
||||||
dev->netdev_ops = &mac802154_monitor_ops;
|
|
||||||
dev->ml_priv = &mac802154_mlme_reduced;
|
|
||||||
|
|
||||||
sdata = IEEE802154_DEV_TO_SUB_IF(dev);
|
|
||||||
sdata->type = IEEE802154_DEV_MONITOR;
|
|
||||||
|
|
||||||
sdata->promisuous_mode = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
mac802154_netdev_register(struct ieee802154_local *local,
|
|
||||||
struct net_device *dev)
|
|
||||||
{
|
|
||||||
struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
|
|
||||||
int err;
|
|
||||||
|
|
||||||
sdata->dev = dev;
|
|
||||||
sdata->local = local;
|
|
||||||
|
|
||||||
dev->needed_headroom = local->hw.extra_tx_headroom;
|
|
||||||
|
|
||||||
SET_NETDEV_DEV(dev, &local->phy->dev);
|
|
||||||
|
|
||||||
err = register_netdev(dev);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
mutex_lock(&local->iflist_mtx);
|
|
||||||
list_add_tail_rcu(&sdata->list, &local->interfaces);
|
|
||||||
mutex_unlock(&local->iflist_mtx);
|
|
||||||
rtnl_unlock();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -475,38 +442,67 @@ struct net_device *
|
|||||||
ieee802154_if_add(struct ieee802154_local *local, const char *name,
|
ieee802154_if_add(struct ieee802154_local *local, const char *name,
|
||||||
struct wpan_dev **new_wpan_dev, int type)
|
struct wpan_dev **new_wpan_dev, int type)
|
||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *ndev = NULL;
|
||||||
int err = -ENOMEM;
|
struct ieee802154_sub_if_data *sdata = NULL;
|
||||||
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
switch (type) {
|
ASSERT_RTNL();
|
||||||
case IEEE802154_DEV_MONITOR:
|
|
||||||
dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
|
ndev = alloc_netdev(sizeof(*sdata), name, NET_NAME_UNKNOWN,
|
||||||
name, NET_NAME_UNKNOWN,
|
ieee802154_if_setup);
|
||||||
mac802154_monitor_setup);
|
if (!ndev)
|
||||||
break;
|
return ERR_PTR(-ENOMEM);
|
||||||
case IEEE802154_DEV_WPAN:
|
|
||||||
dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
|
ndev->needed_headroom = local->hw.extra_tx_headroom;
|
||||||
name, NET_NAME_UNKNOWN,
|
|
||||||
mac802154_wpan_setup);
|
ret = dev_alloc_name(ndev, ndev->name);
|
||||||
break;
|
if (ret < 0)
|
||||||
default:
|
|
||||||
dev = NULL;
|
|
||||||
err = -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!dev)
|
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
err = mac802154_netdev_register(local, dev);
|
switch (type) {
|
||||||
if (err)
|
case IEEE802154_DEV_WPAN:
|
||||||
goto err_free;
|
ndev->type = ARPHRD_IEEE802154;
|
||||||
|
break;
|
||||||
|
case IEEE802154_DEV_MONITOR:
|
||||||
|
ndev->type = ARPHRD_IEEE802154_MONITOR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
return dev;
|
/* TODO check this */
|
||||||
|
SET_NETDEV_DEV(ndev, &local->phy->dev);
|
||||||
|
sdata = netdev_priv(ndev);
|
||||||
|
ndev->ieee802154_ptr = &sdata->wpan_dev;
|
||||||
|
memcpy(sdata->name, ndev->name, IFNAMSIZ);
|
||||||
|
sdata->dev = ndev;
|
||||||
|
sdata->wpan_dev.wpan_phy = local->hw.phy;
|
||||||
|
sdata->local = local;
|
||||||
|
|
||||||
|
/* setup type-dependent data */
|
||||||
|
ret = ieee802154_setup_sdata(sdata, type);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (ndev) {
|
||||||
|
ret = register_netdevice(ndev);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_lock(&local->iflist_mtx);
|
||||||
|
list_add_tail_rcu(&sdata->list, &local->interfaces);
|
||||||
|
mutex_unlock(&local->iflist_mtx);
|
||||||
|
|
||||||
|
if (new_wpan_dev)
|
||||||
|
*new_wpan_dev = &sdata->wpan_dev;
|
||||||
|
|
||||||
|
return ndev;
|
||||||
|
|
||||||
err_free:
|
|
||||||
free_netdev(dev);
|
|
||||||
err:
|
err:
|
||||||
return ERR_PTR(err);
|
free_netdev(ndev);
|
||||||
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata)
|
void ieee802154_if_remove(struct ieee802154_sub_if_data *sdata)
|
||||||
|
Loading…
Reference in New Issue
Block a user