1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2ea6edfbcSNicolas Iooss #ifndef __MAC802154_DRIVER_OPS 3b6eea9caSAlexander Aring #define __MAC802154_DRIVER_OPS 4b6eea9caSAlexander Aring 5b6eea9caSAlexander Aring #include <linux/types.h> 6b6eea9caSAlexander Aring #include <linux/rtnetlink.h> 7b6eea9caSAlexander Aring 8b6eea9caSAlexander Aring #include <net/mac802154.h> 9b6eea9caSAlexander Aring 10b6eea9caSAlexander Aring #include "ieee802154_i.h" 110ecc4e68SVarka Bhadram #include "trace.h" 12b6eea9caSAlexander Aring 13b6eea9caSAlexander Aring static inline int 14b6eea9caSAlexander Aring drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb) 15b6eea9caSAlexander Aring { 16b6eea9caSAlexander Aring return local->ops->xmit_async(&local->hw, skb); 17b6eea9caSAlexander Aring } 18b6eea9caSAlexander Aring 19b6eea9caSAlexander Aring static inline int 20b6eea9caSAlexander Aring drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb) 21b6eea9caSAlexander Aring { 22b6eea9caSAlexander Aring might_sleep(); 23b6eea9caSAlexander Aring 24b6eea9caSAlexander Aring return local->ops->xmit_sync(&local->hw, skb); 25b6eea9caSAlexander Aring } 26b6eea9caSAlexander Aring 27b6eea9caSAlexander Aring static inline int drv_start(struct ieee802154_local *local) 28b6eea9caSAlexander Aring { 290ecc4e68SVarka Bhadram int ret; 300ecc4e68SVarka Bhadram 31b6eea9caSAlexander Aring might_sleep(); 32b6eea9caSAlexander Aring 330ecc4e68SVarka Bhadram trace_802154_drv_start(local); 34e363eca3SAlexander Aring local->started = true; 35538181a8SAlexander Aring smp_mb(); 360ecc4e68SVarka Bhadram ret = local->ops->start(&local->hw); 370ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 380ecc4e68SVarka Bhadram return ret; 39b6eea9caSAlexander Aring } 40b6eea9caSAlexander Aring 41b6eea9caSAlexander Aring static inline void drv_stop(struct ieee802154_local *local) 42b6eea9caSAlexander Aring { 43b6eea9caSAlexander Aring might_sleep(); 44b6eea9caSAlexander Aring 450ecc4e68SVarka Bhadram trace_802154_drv_stop(local); 46b6eea9caSAlexander Aring local->ops->stop(&local->hw); 470ecc4e68SVarka Bhadram trace_802154_drv_return_void(local); 48e363eca3SAlexander Aring 49538181a8SAlexander Aring /* sync away all work on the tasklet before clearing started */ 50538181a8SAlexander Aring tasklet_disable(&local->tasklet); 51538181a8SAlexander Aring tasklet_enable(&local->tasklet); 52538181a8SAlexander Aring 53538181a8SAlexander Aring barrier(); 54538181a8SAlexander Aring 55e363eca3SAlexander Aring local->started = false; 56b6eea9caSAlexander Aring } 57b6eea9caSAlexander Aring 5829cd54b9SAlexander Aring static inline int 5929cd54b9SAlexander Aring drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel) 60b6eea9caSAlexander Aring { 610ecc4e68SVarka Bhadram int ret; 620ecc4e68SVarka Bhadram 63b6eea9caSAlexander Aring might_sleep(); 64b6eea9caSAlexander Aring 650ecc4e68SVarka Bhadram trace_802154_drv_set_channel(local, page, channel); 660ecc4e68SVarka Bhadram ret = local->ops->set_channel(&local->hw, page, channel); 670ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 680ecc4e68SVarka Bhadram return ret; 69b6eea9caSAlexander Aring } 70b6eea9caSAlexander Aring 71e2eb173aSAlexander Aring static inline int drv_set_tx_power(struct ieee802154_local *local, s32 mbm) 72b6eea9caSAlexander Aring { 730ecc4e68SVarka Bhadram int ret; 740ecc4e68SVarka Bhadram 75b6eea9caSAlexander Aring might_sleep(); 76b6eea9caSAlexander Aring 77b6eea9caSAlexander Aring if (!local->ops->set_txpower) { 78b6eea9caSAlexander Aring WARN_ON(1); 79b6eea9caSAlexander Aring return -EOPNOTSUPP; 80b6eea9caSAlexander Aring } 81b6eea9caSAlexander Aring 820ecc4e68SVarka Bhadram trace_802154_drv_set_tx_power(local, mbm); 830ecc4e68SVarka Bhadram ret = local->ops->set_txpower(&local->hw, mbm); 840ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 850ecc4e68SVarka Bhadram return ret; 86b6eea9caSAlexander Aring } 87b6eea9caSAlexander Aring 887fe9a388SAlexander Aring static inline int drv_set_cca_mode(struct ieee802154_local *local, 897fe9a388SAlexander Aring const struct wpan_phy_cca *cca) 90b6eea9caSAlexander Aring { 910ecc4e68SVarka Bhadram int ret; 920ecc4e68SVarka Bhadram 93b6eea9caSAlexander Aring might_sleep(); 94b6eea9caSAlexander Aring 95b6eea9caSAlexander Aring if (!local->ops->set_cca_mode) { 96b6eea9caSAlexander Aring WARN_ON(1); 97b6eea9caSAlexander Aring return -EOPNOTSUPP; 98b6eea9caSAlexander Aring } 99b6eea9caSAlexander Aring 1000ecc4e68SVarka Bhadram trace_802154_drv_set_cca_mode(local, cca); 1010ecc4e68SVarka Bhadram ret = local->ops->set_cca_mode(&local->hw, cca); 1020ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 1030ecc4e68SVarka Bhadram return ret; 104b6eea9caSAlexander Aring } 105b6eea9caSAlexander Aring 10629cd54b9SAlexander Aring static inline int drv_set_lbt_mode(struct ieee802154_local *local, bool mode) 107b6eea9caSAlexander Aring { 1080ecc4e68SVarka Bhadram int ret; 1090ecc4e68SVarka Bhadram 110b6eea9caSAlexander Aring might_sleep(); 111b6eea9caSAlexander Aring 112b6eea9caSAlexander Aring if (!local->ops->set_lbt) { 113b6eea9caSAlexander Aring WARN_ON(1); 114b6eea9caSAlexander Aring return -EOPNOTSUPP; 115b6eea9caSAlexander Aring } 116b6eea9caSAlexander Aring 1170ecc4e68SVarka Bhadram trace_802154_drv_set_lbt_mode(local, mode); 1180ecc4e68SVarka Bhadram ret = local->ops->set_lbt(&local->hw, mode); 1190ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 1200ecc4e68SVarka Bhadram return ret; 121b6eea9caSAlexander Aring } 122b6eea9caSAlexander Aring 12329cd54b9SAlexander Aring static inline int 12432b23550SAlexander Aring drv_set_cca_ed_level(struct ieee802154_local *local, s32 mbm) 125b6eea9caSAlexander Aring { 1260ecc4e68SVarka Bhadram int ret; 1270ecc4e68SVarka Bhadram 128b6eea9caSAlexander Aring might_sleep(); 129b6eea9caSAlexander Aring 130b6eea9caSAlexander Aring if (!local->ops->set_cca_ed_level) { 131b6eea9caSAlexander Aring WARN_ON(1); 132b6eea9caSAlexander Aring return -EOPNOTSUPP; 133b6eea9caSAlexander Aring } 134b6eea9caSAlexander Aring 1350ecc4e68SVarka Bhadram trace_802154_drv_set_cca_ed_level(local, mbm); 1360ecc4e68SVarka Bhadram ret = local->ops->set_cca_ed_level(&local->hw, mbm); 1370ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 1380ecc4e68SVarka Bhadram return ret; 139b6eea9caSAlexander Aring } 140b6eea9caSAlexander Aring 14129cd54b9SAlexander Aring static inline int drv_set_pan_id(struct ieee802154_local *local, __le16 pan_id) 142b6eea9caSAlexander Aring { 143b6eea9caSAlexander Aring struct ieee802154_hw_addr_filt filt; 1440ecc4e68SVarka Bhadram int ret; 145b6eea9caSAlexander Aring 146b6eea9caSAlexander Aring might_sleep(); 147b6eea9caSAlexander Aring 148b6eea9caSAlexander Aring if (!local->ops->set_hw_addr_filt) { 149b6eea9caSAlexander Aring WARN_ON(1); 150b6eea9caSAlexander Aring return -EOPNOTSUPP; 151b6eea9caSAlexander Aring } 152b6eea9caSAlexander Aring 153b6eea9caSAlexander Aring filt.pan_id = pan_id; 154b6eea9caSAlexander Aring 1550ecc4e68SVarka Bhadram trace_802154_drv_set_pan_id(local, pan_id); 1560ecc4e68SVarka Bhadram ret = local->ops->set_hw_addr_filt(&local->hw, &filt, 157b6eea9caSAlexander Aring IEEE802154_AFILT_PANID_CHANGED); 1580ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 1590ecc4e68SVarka Bhadram return ret; 160b6eea9caSAlexander Aring } 161b6eea9caSAlexander Aring 16229cd54b9SAlexander Aring static inline int 16329cd54b9SAlexander Aring drv_set_extended_addr(struct ieee802154_local *local, __le64 extended_addr) 164b6eea9caSAlexander Aring { 165b6eea9caSAlexander Aring struct ieee802154_hw_addr_filt filt; 1660ecc4e68SVarka Bhadram int ret; 167b6eea9caSAlexander Aring 168b6eea9caSAlexander Aring might_sleep(); 169b6eea9caSAlexander Aring 170b6eea9caSAlexander Aring if (!local->ops->set_hw_addr_filt) { 171b6eea9caSAlexander Aring WARN_ON(1); 172b6eea9caSAlexander Aring return -EOPNOTSUPP; 173b6eea9caSAlexander Aring } 174b6eea9caSAlexander Aring 175b6eea9caSAlexander Aring filt.ieee_addr = extended_addr; 176b6eea9caSAlexander Aring 1770ecc4e68SVarka Bhadram trace_802154_drv_set_extended_addr(local, extended_addr); 1780ecc4e68SVarka Bhadram ret = local->ops->set_hw_addr_filt(&local->hw, &filt, 179b6eea9caSAlexander Aring IEEE802154_AFILT_IEEEADDR_CHANGED); 1800ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 1810ecc4e68SVarka Bhadram return ret; 182b6eea9caSAlexander Aring } 183b6eea9caSAlexander Aring 18429cd54b9SAlexander Aring static inline int 18529cd54b9SAlexander Aring drv_set_short_addr(struct ieee802154_local *local, __le16 short_addr) 186b6eea9caSAlexander Aring { 187b6eea9caSAlexander Aring struct ieee802154_hw_addr_filt filt; 1880ecc4e68SVarka Bhadram int ret; 189b6eea9caSAlexander Aring 190b6eea9caSAlexander Aring might_sleep(); 191b6eea9caSAlexander Aring 192b6eea9caSAlexander Aring if (!local->ops->set_hw_addr_filt) { 193b6eea9caSAlexander Aring WARN_ON(1); 194b6eea9caSAlexander Aring return -EOPNOTSUPP; 195b6eea9caSAlexander Aring } 196b6eea9caSAlexander Aring 197b6eea9caSAlexander Aring filt.short_addr = short_addr; 198b6eea9caSAlexander Aring 1990ecc4e68SVarka Bhadram trace_802154_drv_set_short_addr(local, short_addr); 2000ecc4e68SVarka Bhadram ret = local->ops->set_hw_addr_filt(&local->hw, &filt, 201b6eea9caSAlexander Aring IEEE802154_AFILT_SADDR_CHANGED); 2020ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 2030ecc4e68SVarka Bhadram return ret; 204b6eea9caSAlexander Aring } 205b6eea9caSAlexander Aring 20629cd54b9SAlexander Aring static inline int 20729cd54b9SAlexander Aring drv_set_pan_coord(struct ieee802154_local *local, bool is_coord) 208b6eea9caSAlexander Aring { 209b6eea9caSAlexander Aring struct ieee802154_hw_addr_filt filt; 2100ecc4e68SVarka Bhadram int ret; 211b6eea9caSAlexander Aring 212b6eea9caSAlexander Aring might_sleep(); 213b6eea9caSAlexander Aring 214b6eea9caSAlexander Aring if (!local->ops->set_hw_addr_filt) { 215b6eea9caSAlexander Aring WARN_ON(1); 216b6eea9caSAlexander Aring return -EOPNOTSUPP; 217b6eea9caSAlexander Aring } 218b6eea9caSAlexander Aring 219b6eea9caSAlexander Aring filt.pan_coord = is_coord; 220b6eea9caSAlexander Aring 2210ecc4e68SVarka Bhadram trace_802154_drv_set_pan_coord(local, is_coord); 2220ecc4e68SVarka Bhadram ret = local->ops->set_hw_addr_filt(&local->hw, &filt, 223b6eea9caSAlexander Aring IEEE802154_AFILT_PANC_CHANGED); 2240ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 2250ecc4e68SVarka Bhadram return ret; 226b6eea9caSAlexander Aring } 227b6eea9caSAlexander Aring 22829cd54b9SAlexander Aring static inline int 22929cd54b9SAlexander Aring drv_set_csma_params(struct ieee802154_local *local, u8 min_be, u8 max_be, 230b6eea9caSAlexander Aring u8 max_csma_backoffs) 231b6eea9caSAlexander Aring { 2320ecc4e68SVarka Bhadram int ret; 2330ecc4e68SVarka Bhadram 234b6eea9caSAlexander Aring might_sleep(); 235b6eea9caSAlexander Aring 236b6eea9caSAlexander Aring if (!local->ops->set_csma_params) { 237b6eea9caSAlexander Aring WARN_ON(1); 238b6eea9caSAlexander Aring return -EOPNOTSUPP; 239b6eea9caSAlexander Aring } 240b6eea9caSAlexander Aring 2410ecc4e68SVarka Bhadram trace_802154_drv_set_csma_params(local, min_be, max_be, 242b6eea9caSAlexander Aring max_csma_backoffs); 2430ecc4e68SVarka Bhadram ret = local->ops->set_csma_params(&local->hw, min_be, max_be, 2440ecc4e68SVarka Bhadram max_csma_backoffs); 2450ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 2460ecc4e68SVarka Bhadram return ret; 247b6eea9caSAlexander Aring } 248b6eea9caSAlexander Aring 24929cd54b9SAlexander Aring static inline int 25029cd54b9SAlexander Aring drv_set_max_frame_retries(struct ieee802154_local *local, s8 max_frame_retries) 251b6eea9caSAlexander Aring { 2520ecc4e68SVarka Bhadram int ret; 2530ecc4e68SVarka Bhadram 254b6eea9caSAlexander Aring might_sleep(); 255b6eea9caSAlexander Aring 256b6eea9caSAlexander Aring if (!local->ops->set_frame_retries) { 257b6eea9caSAlexander Aring WARN_ON(1); 258b6eea9caSAlexander Aring return -EOPNOTSUPP; 259b6eea9caSAlexander Aring } 260b6eea9caSAlexander Aring 2610ecc4e68SVarka Bhadram trace_802154_drv_set_max_frame_retries(local, max_frame_retries); 2620ecc4e68SVarka Bhadram ret = local->ops->set_frame_retries(&local->hw, max_frame_retries); 2630ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 2640ecc4e68SVarka Bhadram return ret; 265b6eea9caSAlexander Aring } 266b6eea9caSAlexander Aring 26729cd54b9SAlexander Aring static inline int 26829cd54b9SAlexander Aring drv_set_promiscuous_mode(struct ieee802154_local *local, bool on) 26994b79222SAlexander Aring { 2700ecc4e68SVarka Bhadram int ret; 2710ecc4e68SVarka Bhadram 27294b79222SAlexander Aring might_sleep(); 27394b79222SAlexander Aring 27494b79222SAlexander Aring if (!local->ops->set_promiscuous_mode) { 27594b79222SAlexander Aring WARN_ON(1); 27694b79222SAlexander Aring return -EOPNOTSUPP; 27794b79222SAlexander Aring } 27894b79222SAlexander Aring 2790ecc4e68SVarka Bhadram trace_802154_drv_set_promiscuous_mode(local, on); 2800ecc4e68SVarka Bhadram ret = local->ops->set_promiscuous_mode(&local->hw, on); 2810ecc4e68SVarka Bhadram trace_802154_drv_return_int(local, ret); 2820ecc4e68SVarka Bhadram return ret; 28394b79222SAlexander Aring } 28494b79222SAlexander Aring 285ea6edfbcSNicolas Iooss #endif /* __MAC802154_DRIVER_OPS */ 286