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