root/net/mac802154/cfg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ieee802154_add_iface_deprecated
  2. ieee802154_del_iface_deprecated
  3. ieee802154_suspend
  4. ieee802154_resume
  5. ieee802154_add_iface
  6. ieee802154_del_iface
  7. ieee802154_set_channel
  8. ieee802154_set_cca_mode
  9. ieee802154_set_cca_ed_level
  10. ieee802154_set_tx_power
  11. ieee802154_set_pan_id
  12. ieee802154_set_backoff_exponent
  13. ieee802154_set_short_addr
  14. ieee802154_set_max_csma_backoffs
  15. ieee802154_set_max_frame_retries
  16. ieee802154_set_lbt_mode
  17. ieee802154_set_ackreq_default
  18. ieee802154_get_llsec_table
  19. ieee802154_lock_llsec_table
  20. ieee802154_unlock_llsec_table
  21. ieee802154_set_llsec_params
  22. ieee802154_get_llsec_params
  23. ieee802154_add_llsec_key
  24. ieee802154_del_llsec_key
  25. ieee802154_add_seclevel
  26. ieee802154_del_seclevel
  27. ieee802154_add_device
  28. ieee802154_del_device
  29. ieee802154_add_devkey
  30. ieee802154_del_devkey

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *
   4  * Authors:
   5  * Alexander Aring <aar@pengutronix.de>
   6  *
   7  * Based on: net/mac80211/cfg.c
   8  */
   9 
  10 #include <net/rtnetlink.h>
  11 #include <net/cfg802154.h>
  12 
  13 #include "ieee802154_i.h"
  14 #include "driver-ops.h"
  15 #include "cfg.h"
  16 
  17 static struct net_device *
  18 ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy,
  19                                 const char *name,
  20                                 unsigned char name_assign_type, int type)
  21 {
  22         struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
  23         struct net_device *dev;
  24 
  25         rtnl_lock();
  26         dev = ieee802154_if_add(local, name, name_assign_type, type,
  27                                 cpu_to_le64(0x0000000000000000ULL));
  28         rtnl_unlock();
  29 
  30         return dev;
  31 }
  32 
  33 static void ieee802154_del_iface_deprecated(struct wpan_phy *wpan_phy,
  34                                             struct net_device *dev)
  35 {
  36         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
  37 
  38         ieee802154_if_remove(sdata);
  39 }
  40 
  41 #ifdef CONFIG_PM
  42 static int ieee802154_suspend(struct wpan_phy *wpan_phy)
  43 {
  44         struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
  45 
  46         if (!local->open_count)
  47                 goto suspend;
  48 
  49         ieee802154_stop_queue(&local->hw);
  50         synchronize_net();
  51 
  52         /* stop hardware - this must stop RX */
  53         ieee802154_stop_device(local);
  54 
  55 suspend:
  56         local->suspended = true;
  57         return 0;
  58 }
  59 
  60 static int ieee802154_resume(struct wpan_phy *wpan_phy)
  61 {
  62         struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
  63         int ret;
  64 
  65         /* nothing to do if HW shouldn't run */
  66         if (!local->open_count)
  67                 goto wake_up;
  68 
  69         /* restart hardware */
  70         ret = drv_start(local);
  71         if (ret)
  72                 return ret;
  73 
  74 wake_up:
  75         ieee802154_wake_queue(&local->hw);
  76         local->suspended = false;
  77         return 0;
  78 }
  79 #else
  80 #define ieee802154_suspend NULL
  81 #define ieee802154_resume NULL
  82 #endif
  83 
  84 static int
  85 ieee802154_add_iface(struct wpan_phy *phy, const char *name,
  86                      unsigned char name_assign_type,
  87                      enum nl802154_iftype type, __le64 extended_addr)
  88 {
  89         struct ieee802154_local *local = wpan_phy_priv(phy);
  90         struct net_device *err;
  91 
  92         err = ieee802154_if_add(local, name, name_assign_type, type,
  93                                 extended_addr);
  94         return PTR_ERR_OR_ZERO(err);
  95 }
  96 
  97 static int
  98 ieee802154_del_iface(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev)
  99 {
 100         ieee802154_if_remove(IEEE802154_WPAN_DEV_TO_SUB_IF(wpan_dev));
 101 
 102         return 0;
 103 }
 104 
 105 static int
 106 ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
 107 {
 108         struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
 109         int ret;
 110 
 111         ASSERT_RTNL();
 112 
 113         if (wpan_phy->current_page == page &&
 114             wpan_phy->current_channel == channel)
 115                 return 0;
 116 
 117         ret = drv_set_channel(local, page, channel);
 118         if (!ret) {
 119                 wpan_phy->current_page = page;
 120                 wpan_phy->current_channel = channel;
 121         }
 122 
 123         return ret;
 124 }
 125 
 126 static int
 127 ieee802154_set_cca_mode(struct wpan_phy *wpan_phy,
 128                         const struct wpan_phy_cca *cca)
 129 {
 130         struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
 131         int ret;
 132 
 133         ASSERT_RTNL();
 134 
 135         if (wpan_phy_cca_cmp(&wpan_phy->cca, cca))
 136                 return 0;
 137 
 138         ret = drv_set_cca_mode(local, cca);
 139         if (!ret)
 140                 wpan_phy->cca = *cca;
 141 
 142         return ret;
 143 }
 144 
 145 static int
 146 ieee802154_set_cca_ed_level(struct wpan_phy *wpan_phy, s32 ed_level)
 147 {
 148         struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
 149         int ret;
 150 
 151         ASSERT_RTNL();
 152 
 153         if (wpan_phy->cca_ed_level == ed_level)
 154                 return 0;
 155 
 156         ret = drv_set_cca_ed_level(local, ed_level);
 157         if (!ret)
 158                 wpan_phy->cca_ed_level = ed_level;
 159 
 160         return ret;
 161 }
 162 
 163 static int
 164 ieee802154_set_tx_power(struct wpan_phy *wpan_phy, s32 power)
 165 {
 166         struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
 167         int ret;
 168 
 169         ASSERT_RTNL();
 170 
 171         if (wpan_phy->transmit_power == power)
 172                 return 0;
 173 
 174         ret = drv_set_tx_power(local, power);
 175         if (!ret)
 176                 wpan_phy->transmit_power = power;
 177 
 178         return ret;
 179 }
 180 
 181 static int
 182 ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 183                       __le16 pan_id)
 184 {
 185         int ret;
 186 
 187         ASSERT_RTNL();
 188 
 189         if (wpan_dev->pan_id == pan_id)
 190                 return 0;
 191 
 192         ret = mac802154_wpan_update_llsec(wpan_dev->netdev);
 193         if (!ret)
 194                 wpan_dev->pan_id = pan_id;
 195 
 196         return ret;
 197 }
 198 
 199 static int
 200 ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy,
 201                                 struct wpan_dev *wpan_dev,
 202                                 u8 min_be, u8 max_be)
 203 {
 204         ASSERT_RTNL();
 205 
 206         wpan_dev->min_be = min_be;
 207         wpan_dev->max_be = max_be;
 208         return 0;
 209 }
 210 
 211 static int
 212 ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 213                           __le16 short_addr)
 214 {
 215         ASSERT_RTNL();
 216 
 217         wpan_dev->short_addr = short_addr;
 218         return 0;
 219 }
 220 
 221 static int
 222 ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy,
 223                                  struct wpan_dev *wpan_dev,
 224                                  u8 max_csma_backoffs)
 225 {
 226         ASSERT_RTNL();
 227 
 228         wpan_dev->csma_retries = max_csma_backoffs;
 229         return 0;
 230 }
 231 
 232 static int
 233 ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy,
 234                                  struct wpan_dev *wpan_dev,
 235                                  s8 max_frame_retries)
 236 {
 237         ASSERT_RTNL();
 238 
 239         wpan_dev->frame_retries = max_frame_retries;
 240         return 0;
 241 }
 242 
 243 static int
 244 ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 245                         bool mode)
 246 {
 247         ASSERT_RTNL();
 248 
 249         wpan_dev->lbt = mode;
 250         return 0;
 251 }
 252 
 253 static int
 254 ieee802154_set_ackreq_default(struct wpan_phy *wpan_phy,
 255                               struct wpan_dev *wpan_dev, bool ackreq)
 256 {
 257         ASSERT_RTNL();
 258 
 259         wpan_dev->ackreq = ackreq;
 260         return 0;
 261 }
 262 
 263 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 264 static void
 265 ieee802154_get_llsec_table(struct wpan_phy *wpan_phy,
 266                            struct wpan_dev *wpan_dev,
 267                            struct ieee802154_llsec_table **table)
 268 {
 269         struct net_device *dev = wpan_dev->netdev;
 270         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 271 
 272         *table = &sdata->sec.table;
 273 }
 274 
 275 static void
 276 ieee802154_lock_llsec_table(struct wpan_phy *wpan_phy,
 277                             struct wpan_dev *wpan_dev)
 278 {
 279         struct net_device *dev = wpan_dev->netdev;
 280         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 281 
 282         mutex_lock(&sdata->sec_mtx);
 283 }
 284 
 285 static void
 286 ieee802154_unlock_llsec_table(struct wpan_phy *wpan_phy,
 287                               struct wpan_dev *wpan_dev)
 288 {
 289         struct net_device *dev = wpan_dev->netdev;
 290         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 291 
 292         mutex_unlock(&sdata->sec_mtx);
 293 }
 294 
 295 static int
 296 ieee802154_set_llsec_params(struct wpan_phy *wpan_phy,
 297                             struct wpan_dev *wpan_dev,
 298                             const struct ieee802154_llsec_params *params,
 299                             int changed)
 300 {
 301         struct net_device *dev = wpan_dev->netdev;
 302         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 303         int res;
 304 
 305         mutex_lock(&sdata->sec_mtx);
 306         res = mac802154_llsec_set_params(&sdata->sec, params, changed);
 307         mutex_unlock(&sdata->sec_mtx);
 308 
 309         return res;
 310 }
 311 
 312 static int
 313 ieee802154_get_llsec_params(struct wpan_phy *wpan_phy,
 314                             struct wpan_dev *wpan_dev,
 315                             struct ieee802154_llsec_params *params)
 316 {
 317         struct net_device *dev = wpan_dev->netdev;
 318         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 319         int res;
 320 
 321         mutex_lock(&sdata->sec_mtx);
 322         res = mac802154_llsec_get_params(&sdata->sec, params);
 323         mutex_unlock(&sdata->sec_mtx);
 324 
 325         return res;
 326 }
 327 
 328 static int
 329 ieee802154_add_llsec_key(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 330                          const struct ieee802154_llsec_key_id *id,
 331                          const struct ieee802154_llsec_key *key)
 332 {
 333         struct net_device *dev = wpan_dev->netdev;
 334         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 335         int res;
 336 
 337         mutex_lock(&sdata->sec_mtx);
 338         res = mac802154_llsec_key_add(&sdata->sec, id, key);
 339         mutex_unlock(&sdata->sec_mtx);
 340 
 341         return res;
 342 }
 343 
 344 static int
 345 ieee802154_del_llsec_key(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 346                          const struct ieee802154_llsec_key_id *id)
 347 {
 348         struct net_device *dev = wpan_dev->netdev;
 349         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 350         int res;
 351 
 352         mutex_lock(&sdata->sec_mtx);
 353         res = mac802154_llsec_key_del(&sdata->sec, id);
 354         mutex_unlock(&sdata->sec_mtx);
 355 
 356         return res;
 357 }
 358 
 359 static int
 360 ieee802154_add_seclevel(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 361                         const struct ieee802154_llsec_seclevel *sl)
 362 {
 363         struct net_device *dev = wpan_dev->netdev;
 364         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 365         int res;
 366 
 367         mutex_lock(&sdata->sec_mtx);
 368         res = mac802154_llsec_seclevel_add(&sdata->sec, sl);
 369         mutex_unlock(&sdata->sec_mtx);
 370 
 371         return res;
 372 }
 373 
 374 static int
 375 ieee802154_del_seclevel(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 376                         const struct ieee802154_llsec_seclevel *sl)
 377 {
 378         struct net_device *dev = wpan_dev->netdev;
 379         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 380         int res;
 381 
 382         mutex_lock(&sdata->sec_mtx);
 383         res = mac802154_llsec_seclevel_del(&sdata->sec, sl);
 384         mutex_unlock(&sdata->sec_mtx);
 385 
 386         return res;
 387 }
 388 
 389 static int
 390 ieee802154_add_device(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 391                       const struct ieee802154_llsec_device *dev_desc)
 392 {
 393         struct net_device *dev = wpan_dev->netdev;
 394         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 395         int res;
 396 
 397         mutex_lock(&sdata->sec_mtx);
 398         res = mac802154_llsec_dev_add(&sdata->sec, dev_desc);
 399         mutex_unlock(&sdata->sec_mtx);
 400 
 401         return res;
 402 }
 403 
 404 static int
 405 ieee802154_del_device(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 406                       __le64 extended_addr)
 407 {
 408         struct net_device *dev = wpan_dev->netdev;
 409         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 410         int res;
 411 
 412         mutex_lock(&sdata->sec_mtx);
 413         res = mac802154_llsec_dev_del(&sdata->sec, extended_addr);
 414         mutex_unlock(&sdata->sec_mtx);
 415 
 416         return res;
 417 }
 418 
 419 static int
 420 ieee802154_add_devkey(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 421                       __le64 extended_addr,
 422                       const struct ieee802154_llsec_device_key *key)
 423 {
 424         struct net_device *dev = wpan_dev->netdev;
 425         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 426         int res;
 427 
 428         mutex_lock(&sdata->sec_mtx);
 429         res = mac802154_llsec_devkey_add(&sdata->sec, extended_addr, key);
 430         mutex_unlock(&sdata->sec_mtx);
 431 
 432         return res;
 433 }
 434 
 435 static int
 436 ieee802154_del_devkey(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
 437                       __le64 extended_addr,
 438                       const struct ieee802154_llsec_device_key *key)
 439 {
 440         struct net_device *dev = wpan_dev->netdev;
 441         struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
 442         int res;
 443 
 444         mutex_lock(&sdata->sec_mtx);
 445         res = mac802154_llsec_devkey_del(&sdata->sec, extended_addr, key);
 446         mutex_unlock(&sdata->sec_mtx);
 447 
 448         return res;
 449 }
 450 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
 451 
 452 const struct cfg802154_ops mac802154_config_ops = {
 453         .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
 454         .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
 455         .suspend = ieee802154_suspend,
 456         .resume = ieee802154_resume,
 457         .add_virtual_intf = ieee802154_add_iface,
 458         .del_virtual_intf = ieee802154_del_iface,
 459         .set_channel = ieee802154_set_channel,
 460         .set_cca_mode = ieee802154_set_cca_mode,
 461         .set_cca_ed_level = ieee802154_set_cca_ed_level,
 462         .set_tx_power = ieee802154_set_tx_power,
 463         .set_pan_id = ieee802154_set_pan_id,
 464         .set_short_addr = ieee802154_set_short_addr,
 465         .set_backoff_exponent = ieee802154_set_backoff_exponent,
 466         .set_max_csma_backoffs = ieee802154_set_max_csma_backoffs,
 467         .set_max_frame_retries = ieee802154_set_max_frame_retries,
 468         .set_lbt_mode = ieee802154_set_lbt_mode,
 469         .set_ackreq_default = ieee802154_set_ackreq_default,
 470 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 471         .get_llsec_table = ieee802154_get_llsec_table,
 472         .lock_llsec_table = ieee802154_lock_llsec_table,
 473         .unlock_llsec_table = ieee802154_unlock_llsec_table,
 474         /* TODO above */
 475         .set_llsec_params = ieee802154_set_llsec_params,
 476         .get_llsec_params = ieee802154_get_llsec_params,
 477         .add_llsec_key = ieee802154_add_llsec_key,
 478         .del_llsec_key = ieee802154_del_llsec_key,
 479         .add_seclevel = ieee802154_add_seclevel,
 480         .del_seclevel = ieee802154_del_seclevel,
 481         .add_device = ieee802154_add_device,
 482         .del_device = ieee802154_del_device,
 483         .add_devkey = ieee802154_add_devkey,
 484         .del_devkey = ieee802154_del_devkey,
 485 #endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
 486 };

/* [<][>][^][v][top][bottom][index][help] */