blob: fd9daf2ecec97a31c375b491739bd241b109b1c5 [file] [log] [blame]
Nicolas Ioossea6edfb2015-03-19 21:23:40 +08001#ifndef __MAC802154_DRIVER_OPS
Alexander Aringb6eea9c2014-10-28 18:21:20 +01002#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"
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053010#include "trace.h"
Alexander Aringb6eea9c2014-10-28 18:21:20 +010011
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{
Alexander Aringb6eea9c2014-10-28 18:21:20 +010021 might_sleep();
22
23 return local->ops->xmit_sync(&local->hw, skb);
24}
25
26static inline int drv_start(struct ieee802154_local *local)
27{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053028 int ret;
29
Alexander Aringb6eea9c2014-10-28 18:21:20 +010030 might_sleep();
31
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053032 trace_802154_drv_start(local);
Alexander Aringe363eca2014-10-28 18:21:26 +010033 local->started = true;
Alexander Aring538181a2014-10-28 18:21:27 +010034 smp_mb();
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053035 ret = local->ops->start(&local->hw);
36 trace_802154_drv_return_int(local, ret);
37 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +010038}
39
40static inline void drv_stop(struct ieee802154_local *local)
41{
42 might_sleep();
43
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053044 trace_802154_drv_stop(local);
Alexander Aringb6eea9c2014-10-28 18:21:20 +010045 local->ops->stop(&local->hw);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053046 trace_802154_drv_return_void(local);
Alexander Aringe363eca2014-10-28 18:21:26 +010047
Alexander Aring538181a2014-10-28 18:21:27 +010048 /* sync away all work on the tasklet before clearing started */
49 tasklet_disable(&local->tasklet);
50 tasklet_enable(&local->tasklet);
51
52 barrier();
53
Alexander Aringe363eca2014-10-28 18:21:26 +010054 local->started = false;
Alexander Aringb6eea9c2014-10-28 18:21:20 +010055}
56
Alexander Aring29cd54b2014-11-17 08:20:45 +010057static inline int
58drv_set_channel(struct ieee802154_local *local, u8 page, u8 channel)
Alexander Aringb6eea9c2014-10-28 18:21:20 +010059{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053060 int ret;
61
Alexander Aringb6eea9c2014-10-28 18:21:20 +010062 might_sleep();
63
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053064 trace_802154_drv_set_channel(local, page, channel);
65 ret = local->ops->set_channel(&local->hw, page, channel);
66 trace_802154_drv_return_int(local, ret);
67 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +010068}
69
Alexander Aringe2eb1732015-05-17 21:44:40 +020070static inline int drv_set_tx_power(struct ieee802154_local *local, s32 mbm)
Alexander Aringb6eea9c2014-10-28 18:21:20 +010071{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053072 int ret;
73
Alexander Aringb6eea9c2014-10-28 18:21:20 +010074 might_sleep();
75
76 if (!local->ops->set_txpower) {
77 WARN_ON(1);
78 return -EOPNOTSUPP;
79 }
80
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053081 trace_802154_drv_set_tx_power(local, mbm);
82 ret = local->ops->set_txpower(&local->hw, mbm);
83 trace_802154_drv_return_int(local, ret);
84 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +010085}
86
Alexander Aring7fe9a382014-12-10 15:33:12 +010087static inline int drv_set_cca_mode(struct ieee802154_local *local,
88 const struct wpan_phy_cca *cca)
Alexander Aringb6eea9c2014-10-28 18:21:20 +010089{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053090 int ret;
91
Alexander Aringb6eea9c2014-10-28 18:21:20 +010092 might_sleep();
93
94 if (!local->ops->set_cca_mode) {
95 WARN_ON(1);
96 return -EOPNOTSUPP;
97 }
98
Varka Bhadram0ecc4e62015-06-01 14:22:26 +053099 trace_802154_drv_set_cca_mode(local, cca);
100 ret = local->ops->set_cca_mode(&local->hw, cca);
101 trace_802154_drv_return_int(local, ret);
102 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100103}
104
Alexander Aring29cd54b2014-11-17 08:20:45 +0100105static inline int drv_set_lbt_mode(struct ieee802154_local *local, bool mode)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100106{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530107 int ret;
108
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100109 might_sleep();
110
111 if (!local->ops->set_lbt) {
112 WARN_ON(1);
113 return -EOPNOTSUPP;
114 }
115
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530116 trace_802154_drv_set_lbt_mode(local, mode);
117 ret = local->ops->set_lbt(&local->hw, mode);
118 trace_802154_drv_return_int(local, ret);
119 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100120}
121
Alexander Aring29cd54b2014-11-17 08:20:45 +0100122static inline int
Alexander Aring32b23552015-05-17 21:44:41 +0200123drv_set_cca_ed_level(struct ieee802154_local *local, s32 mbm)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100124{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530125 int ret;
126
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100127 might_sleep();
128
129 if (!local->ops->set_cca_ed_level) {
130 WARN_ON(1);
131 return -EOPNOTSUPP;
132 }
133
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530134 trace_802154_drv_set_cca_ed_level(local, mbm);
135 ret = local->ops->set_cca_ed_level(&local->hw, mbm);
136 trace_802154_drv_return_int(local, ret);
137 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100138}
139
Alexander Aring29cd54b2014-11-17 08:20:45 +0100140static inline int drv_set_pan_id(struct ieee802154_local *local, __le16 pan_id)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100141{
142 struct ieee802154_hw_addr_filt filt;
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530143 int ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100144
145 might_sleep();
146
147 if (!local->ops->set_hw_addr_filt) {
148 WARN_ON(1);
149 return -EOPNOTSUPP;
150 }
151
152 filt.pan_id = pan_id;
153
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530154 trace_802154_drv_set_pan_id(local, pan_id);
155 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100156 IEEE802154_AFILT_PANID_CHANGED);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530157 trace_802154_drv_return_int(local, ret);
158 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100159}
160
Alexander Aring29cd54b2014-11-17 08:20:45 +0100161static inline int
162drv_set_extended_addr(struct ieee802154_local *local, __le64 extended_addr)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100163{
164 struct ieee802154_hw_addr_filt filt;
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530165 int ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100166
167 might_sleep();
168
169 if (!local->ops->set_hw_addr_filt) {
170 WARN_ON(1);
171 return -EOPNOTSUPP;
172 }
173
174 filt.ieee_addr = extended_addr;
175
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530176 trace_802154_drv_set_extended_addr(local, extended_addr);
177 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100178 IEEE802154_AFILT_IEEEADDR_CHANGED);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530179 trace_802154_drv_return_int(local, ret);
180 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100181}
182
Alexander Aring29cd54b2014-11-17 08:20:45 +0100183static inline int
184drv_set_short_addr(struct ieee802154_local *local, __le16 short_addr)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100185{
186 struct ieee802154_hw_addr_filt filt;
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530187 int ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100188
189 might_sleep();
190
191 if (!local->ops->set_hw_addr_filt) {
192 WARN_ON(1);
193 return -EOPNOTSUPP;
194 }
195
196 filt.short_addr = short_addr;
197
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530198 trace_802154_drv_set_short_addr(local, short_addr);
199 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100200 IEEE802154_AFILT_SADDR_CHANGED);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530201 trace_802154_drv_return_int(local, ret);
202 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100203}
204
Alexander Aring29cd54b2014-11-17 08:20:45 +0100205static inline int
206drv_set_pan_coord(struct ieee802154_local *local, bool is_coord)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100207{
208 struct ieee802154_hw_addr_filt filt;
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530209 int ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100210
211 might_sleep();
212
213 if (!local->ops->set_hw_addr_filt) {
214 WARN_ON(1);
215 return -EOPNOTSUPP;
216 }
217
218 filt.pan_coord = is_coord;
219
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530220 trace_802154_drv_set_pan_coord(local, is_coord);
221 ret = local->ops->set_hw_addr_filt(&local->hw, &filt,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100222 IEEE802154_AFILT_PANC_CHANGED);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530223 trace_802154_drv_return_int(local, ret);
224 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100225}
226
Alexander Aring29cd54b2014-11-17 08:20:45 +0100227static inline int
228drv_set_csma_params(struct ieee802154_local *local, u8 min_be, u8 max_be,
229 u8 max_csma_backoffs)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100230{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530231 int ret;
232
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100233 might_sleep();
234
235 if (!local->ops->set_csma_params) {
236 WARN_ON(1);
237 return -EOPNOTSUPP;
238 }
239
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530240 trace_802154_drv_set_csma_params(local, min_be, max_be,
241 max_csma_backoffs);
242 ret = local->ops->set_csma_params(&local->hw, min_be, max_be,
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100243 max_csma_backoffs);
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530244 trace_802154_drv_return_int(local, ret);
245 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100246}
247
Alexander Aring29cd54b2014-11-17 08:20:45 +0100248static inline int
249drv_set_max_frame_retries(struct ieee802154_local *local, s8 max_frame_retries)
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100250{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530251 int ret;
252
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100253 might_sleep();
254
255 if (!local->ops->set_frame_retries) {
256 WARN_ON(1);
257 return -EOPNOTSUPP;
258 }
259
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530260 trace_802154_drv_set_max_frame_retries(local, max_frame_retries);
261 ret = local->ops->set_frame_retries(&local->hw, max_frame_retries);
262 trace_802154_drv_return_int(local, ret);
263 return ret;
Alexander Aringb6eea9c2014-10-28 18:21:20 +0100264}
265
Alexander Aring29cd54b2014-11-17 08:20:45 +0100266static inline int
267drv_set_promiscuous_mode(struct ieee802154_local *local, bool on)
Alexander Aring94b79222014-10-29 21:34:32 +0100268{
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530269 int ret;
270
Alexander Aring94b79222014-10-29 21:34:32 +0100271 might_sleep();
272
273 if (!local->ops->set_promiscuous_mode) {
274 WARN_ON(1);
275 return -EOPNOTSUPP;
276 }
277
Varka Bhadram0ecc4e62015-06-01 14:22:26 +0530278 trace_802154_drv_set_promiscuous_mode(local, on);
279 ret = local->ops->set_promiscuous_mode(&local->hw, on);
280 trace_802154_drv_return_int(local, ret);
281 return ret;
Alexander Aring94b79222014-10-29 21:34:32 +0100282}
283
Nicolas Ioossea6edfb2015-03-19 21:23:40 +0800284#endif /* __MAC802154_DRIVER_OPS */