#include <net/netlink.h>
#include <linux/nl802154.h>
#include <net/mac802154.h>
+#include <net/ieee802154_netdev.h>
#include <net/route.h>
#include <net/wpan-phy.h>
int mac802154_slave_open(struct net_device *dev)
{
struct mac802154_sub_if_data *priv = netdev_priv(dev);
+ struct mac802154_sub_if_data *subif;
struct mac802154_priv *ipriv = priv->hw;
int res = 0;
+ ASSERT_RTNL();
+
+ if (priv->type == IEEE802154_DEV_WPAN) {
+ mutex_lock(&priv->hw->slaves_mtx);
+ list_for_each_entry(subif, &priv->hw->slaves, list) {
+ if (subif != priv && subif->type == priv->type &&
+ subif->running) {
+ mutex_unlock(&priv->hw->slaves_mtx);
+ return -EBUSY;
+ }
+ }
+ mutex_unlock(&priv->hw->slaves_mtx);
+ }
+
+ mutex_lock(&priv->hw->slaves_mtx);
+ priv->running = true;
+ mutex_unlock(&priv->hw->slaves_mtx);
+
if (ipriv->open_count++ == 0) {
res = ipriv->ops->start(&ipriv->hw);
WARN_ON(res);
}
if (ipriv->ops->ieee_addr) {
- res = ipriv->ops->ieee_addr(&ipriv->hw, dev->dev_addr);
+ __le64 addr = ieee802154_devaddr_from_raw(dev->dev_addr);
+
+ res = ipriv->ops->ieee_addr(&ipriv->hw, addr);
WARN_ON(res);
if (res)
goto err;
struct mac802154_sub_if_data *priv = netdev_priv(dev);
struct mac802154_priv *ipriv = priv->hw;
+ ASSERT_RTNL();
+
netif_stop_queue(dev);
+ mutex_lock(&priv->hw->slaves_mtx);
+ priv->running = false;
+ mutex_unlock(&priv->hw->slaves_mtx);
+
if (!--ipriv->open_count)
ipriv->ops->stop(&ipriv->hw);
{
struct mac802154_priv *priv = wpan_phy_priv(phy);
- if (!priv->ops->set_txpower)
- return -ENOTSUPP;
-
return priv->ops->set_txpower(&priv->hw, db);
}
{
struct mac802154_priv *priv = wpan_phy_priv(phy);
- if (!priv->ops->set_lbt)
- return -ENOTSUPP;
-
return priv->ops->set_lbt(&priv->hw, on);
}
{
struct mac802154_priv *priv = wpan_phy_priv(phy);
- if (!priv->ops->set_cca_mode)
- return -ENOTSUPP;
-
return priv->ops->set_cca_mode(&priv->hw, mode);
}
{
struct mac802154_priv *priv = wpan_phy_priv(phy);
- if (!priv->ops->set_cca_ed_level)
- return -ENOTSUPP;
-
return priv->ops->set_cca_ed_level(&priv->hw, level);
}
{
struct mac802154_priv *priv = wpan_phy_priv(phy);
- if (!priv->ops->set_csma_params)
- return -ENOTSUPP;
-
return priv->ops->set_csma_params(&priv->hw, min_be, max_be, retries);
}
{
struct mac802154_priv *priv = wpan_phy_priv(phy);
- if (!priv->ops->set_frame_retries)
- return -ENOTSUPP;
-
return priv->ops->set_frame_retries(&priv->hw, retries);
}
priv->phy->add_iface = mac802154_add_iface;
priv->phy->del_iface = mac802154_del_iface;
- priv->phy->set_txpower = mac802154_set_txpower;
- priv->phy->set_lbt = mac802154_set_lbt;
- priv->phy->set_cca_mode = mac802154_set_cca_mode;
- priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level;
- priv->phy->set_csma_params = mac802154_set_csma_params;
- priv->phy->set_frame_retries = mac802154_set_frame_retries;
+ if (priv->ops->set_txpower)
+ priv->phy->set_txpower = mac802154_set_txpower;
+ if (priv->ops->set_lbt)
+ priv->phy->set_lbt = mac802154_set_lbt;
+ if (priv->ops->set_cca_mode)
+ priv->phy->set_cca_mode = mac802154_set_cca_mode;
+ if (priv->ops->set_cca_ed_level)
+ priv->phy->set_cca_ed_level = mac802154_set_cca_ed_level;
+ if (priv->ops->set_csma_params)
+ priv->phy->set_csma_params = mac802154_set_csma_params;
+ if (priv->ops->set_frame_retries)
+ priv->phy->set_frame_retries = mac802154_set_frame_retries;
rc = wpan_phy_register(priv->phy);
if (rc < 0)