xref: /openbmc/linux/net/mac802154/driver-ops.h (revision ac8037c3)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2ea6edfbcSNicolas Iooss #ifndef __MAC802154_DRIVER_OPS
3b6eea9caSAlexander Aring #define __MAC802154_DRIVER_OPS
4b6eea9caSAlexander Aring 
5b6eea9caSAlexander Aring #include <linux/types.h>
6b6eea9caSAlexander Aring #include <linux/rtnetlink.h>
7b6eea9caSAlexander Aring 
8b6eea9caSAlexander Aring #include <net/mac802154.h>
9b6eea9caSAlexander Aring 
10b6eea9caSAlexander Aring #include "ieee802154_i.h"
110ecc4e68SVarka Bhadram #include "trace.h"
12b6eea9caSAlexander Aring 
13b6eea9caSAlexander Aring static inline int
drv_xmit_async(struct ieee802154_local * local,struct sk_buff * skb)14b6eea9caSAlexander Aring drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb)
15b6eea9caSAlexander Aring {
16b6eea9caSAlexander Aring 	return local->ops->xmit_async(&local->hw, skb);
17b6eea9caSAlexander Aring }
18b6eea9caSAlexander Aring 
19b6eea9caSAlexander Aring static inline int
drv_xmit_sync(struct ieee802154_local * local,struct sk_buff * skb)20b6eea9caSAlexander Aring drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb)
21b6eea9caSAlexander Aring {
22b6eea9caSAlexander Aring 	might_sleep();
23b6eea9caSAlexander Aring 
24b6eea9caSAlexander Aring 	return local->ops->xmit_sync(&local->hw, skb);
25b6eea9caSAlexander Aring }
26b6eea9caSAlexander Aring 
drv_set_pan_id(struct ieee802154_local * local,__le16 pan_id)27e9d8d9c4SAlexander Aring static inline int drv_set_pan_id(struct ieee802154_local *local, __le16 pan_id)
28e9d8d9c4SAlexander Aring {
29e9d8d9c4SAlexander Aring 	struct ieee802154_hw_addr_filt filt;
30e9d8d9c4SAlexander Aring 	int ret;
31e9d8d9c4SAlexander Aring 
32e9d8d9c4SAlexander Aring 	might_sleep();
33e9d8d9c4SAlexander Aring 
34e9d8d9c4SAlexander Aring 	if (!local->ops->set_hw_addr_filt) {
35e9d8d9c4SAlexander Aring 		WARN_ON(1);
36e9d8d9c4SAlexander Aring 		return -EOPNOTSUPP;
37e9d8d9c4SAlexander Aring 	}
38e9d8d9c4SAlexander Aring 
39e9d8d9c4SAlexander Aring 	filt.pan_id = pan_id;
40e9d8d9c4SAlexander Aring 
41e9d8d9c4SAlexander Aring 	trace_802154_drv_set_pan_id(local, pan_id);
42e9d8d9c4SAlexander Aring 	ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
43e9d8d9c4SAlexander Aring 					    IEEE802154_AFILT_PANID_CHANGED);
44e9d8d9c4SAlexander Aring 	trace_802154_drv_return_int(local, ret);
45e9d8d9c4SAlexander Aring 	return ret;
46e9d8d9c4SAlexander Aring }
47e9d8d9c4SAlexander Aring 
48e9d8d9c4SAlexander Aring static inline int
drv_set_extended_addr(struct ieee802154_local * local,__le64 extended_addr)49e9d8d9c4SAlexander Aring drv_set_extended_addr(struct ieee802154_local *local, __le64 extended_addr)
50e9d8d9c4SAlexander Aring {
51e9d8d9c4SAlexander Aring 	struct ieee802154_hw_addr_filt filt;
52e9d8d9c4SAlexander Aring 	int ret;
53e9d8d9c4SAlexander Aring 
54e9d8d9c4SAlexander Aring 	might_sleep();
55e9d8d9c4SAlexander Aring 
56e9d8d9c4SAlexander Aring 	if (!local->ops->set_hw_addr_filt) {
57e9d8d9c4SAlexander Aring 		WARN_ON(1);
58e9d8d9c4SAlexander Aring 		return -EOPNOTSUPP;
59e9d8d9c4SAlexander Aring 	}
60e9d8d9c4SAlexander Aring 
61e9d8d9c4SAlexander Aring 	filt.ieee_addr = extended_addr;
62e9d8d9c4SAlexander Aring 
63e9d8d9c4SAlexander Aring 	trace_802154_drv_set_extended_addr(local, extended_addr);
64e9d8d9c4SAlexander Aring 	ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
65e9d8d9c4SAlexander Aring 					    IEEE802154_AFILT_IEEEADDR_CHANGED);
66e9d8d9c4SAlexander Aring 	trace_802154_drv_return_int(local, ret);
67e9d8d9c4SAlexander Aring 	return ret;
68e9d8d9c4SAlexander Aring }
69e9d8d9c4SAlexander Aring 
70e9d8d9c4SAlexander Aring static inline int
drv_set_short_addr(struct ieee802154_local * local,__le16 short_addr)71e9d8d9c4SAlexander Aring drv_set_short_addr(struct ieee802154_local *local, __le16 short_addr)
72e9d8d9c4SAlexander Aring {
73e9d8d9c4SAlexander Aring 	struct ieee802154_hw_addr_filt filt;
74e9d8d9c4SAlexander Aring 	int ret;
75e9d8d9c4SAlexander Aring 
76e9d8d9c4SAlexander Aring 	might_sleep();
77e9d8d9c4SAlexander Aring 
78e9d8d9c4SAlexander Aring 	if (!local->ops->set_hw_addr_filt) {
79e9d8d9c4SAlexander Aring 		WARN_ON(1);
80e9d8d9c4SAlexander Aring 		return -EOPNOTSUPP;
81e9d8d9c4SAlexander Aring 	}
82e9d8d9c4SAlexander Aring 
83e9d8d9c4SAlexander Aring 	filt.short_addr = short_addr;
84e9d8d9c4SAlexander Aring 
85e9d8d9c4SAlexander Aring 	trace_802154_drv_set_short_addr(local, short_addr);
86e9d8d9c4SAlexander Aring 	ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
87e9d8d9c4SAlexander Aring 					    IEEE802154_AFILT_SADDR_CHANGED);
88e9d8d9c4SAlexander Aring 	trace_802154_drv_return_int(local, ret);
89e9d8d9c4SAlexander Aring 	return ret;
90e9d8d9c4SAlexander Aring }
91e9d8d9c4SAlexander Aring 
92e9d8d9c4SAlexander Aring static inline int
drv_set_pan_coord(struct ieee802154_local * local,bool is_coord)93e9d8d9c4SAlexander Aring drv_set_pan_coord(struct ieee802154_local *local, bool is_coord)
94e9d8d9c4SAlexander Aring {
95e9d8d9c4SAlexander Aring 	struct ieee802154_hw_addr_filt filt;
96e9d8d9c4SAlexander Aring 	int ret;
97e9d8d9c4SAlexander Aring 
98e9d8d9c4SAlexander Aring 	might_sleep();
99e9d8d9c4SAlexander Aring 
100e9d8d9c4SAlexander Aring 	if (!local->ops->set_hw_addr_filt) {
101e9d8d9c4SAlexander Aring 		WARN_ON(1);
102e9d8d9c4SAlexander Aring 		return -EOPNOTSUPP;
103e9d8d9c4SAlexander Aring 	}
104e9d8d9c4SAlexander Aring 
105e9d8d9c4SAlexander Aring 	filt.pan_coord = is_coord;
106e9d8d9c4SAlexander Aring 
107e9d8d9c4SAlexander Aring 	trace_802154_drv_set_pan_coord(local, is_coord);
108e9d8d9c4SAlexander Aring 	ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
109e9d8d9c4SAlexander Aring 					    IEEE802154_AFILT_PANC_CHANGED);
110e9d8d9c4SAlexander Aring 	trace_802154_drv_return_int(local, ret);
111e9d8d9c4SAlexander Aring 	return ret;
112e9d8d9c4SAlexander Aring }
113e9d8d9c4SAlexander Aring 
114e9d8d9c4SAlexander Aring static inline int
drv_set_promiscuous_mode(struct ieee802154_local * local,bool on)115e9d8d9c4SAlexander Aring drv_set_promiscuous_mode(struct ieee802154_local *local, bool on)
116e9d8d9c4SAlexander Aring {
117e9d8d9c4SAlexander Aring 	int ret;
118e9d8d9c4SAlexander Aring 
119e9d8d9c4SAlexander Aring 	might_sleep();
120e9d8d9c4SAlexander Aring 
121e9d8d9c4SAlexander Aring 	if (!local->ops->set_promiscuous_mode) {
122e9d8d9c4SAlexander Aring 		WARN_ON(1);
123e9d8d9c4SAlexander Aring 		return -EOPNOTSUPP;
124e9d8d9c4SAlexander Aring 	}
125e9d8d9c4SAlexander Aring 
126e9d8d9c4SAlexander Aring 	trace_802154_drv_set_promiscuous_mode(local, on);
127e9d8d9c4SAlexander Aring 	ret = local->ops->set_promiscuous_mode(&local->hw, on);
128e9d8d9c4SAlexander Aring 	trace_802154_drv_return_int(local, ret);
129e9d8d9c4SAlexander Aring 	return ret;
130e9d8d9c4SAlexander Aring }
131e9d8d9c4SAlexander Aring 
drv_start(struct ieee802154_local * local,enum ieee802154_filtering_level level,const struct ieee802154_hw_addr_filt * addr_filt)132*ac8037c3SAlexander Aring static inline int drv_start(struct ieee802154_local *local,
133*ac8037c3SAlexander Aring 			    enum ieee802154_filtering_level level,
134*ac8037c3SAlexander Aring 			    const struct ieee802154_hw_addr_filt *addr_filt)
135b6eea9caSAlexander Aring {
1360ecc4e68SVarka Bhadram 	int ret;
1370ecc4e68SVarka Bhadram 
138b6eea9caSAlexander Aring 	might_sleep();
139b6eea9caSAlexander Aring 
140*ac8037c3SAlexander Aring 	/* setup receive mode parameters e.g. address mode */
141*ac8037c3SAlexander Aring 	if (local->hw.flags & IEEE802154_HW_AFILT) {
142*ac8037c3SAlexander Aring 		ret = drv_set_pan_id(local, addr_filt->pan_id);
143*ac8037c3SAlexander Aring 		if (ret < 0)
144*ac8037c3SAlexander Aring 			return ret;
145*ac8037c3SAlexander Aring 
146*ac8037c3SAlexander Aring 		ret = drv_set_short_addr(local, addr_filt->short_addr);
147*ac8037c3SAlexander Aring 		if (ret < 0)
148*ac8037c3SAlexander Aring 			return ret;
149*ac8037c3SAlexander Aring 
150*ac8037c3SAlexander Aring 		ret = drv_set_extended_addr(local, addr_filt->ieee_addr);
151*ac8037c3SAlexander Aring 		if (ret < 0)
152*ac8037c3SAlexander Aring 			return ret;
153*ac8037c3SAlexander Aring 	}
154*ac8037c3SAlexander Aring 
155*ac8037c3SAlexander Aring 	switch (level) {
156*ac8037c3SAlexander Aring 	case IEEE802154_FILTERING_NONE:
157*ac8037c3SAlexander Aring 		fallthrough;
158*ac8037c3SAlexander Aring 	case IEEE802154_FILTERING_1_FCS:
159*ac8037c3SAlexander Aring 		fallthrough;
160*ac8037c3SAlexander Aring 	case IEEE802154_FILTERING_2_PROMISCUOUS:
161*ac8037c3SAlexander Aring 		/* TODO: Requires a different receive mode setup e.g.
162*ac8037c3SAlexander Aring 		 * at86rf233 hardware.
163*ac8037c3SAlexander Aring 		 */
164*ac8037c3SAlexander Aring 		fallthrough;
165*ac8037c3SAlexander Aring 	case IEEE802154_FILTERING_3_SCAN:
166*ac8037c3SAlexander Aring 		if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) {
167*ac8037c3SAlexander Aring 			ret = drv_set_promiscuous_mode(local, true);
168*ac8037c3SAlexander Aring 			if (ret < 0)
169*ac8037c3SAlexander Aring 				return ret;
170*ac8037c3SAlexander Aring 		} else {
171*ac8037c3SAlexander Aring 			return -EOPNOTSUPP;
172*ac8037c3SAlexander Aring 		}
173*ac8037c3SAlexander Aring 
174*ac8037c3SAlexander Aring 		/* In practice other filtering levels can be requested, but as
175*ac8037c3SAlexander Aring 		 * for now most hardware/drivers only support
176*ac8037c3SAlexander Aring 		 * IEEE802154_FILTERING_NONE, we fallback to this actual
177*ac8037c3SAlexander Aring 		 * filtering level in hardware and make our own additional
178*ac8037c3SAlexander Aring 		 * filtering in mac802154 receive path.
179*ac8037c3SAlexander Aring 		 *
180*ac8037c3SAlexander Aring 		 * TODO: Move this logic to the device drivers as hardware may
181*ac8037c3SAlexander Aring 		 * support more higher level filters. Hardware may also require
182*ac8037c3SAlexander Aring 		 * a different order how register are set, which could currently
183*ac8037c3SAlexander Aring 		 * be buggy, so all received parameters need to be moved to the
184*ac8037c3SAlexander Aring 		 * start() callback and let the driver go into the mode before
185*ac8037c3SAlexander Aring 		 * it will turn on receive handling.
186*ac8037c3SAlexander Aring 		 */
187*ac8037c3SAlexander Aring 		local->phy->filtering = IEEE802154_FILTERING_NONE;
188*ac8037c3SAlexander Aring 		break;
189*ac8037c3SAlexander Aring 	case IEEE802154_FILTERING_4_FRAME_FIELDS:
190*ac8037c3SAlexander Aring 		/* Do not error out if IEEE802154_HW_PROMISCUOUS because we
191*ac8037c3SAlexander Aring 		 * expect the hardware to operate at the level
192*ac8037c3SAlexander Aring 		 * IEEE802154_FILTERING_4_FRAME_FIELDS anyway.
193*ac8037c3SAlexander Aring 		 */
194*ac8037c3SAlexander Aring 		if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) {
195*ac8037c3SAlexander Aring 			ret = drv_set_promiscuous_mode(local, false);
196*ac8037c3SAlexander Aring 			if (ret < 0)
197*ac8037c3SAlexander Aring 				return ret;
198*ac8037c3SAlexander Aring 		}
199*ac8037c3SAlexander Aring 
200*ac8037c3SAlexander Aring 		local->phy->filtering = IEEE802154_FILTERING_4_FRAME_FIELDS;
201*ac8037c3SAlexander Aring 		break;
202*ac8037c3SAlexander Aring 	default:
203*ac8037c3SAlexander Aring 		WARN_ON(1);
204*ac8037c3SAlexander Aring 		return -EINVAL;
205*ac8037c3SAlexander Aring 	}
206*ac8037c3SAlexander Aring 
2070ecc4e68SVarka Bhadram 	trace_802154_drv_start(local);
208e363eca3SAlexander Aring 	local->started = true;
209538181a8SAlexander Aring 	smp_mb();
2100ecc4e68SVarka Bhadram 	ret = local->ops->start(&local->hw);
2110ecc4e68SVarka Bhadram 	trace_802154_drv_return_int(local, ret);
2120ecc4e68SVarka Bhadram 	return ret;
213b6eea9caSAlexander Aring }
214b6eea9caSAlexander Aring 
drv_stop(struct ieee802154_local * local)215b6eea9caSAlexander Aring static inline void drv_stop(struct ieee802154_local *local)
216b6eea9caSAlexander Aring {
217b6eea9caSAlexander Aring 	might_sleep();
218b6eea9caSAlexander Aring 
2190ecc4e68SVarka Bhadram 	trace_802154_drv_stop(local);
220b6eea9caSAlexander Aring 	local->ops->stop(&local->hw);
2210ecc4e68SVarka Bhadram 	trace_802154_drv_return_void(local);
222e363eca3SAlexander Aring 
223538181a8SAlexander Aring 	/* sync away all work on the tasklet before clearing started */
224538181a8SAlexander Aring 	tasklet_disable(&local->tasklet);
225538181a8SAlexander Aring 	tasklet_enable(&local->tasklet);
226538181a8SAlexander Aring 
227538181a8SAlexander Aring 	barrier();
228538181a8SAlexander Aring 
229e363eca3SAlexander Aring 	local->started = false;
230b6eea9caSAlexander Aring }
231b6eea9caSAlexander Aring 
23229cd54b9SAlexander Aring static inline int
drv_set_channel(struct ieee802154_local * local,u8 page,u8 channel)23329cd54b9SAlexander Aring drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel)
234b6eea9caSAlexander Aring {
2350ecc4e68SVarka Bhadram 	int ret;
2360ecc4e68SVarka Bhadram 
237b6eea9caSAlexander Aring 	might_sleep();
238b6eea9caSAlexander Aring 
2390ecc4e68SVarka Bhadram 	trace_802154_drv_set_channel(local, page, channel);
2400ecc4e68SVarka Bhadram 	ret = local->ops->set_channel(&local->hw, page, channel);
2410ecc4e68SVarka Bhadram 	trace_802154_drv_return_int(local, ret);
2420ecc4e68SVarka Bhadram 	return ret;
243b6eea9caSAlexander Aring }
244b6eea9caSAlexander Aring 
drv_set_tx_power(struct ieee802154_local * local,s32 mbm)245e2eb173aSAlexander Aring static inline int drv_set_tx_power(struct ieee802154_local *local, s32 mbm)
246b6eea9caSAlexander Aring {
2470ecc4e68SVarka Bhadram 	int ret;
2480ecc4e68SVarka Bhadram 
249b6eea9caSAlexander Aring 	might_sleep();
250b6eea9caSAlexander Aring 
251b6eea9caSAlexander Aring 	if (!local->ops->set_txpower) {
252b6eea9caSAlexander Aring 		WARN_ON(1);
253b6eea9caSAlexander Aring 		return -EOPNOTSUPP;
254b6eea9caSAlexander Aring 	}
255b6eea9caSAlexander Aring 
2560ecc4e68SVarka Bhadram 	trace_802154_drv_set_tx_power(local, mbm);
2570ecc4e68SVarka Bhadram 	ret = local->ops->set_txpower(&local->hw, mbm);
2580ecc4e68SVarka Bhadram 	trace_802154_drv_return_int(local, ret);
2590ecc4e68SVarka Bhadram 	return ret;
260b6eea9caSAlexander Aring }
261b6eea9caSAlexander Aring 
drv_set_cca_mode(struct ieee802154_local * local,const struct wpan_phy_cca * cca)2627fe9a388SAlexander Aring static inline int drv_set_cca_mode(struct ieee802154_local *local,
2637fe9a388SAlexander Aring 				   const struct wpan_phy_cca *cca)
264b6eea9caSAlexander Aring {
2650ecc4e68SVarka Bhadram 	int ret;
2660ecc4e68SVarka Bhadram 
267b6eea9caSAlexander Aring 	might_sleep();
268b6eea9caSAlexander Aring 
269b6eea9caSAlexander Aring 	if (!local->ops->set_cca_mode) {
270b6eea9caSAlexander Aring 		WARN_ON(1);
271b6eea9caSAlexander Aring 		return -EOPNOTSUPP;
272b6eea9caSAlexander Aring 	}
273b6eea9caSAlexander Aring 
2740ecc4e68SVarka Bhadram 	trace_802154_drv_set_cca_mode(local, cca);
2750ecc4e68SVarka Bhadram 	ret = local->ops->set_cca_mode(&local->hw, cca);
2760ecc4e68SVarka Bhadram 	trace_802154_drv_return_int(local, ret);
2770ecc4e68SVarka Bhadram 	return ret;
278b6eea9caSAlexander Aring }
279b6eea9caSAlexander Aring 
drv_set_lbt_mode(struct ieee802154_local * local,bool mode)28029cd54b9SAlexander Aring static inline int drv_set_lbt_mode(struct ieee802154_local *local, bool mode)
281b6eea9caSAlexander Aring {
2820ecc4e68SVarka Bhadram 	int ret;
2830ecc4e68SVarka Bhadram 
284b6eea9caSAlexander Aring 	might_sleep();
285b6eea9caSAlexander Aring 
286b6eea9caSAlexander Aring 	if (!local->ops->set_lbt) {
287b6eea9caSAlexander Aring 		WARN_ON(1);
288b6eea9caSAlexander Aring 		return -EOPNOTSUPP;
289b6eea9caSAlexander Aring 	}
290b6eea9caSAlexander Aring 
2910ecc4e68SVarka Bhadram 	trace_802154_drv_set_lbt_mode(local, mode);
2920ecc4e68SVarka Bhadram 	ret = local->ops->set_lbt(&local->hw, mode);
2930ecc4e68SVarka Bhadram 	trace_802154_drv_return_int(local, ret);
2940ecc4e68SVarka Bhadram 	return ret;
295b6eea9caSAlexander Aring }
296b6eea9caSAlexander Aring 
29729cd54b9SAlexander Aring static inline int
drv_set_cca_ed_level(struct ieee802154_local * local,s32 mbm)29832b23550SAlexander Aring drv_set_cca_ed_level(struct ieee802154_local *local, s32 mbm)
299b6eea9caSAlexander Aring {
3000ecc4e68SVarka Bhadram 	int ret;
3010ecc4e68SVarka Bhadram 
302b6eea9caSAlexander Aring 	might_sleep();
303b6eea9caSAlexander Aring 
304b6eea9caSAlexander Aring 	if (!local->ops->set_cca_ed_level) {
305b6eea9caSAlexander Aring 		WARN_ON(1);
306b6eea9caSAlexander Aring 		return -EOPNOTSUPP;
307b6eea9caSAlexander Aring 	}
308b6eea9caSAlexander Aring 
3090ecc4e68SVarka Bhadram 	trace_802154_drv_set_cca_ed_level(local, mbm);
3100ecc4e68SVarka Bhadram 	ret = local->ops->set_cca_ed_level(&local->hw, mbm);
3110ecc4e68SVarka Bhadram 	trace_802154_drv_return_int(local, ret);
3120ecc4e68SVarka Bhadram 	return ret;
313b6eea9caSAlexander Aring }
314b6eea9caSAlexander Aring 
31529cd54b9SAlexander Aring static inline int
drv_set_csma_params(struct ieee802154_local * local,u8 min_be,u8 max_be,u8 max_csma_backoffs)31629cd54b9SAlexander Aring drv_set_csma_params(struct ieee802154_local *local, u8 min_be, u8 max_be,
317b6eea9caSAlexander Aring 		    u8 max_csma_backoffs)
318b6eea9caSAlexander Aring {
3190ecc4e68SVarka Bhadram 	int ret;
3200ecc4e68SVarka Bhadram 
321b6eea9caSAlexander Aring 	might_sleep();
322b6eea9caSAlexander Aring 
323b6eea9caSAlexander Aring 	if (!local->ops->set_csma_params) {
324b6eea9caSAlexander Aring 		WARN_ON(1);
325b6eea9caSAlexander Aring 		return -EOPNOTSUPP;
326b6eea9caSAlexander Aring 	}
327b6eea9caSAlexander Aring 
3280ecc4e68SVarka Bhadram 	trace_802154_drv_set_csma_params(local, min_be, max_be,
329b6eea9caSAlexander Aring 					 max_csma_backoffs);
3300ecc4e68SVarka Bhadram 	ret = local->ops->set_csma_params(&local->hw, min_be, max_be,
3310ecc4e68SVarka Bhadram 					   max_csma_backoffs);
3320ecc4e68SVarka Bhadram 	trace_802154_drv_return_int(local, ret);
3330ecc4e68SVarka Bhadram 	return ret;
334b6eea9caSAlexander Aring }
335b6eea9caSAlexander Aring 
33629cd54b9SAlexander Aring static inline int
drv_set_max_frame_retries(struct ieee802154_local * local,s8 max_frame_retries)33729cd54b9SAlexander Aring drv_set_max_frame_retries(struct ieee802154_local *local, s8 max_frame_retries)
338b6eea9caSAlexander Aring {
3390ecc4e68SVarka Bhadram 	int ret;
3400ecc4e68SVarka Bhadram 
341b6eea9caSAlexander Aring 	might_sleep();
342b6eea9caSAlexander Aring 
343b6eea9caSAlexander Aring 	if (!local->ops->set_frame_retries) {
344b6eea9caSAlexander Aring 		WARN_ON(1);
345b6eea9caSAlexander Aring 		return -EOPNOTSUPP;
346b6eea9caSAlexander Aring 	}
347b6eea9caSAlexander Aring 
3480ecc4e68SVarka Bhadram 	trace_802154_drv_set_max_frame_retries(local, max_frame_retries);
3490ecc4e68SVarka Bhadram 	ret = local->ops->set_frame_retries(&local->hw, max_frame_retries);
3500ecc4e68SVarka Bhadram 	trace_802154_drv_return_int(local, ret);
3510ecc4e68SVarka Bhadram 	return ret;
352b6eea9caSAlexander Aring }
353b6eea9caSAlexander Aring 
354ea6edfbcSNicolas Iooss #endif /* __MAC802154_DRIVER_OPS */
355