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