mib.c revision 4710d806fcb825156e0a7b3a81104915c5e90f5d
1/* 2 * Copyright 2007-2012 Siemens AG 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 6 * as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License along 14 * with this program; if not, write to the Free Software Foundation, Inc., 15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 * 17 * Written by: 18 * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> 19 * Sergey Lapin <slapin@ossfans.org> 20 * Maxim Gorbachyov <maxim.gorbachev@siemens.com> 21 * Alexander Smirnov <alex.bluesman.smirnov@gmail.com> 22 */ 23 24#include <linux/if_arp.h> 25 26#include <net/mac802154.h> 27#include <net/ieee802154_netdev.h> 28#include <net/wpan-phy.h> 29 30#include "mac802154.h" 31 32struct phy_chan_notify_work { 33 struct work_struct work; 34 struct net_device *dev; 35}; 36 37struct hw_addr_filt_notify_work { 38 struct work_struct work; 39 struct net_device *dev; 40 unsigned long changed; 41}; 42 43static struct mac802154_priv *mac802154_slave_get_priv(struct net_device *dev) 44{ 45 struct mac802154_sub_if_data *priv = netdev_priv(dev); 46 47 BUG_ON(dev->type != ARPHRD_IEEE802154); 48 49 return priv->hw; 50} 51 52static void hw_addr_notify(struct work_struct *work) 53{ 54 struct hw_addr_filt_notify_work *nw = container_of(work, 55 struct hw_addr_filt_notify_work, work); 56 struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); 57 int res; 58 59 res = hw->ops->set_hw_addr_filt(&hw->hw, 60 &hw->hw.hw_filt, 61 nw->changed); 62 if (res) 63 pr_debug("failed changed mask %lx\n", nw->changed); 64 65 kfree(nw); 66} 67 68static void set_hw_addr_filt(struct net_device *dev, unsigned long changed) 69{ 70 struct mac802154_sub_if_data *priv = netdev_priv(dev); 71 struct hw_addr_filt_notify_work *work; 72 73 work = kzalloc(sizeof(*work), GFP_ATOMIC); 74 if (!work) 75 return; 76 77 INIT_WORK(&work->work, hw_addr_notify); 78 work->dev = dev; 79 work->changed = changed; 80 queue_work(priv->hw->dev_workqueue, &work->work); 81} 82 83void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) 84{ 85 struct mac802154_sub_if_data *priv = netdev_priv(dev); 86 87 BUG_ON(dev->type != ARPHRD_IEEE802154); 88 89 spin_lock_bh(&priv->mib_lock); 90 priv->short_addr = val; 91 spin_unlock_bh(&priv->mib_lock); 92 93 if ((priv->hw->ops->set_hw_addr_filt) && 94 (priv->hw->hw.hw_filt.short_addr != priv->short_addr)) { 95 priv->hw->hw.hw_filt.short_addr = priv->short_addr; 96 set_hw_addr_filt(dev, IEEE802515_AFILT_SADDR_CHANGED); 97 } 98} 99 100__le16 mac802154_dev_get_short_addr(const struct net_device *dev) 101{ 102 struct mac802154_sub_if_data *priv = netdev_priv(dev); 103 __le16 ret; 104 105 BUG_ON(dev->type != ARPHRD_IEEE802154); 106 107 spin_lock_bh(&priv->mib_lock); 108 ret = priv->short_addr; 109 spin_unlock_bh(&priv->mib_lock); 110 111 return ret; 112} 113 114void mac802154_dev_set_ieee_addr(struct net_device *dev) 115{ 116 struct mac802154_sub_if_data *priv = netdev_priv(dev); 117 struct mac802154_priv *mac = priv->hw; 118 119 priv->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); 120 121 if (mac->ops->set_hw_addr_filt && 122 mac->hw.hw_filt.ieee_addr != priv->extended_addr) { 123 mac->hw.hw_filt.ieee_addr = priv->extended_addr; 124 set_hw_addr_filt(dev, IEEE802515_AFILT_IEEEADDR_CHANGED); 125 } 126} 127 128__le16 mac802154_dev_get_pan_id(const struct net_device *dev) 129{ 130 struct mac802154_sub_if_data *priv = netdev_priv(dev); 131 __le16 ret; 132 133 BUG_ON(dev->type != ARPHRD_IEEE802154); 134 135 spin_lock_bh(&priv->mib_lock); 136 ret = priv->pan_id; 137 spin_unlock_bh(&priv->mib_lock); 138 139 return ret; 140} 141 142void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) 143{ 144 struct mac802154_sub_if_data *priv = netdev_priv(dev); 145 146 BUG_ON(dev->type != ARPHRD_IEEE802154); 147 148 spin_lock_bh(&priv->mib_lock); 149 priv->pan_id = val; 150 spin_unlock_bh(&priv->mib_lock); 151 152 if ((priv->hw->ops->set_hw_addr_filt) && 153 (priv->hw->hw.hw_filt.pan_id != priv->pan_id)) { 154 priv->hw->hw.hw_filt.pan_id = priv->pan_id; 155 set_hw_addr_filt(dev, IEEE802515_AFILT_PANID_CHANGED); 156 } 157} 158 159u8 mac802154_dev_get_dsn(const struct net_device *dev) 160{ 161 struct mac802154_sub_if_data *priv = netdev_priv(dev); 162 163 BUG_ON(dev->type != ARPHRD_IEEE802154); 164 165 return priv->dsn++; 166} 167 168static void phy_chan_notify(struct work_struct *work) 169{ 170 struct phy_chan_notify_work *nw = container_of(work, 171 struct phy_chan_notify_work, work); 172 struct mac802154_priv *hw = mac802154_slave_get_priv(nw->dev); 173 struct mac802154_sub_if_data *priv = netdev_priv(nw->dev); 174 int res; 175 176 mutex_lock(&priv->hw->phy->pib_lock); 177 res = hw->ops->set_channel(&hw->hw, priv->page, priv->chan); 178 if (res) { 179 pr_debug("set_channel failed\n"); 180 } else { 181 priv->hw->phy->current_channel = priv->chan; 182 priv->hw->phy->current_page = priv->page; 183 } 184 mutex_unlock(&priv->hw->phy->pib_lock); 185 186 kfree(nw); 187} 188 189void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan) 190{ 191 struct mac802154_sub_if_data *priv = netdev_priv(dev); 192 struct phy_chan_notify_work *work; 193 194 BUG_ON(dev->type != ARPHRD_IEEE802154); 195 196 spin_lock_bh(&priv->mib_lock); 197 priv->page = page; 198 priv->chan = chan; 199 spin_unlock_bh(&priv->mib_lock); 200 201 mutex_lock(&priv->hw->phy->pib_lock); 202 if (priv->hw->phy->current_channel != priv->chan || 203 priv->hw->phy->current_page != priv->page) { 204 mutex_unlock(&priv->hw->phy->pib_lock); 205 206 work = kzalloc(sizeof(*work), GFP_ATOMIC); 207 if (!work) 208 return; 209 210 INIT_WORK(&work->work, phy_chan_notify); 211 work->dev = dev; 212 queue_work(priv->hw->dev_workqueue, &work->work); 213 } else { 214 mutex_unlock(&priv->hw->phy->pib_lock); 215 } 216} 217 218 219int mac802154_get_params(struct net_device *dev, 220 struct ieee802154_llsec_params *params) 221{ 222 struct mac802154_sub_if_data *priv = netdev_priv(dev); 223 int res; 224 225 BUG_ON(dev->type != ARPHRD_IEEE802154); 226 227 mutex_lock(&priv->sec_mtx); 228 res = mac802154_llsec_get_params(&priv->sec, params); 229 mutex_unlock(&priv->sec_mtx); 230 231 return res; 232} 233 234int mac802154_set_params(struct net_device *dev, 235 const struct ieee802154_llsec_params *params, 236 int changed) 237{ 238 struct mac802154_sub_if_data *priv = netdev_priv(dev); 239 int res; 240 241 BUG_ON(dev->type != ARPHRD_IEEE802154); 242 243 mutex_lock(&priv->sec_mtx); 244 res = mac802154_llsec_set_params(&priv->sec, params, changed); 245 mutex_unlock(&priv->sec_mtx); 246 247 return res; 248} 249 250 251int mac802154_add_key(struct net_device *dev, 252 const struct ieee802154_llsec_key_id *id, 253 const struct ieee802154_llsec_key *key) 254{ 255 struct mac802154_sub_if_data *priv = netdev_priv(dev); 256 int res; 257 258 BUG_ON(dev->type != ARPHRD_IEEE802154); 259 260 mutex_lock(&priv->sec_mtx); 261 res = mac802154_llsec_key_add(&priv->sec, id, key); 262 mutex_unlock(&priv->sec_mtx); 263 264 return res; 265} 266 267int mac802154_del_key(struct net_device *dev, 268 const struct ieee802154_llsec_key_id *id) 269{ 270 struct mac802154_sub_if_data *priv = netdev_priv(dev); 271 int res; 272 273 BUG_ON(dev->type != ARPHRD_IEEE802154); 274 275 mutex_lock(&priv->sec_mtx); 276 res = mac802154_llsec_key_del(&priv->sec, id); 277 mutex_unlock(&priv->sec_mtx); 278 279 return res; 280} 281 282 283int mac802154_add_dev(struct net_device *dev, 284 const struct ieee802154_llsec_device *llsec_dev) 285{ 286 struct mac802154_sub_if_data *priv = netdev_priv(dev); 287 int res; 288 289 BUG_ON(dev->type != ARPHRD_IEEE802154); 290 291 mutex_lock(&priv->sec_mtx); 292 res = mac802154_llsec_dev_add(&priv->sec, llsec_dev); 293 mutex_unlock(&priv->sec_mtx); 294 295 return res; 296} 297 298int mac802154_del_dev(struct net_device *dev, __le64 dev_addr) 299{ 300 struct mac802154_sub_if_data *priv = netdev_priv(dev); 301 int res; 302 303 BUG_ON(dev->type != ARPHRD_IEEE802154); 304 305 mutex_lock(&priv->sec_mtx); 306 res = mac802154_llsec_dev_del(&priv->sec, dev_addr); 307 mutex_unlock(&priv->sec_mtx); 308 309 return res; 310} 311 312 313int mac802154_add_devkey(struct net_device *dev, 314 __le64 device_addr, 315 const struct ieee802154_llsec_device_key *key) 316{ 317 struct mac802154_sub_if_data *priv = netdev_priv(dev); 318 int res; 319 320 BUG_ON(dev->type != ARPHRD_IEEE802154); 321 322 mutex_lock(&priv->sec_mtx); 323 res = mac802154_llsec_devkey_add(&priv->sec, device_addr, key); 324 mutex_unlock(&priv->sec_mtx); 325 326 return res; 327} 328 329int mac802154_del_devkey(struct net_device *dev, 330 __le64 device_addr, 331 const struct ieee802154_llsec_device_key *key) 332{ 333 struct mac802154_sub_if_data *priv = netdev_priv(dev); 334 int res; 335 336 BUG_ON(dev->type != ARPHRD_IEEE802154); 337 338 mutex_lock(&priv->sec_mtx); 339 res = mac802154_llsec_devkey_del(&priv->sec, device_addr, key); 340 mutex_unlock(&priv->sec_mtx); 341 342 return res; 343} 344 345 346int mac802154_add_seclevel(struct net_device *dev, 347 const struct ieee802154_llsec_seclevel *sl) 348{ 349 struct mac802154_sub_if_data *priv = netdev_priv(dev); 350 int res; 351 352 BUG_ON(dev->type != ARPHRD_IEEE802154); 353 354 mutex_lock(&priv->sec_mtx); 355 res = mac802154_llsec_seclevel_add(&priv->sec, sl); 356 mutex_unlock(&priv->sec_mtx); 357 358 return res; 359} 360 361int mac802154_del_seclevel(struct net_device *dev, 362 const struct ieee802154_llsec_seclevel *sl) 363{ 364 struct mac802154_sub_if_data *priv = netdev_priv(dev); 365 int res; 366 367 BUG_ON(dev->type != ARPHRD_IEEE802154); 368 369 mutex_lock(&priv->sec_mtx); 370 res = mac802154_llsec_seclevel_del(&priv->sec, sl); 371 mutex_unlock(&priv->sec_mtx); 372 373 return res; 374} 375 376 377void mac802154_lock_table(struct net_device *dev) 378{ 379 struct mac802154_sub_if_data *priv = netdev_priv(dev); 380 381 BUG_ON(dev->type != ARPHRD_IEEE802154); 382 383 mutex_lock(&priv->sec_mtx); 384} 385 386void mac802154_get_table(struct net_device *dev, 387 struct ieee802154_llsec_table **t) 388{ 389 struct mac802154_sub_if_data *priv = netdev_priv(dev); 390 391 BUG_ON(dev->type != ARPHRD_IEEE802154); 392 393 *t = &priv->sec.table; 394} 395 396void mac802154_unlock_table(struct net_device *dev) 397{ 398 struct mac802154_sub_if_data *priv = netdev_priv(dev); 399 400 BUG_ON(dev->type != ARPHRD_IEEE802154); 401 402 mutex_unlock(&priv->sec_mtx); 403} 404