1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __MAC802154_DRIVER_OPS 3 #define __MAC802154_DRIVER_OPS 4 5 #include <linux/types.h> 6 #include <linux/rtnetlink.h> 7 8 #include <net/mac802154.h> 9 10 #include "ieee802154_i.h" 11 #include "trace.h" 12 13 static inline int 14 drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb) 15 { 16 return local->ops->xmit_async(&local->hw, skb); 17 } 18 19 static inline int 20 drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb) 21 { 22 might_sleep(); 23 24 return local->ops->xmit_sync(&local->hw, skb); 25 } 26 27 static inline int drv_start(struct ieee802154_local *local) 28 { 29 int ret; 30 31 might_sleep(); 32 33 trace_802154_drv_start(local); 34 local->started = true; 35 smp_mb(); 36 ret = local->ops->start(&local->hw); 37 trace_802154_drv_return_int(local, ret); 38 return ret; 39 } 40 41 static inline void drv_stop(struct ieee802154_local *local) 42 { 43 might_sleep(); 44 45 trace_802154_drv_stop(local); 46 local->ops->stop(&local->hw); 47 trace_802154_drv_return_void(local); 48 49 /* sync away all work on the tasklet before clearing started */ 50 tasklet_disable(&local->tasklet); 51 tasklet_enable(&local->tasklet); 52 53 barrier(); 54 55 local->started = false; 56 } 57 58 static inline int 59 drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel) 60 { 61 int ret; 62 63 might_sleep(); 64 65 trace_802154_drv_set_channel(local, page, channel); 66 ret = local->ops->set_channel(&local->hw, page, channel); 67 trace_802154_drv_return_int(local, ret); 68 return ret; 69 } 70 71 static inline int drv_set_tx_power(struct ieee802154_local *local, s32 mbm) 72 { 73 int ret; 74 75 might_sleep(); 76 77 if (!local->ops->set_txpower) { 78 WARN_ON(1); 79 return -EOPNOTSUPP; 80 } 81 82 trace_802154_drv_set_tx_power(local, mbm); 83 ret = local->ops->set_txpower(&local->hw, mbm); 84 trace_802154_drv_return_int(local, ret); 85 return ret; 86 } 87 88 static inline int drv_set_cca_mode(struct ieee802154_local *local, 89 const struct wpan_phy_cca *cca) 90 { 91 int ret; 92 93 might_sleep(); 94 95 if (!local->ops->set_cca_mode) { 96 WARN_ON(1); 97 return -EOPNOTSUPP; 98 } 99 100 trace_802154_drv_set_cca_mode(local, cca); 101 ret = local->ops->set_cca_mode(&local->hw, cca); 102 trace_802154_drv_return_int(local, ret); 103 return ret; 104 } 105 106 static inline int drv_set_lbt_mode(struct ieee802154_local *local, bool mode) 107 { 108 int ret; 109 110 might_sleep(); 111 112 if (!local->ops->set_lbt) { 113 WARN_ON(1); 114 return -EOPNOTSUPP; 115 } 116 117 trace_802154_drv_set_lbt_mode(local, mode); 118 ret = local->ops->set_lbt(&local->hw, mode); 119 trace_802154_drv_return_int(local, ret); 120 return ret; 121 } 122 123 static inline int 124 drv_set_cca_ed_level(struct ieee802154_local *local, s32 mbm) 125 { 126 int ret; 127 128 might_sleep(); 129 130 if (!local->ops->set_cca_ed_level) { 131 WARN_ON(1); 132 return -EOPNOTSUPP; 133 } 134 135 trace_802154_drv_set_cca_ed_level(local, mbm); 136 ret = local->ops->set_cca_ed_level(&local->hw, mbm); 137 trace_802154_drv_return_int(local, ret); 138 return ret; 139 } 140 141 static inline int drv_set_pan_id(struct ieee802154_local *local, __le16 pan_id) 142 { 143 struct ieee802154_hw_addr_filt filt; 144 int ret; 145 146 might_sleep(); 147 148 if (!local->ops->set_hw_addr_filt) { 149 WARN_ON(1); 150 return -EOPNOTSUPP; 151 } 152 153 filt.pan_id = pan_id; 154 155 trace_802154_drv_set_pan_id(local, pan_id); 156 ret = local->ops->set_hw_addr_filt(&local->hw, &filt, 157 IEEE802154_AFILT_PANID_CHANGED); 158 trace_802154_drv_return_int(local, ret); 159 return ret; 160 } 161 162 static inline int 163 drv_set_extended_addr(struct ieee802154_local *local, __le64 extended_addr) 164 { 165 struct ieee802154_hw_addr_filt filt; 166 int ret; 167 168 might_sleep(); 169 170 if (!local->ops->set_hw_addr_filt) { 171 WARN_ON(1); 172 return -EOPNOTSUPP; 173 } 174 175 filt.ieee_addr = extended_addr; 176 177 trace_802154_drv_set_extended_addr(local, extended_addr); 178 ret = local->ops->set_hw_addr_filt(&local->hw, &filt, 179 IEEE802154_AFILT_IEEEADDR_CHANGED); 180 trace_802154_drv_return_int(local, ret); 181 return ret; 182 } 183 184 static inline int 185 drv_set_short_addr(struct ieee802154_local *local, __le16 short_addr) 186 { 187 struct ieee802154_hw_addr_filt filt; 188 int ret; 189 190 might_sleep(); 191 192 if (!local->ops->set_hw_addr_filt) { 193 WARN_ON(1); 194 return -EOPNOTSUPP; 195 } 196 197 filt.short_addr = short_addr; 198 199 trace_802154_drv_set_short_addr(local, short_addr); 200 ret = local->ops->set_hw_addr_filt(&local->hw, &filt, 201 IEEE802154_AFILT_SADDR_CHANGED); 202 trace_802154_drv_return_int(local, ret); 203 return ret; 204 } 205 206 static inline int 207 drv_set_pan_coord(struct ieee802154_local *local, bool is_coord) 208 { 209 struct ieee802154_hw_addr_filt filt; 210 int ret; 211 212 might_sleep(); 213 214 if (!local->ops->set_hw_addr_filt) { 215 WARN_ON(1); 216 return -EOPNOTSUPP; 217 } 218 219 filt.pan_coord = is_coord; 220 221 trace_802154_drv_set_pan_coord(local, is_coord); 222 ret = local->ops->set_hw_addr_filt(&local->hw, &filt, 223 IEEE802154_AFILT_PANC_CHANGED); 224 trace_802154_drv_return_int(local, ret); 225 return ret; 226 } 227 228 static inline int 229 drv_set_csma_params(struct ieee802154_local *local, u8 min_be, u8 max_be, 230 u8 max_csma_backoffs) 231 { 232 int ret; 233 234 might_sleep(); 235 236 if (!local->ops->set_csma_params) { 237 WARN_ON(1); 238 return -EOPNOTSUPP; 239 } 240 241 trace_802154_drv_set_csma_params(local, min_be, max_be, 242 max_csma_backoffs); 243 ret = local->ops->set_csma_params(&local->hw, min_be, max_be, 244 max_csma_backoffs); 245 trace_802154_drv_return_int(local, ret); 246 return ret; 247 } 248 249 static inline int 250 drv_set_max_frame_retries(struct ieee802154_local *local, s8 max_frame_retries) 251 { 252 int ret; 253 254 might_sleep(); 255 256 if (!local->ops->set_frame_retries) { 257 WARN_ON(1); 258 return -EOPNOTSUPP; 259 } 260 261 trace_802154_drv_set_max_frame_retries(local, max_frame_retries); 262 ret = local->ops->set_frame_retries(&local->hw, max_frame_retries); 263 trace_802154_drv_return_int(local, ret); 264 return ret; 265 } 266 267 static inline int 268 drv_set_promiscuous_mode(struct ieee802154_local *local, bool on) 269 { 270 int ret; 271 272 might_sleep(); 273 274 if (!local->ops->set_promiscuous_mode) { 275 WARN_ON(1); 276 return -EOPNOTSUPP; 277 } 278 279 trace_802154_drv_set_promiscuous_mode(local, on); 280 ret = local->ops->set_promiscuous_mode(&local->hw, on); 281 trace_802154_drv_return_int(local, ret); 282 return ret; 283 } 284 285 #endif /* __MAC802154_DRIVER_OPS */ 286