Commit d5ae67ba authored by Alexander Aring's avatar Alexander Aring Committed by Marcel Holtmann

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: default avatarAlexander Aring <alex.aring@gmail.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 12cb56c2
...@@ -65,6 +65,10 @@ struct wpan_phy { ...@@ -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 @@ ...@@ -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, ...@@ -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 @@ ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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);
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; 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)
{
struct ieee802154_sub_if_data *sdata;
dev->needed_tailroom = 2; /* room for FCS */
dev->mtu = IEEE802154_MTU;
dev->tx_queue_len = 10;
dev->type = ARPHRD_IEEE802154_MONITOR;
dev->flags = IFF_NOARP | IFF_BROADCAST;
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;
mac802154_llsec_init(&sdata->sec);
break;
case IEEE802154_DEV_MONITOR:
sdata->dev->destructor = free_netdev;
sdata->dev->netdev_ops = &mac802154_monitor_ops;
sdata->dev->ml_priv = &mac802154_mlme_reduced;
sdata->promisuous_mode = true; sdata->promisuous_mode = true;
} break;
default:
static int BUG();
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 * ...@@ -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;
ASSERT_RTNL();
ndev = alloc_netdev(sizeof(*sdata), name, NET_NAME_UNKNOWN,
ieee802154_if_setup);
if (!ndev)
return ERR_PTR(-ENOMEM);
ndev->needed_headroom = local->hw.extra_tx_headroom;
ret = dev_alloc_name(ndev, ndev->name);
if (ret < 0)
goto err;
switch (type) { switch (type) {
case IEEE802154_DEV_MONITOR:
dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
name, NET_NAME_UNKNOWN,
mac802154_monitor_setup);
break;
case IEEE802154_DEV_WPAN: case IEEE802154_DEV_WPAN:
dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data), ndev->type = ARPHRD_IEEE802154;
name, NET_NAME_UNKNOWN,
mac802154_wpan_setup);
break; break;
default: case IEEE802154_DEV_MONITOR:
dev = NULL; ndev->type = ARPHRD_IEEE802154_MONITOR;
err = -EINVAL;
break; break;
default:
ret = -EINVAL;
goto err;
} }
if (!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; goto err;
err = mac802154_netdev_register(local, dev); if (ndev) {
if (err) ret = register_netdevice(ndev);
goto err_free; if (ret < 0)
goto err;
}
mutex_lock(&local->iflist_mtx);
list_add_tail_rcu(&sdata->list, &local->interfaces);
mutex_unlock(&local->iflist_mtx);
return dev; 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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment