1/*
2 * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
3 * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#ifndef RC80211_PID_H
11#define RC80211_PID_H
12
13/* Sampling period for measuring percentage of failed frames in ms. */
14#define RC_PID_INTERVAL			125
15
16/* Exponential averaging smoothness (used for I part of PID controller) */
17#define RC_PID_SMOOTHING_SHIFT		3
18#define RC_PID_SMOOTHING		(1 << RC_PID_SMOOTHING_SHIFT)
19
20/* Sharpening factor (used for D part of PID controller) */
21#define RC_PID_SHARPENING_FACTOR	0
22#define RC_PID_SHARPENING_DURATION	0
23
24/* Fixed point arithmetic shifting amount. */
25#define RC_PID_ARITH_SHIFT		8
26
27/* Proportional PID component coefficient. */
28#define RC_PID_COEFF_P			15
29/* Integral PID component coefficient. */
30#define RC_PID_COEFF_I			9
31/* Derivative PID component coefficient. */
32#define RC_PID_COEFF_D			15
33
34/* Target failed frames rate for the PID controller. NB: This effectively gives
35 * maximum failed frames percentage we're willing to accept. If the wireless
36 * link quality is good, the controller will fail to adjust failed frames
37 * percentage to the target. This is intentional.
38 */
39#define RC_PID_TARGET_PF		14
40
41/* Rate behaviour normalization quantity over time. */
42#define RC_PID_NORM_OFFSET		3
43
44/* Push high rates right after loading. */
45#define RC_PID_FAST_START		0
46
47/* Arithmetic right shift for positive and negative values for ISO C. */
48#define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
49	((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y))
50
51enum rc_pid_event_type {
52	RC_PID_EVENT_TYPE_TX_STATUS,
53	RC_PID_EVENT_TYPE_RATE_CHANGE,
54	RC_PID_EVENT_TYPE_TX_RATE,
55	RC_PID_EVENT_TYPE_PF_SAMPLE,
56};
57
58union rc_pid_event_data {
59	/* RC_PID_EVENT_TX_STATUS */
60	struct {
61		u32 flags;
62		struct ieee80211_tx_info tx_status;
63	};
64	/* RC_PID_EVENT_TYPE_RATE_CHANGE */
65	/* RC_PID_EVENT_TYPE_TX_RATE */
66	struct {
67		int index;
68		int rate;
69	};
70	/* RC_PID_EVENT_TYPE_PF_SAMPLE */
71	struct {
72		s32 pf_sample;
73		s32 prop_err;
74		s32 int_err;
75		s32 der_err;
76	};
77};
78
79struct rc_pid_event {
80	/* The time when the event occurred */
81	unsigned long timestamp;
82
83	/* Event ID number */
84	unsigned int id;
85
86	/* Type of event */
87	enum rc_pid_event_type type;
88
89	/* type specific data */
90	union rc_pid_event_data data;
91};
92
93/* Size of the event ring buffer. */
94#define RC_PID_EVENT_RING_SIZE 32
95
96struct rc_pid_event_buffer {
97	/* Counter that generates event IDs */
98	unsigned int ev_count;
99
100	/* Ring buffer of events */
101	struct rc_pid_event ring[RC_PID_EVENT_RING_SIZE];
102
103	/* Index to the entry in events_buf to be reused */
104	unsigned int next_entry;
105
106	/* Lock that guards against concurrent access to this buffer struct */
107	spinlock_t lock;
108
109	/* Wait queue for poll/select and blocking I/O */
110	wait_queue_head_t waitqueue;
111};
112
113struct rc_pid_events_file_info {
114	/* The event buffer we read */
115	struct rc_pid_event_buffer *events;
116
117	/* The entry we have should read next */
118	unsigned int next_entry;
119};
120
121/**
122 * struct rc_pid_debugfs_entries - tunable parameters
123 *
124 * Algorithm parameters, tunable via debugfs.
125 * @target: target percentage for failed frames
126 * @sampling_period: error sampling interval in milliseconds
127 * @coeff_p: absolute value of the proportional coefficient
128 * @coeff_i: absolute value of the integral coefficient
129 * @coeff_d: absolute value of the derivative coefficient
130 * @smoothing_shift: absolute value of the integral smoothing factor (i.e.
131 *	amount of smoothing introduced by the exponential moving average)
132 * @sharpen_factor: absolute value of the derivative sharpening factor (i.e.
133 *	amount of emphasis given to the derivative term after low activity
134 *	events)
135 * @sharpen_duration: duration of the sharpening effect after the detected low
136 *	activity event, relative to sampling_period
137 * @norm_offset: amount of normalization periodically performed on the learnt
138 *	rate behaviour values (lower means we should trust more what we learnt
139 *	about behaviour of rates, higher means we should trust more the natural
140 *	ordering of rates)
141 */
142struct rc_pid_debugfs_entries {
143	struct dentry *target;
144	struct dentry *sampling_period;
145	struct dentry *coeff_p;
146	struct dentry *coeff_i;
147	struct dentry *coeff_d;
148	struct dentry *smoothing_shift;
149	struct dentry *sharpen_factor;
150	struct dentry *sharpen_duration;
151	struct dentry *norm_offset;
152};
153
154void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
155				      struct ieee80211_tx_info *stat);
156
157void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
158					       int index, int rate);
159
160void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
161					   int index, int rate);
162
163void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
164					     s32 pf_sample, s32 prop_err,
165					     s32 int_err, s32 der_err);
166
167void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
168					     struct dentry *dir);
169
170void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta);
171
172struct rc_pid_sta_info {
173	unsigned long last_change;
174	unsigned long last_sample;
175
176	u32 tx_num_failed;
177	u32 tx_num_xmit;
178
179	int txrate_idx;
180
181	/* Average failed frames percentage error (i.e. actual vs. target
182	 * percentage), scaled by RC_PID_SMOOTHING. This value is computed
183	 * using using an exponential weighted average technique:
184	 *
185	 *           (RC_PID_SMOOTHING - 1) * err_avg_old + err
186	 * err_avg = ------------------------------------------
187	 *                       RC_PID_SMOOTHING
188	 *
189	 * where err_avg is the new approximation, err_avg_old the previous one
190	 * and err is the error w.r.t. to the current failed frames percentage
191	 * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
192	 * given to the previous estimate, resulting in smoother behavior (i.e.
193	 * corresponding to a longer integration window).
194	 *
195	 * For computation, we actually don't use the above formula, but this
196	 * one:
197	 *
198	 * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
199	 *
200	 * where:
201	 * 	err_avg_scaled = err * RC_PID_SMOOTHING
202	 * 	err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
203	 *
204	 * This avoids floating point numbers and the per_failed_old value can
205	 * easily be obtained by shifting per_failed_old_scaled right by
206	 * RC_PID_SMOOTHING_SHIFT.
207	 */
208	s32 err_avg_sc;
209
210	/* Last framed failes percentage sample. */
211	u32 last_pf;
212
213	/* Sharpening needed. */
214	u8 sharp_cnt;
215
216#ifdef CONFIG_MAC80211_DEBUGFS
217	/* Event buffer */
218	struct rc_pid_event_buffer events;
219
220	/* Events debugfs file entry */
221	struct dentry *events_entry;
222#endif
223};
224
225/* Algorithm parameters. We keep them on a per-algorithm approach, so they can
226 * be tuned individually for each interface.
227 */
228struct rc_pid_rateinfo {
229
230	/* Map sorted rates to rates in ieee80211_hw_mode. */
231	int index;
232
233	/* Map rates in ieee80211_hw_mode to sorted rates. */
234	int rev_index;
235
236	/* Did we do any measurement on this rate? */
237	bool valid;
238
239	/* Comparison with the lowest rate. */
240	int diff;
241};
242
243struct rc_pid_info {
244
245	/* The failed frames percentage target. */
246	unsigned int target;
247
248	/* Rate at which failed frames percentage is sampled in 0.001s. */
249	unsigned int sampling_period;
250
251	/* P, I and D coefficients. */
252	int coeff_p;
253	int coeff_i;
254	int coeff_d;
255
256	/* Exponential averaging shift. */
257	unsigned int smoothing_shift;
258
259	/* Sharpening factor and duration. */
260	unsigned int sharpen_factor;
261	unsigned int sharpen_duration;
262
263	/* Normalization offset. */
264	unsigned int norm_offset;
265
266	/* Rates information. */
267	struct rc_pid_rateinfo *rinfo;
268
269	/* Index of the last used rate. */
270	int oldrate;
271
272#ifdef CONFIG_MAC80211_DEBUGFS
273	/* Debugfs entries created for the parameters above. */
274	struct rc_pid_debugfs_entries dentries;
275#endif
276};
277
278#endif /* RC80211_PID_H */
279