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