|
@@ -175,6 +175,79 @@ err:
|
|
return res;
|
|
return res;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+ieee802154_check_mac_settings(struct ieee802154_local *local,
|
|
|
|
+ struct wpan_dev *wpan_dev,
|
|
|
|
+ struct wpan_dev *nwpan_dev)
|
|
|
|
+{
|
|
|
|
+ ASSERT_RTNL();
|
|
|
|
+
|
|
|
|
+ if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) {
|
|
|
|
+ if (wpan_dev->promiscuous_mode != nwpan_dev->promiscuous_mode)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (local->hw.flags & IEEE802154_HW_AFILT) {
|
|
|
|
+ if (wpan_dev->pan_id != nwpan_dev->pan_id)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+
|
|
|
|
+ if (wpan_dev->short_addr != nwpan_dev->short_addr)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+
|
|
|
|
+ if (wpan_dev->extended_addr != nwpan_dev->extended_addr)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) {
|
|
|
|
+ if (wpan_dev->min_be != nwpan_dev->min_be)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+
|
|
|
|
+ if (wpan_dev->max_be != nwpan_dev->max_be)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+
|
|
|
|
+ if (wpan_dev->csma_retries != nwpan_dev->csma_retries)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) {
|
|
|
|
+ if (wpan_dev->frame_retries != nwpan_dev->frame_retries)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (local->hw.flags & IEEE802154_HW_LBT) {
|
|
|
|
+ if (wpan_dev->lbt != nwpan_dev->lbt)
|
|
|
|
+ return -EBUSY;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
|
|
|
|
+ enum nl802154_iftype iftype)
|
|
|
|
+{
|
|
|
|
+ struct ieee802154_local *local = sdata->local;
|
|
|
|
+ struct wpan_dev *wpan_dev = &sdata->wpan_dev;
|
|
|
|
+ struct ieee802154_sub_if_data *nsdata;
|
|
|
|
+
|
|
|
|
+ /* we hold the RTNL here so can safely walk the list */
|
|
|
|
+ list_for_each_entry(nsdata, &local->interfaces, list) {
|
|
|
|
+ if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ /* check all phy mac sublayer settings are the same.
|
|
|
|
+ * We have only one phy, different values makes trouble.
|
|
|
|
+ */
|
|
|
|
+ ret = ieee802154_check_mac_settings(local, wpan_dev,
|
|
|
|
+ &nsdata->wpan_dev);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int mac802154_wpan_open(struct net_device *dev)
|
|
static int mac802154_wpan_open(struct net_device *dev)
|
|
{
|
|
{
|
|
int rc;
|
|
int rc;
|
|
@@ -183,6 +256,10 @@ static int mac802154_wpan_open(struct net_device *dev)
|
|
struct wpan_dev *wpan_dev = &sdata->wpan_dev;
|
|
struct wpan_dev *wpan_dev = &sdata->wpan_dev;
|
|
struct wpan_phy *phy = sdata->local->phy;
|
|
struct wpan_phy *phy = sdata->local->phy;
|
|
|
|
|
|
|
|
+ rc = ieee802154_check_concurrent_iface(sdata, sdata->vif.type);
|
|
|
|
+ if (rc < 0)
|
|
|
|
+ return rc;
|
|
|
|
+
|
|
rc = mac802154_slave_open(dev);
|
|
rc = mac802154_slave_open(dev);
|
|
if (rc < 0)
|
|
if (rc < 0)
|
|
return rc;
|
|
return rc;
|