0001
0002 #ifndef __MAC802154_DRIVER_OPS
0003 #define __MAC802154_DRIVER_OPS
0004
0005 #include <linux/types.h>
0006 #include <linux/rtnetlink.h>
0007
0008 #include <net/mac802154.h>
0009
0010 #include "ieee802154_i.h"
0011 #include "trace.h"
0012
0013 static inline int
0014 drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb)
0015 {
0016 return local->ops->xmit_async(&local->hw, skb);
0017 }
0018
0019 static inline int
0020 drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb)
0021 {
0022 might_sleep();
0023
0024 return local->ops->xmit_sync(&local->hw, skb);
0025 }
0026
0027 static inline int drv_start(struct ieee802154_local *local)
0028 {
0029 int ret;
0030
0031 might_sleep();
0032
0033 trace_802154_drv_start(local);
0034 local->started = true;
0035 smp_mb();
0036 ret = local->ops->start(&local->hw);
0037 trace_802154_drv_return_int(local, ret);
0038 return ret;
0039 }
0040
0041 static inline void drv_stop(struct ieee802154_local *local)
0042 {
0043 might_sleep();
0044
0045 trace_802154_drv_stop(local);
0046 local->ops->stop(&local->hw);
0047 trace_802154_drv_return_void(local);
0048
0049
0050 tasklet_disable(&local->tasklet);
0051 tasklet_enable(&local->tasklet);
0052
0053 barrier();
0054
0055 local->started = false;
0056 }
0057
0058 static inline int
0059 drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel)
0060 {
0061 int ret;
0062
0063 might_sleep();
0064
0065 trace_802154_drv_set_channel(local, page, channel);
0066 ret = local->ops->set_channel(&local->hw, page, channel);
0067 trace_802154_drv_return_int(local, ret);
0068 return ret;
0069 }
0070
0071 static inline int drv_set_tx_power(struct ieee802154_local *local, s32 mbm)
0072 {
0073 int ret;
0074
0075 might_sleep();
0076
0077 if (!local->ops->set_txpower) {
0078 WARN_ON(1);
0079 return -EOPNOTSUPP;
0080 }
0081
0082 trace_802154_drv_set_tx_power(local, mbm);
0083 ret = local->ops->set_txpower(&local->hw, mbm);
0084 trace_802154_drv_return_int(local, ret);
0085 return ret;
0086 }
0087
0088 static inline int drv_set_cca_mode(struct ieee802154_local *local,
0089 const struct wpan_phy_cca *cca)
0090 {
0091 int ret;
0092
0093 might_sleep();
0094
0095 if (!local->ops->set_cca_mode) {
0096 WARN_ON(1);
0097 return -EOPNOTSUPP;
0098 }
0099
0100 trace_802154_drv_set_cca_mode(local, cca);
0101 ret = local->ops->set_cca_mode(&local->hw, cca);
0102 trace_802154_drv_return_int(local, ret);
0103 return ret;
0104 }
0105
0106 static inline int drv_set_lbt_mode(struct ieee802154_local *local, bool mode)
0107 {
0108 int ret;
0109
0110 might_sleep();
0111
0112 if (!local->ops->set_lbt) {
0113 WARN_ON(1);
0114 return -EOPNOTSUPP;
0115 }
0116
0117 trace_802154_drv_set_lbt_mode(local, mode);
0118 ret = local->ops->set_lbt(&local->hw, mode);
0119 trace_802154_drv_return_int(local, ret);
0120 return ret;
0121 }
0122
0123 static inline int
0124 drv_set_cca_ed_level(struct ieee802154_local *local, s32 mbm)
0125 {
0126 int ret;
0127
0128 might_sleep();
0129
0130 if (!local->ops->set_cca_ed_level) {
0131 WARN_ON(1);
0132 return -EOPNOTSUPP;
0133 }
0134
0135 trace_802154_drv_set_cca_ed_level(local, mbm);
0136 ret = local->ops->set_cca_ed_level(&local->hw, mbm);
0137 trace_802154_drv_return_int(local, ret);
0138 return ret;
0139 }
0140
0141 static inline int drv_set_pan_id(struct ieee802154_local *local, __le16 pan_id)
0142 {
0143 struct ieee802154_hw_addr_filt filt;
0144 int ret;
0145
0146 might_sleep();
0147
0148 if (!local->ops->set_hw_addr_filt) {
0149 WARN_ON(1);
0150 return -EOPNOTSUPP;
0151 }
0152
0153 filt.pan_id = pan_id;
0154
0155 trace_802154_drv_set_pan_id(local, pan_id);
0156 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
0157 IEEE802154_AFILT_PANID_CHANGED);
0158 trace_802154_drv_return_int(local, ret);
0159 return ret;
0160 }
0161
0162 static inline int
0163 drv_set_extended_addr(struct ieee802154_local *local, __le64 extended_addr)
0164 {
0165 struct ieee802154_hw_addr_filt filt;
0166 int ret;
0167
0168 might_sleep();
0169
0170 if (!local->ops->set_hw_addr_filt) {
0171 WARN_ON(1);
0172 return -EOPNOTSUPP;
0173 }
0174
0175 filt.ieee_addr = extended_addr;
0176
0177 trace_802154_drv_set_extended_addr(local, extended_addr);
0178 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
0179 IEEE802154_AFILT_IEEEADDR_CHANGED);
0180 trace_802154_drv_return_int(local, ret);
0181 return ret;
0182 }
0183
0184 static inline int
0185 drv_set_short_addr(struct ieee802154_local *local, __le16 short_addr)
0186 {
0187 struct ieee802154_hw_addr_filt filt;
0188 int ret;
0189
0190 might_sleep();
0191
0192 if (!local->ops->set_hw_addr_filt) {
0193 WARN_ON(1);
0194 return -EOPNOTSUPP;
0195 }
0196
0197 filt.short_addr = short_addr;
0198
0199 trace_802154_drv_set_short_addr(local, short_addr);
0200 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
0201 IEEE802154_AFILT_SADDR_CHANGED);
0202 trace_802154_drv_return_int(local, ret);
0203 return ret;
0204 }
0205
0206 static inline int
0207 drv_set_pan_coord(struct ieee802154_local *local, bool is_coord)
0208 {
0209 struct ieee802154_hw_addr_filt filt;
0210 int ret;
0211
0212 might_sleep();
0213
0214 if (!local->ops->set_hw_addr_filt) {
0215 WARN_ON(1);
0216 return -EOPNOTSUPP;
0217 }
0218
0219 filt.pan_coord = is_coord;
0220
0221 trace_802154_drv_set_pan_coord(local, is_coord);
0222 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
0223 IEEE802154_AFILT_PANC_CHANGED);
0224 trace_802154_drv_return_int(local, ret);
0225 return ret;
0226 }
0227
0228 static inline int
0229 drv_set_csma_params(struct ieee802154_local *local, u8 min_be, u8 max_be,
0230 u8 max_csma_backoffs)
0231 {
0232 int ret;
0233
0234 might_sleep();
0235
0236 if (!local->ops->set_csma_params) {
0237 WARN_ON(1);
0238 return -EOPNOTSUPP;
0239 }
0240
0241 trace_802154_drv_set_csma_params(local, min_be, max_be,
0242 max_csma_backoffs);
0243 ret = local->ops->set_csma_params(&local->hw, min_be, max_be,
0244 max_csma_backoffs);
0245 trace_802154_drv_return_int(local, ret);
0246 return ret;
0247 }
0248
0249 static inline int
0250 drv_set_max_frame_retries(struct ieee802154_local *local, s8 max_frame_retries)
0251 {
0252 int ret;
0253
0254 might_sleep();
0255
0256 if (!local->ops->set_frame_retries) {
0257 WARN_ON(1);
0258 return -EOPNOTSUPP;
0259 }
0260
0261 trace_802154_drv_set_max_frame_retries(local, max_frame_retries);
0262 ret = local->ops->set_frame_retries(&local->hw, max_frame_retries);
0263 trace_802154_drv_return_int(local, ret);
0264 return ret;
0265 }
0266
0267 static inline int
0268 drv_set_promiscuous_mode(struct ieee802154_local *local, bool on)
0269 {
0270 int ret;
0271
0272 might_sleep();
0273
0274 if (!local->ops->set_promiscuous_mode) {
0275 WARN_ON(1);
0276 return -EOPNOTSUPP;
0277 }
0278
0279 trace_802154_drv_set_promiscuous_mode(local, on);
0280 ret = local->ops->set_promiscuous_mode(&local->hw, on);
0281 trace_802154_drv_return_int(local, ret);
0282 return ret;
0283 }
0284
0285 #endif