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