Blame view

kernel/linux-rt-4.4.41/drivers/soc/ti/knav_qos_fw.h 12.8 KB
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