cfg.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /* This program is free software; you can redistribute it and/or modify
  2. * it under the terms of the GNU General Public License version 2
  3. * as published by the Free Software Foundation.
  4. *
  5. * This program is distributed in the hope that it will be useful,
  6. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. * GNU General Public License for more details.
  9. *
  10. * Authors:
  11. * Alexander Aring <aar@pengutronix.de>
  12. *
  13. * Based on: net/mac80211/cfg.c
  14. */
  15. #include <net/rtnetlink.h>
  16. #include <net/cfg802154.h>
  17. #include "ieee802154_i.h"
  18. #include "driver-ops.h"
  19. #include "cfg.h"
  20. static struct net_device *
  21. ieee802154_add_iface_deprecated(struct wpan_phy *wpan_phy,
  22. const char *name,
  23. unsigned char name_assign_type, int type)
  24. {
  25. struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
  26. struct net_device *dev;
  27. rtnl_lock();
  28. dev = ieee802154_if_add(local, name, name_assign_type, type,
  29. cpu_to_le64(0x0000000000000000ULL));
  30. rtnl_unlock();
  31. return dev;
  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. ieee802154_if_remove(sdata);
  38. }
  39. static int
  40. ieee802154_add_iface(struct wpan_phy *phy, const char *name,
  41. unsigned char name_assign_type,
  42. enum nl802154_iftype type, __le64 extended_addr)
  43. {
  44. struct ieee802154_local *local = wpan_phy_priv(phy);
  45. struct net_device *err;
  46. err = ieee802154_if_add(local, name, name_assign_type, type,
  47. extended_addr);
  48. return PTR_ERR_OR_ZERO(err);
  49. }
  50. static int
  51. ieee802154_del_iface(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev)
  52. {
  53. ieee802154_if_remove(IEEE802154_WPAN_DEV_TO_SUB_IF(wpan_dev));
  54. return 0;
  55. }
  56. static int
  57. ieee802154_set_channel(struct wpan_phy *wpan_phy, u8 page, u8 channel)
  58. {
  59. struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
  60. int ret;
  61. ASSERT_RTNL();
  62. if (wpan_phy->current_page == page &&
  63. wpan_phy->current_channel == channel)
  64. return 0;
  65. ret = drv_set_channel(local, page, channel);
  66. if (!ret) {
  67. wpan_phy->current_page = page;
  68. wpan_phy->current_channel = channel;
  69. }
  70. return ret;
  71. }
  72. static int
  73. ieee802154_set_cca_mode(struct wpan_phy *wpan_phy,
  74. const struct wpan_phy_cca *cca)
  75. {
  76. struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
  77. int ret;
  78. ASSERT_RTNL();
  79. if (wpan_phy_cca_cmp(&wpan_phy->cca, cca))
  80. return 0;
  81. ret = drv_set_cca_mode(local, cca);
  82. if (!ret)
  83. wpan_phy->cca = *cca;
  84. return ret;
  85. }
  86. static int
  87. ieee802154_set_cca_ed_level(struct wpan_phy *wpan_phy, s32 ed_level)
  88. {
  89. struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
  90. int ret;
  91. ASSERT_RTNL();
  92. if (wpan_phy->cca_ed_level == ed_level)
  93. return 0;
  94. ret = drv_set_cca_ed_level(local, ed_level);
  95. if (!ret)
  96. wpan_phy->cca_ed_level = ed_level;
  97. return ret;
  98. }
  99. static int
  100. ieee802154_set_tx_power(struct wpan_phy *wpan_phy, s32 power)
  101. {
  102. struct ieee802154_local *local = wpan_phy_priv(wpan_phy);
  103. int ret;
  104. ASSERT_RTNL();
  105. if (wpan_phy->transmit_power == power)
  106. return 0;
  107. ret = drv_set_tx_power(local, power);
  108. if (!ret)
  109. wpan_phy->transmit_power = power;
  110. return ret;
  111. }
  112. static int
  113. ieee802154_set_pan_id(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
  114. __le16 pan_id)
  115. {
  116. ASSERT_RTNL();
  117. if (wpan_dev->pan_id == pan_id)
  118. return 0;
  119. wpan_dev->pan_id = pan_id;
  120. return 0;
  121. }
  122. static int
  123. ieee802154_set_backoff_exponent(struct wpan_phy *wpan_phy,
  124. struct wpan_dev *wpan_dev,
  125. u8 min_be, u8 max_be)
  126. {
  127. ASSERT_RTNL();
  128. if (wpan_dev->min_be == min_be &&
  129. wpan_dev->max_be == max_be)
  130. return 0;
  131. wpan_dev->min_be = min_be;
  132. wpan_dev->max_be = max_be;
  133. return 0;
  134. }
  135. static int
  136. ieee802154_set_short_addr(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
  137. __le16 short_addr)
  138. {
  139. ASSERT_RTNL();
  140. if (wpan_dev->short_addr == short_addr)
  141. return 0;
  142. wpan_dev->short_addr = short_addr;
  143. return 0;
  144. }
  145. static int
  146. ieee802154_set_max_csma_backoffs(struct wpan_phy *wpan_phy,
  147. struct wpan_dev *wpan_dev,
  148. u8 max_csma_backoffs)
  149. {
  150. ASSERT_RTNL();
  151. if (wpan_dev->csma_retries == max_csma_backoffs)
  152. return 0;
  153. wpan_dev->csma_retries = max_csma_backoffs;
  154. return 0;
  155. }
  156. static int
  157. ieee802154_set_max_frame_retries(struct wpan_phy *wpan_phy,
  158. struct wpan_dev *wpan_dev,
  159. s8 max_frame_retries)
  160. {
  161. ASSERT_RTNL();
  162. if (wpan_dev->frame_retries == max_frame_retries)
  163. return 0;
  164. wpan_dev->frame_retries = max_frame_retries;
  165. return 0;
  166. }
  167. static int
  168. ieee802154_set_lbt_mode(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev,
  169. bool mode)
  170. {
  171. ASSERT_RTNL();
  172. if (wpan_dev->lbt == mode)
  173. return 0;
  174. wpan_dev->lbt = mode;
  175. return 0;
  176. }
  177. const struct cfg802154_ops mac802154_config_ops = {
  178. .add_virtual_intf_deprecated = ieee802154_add_iface_deprecated,
  179. .del_virtual_intf_deprecated = ieee802154_del_iface_deprecated,
  180. .add_virtual_intf = ieee802154_add_iface,
  181. .del_virtual_intf = ieee802154_del_iface,
  182. .set_channel = ieee802154_set_channel,
  183. .set_cca_mode = ieee802154_set_cca_mode,
  184. .set_cca_ed_level = ieee802154_set_cca_ed_level,
  185. .set_tx_power = ieee802154_set_tx_power,
  186. .set_pan_id = ieee802154_set_pan_id,
  187. .set_short_addr = ieee802154_set_short_addr,
  188. .set_backoff_exponent = ieee802154_set_backoff_exponent,
  189. .set_max_csma_backoffs = ieee802154_set_max_csma_backoffs,
  190. .set_max_frame_retries = ieee802154_set_max_frame_retries,
  191. .set_lbt_mode = ieee802154_set_lbt_mode,
  192. };