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
11static inline int
12drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb)
13{
14	return local->ops->xmit_async(&local->hw, skb);
15}
16
17static inline int
18drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb)
19{
20	/* don't allow other operations while sync xmit */
21	ASSERT_RTNL();
22
23	might_sleep();
24
25	return local->ops->xmit_sync(&local->hw, skb);
26}
27
28static inline int drv_start(struct ieee802154_local *local)
29{
30	might_sleep();
31
32	local->started = true;
33	smp_mb();
34
35	return local->ops->start(&local->hw);
36}
37
38static inline void drv_stop(struct ieee802154_local *local)
39{
40	might_sleep();
41
42	local->ops->stop(&local->hw);
43
44	/* sync away all work on the tasklet before clearing started */
45	tasklet_disable(&local->tasklet);
46	tasklet_enable(&local->tasklet);
47
48	barrier();
49
50	local->started = false;
51}
52
53static inline int
54drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel)
55{
56	might_sleep();
57
58	return local->ops->set_channel(&local->hw, page, channel);
59}
60
61static inline int drv_set_tx_power(struct ieee802154_local *local, s8 dbm)
62{
63	might_sleep();
64
65	if (!local->ops->set_txpower) {
66		WARN_ON(1);
67		return -EOPNOTSUPP;
68	}
69
70	return local->ops->set_txpower(&local->hw, dbm);
71}
72
73static inline int drv_set_cca_mode(struct ieee802154_local *local,
74				   const struct wpan_phy_cca *cca)
75{
76	might_sleep();
77
78	if (!local->ops->set_cca_mode) {
79		WARN_ON(1);
80		return -EOPNOTSUPP;
81	}
82
83	return local->ops->set_cca_mode(&local->hw, cca);
84}
85
86static inline int drv_set_lbt_mode(struct ieee802154_local *local, bool mode)
87{
88	might_sleep();
89
90	if (!local->ops->set_lbt) {
91		WARN_ON(1);
92		return -EOPNOTSUPP;
93	}
94
95	return local->ops->set_lbt(&local->hw, mode);
96}
97
98static inline int
99drv_set_cca_ed_level(struct ieee802154_local *local, s32 ed_level)
100{
101	might_sleep();
102
103	if (!local->ops->set_cca_ed_level) {
104		WARN_ON(1);
105		return -EOPNOTSUPP;
106	}
107
108	return local->ops->set_cca_ed_level(&local->hw, ed_level);
109}
110
111static inline int drv_set_pan_id(struct ieee802154_local *local, __le16 pan_id)
112{
113	struct ieee802154_hw_addr_filt filt;
114
115	might_sleep();
116
117	if (!local->ops->set_hw_addr_filt) {
118		WARN_ON(1);
119		return -EOPNOTSUPP;
120	}
121
122	filt.pan_id = pan_id;
123
124	return local->ops->set_hw_addr_filt(&local->hw, &filt,
125					    IEEE802154_AFILT_PANID_CHANGED);
126}
127
128static inline int
129drv_set_extended_addr(struct ieee802154_local *local, __le64 extended_addr)
130{
131	struct ieee802154_hw_addr_filt filt;
132
133	might_sleep();
134
135	if (!local->ops->set_hw_addr_filt) {
136		WARN_ON(1);
137		return -EOPNOTSUPP;
138	}
139
140	filt.ieee_addr = extended_addr;
141
142	return local->ops->set_hw_addr_filt(&local->hw, &filt,
143					    IEEE802154_AFILT_IEEEADDR_CHANGED);
144}
145
146static inline int
147drv_set_short_addr(struct ieee802154_local *local, __le16 short_addr)
148{
149	struct ieee802154_hw_addr_filt filt;
150
151	might_sleep();
152
153	if (!local->ops->set_hw_addr_filt) {
154		WARN_ON(1);
155		return -EOPNOTSUPP;
156	}
157
158	filt.short_addr = short_addr;
159
160	return local->ops->set_hw_addr_filt(&local->hw, &filt,
161					    IEEE802154_AFILT_SADDR_CHANGED);
162}
163
164static inline int
165drv_set_pan_coord(struct ieee802154_local *local, bool is_coord)
166{
167	struct ieee802154_hw_addr_filt filt;
168
169	might_sleep();
170
171	if (!local->ops->set_hw_addr_filt) {
172		WARN_ON(1);
173		return -EOPNOTSUPP;
174	}
175
176	filt.pan_coord = is_coord;
177
178	return local->ops->set_hw_addr_filt(&local->hw, &filt,
179					    IEEE802154_AFILT_PANC_CHANGED);
180}
181
182static inline int
183drv_set_csma_params(struct ieee802154_local *local, u8 min_be, u8 max_be,
184		    u8 max_csma_backoffs)
185{
186	might_sleep();
187
188	if (!local->ops->set_csma_params) {
189		WARN_ON(1);
190		return -EOPNOTSUPP;
191	}
192
193	return local->ops->set_csma_params(&local->hw, min_be, max_be,
194					   max_csma_backoffs);
195}
196
197static inline int
198drv_set_max_frame_retries(struct ieee802154_local *local, s8 max_frame_retries)
199{
200	might_sleep();
201
202	if (!local->ops->set_frame_retries) {
203		WARN_ON(1);
204		return -EOPNOTSUPP;
205	}
206
207	return local->ops->set_frame_retries(&local->hw, max_frame_retries);
208}
209
210static inline int
211drv_set_promiscuous_mode(struct ieee802154_local *local, bool on)
212{
213	might_sleep();
214
215	if (!local->ops->set_promiscuous_mode) {
216		WARN_ON(1);
217		return -EOPNOTSUPP;
218	}
219
220	return local->ops->set_promiscuous_mode(&local->hw, on);
221}
222
223#endif /* __MAC802154_DRIVER_OPS */
224