blob: d23f0db98015a6fdc421f9a0b1b17acb2b1b1da0 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Nicolas Ioossea6edfb2015-03-19 21:23:40 +08002#ifndef __MAC802154_DRIVER_OPS
Alexander Aringb6eea9c2014-10-28 18:21:20 +01003#define __MAC802154_DRIVER_OPS
4
5#include <linux/types.h>
6#include <linux/rtnetlink.h>
7
8#include <net/mac802154.h>
9
10#include "ieee802154_i.h"
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053011#include "trace.h"
Alexander Aringb6eea9c2014-10-28 18:21:20 +010012
13static inline int
14drv_xmit_async(struct ieee802154_local *local, struct sk_buff *skb)
15{
16 return local->ops->xmit_async(&local->hw, skb);
17}
18
19static inline int
20drv_xmit_sync(struct ieee802154_local *local, struct sk_buff *skb)
21{
Alexander Aringb6eea9c2014-10-28 18:21:20 +010022 might_sleep();
23
24 return local->ops->xmit_sync(&local->hw, skb);
25}
26
27static inline int drv_start(struct ieee802154_local *local)
28{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053029 int ret;
30
Alexander Aringb6eea9c2014-10-28 18:21:20 +010031 might_sleep();
32
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053033 trace_802154_drv_start(local);
Alexander Aringe363eca2014-10-28 18:21:26 +010034 local->started = true;
Alexander Aring538181a2014-10-28 18:21:27 +010035 smp_mb();
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053036 ret = local->ops->start(&local->hw);
37 trace_802154_drv_return_int(local, ret);
38 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +010039}
40
41static inline void drv_stop(struct ieee802154_local *local)
42{
43 might_sleep();
44
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053045 trace_802154_drv_stop(local);
Alexander Aringb6eea9c2014-10-28 18:21:20 +010046 local->ops->stop(&local->hw);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053047 trace_802154_drv_return_void(local);
Alexander Aringe363eca2014-10-28 18:21:26 +010048
Alexander Aring538181a2014-10-28 18:21:27 +010049 /* sync away all work on the tasklet before clearing started */
50 tasklet_disable(&local->tasklet);
51 tasklet_enable(&local->tasklet);
52
53 barrier();
54
Alexander Aringe363eca2014-10-28 18:21:26 +010055 local->started = false;
Alexander Aringb6eea9c2014-10-28 18:21:20 +010056}
57
Alexander Aring29cd54b2014-11-17 08:20:45 +010058static inline int
59drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel)
Alexander Aringb6eea9c2014-10-28 18:21:20 +010060{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053061 int ret;
62
Alexander Aringb6eea9c2014-10-28 18:21:20 +010063 might_sleep();
64
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053065 trace_802154_drv_set_channel(local, page, channel);
66 ret = local->ops->set_channel(&local->hw, page, channel);
67 trace_802154_drv_return_int(local, ret);
68 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +010069}
70
Alexander Aringe2eb1732015-05-17 21:44:40 +020071static inline int drv_set_tx_power(struct ieee802154_local *local, s32 mbm)
Alexander Aringb6eea9c2014-10-28 18:21:20 +010072{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053073 int ret;
74
Alexander Aringb6eea9c2014-10-28 18:21:20 +010075 might_sleep();
76
77 if (!local->ops->set_txpower) {
78 WARN_ON(1);
79 return -EOPNOTSUPP;
80 }
81
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053082 trace_802154_drv_set_tx_power(local, mbm);
83 ret = local->ops->set_txpower(&local->hw, mbm);
84 trace_802154_drv_return_int(local, ret);
85 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +010086}
87
Alexander Aring7fe9a382014-12-10 15:33:12 +010088static inline int drv_set_cca_mode(struct ieee802154_local *local,
89 const struct wpan_phy_cca *cca)
Alexander Aringb6eea9c2014-10-28 18:21:20 +010090{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053091 int ret;
92
Alexander Aringb6eea9c2014-10-28 18:21:20 +010093 might_sleep();
94
95 if (!local->ops->set_cca_mode) {
96 WARN_ON(1);
97 return -EOPNOTSUPP;
98 }
99
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530100 trace_802154_drv_set_cca_mode(local, cca);
101 ret = local->ops->set_cca_mode(&local->hw, cca);
102 trace_802154_drv_return_int(local, ret);
103 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100104}
105
Alexander Aring29cd54b2014-11-17 08:20:45 +0100106static inline int drv_set_lbt_mode(struct ieee802154_local *local, bool mode)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100107{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530108 int ret;
109
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100110 might_sleep();
111
112 if (!local->ops->set_lbt) {
113 WARN_ON(1);
114 return -EOPNOTSUPP;
115 }
116
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530117 trace_802154_drv_set_lbt_mode(local, mode);
118 ret = local->ops->set_lbt(&local->hw, mode);
119 trace_802154_drv_return_int(local, ret);
120 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100121}
122
Alexander Aring29cd54b2014-11-17 08:20:45 +0100123static inline int
Alexander Aring32b23552015-05-17 21:44:41 +0200124drv_set_cca_ed_level(struct ieee802154_local *local, s32 mbm)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100125{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530126 int ret;
127
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100128 might_sleep();
129
130 if (!local->ops->set_cca_ed_level) {
131 WARN_ON(1);
132 return -EOPNOTSUPP;
133 }
134
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530135 trace_802154_drv_set_cca_ed_level(local, mbm);
136 ret = local->ops->set_cca_ed_level(&local->hw, mbm);
137 trace_802154_drv_return_int(local, ret);
138 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100139}
140
Alexander Aring29cd54b2014-11-17 08:20:45 +0100141static inline int drv_set_pan_id(struct ieee802154_local *local, __le16 pan_id)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100142{
143 struct ieee802154_hw_addr_filt filt;
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530144 int ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100145
146 might_sleep();
147
148 if (!local->ops->set_hw_addr_filt) {
149 WARN_ON(1);
150 return -EOPNOTSUPP;
151 }
152
153 filt.pan_id = pan_id;
154
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530155 trace_802154_drv_set_pan_id(local, pan_id);
156 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100157 IEEE802154_AFILT_PANID_CHANGED);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530158 trace_802154_drv_return_int(local, ret);
159 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100160}
161
Alexander Aring29cd54b2014-11-17 08:20:45 +0100162static inline int
163drv_set_extended_addr(struct ieee802154_local *local, __le64 extended_addr)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100164{
165 struct ieee802154_hw_addr_filt filt;
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530166 int ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100167
168 might_sleep();
169
170 if (!local->ops->set_hw_addr_filt) {
171 WARN_ON(1);
172 return -EOPNOTSUPP;
173 }
174
175 filt.ieee_addr = extended_addr;
176
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530177 trace_802154_drv_set_extended_addr(local, extended_addr);
178 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100179 IEEE802154_AFILT_IEEEADDR_CHANGED);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530180 trace_802154_drv_return_int(local, ret);
181 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100182}
183
Alexander Aring29cd54b2014-11-17 08:20:45 +0100184static inline int
185drv_set_short_addr(struct ieee802154_local *local, __le16 short_addr)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100186{
187 struct ieee802154_hw_addr_filt filt;
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530188 int ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100189
190 might_sleep();
191
192 if (!local->ops->set_hw_addr_filt) {
193 WARN_ON(1);
194 return -EOPNOTSUPP;
195 }
196
197 filt.short_addr = short_addr;
198
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530199 trace_802154_drv_set_short_addr(local, short_addr);
200 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100201 IEEE802154_AFILT_SADDR_CHANGED);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530202 trace_802154_drv_return_int(local, ret);
203 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100204}
205
Alexander Aring29cd54b2014-11-17 08:20:45 +0100206static inline int
207drv_set_pan_coord(struct ieee802154_local *local, bool is_coord)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100208{
209 struct ieee802154_hw_addr_filt filt;
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530210 int ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100211
212 might_sleep();
213
214 if (!local->ops->set_hw_addr_filt) {
215 WARN_ON(1);
216 return -EOPNOTSUPP;
217 }
218
219 filt.pan_coord = is_coord;
220
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530221 trace_802154_drv_set_pan_coord(local, is_coord);
222 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100223 IEEE802154_AFILT_PANC_CHANGED);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530224 trace_802154_drv_return_int(local, ret);
225 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100226}
227
Alexander Aring29cd54b2014-11-17 08:20:45 +0100228static inline int
229drv_set_csma_params(struct ieee802154_local *local, u8 min_be, u8 max_be,
230 u8 max_csma_backoffs)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100231{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530232 int ret;
233
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100234 might_sleep();
235
236 if (!local->ops->set_csma_params) {
237 WARN_ON(1);
238 return -EOPNOTSUPP;
239 }
240
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530241 trace_802154_drv_set_csma_params(local, min_be, max_be,
242 max_csma_backoffs);
243 ret = local->ops->set_csma_params(&local->hw, min_be, max_be,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100244 max_csma_backoffs);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530245 trace_802154_drv_return_int(local, ret);
246 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100247}
248
Alexander Aring29cd54b2014-11-17 08:20:45 +0100249static inline int
250drv_set_max_frame_retries(struct ieee802154_local *local, s8 max_frame_retries)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100251{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530252 int ret;
253
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100254 might_sleep();
255
256 if (!local->ops->set_frame_retries) {
257 WARN_ON(1);
258 return -EOPNOTSUPP;
259 }
260
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530261 trace_802154_drv_set_max_frame_retries(local, max_frame_retries);
262 ret = local->ops->set_frame_retries(&local->hw, max_frame_retries);
263 trace_802154_drv_return_int(local, ret);
264 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100265}
266
Alexander Aring29cd54b2014-11-17 08:20:45 +0100267static inline int
268drv_set_promiscuous_mode(struct ieee802154_local *local, bool on)
Alexander Aring94b79222014-10-29 21:34:32 +0100269{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530270 int ret;
271
Alexander Aring94b79222014-10-29 21:34:32 +0100272 might_sleep();
273
274 if (!local->ops->set_promiscuous_mode) {
275 WARN_ON(1);
276 return -EOPNOTSUPP;
277 }
278
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530279 trace_802154_drv_set_promiscuous_mode(local, on);
280 ret = local->ops->set_promiscuous_mode(&local->hw, on);
281 trace_802154_drv_return_int(local, ret);
282 return ret;
Alexander Aring94b79222014-10-29 21:34:32 +0100283}
284
Nicolas Ioossea6edfb2015-03-19 21:23:40 +0800285#endif /* __MAC802154_DRIVER_OPS */