1b6eea9caSAlexander Aring #ifndef __MAC802154_DRVIER_OPS 2b6eea9caSAlexander Aring #define __MAC802154_DRIVER_OPS 3b6eea9caSAlexander Aring 4b6eea9caSAlexander Aring #include <linux/types.h> 5b6eea9caSAlexander Aring #include <linux/rtnetlink.h> 6b6eea9caSAlexander Aring 7b6eea9caSAlexander Aring #include <net/mac802154.h> 8b6eea9caSAlexander Aring 9b6eea9caSAlexander Aring #include "ieee802154_i.h" 10b6eea9caSAlexander Aring 11b6eea9caSAlexander Aring static inline int 12b6eea9caSAlexander Aring drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb) 13b6eea9caSAlexander Aring { 14b6eea9caSAlexander Aring return local->ops->xmit_async(&local->hw, skb); 15b6eea9caSAlexander Aring } 16b6eea9caSAlexander Aring 17b6eea9caSAlexander Aring static inline int 18b6eea9caSAlexander Aring drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb) 19b6eea9caSAlexander Aring { 20b6eea9caSAlexander Aring /* don't allow other operations while sync xmit */ 21b6eea9caSAlexander Aring ASSERT_RTNL(); 22b6eea9caSAlexander Aring 23b6eea9caSAlexander Aring might_sleep(); 24b6eea9caSAlexander Aring 25b6eea9caSAlexander Aring return local->ops->xmit_sync(&local->hw, skb); 26b6eea9caSAlexander Aring } 27b6eea9caSAlexander Aring 28b6eea9caSAlexander Aring static inline int drv_start(struct ieee802154_local *local) 29b6eea9caSAlexander Aring { 30b6eea9caSAlexander Aring might_sleep(); 31b6eea9caSAlexander Aring 32e363eca3SAlexander Aring local->started = true; 33538181a8SAlexander Aring smp_mb(); 34e363eca3SAlexander Aring 35b6eea9caSAlexander Aring return local->ops->start(&local->hw); 36b6eea9caSAlexander Aring } 37b6eea9caSAlexander Aring 38b6eea9caSAlexander Aring static inline void drv_stop(struct ieee802154_local *local) 39b6eea9caSAlexander Aring { 40b6eea9caSAlexander Aring might_sleep(); 41b6eea9caSAlexander Aring 42b6eea9caSAlexander Aring local->ops->stop(&local->hw); 43e363eca3SAlexander Aring 44538181a8SAlexander Aring /* sync away all work on the tasklet before clearing started */ 45538181a8SAlexander Aring tasklet_disable(&local->tasklet); 46538181a8SAlexander Aring tasklet_enable(&local->tasklet); 47538181a8SAlexander Aring 48538181a8SAlexander Aring barrier(); 49538181a8SAlexander Aring 50e363eca3SAlexander Aring local->started = false; 51b6eea9caSAlexander Aring } 52b6eea9caSAlexander Aring 53b6eea9caSAlexander Aring static inline int drv_set_channel(struct ieee802154_local *local, 54b6eea9caSAlexander Aring const u8 page, const u8 channel) 55b6eea9caSAlexander Aring { 56b6eea9caSAlexander Aring might_sleep(); 57b6eea9caSAlexander Aring 58b6eea9caSAlexander Aring return local->ops->set_channel(&local->hw, page, channel); 59b6eea9caSAlexander Aring } 60b6eea9caSAlexander Aring 61b6eea9caSAlexander Aring static inline int drv_set_tx_power(struct ieee802154_local *local, 62b6eea9caSAlexander Aring const s8 dbm) 63b6eea9caSAlexander Aring { 64b6eea9caSAlexander Aring might_sleep(); 65b6eea9caSAlexander Aring 66b6eea9caSAlexander Aring if (!local->ops->set_txpower) { 67b6eea9caSAlexander Aring WARN_ON(1); 68b6eea9caSAlexander Aring return -EOPNOTSUPP; 69b6eea9caSAlexander Aring } 70b6eea9caSAlexander Aring 71b6eea9caSAlexander Aring return local->ops->set_txpower(&local->hw, dbm); 72b6eea9caSAlexander Aring } 73b6eea9caSAlexander Aring 74b6eea9caSAlexander Aring static inline int drv_set_cca_mode(struct ieee802154_local *local, 75b6eea9caSAlexander Aring const u8 cca_mode) 76b6eea9caSAlexander Aring { 77b6eea9caSAlexander Aring might_sleep(); 78b6eea9caSAlexander Aring 79b6eea9caSAlexander Aring if (!local->ops->set_cca_mode) { 80b6eea9caSAlexander Aring WARN_ON(1); 81b6eea9caSAlexander Aring return -EOPNOTSUPP; 82b6eea9caSAlexander Aring } 83b6eea9caSAlexander Aring 84b6eea9caSAlexander Aring return local->ops->set_cca_mode(&local->hw, cca_mode); 85b6eea9caSAlexander Aring } 86b6eea9caSAlexander Aring 87b6eea9caSAlexander Aring static inline int drv_set_lbt_mode(struct ieee802154_local *local, 88b6eea9caSAlexander Aring const bool mode) 89b6eea9caSAlexander Aring { 90b6eea9caSAlexander Aring might_sleep(); 91b6eea9caSAlexander Aring 92b6eea9caSAlexander Aring if (!local->ops->set_lbt) { 93b6eea9caSAlexander Aring WARN_ON(1); 94b6eea9caSAlexander Aring return -EOPNOTSUPP; 95b6eea9caSAlexander Aring } 96b6eea9caSAlexander Aring 97b6eea9caSAlexander Aring return local->ops->set_lbt(&local->hw, mode); 98b6eea9caSAlexander Aring } 99b6eea9caSAlexander Aring 100b6eea9caSAlexander Aring static inline int drv_set_cca_ed_level(struct ieee802154_local *local, 101b6eea9caSAlexander Aring const s32 ed_level) 102b6eea9caSAlexander Aring { 103b6eea9caSAlexander Aring might_sleep(); 104b6eea9caSAlexander Aring 105b6eea9caSAlexander Aring if (!local->ops->set_cca_ed_level) { 106b6eea9caSAlexander Aring WARN_ON(1); 107b6eea9caSAlexander Aring return -EOPNOTSUPP; 108b6eea9caSAlexander Aring } 109b6eea9caSAlexander Aring 110b6eea9caSAlexander Aring return local->ops->set_cca_ed_level(&local->hw, ed_level); 111b6eea9caSAlexander Aring } 112b6eea9caSAlexander Aring 113b6eea9caSAlexander Aring static inline int drv_set_pan_id(struct ieee802154_local *local, 114b6eea9caSAlexander Aring const __le16 pan_id) 115b6eea9caSAlexander Aring { 116b6eea9caSAlexander Aring struct ieee802154_hw_addr_filt filt; 117b6eea9caSAlexander Aring 118b6eea9caSAlexander Aring might_sleep(); 119b6eea9caSAlexander Aring 120b6eea9caSAlexander Aring if (!local->ops->set_hw_addr_filt) { 121b6eea9caSAlexander Aring WARN_ON(1); 122b6eea9caSAlexander Aring return -EOPNOTSUPP; 123b6eea9caSAlexander Aring } 124b6eea9caSAlexander Aring 125b6eea9caSAlexander Aring filt.pan_id = pan_id; 126b6eea9caSAlexander Aring 127b6eea9caSAlexander Aring return local->ops->set_hw_addr_filt(&local->hw, &filt, 128b6eea9caSAlexander Aring IEEE802154_AFILT_PANID_CHANGED); 129b6eea9caSAlexander Aring } 130b6eea9caSAlexander Aring 131b6eea9caSAlexander Aring static inline int drv_set_extended_addr(struct ieee802154_local *local, 132b6eea9caSAlexander Aring const __le64 extended_addr) 133b6eea9caSAlexander Aring { 134b6eea9caSAlexander Aring struct ieee802154_hw_addr_filt filt; 135b6eea9caSAlexander Aring 136b6eea9caSAlexander Aring might_sleep(); 137b6eea9caSAlexander Aring 138b6eea9caSAlexander Aring if (!local->ops->set_hw_addr_filt) { 139b6eea9caSAlexander Aring WARN_ON(1); 140b6eea9caSAlexander Aring return -EOPNOTSUPP; 141b6eea9caSAlexander Aring } 142b6eea9caSAlexander Aring 143b6eea9caSAlexander Aring filt.ieee_addr = extended_addr; 144b6eea9caSAlexander Aring 145b6eea9caSAlexander Aring return local->ops->set_hw_addr_filt(&local->hw, &filt, 146b6eea9caSAlexander Aring IEEE802154_AFILT_IEEEADDR_CHANGED); 147b6eea9caSAlexander Aring } 148b6eea9caSAlexander Aring 149b6eea9caSAlexander Aring static inline int drv_set_short_addr(struct ieee802154_local *local, 150b6eea9caSAlexander Aring const __le16 short_addr) 151b6eea9caSAlexander Aring { 152b6eea9caSAlexander Aring struct ieee802154_hw_addr_filt filt; 153b6eea9caSAlexander Aring 154b6eea9caSAlexander Aring might_sleep(); 155b6eea9caSAlexander Aring 156b6eea9caSAlexander Aring if (!local->ops->set_hw_addr_filt) { 157b6eea9caSAlexander Aring WARN_ON(1); 158b6eea9caSAlexander Aring return -EOPNOTSUPP; 159b6eea9caSAlexander Aring } 160b6eea9caSAlexander Aring 161b6eea9caSAlexander Aring filt.short_addr = short_addr; 162b6eea9caSAlexander Aring 163b6eea9caSAlexander Aring return local->ops->set_hw_addr_filt(&local->hw, &filt, 164b6eea9caSAlexander Aring IEEE802154_AFILT_SADDR_CHANGED); 165b6eea9caSAlexander Aring } 166b6eea9caSAlexander Aring 167b6eea9caSAlexander Aring static inline int drv_set_pan_coord(struct ieee802154_local *local, 168b6eea9caSAlexander Aring const bool is_coord) 169b6eea9caSAlexander Aring { 170b6eea9caSAlexander Aring struct ieee802154_hw_addr_filt filt; 171b6eea9caSAlexander Aring 172b6eea9caSAlexander Aring might_sleep(); 173b6eea9caSAlexander Aring 174b6eea9caSAlexander Aring if (!local->ops->set_hw_addr_filt) { 175b6eea9caSAlexander Aring WARN_ON(1); 176b6eea9caSAlexander Aring return -EOPNOTSUPP; 177b6eea9caSAlexander Aring } 178b6eea9caSAlexander Aring 179b6eea9caSAlexander Aring filt.pan_coord = is_coord; 180b6eea9caSAlexander Aring 181b6eea9caSAlexander Aring return local->ops->set_hw_addr_filt(&local->hw, &filt, 182b6eea9caSAlexander Aring IEEE802154_AFILT_PANC_CHANGED); 183b6eea9caSAlexander Aring } 184b6eea9caSAlexander Aring 185b6eea9caSAlexander Aring static inline int drv_set_csma_params(struct ieee802154_local *local, 186b6eea9caSAlexander Aring u8 min_be, u8 max_be, 187b6eea9caSAlexander Aring u8 max_csma_backoffs) 188b6eea9caSAlexander Aring { 189b6eea9caSAlexander Aring might_sleep(); 190b6eea9caSAlexander Aring 191b6eea9caSAlexander Aring if (!local->ops->set_csma_params) { 192b6eea9caSAlexander Aring WARN_ON(1); 193b6eea9caSAlexander Aring return -EOPNOTSUPP; 194b6eea9caSAlexander Aring } 195b6eea9caSAlexander Aring 196b6eea9caSAlexander Aring return local->ops->set_csma_params(&local->hw, min_be, max_be, 197b6eea9caSAlexander Aring max_csma_backoffs); 198b6eea9caSAlexander Aring } 199b6eea9caSAlexander Aring 200b6eea9caSAlexander Aring static inline int drv_set_max_frame_retries(struct ieee802154_local *local, 201b6eea9caSAlexander Aring s8 max_frame_retries) 202b6eea9caSAlexander Aring { 203b6eea9caSAlexander Aring might_sleep(); 204b6eea9caSAlexander Aring 205b6eea9caSAlexander Aring if (!local->ops->set_frame_retries) { 206b6eea9caSAlexander Aring WARN_ON(1); 207b6eea9caSAlexander Aring return -EOPNOTSUPP; 208b6eea9caSAlexander Aring } 209b6eea9caSAlexander Aring 210b6eea9caSAlexander Aring return local->ops->set_frame_retries(&local->hw, max_frame_retries); 211b6eea9caSAlexander Aring } 212b6eea9caSAlexander Aring 213b6eea9caSAlexander Aring #endif /* __MAC802154_DRVIER_OPS */ 214