kernel: add Intel/Lantiq VRX518 TC driver
[openwrt/staging/hauke.git] / package / kernel / lantiq / vrx518_tc / patches / 201-desc-length.patch
1 Port FEATURE_CONF_DESC_LENGTH from the grx500 variant of the driver.
2 This also reduces the default length of some descriptors, resulting in
3 significantly lower latencies when the line is saturated.
4
5 --- a/dcdp/inc/tc_common.h
6 +++ b/dcdp/inc/tc_common.h
7 @@ -27,7 +27,11 @@
8 #define UMT_DEF_PERIOD 400 /* microseconds */
9
10 #define MAX_MTU (DMA_PACKET_SZ - ETH_HLEN - HD_RSRV_SZ)
11 +#ifdef FEATURE_CONF_DESC_LENGTH
12 +#define QOSQ_NUM 8
13 +#else
14 #define QOSQ_NUM 2
15 +#endif
16 #define FW_STOP_TIMEOUT 20 /* millisecond */
17 #define QOS_DISPATCH_OWN 0
18 #define ACA_TXIN_POLL_INTVAL 10 /* millisecond */
19 --- a/dcdp/inc/tc_main.h
20 +++ b/dcdp/inc/tc_main.h
21 @@ -30,6 +30,7 @@
22 #define TCPRIV_ALIGN 32
23 #define DMA_PACKET_SZ 2048
24
25 +#define FEATURE_CONF_DESC_LENGTH 1
26 #define FEATURE_POWER_DOWN 1
27
28 enum {
29 @@ -157,6 +158,25 @@ struct tc_param {
30 unsigned int txout_dnum;
31 unsigned int rxin_dnum;
32 unsigned int rxout_dnum;
33 +
34 +#ifdef FEATURE_CONF_DESC_LENGTH
35 + /* __US_FAST_PATH_DES_LIST_NUM:64
36 + * __ACA_TX_IN_PD_LIST_NUM
37 + * __ACA_TX_OUT_PD_LIST_NUM
38 + * */
39 + u32 conf_us_fp_desq_len;
40 + /*
41 + * Number of queue per QoS queue: QOS_DES_NUM / QOSQ_NUM
42 + * */
43 + u32 conf_us_qos_queue_len;
44 + /* __US_OUTQ0_DES_LIST_NUM: 32
45 + * __US_OUTQ1_DES_LIST_NUM: 32
46 + * OUTQ_DESC_PER_Q
47 + * */
48 + u32 conf_us_outq_len;
49 + /**/
50 + u32 conf_us_local_q0_desq_len;
51 +#endif
52 };
53
54 struct cdma {
55 --- a/dcdp/ptm_tc.c
56 +++ b/dcdp/ptm_tc.c
57 @@ -75,7 +75,11 @@ static const u32 tx_kvec[] = {
58 0x30B1B233, 0xB43536B7, 0xB8393ABB, 0x3CBDBE3F,
59 0xC04142C3, 0x44C5C647, 0x48C9CA4B, 0xCC4D4ECF
60 };
61 +#ifndef FEATURE_CONF_DESC_LENGTH
62 static const u32 def_outq_map[OUTQ_PNUM] = {0x1, 0xFE};
63 +#else
64 +static const u32 def_outq_map[OUTQ_PNUM] = {0x0, 0xFF};
65 +#endif
66 static const char ptm_drv_name[] = "PTM SL";
67 static const char ptm_bond_name[][IFNAMSIZ] = {"PTM US BOND", "PTM DS BOND"};
68
69 @@ -1005,6 +1009,10 @@ static void us_fp_desq_cfg_ctxt_init(str
70 int i;
71 u32 desc_addr;
72 rx_descriptor_t desc;
73 +#ifdef FEATURE_CONF_DESC_LENGTH
74 + struct tc_priv *tc_priv;
75 + tc_priv = priv->tc_priv;
76 +#endif
77
78 memset(&desq_cfg, 0, sizeof(desq_cfg));
79 /* Initialize US Fast-Path Descriptor Queue Config/Context */
80 @@ -1012,7 +1020,11 @@ static void us_fp_desq_cfg_ctxt_init(str
81 desq_cfg.fast_path = 1;
82 desq_cfg.mbox_int_en = 0;
83 desq_cfg.des_sync_needed = 0;
84 +#ifndef FEATURE_CONF_DESC_LENGTH
85 desq_cfg.des_num = __US_FAST_PATH_DES_LIST_NUM;
86 +#else
87 + desq_cfg.des_num = tc_priv->param.conf_us_fp_desq_len;
88 +#endif
89 desq_cfg.des_base_addr = __US_FAST_PATH_DES_LIST_BASE;
90
91 tc_mem_write(priv, fpi_addr(__US_FP_INQ_DES_CFG_CTXT),
92 @@ -1036,12 +1048,20 @@ static void us_qos_desq_cfg_ctxt_init(st
93 int offset, i;
94 rx_descriptor_t desc;
95 u32 phy_addr;
96 +#ifdef FEATURE_CONF_DESC_LENGTH
97 + struct tc_priv *tc_priv;
98 + tc_priv = priv->tc_priv;
99 +#endif
100
101 /* Setup QoSQ_CFG_CTXT */
102 memset(&qosq_cfg_ctxt, 0, sizeof(qosq_cfg_ctxt));
103
104 qosq_cfg_ctxt.threshold = 8;
105 +#ifdef FEATURE_CONF_DESC_LENGTH
106 + qosq_cfg_ctxt.des_num = tc_priv->param.conf_us_qos_queue_len;
107 +#else
108 qosq_cfg_ctxt.des_num = QOS_DES_NUM / QOSQ_NUM;
109 +#endif
110
111 offset = 0;
112 for (i = 0; i < QOSQ_NUM; i++) {
113 @@ -1080,6 +1100,10 @@ static void us_outq_desq_cfg_ctxt_init(s
114 u32 phy_addr;
115 int i;
116 u32 offset;
117 +#ifdef FEATURE_CONF_DESC_LENGTH
118 + struct tc_priv *tc_priv;
119 + tc_priv = priv->tc_priv;
120 +#endif
121
122 /* Setup OUTQ_QoS_CFG_CTXT */
123 /* NOTE: By default, Shaping & WFQ both are DISABLED!! */
124 @@ -1108,7 +1132,11 @@ static void us_outq_desq_cfg_ctxt_init(s
125 desq_cfg.des_in_own_val = US_OUTQ_DES_OWN;
126 desq_cfg.mbox_int_en = 0;
127 desq_cfg.des_sync_needed = 0;
128 - desq_cfg.des_num = 32;
129 +#ifndef FEATURE_CONF_DESC_LENGTH
130 + desq_cfg.des_num = OUTQ_DESC_PER_Q;
131 +#else
132 + desq_cfg.des_num = tc_priv->param.conf_us_outq_len;
133 +#endif
134 /**
135 * Only BC0 is used in VRX518
136 */
137 @@ -1174,7 +1202,11 @@ static void us_qos_cfg_init(struct ptm_e
138 /* Set QoS NO DROP */
139 sb_w32(1, __QOSQ_NO_DROP);
140 /* Enable Preemption function/Disable QoS by default */
141 +#ifdef FEATURE_CONF_DESC_LENGTH
142 + sb_w32(0, _CHK_PREEMP_MAP);
143 +#else
144 sb_w32(1, _CHK_PREEMP_MAP);
145 +#endif
146 /* By default, all qid mappint to non-preemption queue */
147 sb_w32(0x0, _QID2PREEMP_MAP);
148
149 @@ -1376,6 +1408,11 @@ static void ptm_local_desq_cfg_ctxt_init
150 u32 dcnt, addr, pdbram_base;
151 unsigned int us_des_alloc[] = {
152 __US_TC_LOCAL_Q0_DES_LIST_NUM, __US_TC_LOCAL_Q1_DES_LIST_NUM};
153 +#ifdef FEATURE_CONF_DESC_LENGTH
154 + struct tc_priv *tc_priv;
155 + tc_priv = priv->tc_priv;
156 + us_des_alloc[0] = tc_priv->param.conf_us_local_q0_desq_len;
157 +#endif
158
159 /* Setup the Local DESQ Configuration/Context for UpStream Queues */
160 memset(&desq_cfg, 0, sizeof(desq_cfg));
161 @@ -2321,6 +2358,10 @@ static void ptm_aca_init(struct ptm_ep_p
162 u32 phybase = priv->ep->phy_membase;
163 u32 start;
164 u32 type;
165 +#ifdef FEATURE_CONF_DESC_LENGTH
166 + struct tc_priv *tc_priv;
167 + tc_priv = priv->tc_priv;
168 +#endif
169
170 priv->tc_priv->tc_ops.soc_cfg_get(&priv->tc_priv->cfg, ptm_id(priv));
171 memset(&param, 0, sizeof(param));
172 @@ -2334,7 +2375,11 @@ static void ptm_aca_init(struct ptm_ep_p
173 #endif
174 txin->hd_size_in_dw = cfg->txin.soc_desc_dwsz;
175 txin->pd_desc_base = SB_XBAR_ADDR(__ACA_TX_IN_PD_LIST_BASE);
176 +#ifndef FEATURE_CONF_DESC_LENGTH
177 txin->pd_desc_num = __ACA_TX_IN_PD_LIST_NUM;
178 +#else
179 + txin->pd_desc_num = tc_priv->param.conf_us_fp_desq_len;
180 +#endif
181 txin->pd_size_in_dw = DESC_DWSZ;
182 txin->soc_desc_base = cfg->txin.soc_phydbase;
183 txin->soc_desc_num = cfg->txin.soc_dnum;
184 --- a/dcdp/tc_main.c
185 +++ b/dcdp/tc_main.c
186 @@ -182,6 +182,12 @@ static inline void init_local_param(stru
187 priv->param.txout_dnum = txout_num;
188 priv->param.rxin_dnum = rxin_num;
189 priv->param.rxout_dnum = rxout_num;
190 +#ifdef FEATURE_CONF_DESC_LENGTH
191 + priv->param.conf_us_fp_desq_len = 32;
192 + priv->param.conf_us_qos_queue_len = 32;
193 + priv->param.conf_us_outq_len = 32;
194 + priv->param.conf_us_local_q0_desq_len = 16;
195 +#endif
196 priv->tc_mode = TC_NONE_MODE;
197 priv->tc_stat = NO_TC;
198
199 --- a/dcdp/tc_proc.c
200 +++ b/dcdp/tc_proc.c
201 @@ -1114,6 +1114,9 @@ static int proc_read_ver(struct seq_file
202 (date >> 16) & 0xff,
203 (date & 0xffff));
204
205 +#ifdef FEATURE_CONF_DESC_LENGTH
206 + seq_puts(seq, " + Support QoS and Configurable descriptor length\n");
207 +#endif
208 #ifdef FEATURE_POWER_DOWN
209 seq_puts(seq, " + Support Power Down enhancement feature\n");
210 #endif
211 @@ -1166,6 +1169,113 @@ static const struct proc_ops tc_soc_proc
212 .proc_release = single_release,
213 };
214
215 +#ifdef FEATURE_CONF_DESC_LENGTH
216 +static ssize_t proc_write_desc_conf(struct file *file, const char __user *buf,
217 + size_t count, loff_t *data)
218 +{
219 + struct tc_priv *priv;
220 + char str[32];
221 + int len, rlen, temp;
222 + int num, temp_num;
223 + char *param_list[20];
224 + len = count < sizeof(str) ? count : sizeof(str) - 1;
225 + rlen = len - copy_from_user(str, buf, len);
226 + str[rlen] = 0;
227 +
228 + if (!capable(CAP_SYS_ADMIN))
229 + return -EPERM;
230 +
231 + priv = (struct tc_priv *)PDE_DATA(file_inode(file));
232 + if (priv == NULL)
233 + return count;
234 +
235 + num = vrx_split_buffer(str, param_list, ARRAY_SIZE(param_list));
236 + if (num < 1 || num > 4)
237 + goto proc_dbg_desc_conf;
238 +
239 + temp_num = num;
240 + if (num-- != 0) {
241 + temp = vrx_atoi(param_list[0]);
242 + if (temp < 1 || temp > 128) {
243 + pr_info("Fastpath valid range: 1 -> 128\n");
244 + goto proc_dbg_desc_conf;
245 + }
246 + }
247 + if (num-- != 0) {
248 + temp = vrx_atoi(param_list[1]);
249 + if (temp < 1 || temp > 63) {
250 + pr_info("QoS valid range: 1 -> 63\n");
251 + goto proc_dbg_desc_conf;
252 + }
253 + }
254 + if (num-- != 0) {
255 + temp = vrx_atoi(param_list[2]);
256 + if (temp < 1 || temp > 128) {
257 + pr_info("OutQ valid range: 1 -> 128\n");
258 + goto proc_dbg_desc_conf;
259 + }
260 + }
261 + if (num-- != 0) {
262 + temp = vrx_atoi(param_list[3]);
263 + if (temp < 4 || temp > 16) {
264 + pr_info("Local Q0 valid range: 4 -> 16\n");
265 + goto proc_dbg_desc_conf;
266 + }
267 + }
268 + num = temp_num;
269 + if (num-- != 0) {
270 + priv->param.conf_us_fp_desq_len = vrx_atoi(param_list[0]);
271 + }
272 + if (num-- != 0) {
273 + priv->param.conf_us_qos_queue_len = vrx_atoi(param_list[1]);
274 + }
275 + if (num-- != 0) {
276 + priv->param.conf_us_outq_len = vrx_atoi(param_list[2]);
277 + }
278 + if (num-- != 0) {
279 + priv->param.conf_us_local_q0_desq_len = vrx_atoi(param_list[3]);
280 + }
281 +
282 + return count;
283 +
284 +proc_dbg_desc_conf:
285 + pr_info("echo [FP] [QoS] [OutQ] [LocalQ0]> desc_conf\n");
286 + return count;
287 +}
288 +
289 +static int proc_read_desc_conf(struct seq_file *seq, void *v)
290 +{
291 + struct tc_priv *priv;
292 + priv = (struct tc_priv *)seq->private;
293 + if (priv == NULL)
294 + return -1;
295 + seq_puts(seq, "Upstream descriptor length information:\n");
296 + seq_printf(seq, " - Fastpath: %d\n",
297 + priv->param.conf_us_fp_desq_len);
298 + seq_printf(seq, " - QoS: %d\n",
299 + priv->param.conf_us_qos_queue_len);
300 + seq_printf(seq, " - OutQ: %d\n",
301 + priv->param.conf_us_outq_len);
302 + seq_printf(seq, " - Local Q0: %d\n",
303 + priv->param.conf_us_local_q0_desq_len);
304 + seq_puts(seq, "\n");
305 + return 0;
306 +}
307 +
308 +static int proc_read_desc_conf_seq_open(struct inode *inode, struct file *file)
309 +{
310 + return single_open(file, proc_read_desc_conf, PDE_DATA(inode));
311 +}
312 +#endif
313 +
314 +static const struct proc_ops tc_desc_conf_proc_fops = {
315 + .proc_open = proc_read_desc_conf_seq_open,
316 + .proc_read = seq_read,
317 + .proc_write = proc_write_desc_conf,
318 + .proc_lseek = seq_lseek,
319 + .proc_release = single_release,
320 +};
321 +
322 static struct tc_proc_list tc_procs[] = {
323 {TC_PROC_DIR, 0, NULL, 1},
324 {"cfg", 0644, &tc_cfg_proc_fops, 0},
325 @@ -1174,6 +1284,9 @@ static struct tc_proc_list tc_procs[] =
326 {"showtime", 0200, &tc_show_time_proc_fops, 0},
327 {"ver", 0644, &tc_ver_proc_fops, 0},
328 {"soc", 0644, &tc_soc_proc_fops, 0},
329 +#ifdef FEATURE_CONF_DESC_LENGTH
330 + {"desc_conf", 0644, &tc_desc_conf_proc_fops, 0},
331 +#endif
332 };
333
334 int tc_proc_init(struct tc_priv *priv)
335 @@ -1333,7 +1446,6 @@ proc_ptm_cfg_help:
336 return count;
337 }
338
339 -
340 static const struct proc_ops ptm_cfg_proc_fops = {
341 .proc_open = proc_read_cfg_seq_open,
342 .proc_read = seq_read,