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
|
Port FEATURE_CONF_DESC_LENGTH from the grx500 variant of the driver.
This also reduces the default length of some descriptors, resulting in
significantly lower latencies when the line is saturated.
--- a/dcdp/inc/tc_common.h
+++ b/dcdp/inc/tc_common.h
@@ -27,7 +27,11 @@
#define UMT_DEF_PERIOD 400 /* microseconds */
#define MAX_MTU (DMA_PACKET_SZ - ETH_HLEN - HD_RSRV_SZ)
+#ifdef FEATURE_CONF_DESC_LENGTH
+#define QOSQ_NUM 8
+#else
#define QOSQ_NUM 2
+#endif
#define FW_STOP_TIMEOUT 20 /* millisecond */
#define QOS_DISPATCH_OWN 0
#define ACA_TXIN_POLL_INTVAL 10 /* millisecond */
--- a/dcdp/inc/tc_main.h
+++ b/dcdp/inc/tc_main.h
@@ -30,6 +30,7 @@
#define TCPRIV_ALIGN 32
#define DMA_PACKET_SZ 2048
+#define FEATURE_CONF_DESC_LENGTH 1
#define FEATURE_POWER_DOWN 1
enum {
@@ -157,6 +158,25 @@ struct tc_param {
unsigned int txout_dnum;
unsigned int rxin_dnum;
unsigned int rxout_dnum;
+
+#ifdef FEATURE_CONF_DESC_LENGTH
+ /* __US_FAST_PATH_DES_LIST_NUM:64
+ * __ACA_TX_IN_PD_LIST_NUM
+ * __ACA_TX_OUT_PD_LIST_NUM
+ * */
+ u32 conf_us_fp_desq_len;
+ /*
+ * Number of queue per QoS queue: QOS_DES_NUM / QOSQ_NUM
+ * */
+ u32 conf_us_qos_queue_len;
+ /* __US_OUTQ0_DES_LIST_NUM: 32
+ * __US_OUTQ1_DES_LIST_NUM: 32
+ * OUTQ_DESC_PER_Q
+ * */
+ u32 conf_us_outq_len;
+ /**/
+ u32 conf_us_local_q0_desq_len;
+#endif
};
struct cdma {
--- a/dcdp/ptm_tc.c
+++ b/dcdp/ptm_tc.c
@@ -75,7 +75,11 @@ static const u32 tx_kvec[] = {
0x30B1B233, 0xB43536B7, 0xB8393ABB, 0x3CBDBE3F,
0xC04142C3, 0x44C5C647, 0x48C9CA4B, 0xCC4D4ECF
};
+#ifndef FEATURE_CONF_DESC_LENGTH
static const u32 def_outq_map[OUTQ_PNUM] = {0x1, 0xFE};
+#else
+static const u32 def_outq_map[OUTQ_PNUM] = {0x0, 0xFF};
+#endif
static const char ptm_drv_name[] = "PTM SL";
static const char ptm_bond_name[][IFNAMSIZ] = {"PTM US BOND", "PTM DS BOND"};
@@ -1005,6 +1009,10 @@ static void us_fp_desq_cfg_ctxt_init(str
int i;
u32 desc_addr;
rx_descriptor_t desc;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+#endif
memset(&desq_cfg, 0, sizeof(desq_cfg));
/* Initialize US Fast-Path Descriptor Queue Config/Context */
@@ -1012,7 +1020,11 @@ static void us_fp_desq_cfg_ctxt_init(str
desq_cfg.fast_path = 1;
desq_cfg.mbox_int_en = 0;
desq_cfg.des_sync_needed = 0;
+#ifndef FEATURE_CONF_DESC_LENGTH
desq_cfg.des_num = __US_FAST_PATH_DES_LIST_NUM;
+#else
+ desq_cfg.des_num = tc_priv->param.conf_us_fp_desq_len;
+#endif
desq_cfg.des_base_addr = __US_FAST_PATH_DES_LIST_BASE;
tc_mem_write(priv, fpi_addr(__US_FP_INQ_DES_CFG_CTXT),
@@ -1036,12 +1048,20 @@ static void us_qos_desq_cfg_ctxt_init(st
int offset, i;
rx_descriptor_t desc;
u32 phy_addr;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+#endif
/* Setup QoSQ_CFG_CTXT */
memset(&qosq_cfg_ctxt, 0, sizeof(qosq_cfg_ctxt));
qosq_cfg_ctxt.threshold = 8;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ qosq_cfg_ctxt.des_num = tc_priv->param.conf_us_qos_queue_len;
+#else
qosq_cfg_ctxt.des_num = QOS_DES_NUM / QOSQ_NUM;
+#endif
offset = 0;
for (i = 0; i < QOSQ_NUM; i++) {
@@ -1080,6 +1100,10 @@ static void us_outq_desq_cfg_ctxt_init(s
u32 phy_addr;
int i;
u32 offset;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+#endif
/* Setup OUTQ_QoS_CFG_CTXT */
/* NOTE: By default, Shaping & WFQ both are DISABLED!! */
@@ -1108,7 +1132,11 @@ static void us_outq_desq_cfg_ctxt_init(s
desq_cfg.des_in_own_val = US_OUTQ_DES_OWN;
desq_cfg.mbox_int_en = 0;
desq_cfg.des_sync_needed = 0;
- desq_cfg.des_num = 32;
+#ifndef FEATURE_CONF_DESC_LENGTH
+ desq_cfg.des_num = OUTQ_DESC_PER_Q;
+#else
+ desq_cfg.des_num = tc_priv->param.conf_us_outq_len;
+#endif
/**
* Only BC0 is used in VRX518
*/
@@ -1174,7 +1202,11 @@ static void us_qos_cfg_init(struct ptm_e
/* Set QoS NO DROP */
sb_w32(1, __QOSQ_NO_DROP);
/* Enable Preemption function/Disable QoS by default */
+#ifdef FEATURE_CONF_DESC_LENGTH
+ sb_w32(0, _CHK_PREEMP_MAP);
+#else
sb_w32(1, _CHK_PREEMP_MAP);
+#endif
/* By default, all qid mappint to non-preemption queue */
sb_w32(0x0, _QID2PREEMP_MAP);
@@ -1376,6 +1408,11 @@ static void ptm_local_desq_cfg_ctxt_init
u32 dcnt, addr, pdbram_base;
unsigned int us_des_alloc[] = {
__US_TC_LOCAL_Q0_DES_LIST_NUM, __US_TC_LOCAL_Q1_DES_LIST_NUM};
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+ us_des_alloc[0] = tc_priv->param.conf_us_local_q0_desq_len;
+#endif
/* Setup the Local DESQ Configuration/Context for UpStream Queues */
memset(&desq_cfg, 0, sizeof(desq_cfg));
@@ -2321,6 +2358,10 @@ static void ptm_aca_init(struct ptm_ep_p
u32 phybase = priv->ep->phy_membase;
u32 start;
u32 type;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ struct tc_priv *tc_priv;
+ tc_priv = priv->tc_priv;
+#endif
priv->tc_priv->tc_ops.soc_cfg_get(&priv->tc_priv->cfg, ptm_id(priv));
memset(¶m, 0, sizeof(param));
@@ -2334,7 +2375,11 @@ static void ptm_aca_init(struct ptm_ep_p
#endif
txin->hd_size_in_dw = cfg->txin.soc_desc_dwsz;
txin->pd_desc_base = SB_XBAR_ADDR(__ACA_TX_IN_PD_LIST_BASE);
+#ifndef FEATURE_CONF_DESC_LENGTH
txin->pd_desc_num = __ACA_TX_IN_PD_LIST_NUM;
+#else
+ txin->pd_desc_num = tc_priv->param.conf_us_fp_desq_len;
+#endif
txin->pd_size_in_dw = DESC_DWSZ;
txin->soc_desc_base = cfg->txin.soc_phydbase;
txin->soc_desc_num = cfg->txin.soc_dnum;
--- a/dcdp/tc_main.c
+++ b/dcdp/tc_main.c
@@ -182,6 +182,12 @@ static inline void init_local_param(stru
priv->param.txout_dnum = txout_num;
priv->param.rxin_dnum = rxin_num;
priv->param.rxout_dnum = rxout_num;
+#ifdef FEATURE_CONF_DESC_LENGTH
+ priv->param.conf_us_fp_desq_len = 32;
+ priv->param.conf_us_qos_queue_len = 32;
+ priv->param.conf_us_outq_len = 32;
+ priv->param.conf_us_local_q0_desq_len = 16;
+#endif
priv->tc_mode = TC_NONE_MODE;
priv->tc_stat = NO_TC;
--- a/dcdp/tc_proc.c
+++ b/dcdp/tc_proc.c
@@ -1114,6 +1114,9 @@ static int proc_read_ver(struct seq_file
(date >> 16) & 0xff,
(date & 0xffff));
+#ifdef FEATURE_CONF_DESC_LENGTH
+ seq_puts(seq, " + Support QoS and Configurable descriptor length\n");
+#endif
#ifdef FEATURE_POWER_DOWN
seq_puts(seq, " + Support Power Down enhancement feature\n");
#endif
@@ -1166,6 +1169,113 @@ static const struct proc_ops tc_soc_proc
.proc_release = single_release,
};
+#ifdef FEATURE_CONF_DESC_LENGTH
+static ssize_t proc_write_desc_conf(struct file *file, const char __user *buf,
+ size_t count, loff_t *data)
+{
+ struct tc_priv *priv;
+ char str[32];
+ int len, rlen, temp;
+ int num, temp_num;
+ char *param_list[20];
+ len = count < sizeof(str) ? count : sizeof(str) - 1;
+ rlen = len - copy_from_user(str, buf, len);
+ str[rlen] = 0;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ priv = (struct tc_priv *)PDE_DATA(file_inode(file));
+ if (priv == NULL)
+ return count;
+
+ num = vrx_split_buffer(str, param_list, ARRAY_SIZE(param_list));
+ if (num < 1 || num > 4)
+ goto proc_dbg_desc_conf;
+
+ temp_num = num;
+ if (num-- != 0) {
+ temp = vrx_atoi(param_list[0]);
+ if (temp < 1 || temp > 128) {
+ pr_info("Fastpath valid range: 1 -> 128\n");
+ goto proc_dbg_desc_conf;
+ }
+ }
+ if (num-- != 0) {
+ temp = vrx_atoi(param_list[1]);
+ if (temp < 1 || temp > 63) {
+ pr_info("QoS valid range: 1 -> 63\n");
+ goto proc_dbg_desc_conf;
+ }
+ }
+ if (num-- != 0) {
+ temp = vrx_atoi(param_list[2]);
+ if (temp < 1 || temp > 128) {
+ pr_info("OutQ valid range: 1 -> 128\n");
+ goto proc_dbg_desc_conf;
+ }
+ }
+ if (num-- != 0) {
+ temp = vrx_atoi(param_list[3]);
+ if (temp < 4 || temp > 16) {
+ pr_info("Local Q0 valid range: 4 -> 16\n");
+ goto proc_dbg_desc_conf;
+ }
+ }
+ num = temp_num;
+ if (num-- != 0) {
+ priv->param.conf_us_fp_desq_len = vrx_atoi(param_list[0]);
+ }
+ if (num-- != 0) {
+ priv->param.conf_us_qos_queue_len = vrx_atoi(param_list[1]);
+ }
+ if (num-- != 0) {
+ priv->param.conf_us_outq_len = vrx_atoi(param_list[2]);
+ }
+ if (num-- != 0) {
+ priv->param.conf_us_local_q0_desq_len = vrx_atoi(param_list[3]);
+ }
+
+ return count;
+
+proc_dbg_desc_conf:
+ pr_info("echo [FP] [QoS] [OutQ] [LocalQ0]> desc_conf\n");
+ return count;
+}
+
+static int proc_read_desc_conf(struct seq_file *seq, void *v)
+{
+ struct tc_priv *priv;
+ priv = (struct tc_priv *)seq->private;
+ if (priv == NULL)
+ return -1;
+ seq_puts(seq, "Upstream descriptor length information:\n");
+ seq_printf(seq, " - Fastpath: %d\n",
+ priv->param.conf_us_fp_desq_len);
+ seq_printf(seq, " - QoS: %d\n",
+ priv->param.conf_us_qos_queue_len);
+ seq_printf(seq, " - OutQ: %d\n",
+ priv->param.conf_us_outq_len);
+ seq_printf(seq, " - Local Q0: %d\n",
+ priv->param.conf_us_local_q0_desq_len);
+ seq_puts(seq, "\n");
+ return 0;
+}
+
+static int proc_read_desc_conf_seq_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_read_desc_conf, PDE_DATA(inode));
+}
+#endif
+
+static const struct proc_ops tc_desc_conf_proc_fops = {
+ .proc_open = proc_read_desc_conf_seq_open,
+ .proc_read = seq_read,
+ .proc_write = proc_write_desc_conf,
+ .proc_lseek = seq_lseek,
+ .proc_release = single_release,
+};
+
static struct tc_proc_list tc_procs[] = {
{TC_PROC_DIR, 0, NULL, 1},
{"cfg", 0644, &tc_cfg_proc_fops, 0},
@@ -1174,6 +1284,9 @@ static struct tc_proc_list tc_procs[] =
{"showtime", 0200, &tc_show_time_proc_fops, 0},
{"ver", 0644, &tc_ver_proc_fops, 0},
{"soc", 0644, &tc_soc_proc_fops, 0},
+#ifdef FEATURE_CONF_DESC_LENGTH
+ {"desc_conf", 0644, &tc_desc_conf_proc_fops, 0},
+#endif
};
int tc_proc_init(struct tc_priv *priv)
@@ -1333,7 +1446,6 @@ proc_ptm_cfg_help:
return count;
}
-
static const struct proc_ops ptm_cfg_proc_fops = {
.proc_open = proc_read_cfg_seq_open,
.proc_read = seq_read,
|