aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac802154
diff options
context:
space:
mode:
authorAlexander Aring <alex.aring@gmail.com>2014-12-19 17:45:58 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-12-19 18:06:55 -0500
commitbd37a78de91e1b67b540b43f10bbb2d552348cbd (patch)
tree885491af401b6f29f733ea8ca1adc2cb0ad20d0e /net/mac802154
parent405a26110a735b88963875459efe63f4d274f49d (diff)
mac802154: iface: check concurrent ifaces
This patch adds a check for concurrent interfaces while calling interface up. This avoids to have different mac parameters on one phy. Otherwise it could be that a interface can overwrite current phy mac settings which is set by an another interface. Signed-off-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/mac802154')
-rw-r--r--net/mac802154/iface.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index 9ae893057dd7..61f3ff00a508 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -175,6 +175,79 @@ err:
175 return res; 175 return res;
176} 176}
177 177
178static int
179ieee802154_check_mac_settings(struct ieee802154_local *local,
180 struct wpan_dev *wpan_dev,
181 struct wpan_dev *nwpan_dev)
182{
183 ASSERT_RTNL();
184
185 if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) {
186 if (wpan_dev->promiscuous_mode != nwpan_dev->promiscuous_mode)
187 return -EBUSY;
188 }
189
190 if (local->hw.flags & IEEE802154_HW_AFILT) {
191 if (wpan_dev->pan_id != nwpan_dev->pan_id)
192 return -EBUSY;
193
194 if (wpan_dev->short_addr != nwpan_dev->short_addr)
195 return -EBUSY;
196
197 if (wpan_dev->extended_addr != nwpan_dev->extended_addr)
198 return -EBUSY;
199 }
200
201 if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) {
202 if (wpan_dev->min_be != nwpan_dev->min_be)
203 return -EBUSY;
204
205 if (wpan_dev->max_be != nwpan_dev->max_be)
206 return -EBUSY;
207
208 if (wpan_dev->csma_retries != nwpan_dev->csma_retries)
209 return -EBUSY;
210 }
211
212 if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) {
213 if (wpan_dev->frame_retries != nwpan_dev->frame_retries)
214 return -EBUSY;
215 }
216
217 if (local->hw.flags & IEEE802154_HW_LBT) {
218 if (wpan_dev->lbt != nwpan_dev->lbt)
219 return -EBUSY;
220 }
221
222 return 0;
223}
224
225static int
226ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata,
227 enum nl802154_iftype iftype)
228{
229 struct ieee802154_local *local = sdata->local;
230 struct wpan_dev *wpan_dev = &sdata->wpan_dev;
231 struct ieee802154_sub_if_data *nsdata;
232
233 /* we hold the RTNL here so can safely walk the list */
234 list_for_each_entry(nsdata, &local->interfaces, list) {
235 if (nsdata != sdata && ieee802154_sdata_running(nsdata)) {
236 int ret;
237
238 /* check all phy mac sublayer settings are the same.
239 * We have only one phy, different values makes trouble.
240 */
241 ret = ieee802154_check_mac_settings(local, wpan_dev,
242 &nsdata->wpan_dev);
243 if (ret < 0)
244 return ret;
245 }
246 }
247
248 return 0;
249}
250
178static int mac802154_wpan_open(struct net_device *dev) 251static int mac802154_wpan_open(struct net_device *dev)
179{ 252{
180 int rc; 253 int rc;
@@ -183,6 +256,10 @@ static int mac802154_wpan_open(struct net_device *dev)
183 struct wpan_dev *wpan_dev = &sdata->wpan_dev; 256 struct wpan_dev *wpan_dev = &sdata->wpan_dev;
184 struct wpan_phy *phy = sdata->local->phy; 257 struct wpan_phy *phy = sdata->local->phy;
185 258
259 rc = ieee802154_check_concurrent_iface(sdata, sdata->vif.type);
260 if (rc < 0)
261 return rc;
262
186 rc = mac802154_slave_open(dev); 263 rc = mac802154_slave_open(dev);
187 if (rc < 0) 264 if (rc < 0)
188 return rc; 265 return rc;