5113f6f70
김현기
kernel add
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
|
/*
* Keystone Navigator QMSS QoS firmware internal header
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
* Author: Sandeep Paulraj <s-paulraj@ti.com>
* Reece R. Pollack <x0183204@ti.com>
* WingMan Kwok <w-kwok2@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#ifndef __KNAV_QOS_FW_H
#define __KNAV_QOS_FW_H
#define QOS_MAX_INPUTS 128
#define QOS_MAX_CHILDREN 8
#define QOS_MAX_TREES 8
#define QOS_RETCODE_SUCCESS 1
#define QOS_COMMAND_TIMEOUT 20 /* msecs */
#define QOS_COMMAND_DELAY 10 /* usecs */
#define QOS_CMD_GET_QUEUE_BASE 0x80
#define QOS_CMD_SET_QUEUE_BASE 0x81
#define QOS_CMD_SET_TIMER_CONFIG 0x82
#define QOS_CMD_ENABLE_PORT 0x90
#define QOS_CMD_PORT_SHADOW 0x91
#define QOS_CMD_STATS_REQUEST 0x92
#define QOS_MAGIC_DROPSCHED 0x8020
#define QOS_QUEUE_BASE_DROP_SCHED BIT(8)
#define QOS_QUEUE_BASE_QOS_SCHED 0
#define QOS_ENABLE BIT(8)
#define QOS_DISABLE 0
#define QOS_COPY_ACTIVE_TO_SHADOW 0
#define QOS_COPY_SHADOW_TO_ACTIVE BIT(8)
#define QOS_DROP_SCHED_CFG 4
#define QOS_DROP_SCHED_ENABLE BIT(24)
#define QOS_SCHED_FLAG_WRR_BYTES BIT(0)
#define QOS_SCHED_FLAG_CIR_BYTES BIT(1)
#define QOS_SCHED_FLAG_CONG_BYTES BIT(2)
#define QOS_SCHED_FLAG_THROTL_BYTES BIT(3)
#define QOS_SCHED_FLAG_IS_JOINT BIT(4)
#define QOS_DEFAULT_OVERHEAD_BYTES 24
#define QOS_CREDITS_PACKET_SHIFT 20
#define QOS_CREDITS_BYTE_SHIFT 11
#define QOS_WRR_PACKET_SHIFT 17
#define QOS_WRR_BYTE_SHIFT 8
#define QOS_BYTE_NORMALIZATION_FACTOR (1500u << QOS_WRR_BYTE_SHIFT)
#define QOS_PACKET_NORMALIZATION_FACTOR (2u << QOS_WRR_PACKET_SHIFT)
#define QOS_MAX_WEIGHT U32_MAX
#define QOS_MAX_CREDITS 0x08000000
#define QOS_MIN_CREDITS_WARN (1500u << QOS_WRR_BYTE_SHIFT)
#define to_qnode(_n) container_of(_n, struct knav_qos_tree_node, node)
enum knav_qos_normalize {
DIVIDE,
MULTIPLY
};
enum knav_qos_accounting_type {
QOS_PACKET_ACCT,
QOS_BYTE_ACCT
};
enum knav_qos_drop_mode {
QOS_TAILDROP,
QOS_RED,
};
enum knav_qos_tree_node_type {
QOS_NODE_DEFAULT,
QOS_NODE_PRIO,
QOS_NODE_WRR,
QOS_NODE_BLENDED,
};
enum knav_qos_shadow_type {
QOS_SCHED_PORT_CFG,
QOS_DROP_CFG_PROF,
QOS_DROP_QUEUE_CFG,
QOS_DROP_OUT_PROF,
QOS_MAX_SHADOW /* last */
};
enum knav_qos_control_type {
QOS_CONTROL_ENABLE,
QOS_CONTROL_GET_INPUT,
};
struct knav_qos_shadow {
enum knav_qos_shadow_type type;
struct knav_qos_info *info;
const char *name;
void *data;
unsigned long *dirty;
unsigned long *avail;
unsigned long *running;
int start, count, size;
int (*sync)(struct knav_qos_shadow *shadow, int idx);
int (*control)(struct knav_qos_shadow *shadow,
enum knav_qos_control_type ctrl,
int idx, u32 arg);
};
struct knav_qos_stats {
enum knav_qos_shadow_type type;
const char *name;
void *data;
unsigned long *dirty;
unsigned long *avail;
unsigned long *running;
int start, count, size;
int (*get_stats)(struct knav_qos_stats *stats, int idx);
};
struct knav_qos_drop_policy {
const char *name;
struct knav_qos_info *info;
bool usecount;
enum knav_qos_accounting_type acct;
enum knav_qos_drop_mode mode;
u32 limit;
u32 red_low;
u32 red_high;
u32 half_life;
u32 max_drop_prob;
int drop_cfg_idx;
struct list_head list;
struct kobject kobj;
};
struct knav_qos_info {
spinlock_t lock; /* protects shadow area access */
struct knav_device *kdev;
struct knav_pdsp_info *pdsp;
u32 refcount;
struct knav_qos_shadow shadows[QOS_MAX_SHADOW];
struct knav_qos_stats stats;
int qos_tree_count;
struct ktree qos_trees[QOS_MAX_TREES];
struct list_head drop_policies;
struct list_head stats_classes;
struct knav_qos_drop_policy *default_drop_policy;
struct dentry *root_dir;
struct dentry *config_profiles;
struct dentry *out_profiles;
struct dentry *queue_configs;
struct dentry *port_configs;
int sched_port_queue_base,
drop_sched_queue_base,
inputs_per_port,
ticks_per_sec,
pdsp_id;
struct {
u8 int_num;
u8 qos_ticks;
u8 drop_ticks;
u32 seed[3];
} drop_cfg;
struct timer_list timer;
struct kobject *kobj;
struct kobject *kobj_stats;
struct kobject *kobj_policies;
};
struct knav_qos_stats_class {
const char *name;
struct knav_qos_info *info;
struct list_head list;
int stats_block_idx;
bool usecount;
struct kobject kobj;
};
struct knav_qos_input_queue {
bool valid;
u32 queue;
int drop_queue_idx;
};
struct knav_qos_tree_node {
struct knav_qos_tree_node *parent;
struct knav_qos_info *info;
struct ktree_node node;
enum knav_qos_tree_node_type type;
u32 weight;
u32 priority;
u32 low_priority;
int prio_children;
int wrr_children;
int lowprio_children;
enum knav_qos_accounting_type acct;
const char *name;
int overhead_bytes;
int output_rate;
int burst_size;
int num_input_queues;
u32 input_queues[QOS_MAX_INPUTS];
struct knav_qos_input_queue input_queue[QOS_MAX_INPUTS];
struct knav_qos_drop_policy *drop_policy;
struct knav_qos_stats_class *stats_class;
int child_port_count; /* children that need ports */
int child_count; /* number of children */
int parent_input; /* input number of parent */
u32 child_weight[QOS_MAX_CHILDREN];
bool is_drop_input; /* indicates that child's output
* feeds to the drop sched
*/
bool has_sched_port; /* does this port need a sched? */
bool is_joint_port; /* Even/odd joint pair */
int output_queue; /* from DT or calculated */
int tree_index; /* knav_qos_info.qos_trees index */
/* allocated resources */
int sched_port_idx; /* inherited by default nodes */
int drop_out_idx; /* inherited by default nodes */
int drop_queue_idx[QOS_MAX_INPUTS];
struct kobject kobj;
};
struct knav_semaphore_regs {
u32 sem;
};
struct knav_push_stats_regs {
u32 stats_info;
u32 bytes_forwarded;
u32 bytes_discarded;
u32 packets_forwarded;
u32 packets_discarded;
};
struct knav_query_stats_regs {
u32 bytes_forwarded_lsw;
u32 bytes_forwarded_msw;
u32 bytes_discarded_lsw;
u32 bytes_discarded_msw;
u32 packets_forwarded;
u32 packets_discarded;
};
#define QOS_SHADOW_OFFSET 0x40
#define QOS_PUSH_PROXY_OFFSET 0x2e0
#define QOS_STATS_OFFSET 0x300
#define QOS_MAGIC_OFFSET 0x1ff8
#define QOS_VERSION_OFFSET 0x1ffc
#define knav_qos_id_to_idx(idx) ((idx) & 0xffff)
#define knav_qos_id_to_pdsp(idx) ((idx) >> 16)
#define knav_qos_make_id(pdsp, idx) ((pdsp) << 16 | (idx))
#define knav_qos_id_to_queue(info, idx) \
((info)->drop_sched_queue_base + knav_qos_id_to_idx(idx))
#define knav_qos_id_even(idx) ((idx) & ~0x0001)
#define knav_qos_id_odd(idx) ((idx) | 0x0001)
int knav_qos_alloc(struct knav_qos_info *info, enum knav_qos_shadow_type type);
int knav_qos_free(struct knav_qos_info *info, enum knav_qos_shadow_type type,
int idx);
int knav_qos_control(struct knav_qos_info *info, enum knav_qos_shadow_type type,
enum knav_qos_control_type ctrl, int idx, u32 arg,
bool internal);
int knav_qos_sync(struct knav_qos_info *info, enum knav_qos_shadow_type type,
int idx, bool internal);
int knav_qos_get(struct knav_qos_info *info, enum knav_qos_shadow_type type,
const char *name, int idx, int offset, int startbit,
int nbits, u32 *value);
int knav_qos_set(struct knav_qos_info *info, enum knav_qos_shadow_type type,
const char *name, int idx, int offset, int startbit,
int nbits, bool sync, u32 value, bool internal);
#define DEFINE_SHADOW(_type, _field) \
static inline int knav_qos_control_##_field(struct knav_qos_info *info, \
enum knav_qos_control_type ctrl, \
int idx, u32 arg) \
{ \
return knav_qos_control(info, _type, ctrl, idx, arg, false); \
} \
static inline int knav_qos_sync_##_field(struct knav_qos_info *info, \
int idx) \
{ \
return knav_qos_sync(info, _type, idx, false); \
}
DEFINE_SHADOW(QOS_DROP_CFG_PROF, drop_cfg);
DEFINE_SHADOW(QOS_DROP_OUT_PROF, drop_out);
DEFINE_SHADOW(QOS_SCHED_PORT_CFG, sched_port);
DEFINE_SHADOW(QOS_DROP_QUEUE_CFG, drop_queue);
#define DEFINE_ALLOC(_type, _field) \
static inline int knav_qos_alloc_##_field(struct knav_qos_info *info) \
{ \
return knav_qos_alloc(info, _type); \
} \
static inline int knav_qos_free_##_field(struct knav_qos_info *info, \
int idx) \
{ \
return knav_qos_free(info, _type, idx); \
}
DEFINE_ALLOC(QOS_DROP_CFG_PROF, drop_cfg);
DEFINE_ALLOC(QOS_DROP_OUT_PROF, drop_out);
#define DEFINE_FIELD_U32(_type, _field, _offset, _startbit, _nbits) \
static inline int knav_qos_get_##_field(struct knav_qos_info *info, \
int idx, u32 *value) \
{ \
return knav_qos_get(info, _type, #_field, idx, _offset, \
_startbit, _nbits, value); \
} \
static inline int knav_qos_set_##_field(struct knav_qos_info *info, \
int idx, u32 value, bool sync) \
{ \
return knav_qos_set(info, _type, #_field, idx, _offset, \
_startbit, _nbits, sync, value, false); \
} \
static inline int __knav_qos_set_##_field(struct knav_qos_info *info, \
int idx, u32 value, bool sync) \
{ \
return knav_qos_set(info, _type, #_field, idx, _offset, \
_startbit, _nbits, sync, value, true); \
}
#define DEFINE_FIELD_U32_ARRAY(_type, _field, _offset, _size) \
static inline int knav_qos_get_##_field(struct knav_qos_info *info, \
int idx, int elem, u32 *value) \
{ \
int ofs = _offset + elem * _size; \
return knav_qos_get(info, _type, #_field, idx, ofs, 0, 32, \
value); \
} \
static inline int knav_qos_set_##_field(struct knav_qos_info *info, \
int idx, int elem, u32 value, bool sync) \
{ \
int ofs = _offset + elem * _size; \
return knav_qos_set(info, _type, #_field, idx, ofs, 0, 32, \
sync, value, false); \
} \
static inline int __knav_qos_set_##_field(struct knav_qos_info *info, \
int idx, int elem, u32 value, bool sync) \
{ \
int ofs = _offset + elem * _size; \
return knav_qos_set(info, _type, #_field, idx, ofs, 0, 32, \
sync, value, true); \
}
DEFINE_FIELD_U32(QOS_DROP_CFG_PROF, drop_cfg_unit_flags, 0x00, 0, 8)
DEFINE_FIELD_U32(QOS_DROP_CFG_PROF, drop_cfg_mode, 0x00, 8, 8)
DEFINE_FIELD_U32(QOS_DROP_CFG_PROF, drop_cfg_time_const, 0x00, 16, 8)
DEFINE_FIELD_U32(QOS_DROP_CFG_PROF, drop_cfg_tail_thresh, 0x04, 0, 32)
DEFINE_FIELD_U32(QOS_DROP_CFG_PROF, drop_cfg_red_low, 0x08, 0, 32)
DEFINE_FIELD_U32(QOS_DROP_CFG_PROF, drop_cfg_red_high, 0x0c, 0, 32)
DEFINE_FIELD_U32(QOS_DROP_CFG_PROF, drop_cfg_thresh_recip, 0x10, 0, 32)
DEFINE_FIELD_U32(QOS_DROP_OUT_PROF, drop_out_queue_number, 0x00, 0, 16)
DEFINE_FIELD_U32(QOS_DROP_OUT_PROF, drop_out_red_prob, 0x00, 16, 16)
DEFINE_FIELD_U32(QOS_DROP_OUT_PROF, drop_out_cfg_prof_idx, 0x04, 0, 8)
DEFINE_FIELD_U32(QOS_DROP_OUT_PROF, drop_out_enable, 0x04, 8, 8)
DEFINE_FIELD_U32(QOS_DROP_OUT_PROF, drop_out_avg_depth, 0x08, 0, 32)
DEFINE_FIELD_U32(QOS_DROP_QUEUE_CFG, drop_q_out_prof_idx, 0x00, 0, 8)
DEFINE_FIELD_U32(QOS_DROP_QUEUE_CFG, drop_q_stat_blk_idx, 0x00, 8, 8)
DEFINE_FIELD_U32(QOS_DROP_QUEUE_CFG, drop_q_stat_irq_pair_idx, 0x00, 16, 8)
DEFINE_FIELD_U32(QOS_DROP_QUEUE_CFG, drop_q_valid, 0x00, 24, 8)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_unit_flags, 0x00, 0, 8)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_group_count, 0x00, 8, 8)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_out_queue, 0x00, 16, 16)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_overhead_bytes, 0x04, 0, 8)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_remove_bytes, 0x04, 8, 8)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_out_throttle, 0x04, 16, 16)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_cir_credit, 0x08, 0, 32)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_cir_max, 0x0c, 0, 32)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_total_q_count, 0x24, 0, 8)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_sp_q_count, 0x24, 8, 8)
DEFINE_FIELD_U32(QOS_SCHED_PORT_CFG, sched_wrr_q_count, 0x24, 16, 8)
DEFINE_FIELD_U32_ARRAY(QOS_SCHED_PORT_CFG, sched_wrr_credit, 0x28, 0x8)
DEFINE_FIELD_U32_ARRAY(QOS_SCHED_PORT_CFG, sched_cong_thresh, 0x2c, 0x8)
int knav_qos_start(struct knav_qos_info *info);
int knav_qos_stop(struct knav_qos_info *info);
int knav_qos_tree_start(struct knav_qos_info *info);
int knav_qos_tree_stop(struct knav_qos_info *info);
#endif
|