add wireless measurement probe infrastructure, developed at Fraunhofer FOKUS
[openwrt/openwrt.git] / package / wprobe / src / kernel / linux / wprobe.h
1 /*
2 * wprobe.h: API for the wireless probe interface
3 * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16 #ifndef __WPROBE_H
17 #define __WPROBE_H
18
19 #ifdef __KERNEL__
20 #include <linux/types.h>
21 #include <linux/if_ether.h>
22 #include <linux/spinlock.h>
23 #include <linux/module.h>
24 #include <linux/list.h>
25 #include <net/genetlink.h>
26 #endif
27
28 /**
29 * enum wprobe_attr: netlink attribute list
30 *
31 * @WPROBE_ATTR_UNSPEC: unused
32 *
33 * @WPROBE_ATTR_INTERFACE: interface name to process query on (NLA_STRING)
34 * @WPROBE_ATTR_MAC: mac address (used for wireless links) (NLA_STRING)
35 * @WPROBE_ATTR_FLAGS: interface/link/attribute flags (see enum wprobe_flags) (NLA_U32)
36 * @WPROBE_ATTR_DURATION: sampling duration (in milliseconds) (NLA_MSECS)
37 *
38 * @WPROBE_ATTR_ID: attribute id (NLA_U32)
39 * @WPROBE_ATTR_NAME: attribute name (NLA_STRING)
40 * @WPROBE_ATTR_TYPE: attribute type (NLA_U8)
41 * @WPROBE_ATTR_SCALE: attribute scale factor (NLA_U32)
42 *
43 * attribute values:
44 *
45 * @WPROBE_VAL_STRING: string value (NLA_STRING)
46 * @WPROBE_VAL_S8: signed 8-bit integer (NLA_U8)
47 * @WPROBE_VAL_S16: signed 16-bit integer (NLA_U16)
48 * @WPROBE_VAL_S32: signed 32-bit integer (NLA_U32)
49 * @WPROBE_VAL_S64: signed 64-bit integer (NLA_U64)
50 * @WPROBE_VAL_U8: unsigned 8-bit integer (NLA_U8)
51 * @WPROBE_VAL_U16: unsigned 16-bit integer (NLA_U16)
52 * @WPROBE_VAL_U32: unsigned 32-bit integer (NLA_U32)
53 * @WPROBE_VAL_U64: unsigned 64-bit integer (NLA_U64)
54 *
55 * statistics:
56 * @WPROBE_VAL_SUM: sum of all samples
57 * @WPROBE_VAL_SUM_SQ: sum of all samples^2
58 * @WPROBE_VAL_SAMPLES: number of samples
59 *
60 * @WPROBE_ATTR_LAST: unused
61 */
62 enum wprobe_attr {
63 WPROBE_ATTR_UNSPEC,
64 WPROBE_ATTR_INTERFACE,
65 WPROBE_ATTR_MAC,
66 WPROBE_ATTR_FLAGS,
67 WPROBE_ATTR_DURATION,
68 WPROBE_ATTR_SCALE,
69 /* end of query attributes */
70
71 /* response data */
72 WPROBE_ATTR_ID,
73 WPROBE_ATTR_NAME,
74 WPROBE_ATTR_TYPE,
75
76 /* value type attributes */
77 WPROBE_VAL_STRING,
78 WPROBE_VAL_S8,
79 WPROBE_VAL_S16,
80 WPROBE_VAL_S32,
81 WPROBE_VAL_S64,
82 WPROBE_VAL_U8,
83 WPROBE_VAL_U16,
84 WPROBE_VAL_U32,
85 WPROBE_VAL_U64,
86
87 /* aggregates for statistics */
88 WPROBE_VAL_SUM,
89 WPROBE_VAL_SUM_SQ,
90 WPROBE_VAL_SAMPLES,
91
92 WPROBE_ATTR_LAST
93 };
94
95
96 /**
97 * enum wprobe_cmd: netlink commands for interacting with wprobe
98 *
99 * @WPROBE_CMD_UNSPEC: unused
100 *
101 * @WPROBE_CMD_GET_LIST: get global/link property list
102 * @WPROBE_CMD_GET_INFO: get global/link properties
103 * @WPROBE_CMD_SET_FLAGS: set global/link flags
104 * @WPROBE_CMD_MEASURE: take a snapshot of the current data
105 * @WPROBE_CMD_GET_LINKS: get a list of links
106 *
107 * @WPROBE_CMD_LAST: unused
108 *
109 * options for GET_INFO and SET_FLAGS:
110 * - mac address set: per-link
111 * - mac address unset: globalsa
112 */
113 enum wprobe_cmd {
114 WPROBE_CMD_UNSPEC,
115 WPROBE_CMD_GET_LIST,
116 WPROBE_CMD_GET_INFO,
117 WPROBE_CMD_SET_FLAGS,
118 WPROBE_CMD_MEASURE,
119 WPROBE_CMD_GET_LINKS,
120 WPROBE_CMD_LAST
121 };
122
123 /**
124 * enum wprobe_flags: flags for wprobe links and items
125 * @WPROBE_F_KEEPSTAT: keep statistics for this link/device
126 * @WPROBE_F_RESET: reset statistics now (used only in WPROBE_CMD_SET_LINK)
127 * @WPROBE_F_NEWDATA: used to indicate that a value has been updated
128 */
129 enum wprobe_flags {
130 WPROBE_F_KEEPSTAT = (1 << 0),
131 WPROBE_F_RESET = (1 << 1),
132 WPROBE_F_NEWDATA = (1 << 2),
133 };
134
135 #ifdef __KERNEL__
136
137 struct wprobe_link;
138 struct wprobe_item;
139 struct wprobe_source;
140
141 /**
142 * struct wprobe_link - data structure describing a wireless link
143 * @iface: pointer to the wprobe_iface that this link belongs to
144 * @addr: BSSID of the remote link partner
145 * @flags: link flags (see wprobe_flags)
146 * @priv: user pointer
147 *
148 * @list: for internal use
149 * @val: for internal use
150 */
151 struct wprobe_link {
152 struct list_head list;
153 struct wprobe_iface *iface;
154 char addr[ETH_ALEN];
155 u32 flags;
156 void *priv;
157 void *val;
158 };
159
160 /**
161 * struct wprobe_item - data structure describing the format of wprobe_link::data or wprobe_iface::data
162 * @name: name of the field
163 * @type: data type of this field
164 * @flags: measurement item flags (see wprobe_flags)
165 */
166 struct wprobe_item {
167 const char *name;
168 enum wprobe_attr type;
169 u32 flags;
170 };
171
172 struct wprobe_value {
173 bool pending;
174 union {
175 /*
176 * the following are kept uppercase to allow
177 * for automated checking against WPROBE_VAL_*
178 * via BUG_ON()
179 */
180 const char *STRING;
181 u8 U8;
182 u16 U16;
183 u32 U32;
184 u64 U64;
185 s8 S8;
186 s16 S16;
187 s32 S32;
188 s64 S64;
189 };
190 s64 s, ss;
191 unsigned int n;
192
193 /* timestamps */
194 u64 first, last;
195 };
196
197 /**
198 * struct wprobe_source - data structure describing a wireless interface
199 *
200 * @name: name of the interface
201 * @addr: local mac address of the interface
202 * @links: list of wireless links to poll
203 * @link_items: description of the per-link data structure
204 * @n_link_items: number of link description items
205 * @global_items: description of the per-interface data structure
206 * @n_global_items: number of per-interface description items
207 * @sync_data: callback allowing the driver to prepare data for the wprobe poll
208 *
209 * @list: head for the list of interfaces
210 * @priv: user pointer
211 * @lock: spinlock protecting value data access
212 * @val: internal use
213 * @query_val: internal use
214 *
215 * if sync_data is NULL, wprobe assumes that it can access the data structure
216 * at any time (in atomic context). if sync_data returns a negative error code,
217 * the poll request will not be handled for the given link
218 */
219 struct wprobe_iface {
220 /* to be filled in by wprobe source drivers */
221 const char *name;
222 const char *addr;
223 const struct wprobe_item *link_items;
224 int n_link_items;
225 const struct wprobe_item *global_items;
226 int n_global_items;
227
228 int (*sync_data)(struct wprobe_iface *dev, struct wprobe_link *l, struct wprobe_value *val, bool measure);
229 void *priv;
230
231 /* handled by the wprobe core */
232 struct list_head list;
233 struct list_head links;
234 spinlock_t lock;
235 void *val;
236 void *query_val;
237 };
238
239 #define WPROBE_FILL_BEGIN(_ptr, _list) do { \
240 struct wprobe_value *__val = (_ptr); \
241 const struct wprobe_item *__item = _list; \
242 u64 __msecs = jiffies_to_msecs(jiffies)
243
244 #define WPROBE_SET(_idx, _type, _value) \
245 if (__item[_idx].type != WPROBE_VAL_##_type) { \
246 printk("ERROR: invalid data type at %s:%d\n", __FILE__, __LINE__); \
247 break; \
248 } \
249 __val[_idx].pending = true; \
250 __val[_idx]._type = _value; \
251 if (!__val[_idx].first) \
252 __val[_idx].first = __msecs; \
253 __val[_idx].first = __msecs
254
255 #define WPROBE_FILL_END() \
256 } while(0)
257
258 /**
259 * wprobe_add_iface: register an interface with the wireless probe subsystem
260 * @dev: wprobe_iface structure describing the interface
261 */
262 extern int __weak wprobe_add_iface(struct wprobe_iface *dev);
263
264 /**
265 * wprobe_remove_iface: deregister an interface from the wireless probe subsystem
266 * @dev: wprobe_iface structure describing the interface
267 */
268 extern void __weak wprobe_remove_iface(struct wprobe_iface *dev);
269
270 /**
271 * wprobe_add_link: register a new wireless link
272 * @dev: wprobe_iface structure describing the interface
273 * @l: storage space for the wprobe_link structure
274 * @addr: mac address of the new link
275 *
276 * the entire wprobe_link structure is overwritten by this function call
277 */
278 extern int __weak wprobe_add_link(struct wprobe_iface *dev, struct wprobe_link *l, const char *addr);
279
280 /**
281 * wprobe_remove_link: deregister a previously registered wireless link
282 * @dev: wprobe_iface structure describing the interface
283 * @l: wprobe_link data structure
284 */
285 extern void __weak wprobe_remove_link(struct wprobe_iface *dev, struct wprobe_link *l);
286
287 /**
288 * wprobe_update_stats: update statistics after sampling values
289 * @dev: wprobe_iface structure describing the interface
290 * @l: wprobe_link data structure
291 *
292 * if l == NULL, then the stats for globals are updated
293 */
294 extern void __weak wprobe_update_stats(struct wprobe_iface *dev, struct wprobe_link *l);
295
296 #endif /* __KERNEL__ */
297
298 #endif