mediatek: mt7622: add Linux 5.10 support
[openwrt/staging/rmilecki.git] / target / linux / mediatek / files-5.10 / drivers / net / phy / rtk / rtl8367c / acl.c
1 /*
2 * Copyright (C) 2013 Realtek Semiconductor Corp.
3 * All Rights Reserved.
4 *
5 * Unless you and Realtek execute a separate written software license
6 * agreement governing use of this software, this software is licensed
7 * to you under the terms of the GNU General Public License version 2,
8 * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
9 *
10 * $Revision: 76306 $
11 * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $
12 *
13 * Purpose : RTK switch high-level API for RTL8367/RTL8367C
14 * Feature : Here is a list of all functions and variables in ACL module.
15 *
16 */
17
18 #include <rtk_switch.h>
19 #include <rtk_error.h>
20 #include <acl.h>
21 #include <vlan.h>
22 #include <svlan.h>
23 #include <rate.h>
24 #include <string.h>
25
26 #include <rtl8367c_asicdrv.h>
27 #include <rtl8367c_asicdrv_acl.h>
28 #include <rtl8367c_asicdrv_hsb.h>
29 #include <rtl8367c_asicdrv_vlan.h>
30 #include <rtl8367c_asicdrv_svlan.h>
31 #include <rtl8367c_asicdrv_cputag.h>
32 #include <rtl8367c_asicdrv_mib.h>
33
34 CONST_T rtk_uint8 filter_templateField[RTL8367C_ACLTEMPLATENO][RTL8367C_ACLRULEFIELDNO] = {
35 {ACL_DMAC0, ACL_DMAC1, ACL_DMAC2, ACL_SMAC0, ACL_SMAC1, ACL_SMAC2, ACL_ETHERTYPE, ACL_FIELD_SELECT15},
36 {ACL_IP4SIP0, ACL_IP4SIP1, ACL_IP4DIP0, ACL_IP4DIP1, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT02, ACL_FIELD_SELECT15},
37 {ACL_IP6SIP0WITHIPV4, ACL_IP6SIP1WITHIPV4,ACL_FIELD_SELECT03, ACL_FIELD_SELECT04, ACL_FIELD_SELECT05, ACL_FIELD_SELECT06, ACL_FIELD_SELECT07, ACL_FIELD_SELECT08},
38 {ACL_IP6DIP0WITHIPV4, ACL_IP6DIP1WITHIPV4,ACL_FIELD_SELECT09, ACL_FIELD_SELECT10, ACL_FIELD_SELECT11, ACL_FIELD_SELECT12, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14},
39 {ACL_VIDRANGE, ACL_IPRANGE, ACL_PORTRANGE, ACL_CTAG, ACL_STAG, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT15}
40 };
41
42 CONST_T rtk_uint8 filter_advanceCaretagField[RTL8367C_ACLTEMPLATENO][2] = {
43 {TRUE, 7},
44 {TRUE, 7},
45 {FALSE, 0},
46 {FALSE, 0},
47 {TRUE, 7},
48 };
49
50
51 CONST_T rtk_uint8 filter_fieldTemplateIndex[FILTER_FIELD_END][RTK_FILTER_FIELD_USED_MAX] = {
52 {0x00, 0x01,0x02},
53 {0x03, 0x04,0x05},
54 {0x06},
55 {0x43},
56 {0x44},
57 {0x10, 0x11},
58 {0x12, 0x13},
59 {0x24},
60 {0x25},
61 {0x35},
62 {0x35},
63 {0x20, 0x21,0x22,0x23},
64 {0x30, 0x31,0x32,0x33},
65 {0x26},
66 {0x27},
67 {0x14},
68 {0x15},
69 {0x16},
70 {0x14},
71 {0x15},
72 {0x14},
73 {0x14},
74 {0x14},
75
76 {0x40},
77 {0x41},
78 {0x42},
79
80 {0x14},
81 {0x15},
82 {0x16},
83 {0x22},
84 {0x23},
85 {0x24},
86 {0x25},
87 {0x26},
88 {0x27},
89 {0x32},
90 {0x33},
91 {0x34},
92 {0x35},
93 {0x36},
94 {0x37},
95 {0x47},
96
97 {0xFF} /* Pattern Match */
98 };
99
100 CONST_T rtk_uint8 filter_fieldSize[FILTER_FIELD_END] = {
101 3, 3, 1, 1, 1,
102 2, 2, 1, 1, 1, 1, 4, 4, 1, 1,
103 1, 1, 1, 1, 1, 1, 1, 1,
104 1, 1, 1,
105 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
106 8
107 };
108
109 CONST_T rtk_uint16 field_selector[RTL8367C_FIELDSEL_FORMAT_NUMBER][2] =
110 {
111 {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 0 */
112 {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 1 */
113 {FIELDSEL_FORMAT_IPPAYLOAD, 12}, /* Field Selector 2 */
114 {FIELDSEL_FORMAT_IPV6, 10}, /* Field Selector 3 */
115 {FIELDSEL_FORMAT_IPV6, 8}, /* Field Selector 4 */
116 {FIELDSEL_FORMAT_IPV4, 0}, /* Field Selector 5 */
117 {FIELDSEL_FORMAT_IPV4, 8}, /* Field Selector 6 */
118 {FIELDSEL_FORMAT_IPV6, 0}, /* Field Selector 7 */
119 {FIELDSEL_FORMAT_IPV6, 6}, /* Field Selector 8 */
120 {FIELDSEL_FORMAT_IPV6, 26}, /* Field Selector 9 */
121 {FIELDSEL_FORMAT_IPV6, 24}, /* Field Selector 10 */
122 {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 11 */
123 {FIELDSEL_FORMAT_IPV4, 6}, /* Field Selector 12 */
124 {FIELDSEL_FORMAT_IPPAYLOAD, 0}, /* Field Selector 13 */
125 {FIELDSEL_FORMAT_IPPAYLOAD, 2}, /* Field Selector 14 */
126 {FIELDSEL_FORMAT_DEFAULT, 0} /* Field Selector 15 */
127 };
128
129
130 static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr);
131
132
133 /* Function Name:
134 * rtk_filter_igrAcl_init
135 * Description:
136 * ACL initialization function
137 * Input:
138 * None
139 * Output:
140 * None
141 * Return:
142 * RT_ERR_OK - OK
143 * RT_ERR_FAILED - Failed
144 * RT_ERR_SMI - SMI access error
145 * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
146 * Note:
147 * This function enable and intialize ACL function
148 */
149 rtk_api_ret_t rtk_filter_igrAcl_init(void)
150 {
151 rtl8367c_acltemplate_t aclTemp;
152 rtk_uint32 i, j;
153 rtk_api_ret_t ret;
154
155 /* Check initialization state */
156 RTK_CHK_INIT_STATE();
157
158 if ((ret = rtk_filter_igrAcl_cfg_delAll()) != RT_ERR_OK)
159 return ret;
160
161 for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
162 {
163 for(j = 0; j < RTL8367C_ACLRULEFIELDNO;j++)
164 aclTemp.field[j] = filter_templateField[i][j];
165
166 if ((ret = rtl8367c_setAsicAclTemplate(i, &aclTemp)) != RT_ERR_OK)
167 return ret;
168 }
169
170 for(i = 0; i < RTL8367C_FIELDSEL_FORMAT_NUMBER; i++)
171 {
172 if ((ret = rtl8367c_setAsicFieldSelector(i, field_selector[i][0], field_selector[i][1])) != RT_ERR_OK)
173 return ret;
174 }
175
176 RTK_SCAN_ALL_PHY_PORTMASK(i)
177 {
178 if ((ret = rtl8367c_setAsicAcl(i, TRUE)) != RT_ERR_OK)
179 return ret;
180
181 if ((ret = rtl8367c_setAsicAclUnmatchedPermit(i, TRUE)) != RT_ERR_OK)
182 return ret;
183 }
184
185 return RT_ERR_OK;
186 }
187
188 /* Function Name:
189 * rtk_filter_igrAcl_field_add
190 * Description:
191 * Add comparison rule to an ACL configuration
192 * Input:
193 * pFilter_cfg - The ACL configuration that this function will add comparison rule
194 * pFilter_field - The comparison rule that will be added.
195 * Output:
196 * None
197 * Return:
198 * RT_ERR_OK - OK
199 * RT_ERR_FAILED - Failed
200 * RT_ERR_SMI - SMI access error
201 * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
202 * RT_ERR_INPUT - Invalid input parameters.
203 * Note:
204 * This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg).
205 * Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL
206 * comparison rules by means of linked list. Pointer pFilter_field will be added to linked
207 * list keeped by structure that pFilter_cfg points to.
208 */
209 rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t* pFilter_cfg, rtk_filter_field_t* pFilter_field)
210 {
211 rtk_uint32 i;
212 rtk_filter_field_t *tailPtr;
213
214 /* Check initialization state */
215 RTK_CHK_INIT_STATE();
216
217 if(NULL == pFilter_cfg || NULL == pFilter_field)
218 return RT_ERR_NULL_POINTER;
219
220 if(pFilter_field->fieldType >= FILTER_FIELD_END)
221 return RT_ERR_ENTRY_INDEX;
222
223
224 if(0 == pFilter_field->fieldTemplateNo)
225 {
226 pFilter_field->fieldTemplateNo = filter_fieldSize[pFilter_field->fieldType];
227
228 for(i = 0; i < pFilter_field->fieldTemplateNo; i++)
229 {
230 pFilter_field->fieldTemplateIdx[i] = filter_fieldTemplateIndex[pFilter_field->fieldType][i];
231 }
232 }
233
234 if(NULL == pFilter_cfg->fieldHead)
235 {
236 pFilter_cfg->fieldHead = pFilter_field;
237 }
238 else
239 {
240 if (pFilter_cfg->fieldHead->next == NULL)
241 {
242 pFilter_cfg->fieldHead->next = pFilter_field;
243 }
244 else
245 {
246 tailPtr = pFilter_cfg->fieldHead->next;
247 while( tailPtr->next != NULL)
248 {
249 tailPtr = tailPtr->next;
250 }
251 tailPtr->next = pFilter_field;
252 }
253 }
254
255 return RT_ERR_OK;
256 }
257
258 static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr)
259 {
260 rtk_uint32 i, tempIdx,fieldIdx, ipValue, ipMask;
261 rtk_uint32 ip6addr[RTK_IPV6_ADDR_WORD_LENGTH];
262 rtk_uint32 ip6mask[RTK_IPV6_ADDR_WORD_LENGTH];
263
264 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
265 {
266 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
267
268 aclRule[tempIdx].valid = TRUE;
269 }
270
271 switch (fieldPtr->fieldType)
272 {
273 /* use DMAC structure as representative for mac structure */
274 case FILTER_FIELD_DMAC:
275 case FILTER_FIELD_SMAC:
276
277 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
278 {
279 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
280 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
281
282 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.value.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.value.octet[5 - (i*2 + 1)] << 8);
283 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.mask.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.mask.octet[5 - (i*2 + 1)] << 8);
284 }
285 break;
286 case FILTER_FIELD_ETHERTYPE:
287 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
288 {
289 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
290 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
291
292 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.value;
293 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.mask;
294 }
295 break;
296 case FILTER_FIELD_IPV4_SIP:
297 case FILTER_FIELD_IPV4_DIP:
298
299 ipValue = fieldPtr->filter_pattern_union.sip.value;
300 ipMask = fieldPtr->filter_pattern_union.sip.mask;
301
302 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
303 {
304 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
305 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
306
307 aclRule[tempIdx].data_bits.field[fieldIdx] = (0xFFFF & (ipValue >> (i*16)));
308 aclRule[tempIdx].care_bits.field[fieldIdx] = (0xFFFF & (ipMask >> (i*16)));
309 }
310 break;
311 case FILTER_FIELD_IPV4_TOS:
312 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
313 {
314 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
315 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
316
317 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.value & 0xFF;
318 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.mask & 0xFF;
319 }
320 break;
321 case FILTER_FIELD_IPV4_PROTOCOL:
322 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
323 {
324 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
325 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
326
327 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.value & 0xFF;
328 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.mask & 0xFF;
329 }
330 break;
331 case FILTER_FIELD_IPV6_SIPV6:
332 case FILTER_FIELD_IPV6_DIPV6:
333 for(i = 0; i < RTK_IPV6_ADDR_WORD_LENGTH; i++)
334 {
335 ip6addr[i] = fieldPtr->filter_pattern_union.sipv6.value.addr[i];
336 ip6mask[i] = fieldPtr->filter_pattern_union.sipv6.mask.addr[i];
337 }
338
339 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
340 {
341 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
342 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
343
344 if(i < 2)
345 {
346 aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[0] & (0xFFFF << (i * 16))) >> (i * 16));
347 aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[0] & (0xFFFF << (i * 16))) >> (i * 16));
348 }
349 else
350 {
351 /*default acl template for ipv6 address supports MSB 32-bits and LSB 32-bits only*/
352 aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16));
353 aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16));
354 }
355 }
356
357 break;
358 case FILTER_FIELD_CTAG:
359 case FILTER_FIELD_STAG:
360
361 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
362 {
363 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
364 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
365
366 aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.value << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.value << 12) | fieldPtr->filter_pattern_union.l2tag.vid.value;
367 aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.mask << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.mask << 12) | fieldPtr->filter_pattern_union.l2tag.vid.mask;
368 }
369 break;
370 case FILTER_FIELD_IPV4_FLAG:
371
372 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
373 {
374 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
375 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
376
377 aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x1FFF;
378 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.value << 15);
379 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.value << 14);
380 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.value << 13);
381
382 aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x1FFF;
383 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.mask << 15);
384 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.mask << 14);
385 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.mask << 13);
386 }
387
388 break;
389 case FILTER_FIELD_IPV4_OFFSET:
390
391 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
392 {
393 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
394 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
395
396 aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xE000;
397 aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.value;
398
399 aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xE000;
400 aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.mask;
401 }
402
403 break;
404
405 case FILTER_FIELD_IPV6_TRAFFIC_CLASS:
406 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
407 {
408 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
409 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
410
411
412 aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.value << 4)&0x0FF0;
413 aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.mask << 4)&0x0FF0;
414 }
415 break;
416 case FILTER_FIELD_IPV6_NEXT_HEADER:
417 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
418 {
419 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
420 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
421
422 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value << 8;
423 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask << 8;
424 }
425 break;
426 case FILTER_FIELD_TCP_SPORT:
427 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
428 {
429 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
430 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
431
432 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.value;
433 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.mask;
434 }
435 break;
436 case FILTER_FIELD_TCP_DPORT:
437 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
438 {
439 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
440 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
441
442 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.value;
443 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.mask;
444 }
445 break;
446 case FILTER_FIELD_TCP_FLAG:
447
448 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
449 {
450 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
451 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
452
453 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.value << 7);
454 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.value << 6);
455 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.value << 5);
456 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.value << 4);
457 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.value << 3);
458 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.value << 2);
459 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.value << 1);
460 aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.value;
461
462 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.mask << 7);
463 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.mask << 6);
464 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.mask << 5);
465 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.mask << 4);
466 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.mask << 3);
467 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.mask << 2);
468 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.mask << 1);
469 aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.mask;
470 }
471 break;
472 case FILTER_FIELD_UDP_SPORT:
473 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
474 {
475 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
476 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
477
478 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.value;
479 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.mask;
480 }
481 break;
482 case FILTER_FIELD_UDP_DPORT:
483 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
484 {
485 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
486 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
487
488 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.value;
489 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.mask;
490 }
491 break;
492 case FILTER_FIELD_ICMP_CODE:
493 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
494 {
495 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
496 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
497
498 aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xFF00;
499 aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.value;
500 aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xFF00;
501 aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.mask;
502 }
503 break;
504 case FILTER_FIELD_ICMP_TYPE:
505 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
506 {
507 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
508 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
509
510 aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x00FF;
511 aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.value << 8);
512 aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x00FF;
513 aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.mask << 8);
514 }
515 break;
516 case FILTER_FIELD_IGMP_TYPE:
517 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
518 {
519 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
520 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
521
522 aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.value << 8);
523 aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.mask << 8);
524 }
525 break;
526 case FILTER_FIELD_PATTERN_MATCH:
527 for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
528 {
529 tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
530 fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
531
532 aclRule[tempIdx].data_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.value[i/2] >> (16 * (i%2))) & 0x0000FFFF );
533 aclRule[tempIdx].care_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.mask[i/2] >> (16 * (i%2))) & 0x0000FFFF );
534 }
535 break;
536 case FILTER_FIELD_VID_RANGE:
537 case FILTER_FIELD_IP_RANGE:
538 case FILTER_FIELD_PORT_RANGE:
539 default:
540 tempIdx = (fieldPtr->fieldTemplateIdx[0] & 0xF0) >> 4;
541 fieldIdx = fieldPtr->fieldTemplateIdx[0] & 0x0F;
542
543 aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value;
544 aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask;
545 break;
546 }
547
548 return RT_ERR_OK;
549 }
550
551 /* Function Name:
552 * rtk_filter_igrAcl_cfg_add
553 * Description:
554 * Add an ACL configuration to ASIC
555 * Input:
556 * filter_id - Start index of ACL configuration.
557 * pFilter_cfg - The ACL configuration that this function will add comparison rule
558 * pFilter_action - Action(s) of ACL configuration.
559 * Output:
560 * ruleNum - number of rules written in acl table
561 * Return:
562 * RT_ERR_OK - OK
563 * RT_ERR_FAILED - Failed
564 * RT_ERR_SMI - SMI access error
565 * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
566 * RT_ERR_INPUT - Invalid input parameters.
567 * RT_ERR_ENTRY_INDEX - Invalid filter_id .
568 * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL.
569 * RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip.
570 * RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported.
571 * Note:
572 * This function store pFilter_cfg, pFilter_action into ASIC. The starting
573 * index(es) is filter_id.
574 */
575 rtk_api_ret_t rtk_filter_igrAcl_cfg_add(rtk_filter_id_t filter_id, rtk_filter_cfg_t* pFilter_cfg, rtk_filter_action_t* pFilter_action, rtk_filter_number_t *ruleNum)
576 {
577 rtk_api_ret_t retVal;
578 rtk_uint32 careTagData, careTagMask;
579 rtk_uint32 i,vidx, svidx, actType, ruleId;
580 rtk_uint32 aclActCtrl;
581 rtk_uint32 cpuPort;
582 rtk_filter_field_t* fieldPtr;
583 rtl8367c_aclrule aclRule[RTL8367C_ACLTEMPLATENO];
584 rtl8367c_aclrule tempRule;
585 rtl8367c_acl_act_t aclAct;
586 rtk_uint32 noRulesAdd;
587 rtk_uint32 portmask;
588 /* Check initialization state */
589 RTK_CHK_INIT_STATE();
590
591 if(filter_id > RTL8367C_ACLRULEMAX )
592 return RT_ERR_ENTRY_INDEX;
593
594 if((NULL == pFilter_cfg) || (NULL == pFilter_action) || (NULL == ruleNum))
595 return RT_ERR_NULL_POINTER;
596
597 fieldPtr = pFilter_cfg->fieldHead;
598
599 /* init RULE */
600 for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
601 {
602 memset(&aclRule[i], 0, sizeof(rtl8367c_aclrule));
603
604 aclRule[i].data_bits.type= i;
605 aclRule[i].care_bits.type= 0x7;
606 }
607
608 while(NULL != fieldPtr)
609 {
610 _rtk_filter_igrAcl_writeDataField(aclRule, fieldPtr);
611
612 fieldPtr = fieldPtr->next;
613 }
614
615 /*set care tag mask in User Defined Field 15*/
616 /*Follow care tag should not be used while ACL template and User defined fields are fully control by system designer*/
617 /*those advanced packet type care tag is used in default template design structure only*/
618 careTagData = 0;
619 careTagMask = 0;
620
621 for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++)
622 {
623 if(pFilter_cfg->careTag.tagType[i].mask)
624 careTagMask = careTagMask | (1 << (i-CARE_TAG_TCP));
625
626 if(pFilter_cfg->careTag.tagType[i].value)
627 careTagData = careTagData | (1 << (i-CARE_TAG_TCP));
628 }
629
630 if(careTagData || careTagMask)
631 {
632 i = 0;
633 while(i < RTL8367C_ACLTEMPLATENO)
634 {
635 if(aclRule[i].valid == 1 && filter_advanceCaretagField[i][0] == TRUE)
636 {
637
638 aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF;
639 aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF;
640 break;
641 }
642 i++;
643 }
644 /*none of previous used template containing field 15*/
645 if(i == RTL8367C_ACLTEMPLATENO)
646 {
647 i = 0;
648 while(i < RTL8367C_ACLTEMPLATENO)
649 {
650 if(filter_advanceCaretagField[i][0] == TRUE)
651 {
652 aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF;
653 aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF;
654 aclRule[i].valid = 1;
655 break;
656 }
657 i++;
658 }
659 }
660 }
661
662 /*Check rule number*/
663 noRulesAdd = 0;
664 for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
665 {
666 if(1 == aclRule[i].valid)
667 {
668 noRulesAdd ++;
669 }
670 }
671
672 *ruleNum = noRulesAdd;
673
674 if((filter_id + noRulesAdd - 1) > RTL8367C_ACLRULEMAX)
675 {
676 return RT_ERR_ENTRY_INDEX;
677 }
678
679 /*set care tag mask in TAG Indicator*/
680 careTagData = 0;
681 careTagMask = 0;
682
683 for(i = 0; i <= CARE_TAG_IPV6;i++)
684 {
685 if(0 == pFilter_cfg->careTag.tagType[i].mask )
686 {
687 careTagMask &= ~(1 << i);
688 }
689 else
690 {
691 careTagMask |= (1 << i);
692 if(0 == pFilter_cfg->careTag.tagType[i].value )
693 careTagData &= ~(1 << i);
694 else
695 careTagData |= (1 << i);
696 }
697 }
698
699 for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
700 {
701 aclRule[i].data_bits.tag_exist = (careTagData) & ACL_RULE_CARETAG_MASK;
702 aclRule[i].care_bits.tag_exist = (careTagMask) & ACL_RULE_CARETAG_MASK;
703 }
704
705 RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.value);
706 RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.mask);
707
708 for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
709 {
710 if(TRUE == aclRule[i].valid)
711 {
712 if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.value, &portmask) != RT_ERR_OK)
713 return RT_ERR_PORT_MASK;
714
715 aclRule[i].data_bits.active_portmsk = portmask;
716
717 if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.mask, &portmask) != RT_ERR_OK)
718 return RT_ERR_PORT_MASK;
719
720 aclRule[i].care_bits.active_portmsk = portmask;
721 }
722 }
723
724 if(pFilter_cfg->invert >= FILTER_INVERT_END )
725 return RT_ERR_INPUT;
726
727
728 /*Last action gets high priority if actions are the same*/
729 memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t));
730 aclActCtrl = 0;
731 for(actType = 0; actType < FILTER_ENACT_END; actType ++)
732 {
733 if(pFilter_action->actEnable[actType])
734 {
735 switch (actType)
736 {
737 case FILTER_ENACT_CVLAN_INGRESS:
738 if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX)
739 return RT_ERR_INPUT;
740
741 if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK)
742 {
743 return retVal;
744 }
745 aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
746 aclAct.cvidx_cact = vidx;
747
748 if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
749 {
750 if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
751 aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
752 }
753 else
754 {
755 aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
756 }
757
758 aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
759 break;
760 case FILTER_ENACT_CVLAN_EGRESS:
761 if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX)
762 return RT_ERR_INPUT;
763
764 if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK)
765 return retVal;
766
767 aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
768 aclAct.cvidx_cact = vidx;
769
770 if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
771 {
772 if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
773 aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
774 }
775 else
776 {
777 aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
778 }
779
780 aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
781 break;
782 case FILTER_ENACT_CVLAN_SVID:
783
784 aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
785
786 if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
787 {
788 if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
789 aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
790 }
791 else
792 {
793 aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
794 }
795
796 aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
797 break;
798 case FILTER_ENACT_POLICING_1:
799 if(pFilter_action->filterPolicingIdx[1] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
800 return RT_ERR_INPUT;
801
802 aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
803 aclAct.cvidx_cact = pFilter_action->filterPolicingIdx[1];
804
805 if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
806 {
807 if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
808 aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
809 }
810 else
811 {
812 aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
813 }
814
815 aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
816 break;
817
818 case FILTER_ENACT_SVLAN_INGRESS:
819 case FILTER_ENACT_SVLAN_EGRESS:
820
821 if((retVal = rtk_svlan_checkAndCreateMbr(pFilter_action->filterSvlanVid, &svidx)) != RT_ERR_OK)
822 return retVal;
823
824 aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType);
825 aclAct.svidx_sact = svidx;
826 aclActCtrl |= FILTER_ENACT_SVLAN_MASK;
827 break;
828 case FILTER_ENACT_SVLAN_CVID:
829
830 aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType);
831 aclActCtrl |= FILTER_ENACT_SVLAN_MASK;
832 break;
833 case FILTER_ENACT_POLICING_2:
834 if(pFilter_action->filterPolicingIdx[2] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
835 return RT_ERR_INPUT;
836
837 aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType);
838 aclAct.svidx_sact = pFilter_action->filterPolicingIdx[2];
839 aclActCtrl |= FILTER_ENACT_SVLAN_MASK;
840 break;
841 case FILTER_ENACT_POLICING_0:
842 if(pFilter_action->filterPolicingIdx[0] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
843 return RT_ERR_INPUT;
844
845 aclAct.aclmeteridx = pFilter_action->filterPolicingIdx[0];
846 aclActCtrl |= FILTER_ENACT_POLICING_MASK;
847 break;
848 case FILTER_ENACT_PRIORITY:
849 case FILTER_ENACT_1P_REMARK:
850 if(pFilter_action->filterPriority > RTL8367C_PRIMAX)
851 return RT_ERR_INPUT;
852
853 aclAct.priact = FILTER_ENACT_PRI_TYPE(actType);
854 aclAct.pridx = pFilter_action->filterPriority;
855 aclActCtrl |= FILTER_ENACT_PRIORITY_MASK;
856 break;
857 case FILTER_ENACT_DSCP_REMARK:
858 if(pFilter_action->filterPriority > RTL8367C_DSCPMAX)
859 return RT_ERR_INPUT;
860
861 aclAct.priact = FILTER_ENACT_PRI_TYPE(actType);
862 aclAct.pridx = pFilter_action->filterPriority;
863 aclActCtrl |= FILTER_ENACT_PRIORITY_MASK;
864 break;
865 case FILTER_ENACT_POLICING_3:
866 if(pFilter_action->filterPriority >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
867 return RT_ERR_INPUT;
868
869 aclAct.priact = FILTER_ENACT_PRI_TYPE(actType);
870 aclAct.pridx = pFilter_action->filterPolicingIdx[3];
871 aclActCtrl |= FILTER_ENACT_PRIORITY_MASK;
872 break;
873 case FILTER_ENACT_DROP:
874
875 aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_REDIRECT);
876 aclAct.fwdact_ext = FALSE;
877
878 aclAct.fwdpmask = 0;
879 aclActCtrl |= FILTER_ENACT_FWD_MASK;
880 break;
881 case FILTER_ENACT_REDIRECT:
882 RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
883
884 aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
885 aclAct.fwdact_ext = FALSE;
886
887 if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
888 return RT_ERR_PORT_MASK;
889 aclAct.fwdpmask = portmask;
890
891 aclActCtrl |= FILTER_ENACT_FWD_MASK;
892 break;
893
894 case FILTER_ENACT_ADD_DSTPORT:
895 RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
896
897 aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
898 aclAct.fwdact_ext = FALSE;
899
900 if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
901 return RT_ERR_PORT_MASK;
902 aclAct.fwdpmask = portmask;
903
904 aclActCtrl |= FILTER_ENACT_FWD_MASK;
905 break;
906 case FILTER_ENACT_MIRROR:
907 RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
908
909 aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
910 aclAct.cact_ext = FALSE;
911
912 if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
913 return RT_ERR_PORT_MASK;
914 aclAct.fwdpmask = portmask;
915
916 aclActCtrl |= FILTER_ENACT_FWD_MASK;
917 break;
918 case FILTER_ENACT_TRAP_CPU:
919
920 aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
921 aclAct.fwdact_ext = FALSE;
922
923 aclActCtrl |= FILTER_ENACT_FWD_MASK;
924 break;
925 case FILTER_ENACT_COPY_CPU:
926 if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK)
927 return retVal;
928
929 aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_MIRROR);
930 aclAct.fwdact_ext = FALSE;
931
932 aclAct.fwdpmask = 1 << cpuPort;
933 aclActCtrl |= FILTER_ENACT_FWD_MASK;
934 break;
935 case FILTER_ENACT_ISOLATION:
936 RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
937
938 aclAct.fwdact_ext = TRUE;
939
940 if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
941 return RT_ERR_PORT_MASK;
942 aclAct.fwdpmask = portmask;
943
944 aclActCtrl |= FILTER_ENACT_FWD_MASK;
945 break;
946
947 case FILTER_ENACT_INTERRUPT:
948
949 aclAct.aclint = TRUE;
950 aclActCtrl |= FILTER_ENACT_INTGPIO_MASK;
951 break;
952 case FILTER_ENACT_GPO:
953
954 aclAct.gpio_en = TRUE;
955 aclAct.gpio_pin = pFilter_action->filterPin;
956 aclActCtrl |= FILTER_ENACT_INTGPIO_MASK;
957 break;
958 case FILTER_ENACT_EGRESSCTAG_TAG:
959
960 if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
961 {
962 if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
963 aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
964 }
965 else
966 {
967 aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
968 }
969 aclAct.tag_fmt = FILTER_CTAGFMT_TAG;
970 aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
971 break;
972 case FILTER_ENACT_EGRESSCTAG_UNTAG:
973
974 if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
975 {
976 if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
977 aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
978 }
979 else
980 {
981 aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
982 }
983 aclAct.tag_fmt = FILTER_CTAGFMT_UNTAG;
984 aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
985 break;
986 case FILTER_ENACT_EGRESSCTAG_KEEP:
987
988 if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
989 {
990 if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
991 aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
992 }
993 else
994 {
995 aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
996 }
997 aclAct.tag_fmt = FILTER_CTAGFMT_KEEP;
998 aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
999 break;
1000 case FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK:
1001
1002 if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
1003 {
1004 if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
1005 aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
1006 }
1007 else
1008 {
1009 aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
1010 }
1011 aclAct.tag_fmt = FILTER_CTAGFMT_KEEP1PRMK;
1012 aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
1013 break;
1014 default:
1015 return RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT;
1016 }
1017 }
1018 }
1019
1020
1021 /*check if free ACL rules are enough*/
1022 for(i = filter_id; i < (filter_id + noRulesAdd); i++)
1023 {
1024 if((retVal = rtl8367c_getAsicAclRule(i, &tempRule)) != RT_ERR_OK )
1025 return retVal;
1026
1027 if(tempRule.valid == TRUE)
1028 {
1029 return RT_ERR_TBL_FULL;
1030 }
1031 }
1032
1033 ruleId = 0;
1034 for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
1035 {
1036 if(aclRule[i].valid == TRUE)
1037 {
1038 /* write ACL action control */
1039 if((retVal = rtl8367c_setAsicAclActCtrl(filter_id + ruleId, aclActCtrl)) != RT_ERR_OK )
1040 return retVal;
1041 /* write ACL action */
1042 if((retVal = rtl8367c_setAsicAclAct(filter_id + ruleId, &aclAct)) != RT_ERR_OK )
1043 return retVal;
1044
1045 /* write ACL not */
1046 if((retVal = rtl8367c_setAsicAclNot(filter_id + ruleId, pFilter_cfg->invert)) != RT_ERR_OK )
1047 return retVal;
1048 /* write ACL rule */
1049 if((retVal = rtl8367c_setAsicAclRule(filter_id + ruleId, &aclRule[i])) != RT_ERR_OK )
1050 return retVal;
1051
1052 /* only the first rule will be written with input action control, aclActCtrl of other rules will be zero */
1053 aclActCtrl = 0;
1054 memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t));
1055
1056 ruleId ++;
1057 }
1058 }
1059
1060 return RT_ERR_OK;
1061 }
1062
1063 /* Function Name:
1064 * rtk_filter_igrAcl_cfg_del
1065 * Description:
1066 * Delete an ACL configuration from ASIC
1067 * Input:
1068 * filter_id - Start index of ACL configuration.
1069 * Output:
1070 * None
1071 * Return:
1072 * RT_ERR_OK - OK
1073 * RT_ERR_FAILED - Failed
1074 * RT_ERR_SMI - SMI access error
1075 * RT_ERR_FILTER_ENTRYIDX - Invalid filter_id.
1076 * Note:
1077 * This function delete a group of ACL rules starting from filter_id.
1078 */
1079 rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id)
1080 {
1081 rtl8367c_aclrule initRule;
1082 rtl8367c_acl_act_t initAct;
1083 rtk_api_ret_t ret;
1084
1085 /* Check initialization state */
1086 RTK_CHK_INIT_STATE();
1087
1088 if(filter_id > RTL8367C_ACLRULEMAX )
1089 return RT_ERR_FILTER_ENTRYIDX;
1090
1091 memset(&initRule, 0, sizeof(rtl8367c_aclrule));
1092 memset(&initAct, 0, sizeof(rtl8367c_acl_act_t));
1093
1094 if((ret = rtl8367c_setAsicAclRule(filter_id, &initRule)) != RT_ERR_OK)
1095 return ret;
1096 if((ret = rtl8367c_setAsicAclActCtrl(filter_id, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK)
1097 return ret;
1098 if((ret = rtl8367c_setAsicAclAct(filter_id, &initAct)) != RT_ERR_OK)
1099 return ret;
1100 if((ret = rtl8367c_setAsicAclNot(filter_id, DISABLED)) != RT_ERR_OK )
1101 return ret;
1102
1103 return RT_ERR_OK;
1104 }
1105
1106 /* Function Name:
1107 * rtk_filter_igrAcl_cfg_delAll
1108 * Description:
1109 * Delete all ACL entries from ASIC
1110 * Input:
1111 * None
1112 * Output:
1113 * None
1114 * Return:
1115 * RT_ERR_OK - OK
1116 * RT_ERR_FAILED - Failed
1117 * RT_ERR_SMI - SMI access error
1118 * Note:
1119 * This function delete all ACL configuration from ASIC.
1120 */
1121 rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void)
1122 {
1123 rtk_uint32 i;
1124 rtk_api_ret_t ret;
1125
1126 /* Check initialization state */
1127 RTK_CHK_INIT_STATE();
1128
1129 for(i = 0; i < RTL8367C_ACLRULENO; i++)
1130 {
1131 if((ret = rtl8367c_setAsicAclActCtrl(i, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK)
1132 return ret;
1133 if((ret = rtl8367c_setAsicAclNot(i, DISABLED)) != RT_ERR_OK )
1134 return ret;
1135 }
1136
1137 return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_RESET_CFG, RTL8367C_ACL_RESET_CFG_OFFSET, TRUE);;
1138 }
1139
1140 /* Function Name:
1141 * rtk_filter_igrAcl_cfg_get
1142 * Description:
1143 * Get one ingress acl configuration from ASIC.
1144 * Input:
1145 * filter_id - Start index of ACL configuration.
1146 * Output:
1147 * pFilter_cfg - buffer pointer of ingress acl data
1148 * pFilter_action - buffer pointer of ingress acl action
1149 * Return:
1150 * RT_ERR_OK - OK
1151 * RT_ERR_FAILED - Failed
1152 * RT_ERR_SMI - SMI access error
1153 * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL.
1154 * RT_ERR_FILTER_ENTRYIDX - Invalid entry index.
1155 * Note:
1156 * This function get configuration from ASIC.
1157 */
1158 rtk_api_ret_t rtk_filter_igrAcl_cfg_get(rtk_filter_id_t filter_id, rtk_filter_cfg_raw_t *pFilter_cfg, rtk_filter_action_t *pAction)
1159 {
1160 rtk_api_ret_t retVal;
1161 rtk_uint32 i, tmp;
1162 rtl8367c_aclrule aclRule;
1163 rtl8367c_acl_act_t aclAct;
1164 rtk_uint32 cpuPort;
1165 rtl8367c_acltemplate_t type;
1166 rtl8367c_svlan_memconf_t svlan_cfg;
1167 rtl8367c_vlanconfiguser vlanMC;
1168 rtk_uint32 phyPmask;
1169
1170 /* Check initialization state */
1171 RTK_CHK_INIT_STATE();
1172
1173 if(NULL == pFilter_cfg || NULL == pAction)
1174 return RT_ERR_NULL_POINTER;
1175
1176 if(filter_id > RTL8367C_ACLRULEMAX)
1177 return RT_ERR_ENTRY_INDEX;
1178
1179 if ((retVal = rtl8367c_getAsicAclRule(filter_id, &aclRule)) != RT_ERR_OK)
1180 return retVal;
1181
1182 /* Check valid */
1183 if(aclRule.valid == 0)
1184 {
1185 pFilter_cfg->valid = DISABLED;
1186 return RT_ERR_OK;
1187 }
1188
1189 phyPmask = aclRule.data_bits.active_portmsk;
1190 if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.value)) != RT_ERR_OK)
1191 return RT_ERR_FAILED;
1192
1193 phyPmask = aclRule.care_bits.active_portmsk;
1194 if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.mask)) != RT_ERR_OK)
1195 return RT_ERR_FAILED;
1196
1197 for(i = 0; i <= CARE_TAG_IPV6; i++)
1198 {
1199 if(aclRule.data_bits.tag_exist & (1 << i))
1200 pFilter_cfg->careTag.tagType[i].value = 1;
1201 else
1202 pFilter_cfg->careTag.tagType[i].value = 0;
1203
1204 if (aclRule.care_bits.tag_exist & (1 << i))
1205 pFilter_cfg->careTag.tagType[i].mask = 1;
1206 else
1207 pFilter_cfg->careTag.tagType[i].mask = 0;
1208 }
1209
1210 if(filter_advanceCaretagField[aclRule.data_bits.type][0] == TRUE)
1211 {
1212 /* Advanced Care tag setting */
1213 for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++)
1214 {
1215 if(aclRule.data_bits.field[filter_advanceCaretagField[aclRule.data_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) )
1216 pFilter_cfg->careTag.tagType[i].value = 1;
1217 else
1218 pFilter_cfg->careTag.tagType[i].value = 0;
1219
1220 if(aclRule.care_bits.field[filter_advanceCaretagField[aclRule.care_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) )
1221 pFilter_cfg->careTag.tagType[i].mask = 1;
1222 else
1223 pFilter_cfg->careTag.tagType[i].mask = 0;
1224 }
1225 }
1226
1227 for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++)
1228 {
1229 pFilter_cfg->careFieldRaw[i] = aclRule.care_bits.field[i];
1230 pFilter_cfg->dataFieldRaw[i] = aclRule.data_bits.field[i];
1231 }
1232
1233 if ((retVal = rtl8367c_getAsicAclNot(filter_id, &tmp))!= RT_ERR_OK)
1234 return retVal;
1235
1236 pFilter_cfg->invert = tmp;
1237
1238 pFilter_cfg->valid = aclRule.valid;
1239
1240 memset(pAction, 0, sizeof(rtk_filter_action_t));
1241
1242 if ((retVal = rtl8367c_getAsicAclActCtrl(filter_id, &tmp))!= RT_ERR_OK)
1243 return retVal;
1244
1245 if ((retVal = rtl8367c_getAsicAclAct(filter_id, &aclAct)) != RT_ERR_OK)
1246 return retVal;
1247
1248 if(tmp & FILTER_ENACT_FWD_MASK)
1249 {
1250 if(TRUE == aclAct.fwdact_ext)
1251 {
1252 pAction->actEnable[FILTER_ENACT_ISOLATION] = TRUE;
1253
1254 phyPmask = aclAct.fwdpmask;
1255 if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
1256 return RT_ERR_FAILED;
1257 }
1258 else if(aclAct.fwdact == RTL8367C_ACL_FWD_TRAP)
1259 {
1260 pAction->actEnable[FILTER_ENACT_TRAP_CPU] = TRUE;
1261 }
1262 else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRRORFUNTION )
1263 {
1264 pAction->actEnable[FILTER_ENACT_MIRROR] = TRUE;
1265
1266 phyPmask = aclAct.fwdpmask;
1267 if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
1268 return RT_ERR_FAILED;
1269 }
1270 else if (aclAct.fwdact == RTL8367C_ACL_FWD_REDIRECT)
1271 {
1272 if(aclAct.fwdpmask == 0 )
1273 pAction->actEnable[FILTER_ENACT_DROP] = TRUE;
1274 else
1275 {
1276 pAction->actEnable[FILTER_ENACT_REDIRECT] = TRUE;
1277
1278 phyPmask = aclAct.fwdpmask;
1279 if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
1280 return RT_ERR_FAILED;
1281 }
1282 }
1283 else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRROR)
1284 {
1285 if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK)
1286 return retVal;
1287 if (aclAct.fwdpmask == (1 << cpuPort))
1288 {
1289 pAction->actEnable[FILTER_ENACT_COPY_CPU] = TRUE;
1290 }
1291 else
1292 {
1293 pAction->actEnable[FILTER_ENACT_ADD_DSTPORT] = TRUE;
1294
1295 phyPmask = aclAct.fwdpmask;
1296 if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
1297 return RT_ERR_FAILED;
1298 }
1299 }
1300 else
1301 {
1302 return RT_ERR_FAILED;
1303 }
1304 }
1305
1306 if(tmp & FILTER_ENACT_POLICING_MASK)
1307 {
1308 pAction->actEnable[FILTER_ENACT_POLICING_0] = TRUE;
1309 pAction->filterPolicingIdx[0] = aclAct.aclmeteridx;
1310 }
1311
1312 if(tmp & FILTER_ENACT_PRIORITY_MASK)
1313 {
1314 if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_PRIORITY))
1315 {
1316 pAction->actEnable[FILTER_ENACT_PRIORITY] = TRUE;
1317 pAction->filterPriority = aclAct.pridx;
1318 }
1319 else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_1P_REMARK))
1320 {
1321 pAction->actEnable[FILTER_ENACT_1P_REMARK] = TRUE;
1322 pAction->filterPriority = aclAct.pridx;
1323 }
1324 else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_DSCP_REMARK))
1325 {
1326 pAction->actEnable[FILTER_ENACT_DSCP_REMARK] = TRUE;
1327 pAction->filterPriority = aclAct.pridx;
1328 }
1329 else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_POLICING_3))
1330 {
1331 pAction->actEnable[FILTER_ENACT_POLICING_3] = TRUE;
1332 pAction->filterPolicingIdx[3] = aclAct.pridx;
1333 }
1334 }
1335
1336 if(tmp & FILTER_ENACT_SVLAN_MASK)
1337 {
1338 if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_INGRESS))
1339 {
1340 if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK)
1341 return retVal;
1342
1343 pAction->actEnable[FILTER_ENACT_SVLAN_INGRESS] = TRUE;
1344 pAction->filterSvlanIdx = aclAct.svidx_sact;
1345 pAction->filterSvlanVid = svlan_cfg.vs_svid;
1346 }
1347 else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_EGRESS))
1348 {
1349 if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK)
1350 return retVal;
1351
1352 pAction->actEnable[FILTER_ENACT_SVLAN_EGRESS] = TRUE;
1353 pAction->filterSvlanIdx = aclAct.svidx_sact;
1354 pAction->filterSvlanVid = svlan_cfg.vs_svid;
1355 }
1356 else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_CVID))
1357 pAction->actEnable[FILTER_ENACT_SVLAN_CVID] = TRUE;
1358 else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_POLICING_2))
1359 {
1360 pAction->actEnable[FILTER_ENACT_POLICING_2] = TRUE;
1361 pAction->filterPolicingIdx[2] = aclAct.svidx_sact;
1362 }
1363 }
1364
1365
1366 if(tmp & FILTER_ENACT_CVLAN_MASK)
1367 {
1368 if(FILTER_ENACT_CACTEXT_TAGONLY == aclAct.cact_ext ||
1369 FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext )
1370 {
1371 if(FILTER_CTAGFMT_UNTAG == aclAct.tag_fmt)
1372 {
1373 pAction->actEnable[FILTER_ENACT_EGRESSCTAG_UNTAG] = TRUE;
1374 }
1375 else if(FILTER_CTAGFMT_TAG == aclAct.tag_fmt)
1376 {
1377 pAction->actEnable[FILTER_ENACT_EGRESSCTAG_TAG] = TRUE;
1378 }
1379 else if(FILTER_CTAGFMT_KEEP == aclAct.tag_fmt)
1380 {
1381 pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEP] = TRUE;
1382 }
1383 else if(FILTER_CTAGFMT_KEEP1PRMK== aclAct.tag_fmt)
1384 {
1385 pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK] = TRUE;
1386 }
1387
1388 }
1389
1390 if(FILTER_ENACT_CACTEXT_VLANONLY == aclAct.cact_ext ||
1391 FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext )
1392 {
1393 if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_INGRESS))
1394 {
1395 if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK)
1396 return retVal;
1397
1398 pAction->actEnable[FILTER_ENACT_CVLAN_INGRESS] = TRUE;
1399 pAction->filterCvlanIdx = aclAct.cvidx_cact;
1400 pAction->filterCvlanVid = vlanMC.evid;
1401 }
1402 else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_EGRESS))
1403 {
1404 if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK)
1405 return retVal;
1406
1407 pAction->actEnable[FILTER_ENACT_CVLAN_EGRESS] = TRUE;
1408 pAction->filterCvlanIdx = aclAct.cvidx_cact;
1409 pAction->filterCvlanVid = vlanMC.evid;
1410 }
1411 else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_SVID))
1412 {
1413 pAction->actEnable[FILTER_ENACT_CVLAN_SVID] = TRUE;
1414 }
1415 else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_POLICING_1))
1416 {
1417 pAction->actEnable[FILTER_ENACT_POLICING_1] = TRUE;
1418 pAction->filterPolicingIdx[1] = aclAct.cvidx_cact;
1419 }
1420 }
1421 }
1422
1423 if(tmp & FILTER_ENACT_INTGPIO_MASK)
1424 {
1425 if(TRUE == aclAct.aclint)
1426 {
1427 pAction->actEnable[FILTER_ENACT_INTERRUPT] = TRUE;
1428 }
1429
1430 if(TRUE == aclAct.gpio_en)
1431 {
1432 pAction->actEnable[FILTER_ENACT_GPO] = TRUE;
1433 pAction->filterPin = aclAct.gpio_pin;
1434 }
1435 }
1436
1437 /* Get field type of RAW data */
1438 if ((retVal = rtl8367c_getAsicAclTemplate(aclRule.data_bits.type, &type))!= RT_ERR_OK)
1439 return retVal;
1440
1441 for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++)
1442 {
1443 pFilter_cfg->fieldRawType[i] = type.field[i];
1444 }/* end of for(i...) */
1445
1446 return RT_ERR_OK;
1447 }
1448
1449 /* Function Name:
1450 * rtk_filter_igrAcl_unmatchAction_set
1451 * Description:
1452 * Set action to packets when no ACL configuration match
1453 * Input:
1454 * port - Port id.
1455 * action - Action.
1456 * Output:
1457 * None
1458 * Return:
1459 * RT_ERR_OK - OK
1460 * RT_ERR_FAILED - Failed
1461 * RT_ERR_SMI - SMI access error
1462 * RT_ERR_PORT_ID - Invalid port id.
1463 * RT_ERR_INPUT - Invalid input parameters.
1464 * Note:
1465 * This function sets action of packets when no ACL configruation matches.
1466 */
1467 rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action)
1468 {
1469 rtk_api_ret_t ret;
1470
1471 /* Check initialization state */
1472 RTK_CHK_INIT_STATE();
1473
1474 /* Check port valid */
1475 RTK_CHK_PORT_VALID(port);
1476
1477 if(action >= FILTER_UNMATCH_END)
1478 return RT_ERR_INPUT;
1479
1480 if((ret = rtl8367c_setAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), action)) != RT_ERR_OK)
1481 return ret;
1482
1483 return RT_ERR_OK;
1484 }
1485
1486 /* Function Name:
1487 * rtk_filter_igrAcl_unmatchAction_get
1488 * Description:
1489 * Get action to packets when no ACL configuration match
1490 * Input:
1491 * port - Port id.
1492 * Output:
1493 * pAction - Action.
1494 * Return:
1495 * RT_ERR_OK - OK
1496 * RT_ERR_FAILED - Failed
1497 * RT_ERR_SMI - SMI access error
1498 * RT_ERR_PORT_ID - Invalid port id.
1499 * RT_ERR_INPUT - Invalid input parameters.
1500 * Note:
1501 * This function gets action of packets when no ACL configruation matches.
1502 */
1503 rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* pAction)
1504 {
1505 rtk_api_ret_t ret;
1506
1507 /* Check initialization state */
1508 RTK_CHK_INIT_STATE();
1509
1510 if(NULL == pAction)
1511 return RT_ERR_NULL_POINTER;
1512
1513 /* Check port valid */
1514 RTK_CHK_PORT_VALID(port);
1515
1516 if((ret = rtl8367c_getAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), pAction)) != RT_ERR_OK)
1517 return ret;
1518
1519 return RT_ERR_OK;
1520 }
1521
1522 /* Function Name:
1523 * rtk_filter_igrAcl_state_set
1524 * Description:
1525 * Set state of ingress ACL.
1526 * Input:
1527 * port - Port id.
1528 * state - Ingress ACL state.
1529 * Output:
1530 * None
1531 * Return:
1532 * RT_ERR_OK - OK
1533 * RT_ERR_FAILED - Failed
1534 * RT_ERR_SMI - SMI access error
1535 * RT_ERR_PORT_ID - Invalid port id.
1536 * RT_ERR_INPUT - Invalid input parameters.
1537 * Note:
1538 * This function gets action of packets when no ACL configruation matches.
1539 */
1540 rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state)
1541 {
1542 rtk_api_ret_t ret;
1543
1544 /* Check initialization state */
1545 RTK_CHK_INIT_STATE();
1546
1547 /* Check port valid */
1548 RTK_CHK_PORT_VALID(port);
1549
1550 if(state >= RTK_ENABLE_END)
1551 return RT_ERR_INPUT;
1552
1553 if((ret = rtl8367c_setAsicAcl(rtk_switch_port_L2P_get(port), state)) != RT_ERR_OK)
1554 return ret;
1555
1556 return RT_ERR_OK;
1557 }
1558
1559 /* Function Name:
1560 * rtk_filter_igrAcl_state_get
1561 * Description:
1562 * Get state of ingress ACL.
1563 * Input:
1564 * port - Port id.
1565 * Output:
1566 * pState - Ingress ACL state.
1567 * Return:
1568 * RT_ERR_OK - OK
1569 * RT_ERR_FAILED - Failed
1570 * RT_ERR_SMI - SMI access error
1571 * RT_ERR_PORT_ID - Invalid port id.
1572 * RT_ERR_INPUT - Invalid input parameters.
1573 * Note:
1574 * This function gets action of packets when no ACL configruation matches.
1575 */
1576 rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* pState)
1577 {
1578 rtk_api_ret_t ret;
1579
1580 /* Check initialization state */
1581 RTK_CHK_INIT_STATE();
1582
1583 if(NULL == pState)
1584 return RT_ERR_NULL_POINTER;
1585
1586 /* Check port valid */
1587 RTK_CHK_PORT_VALID(port);
1588
1589 if((ret = rtl8367c_getAsicAcl(rtk_switch_port_L2P_get(port), pState)) != RT_ERR_OK)
1590 return ret;
1591
1592 return RT_ERR_OK;
1593 }
1594 /* Function Name:
1595 * rtk_filter_igrAcl_template_set
1596 * Description:
1597 * Set template of ingress ACL.
1598 * Input:
1599 * template - Ingress ACL template
1600 * Output:
1601 * None
1602 * Return:
1603 * RT_ERR_OK - OK
1604 * RT_ERR_FAILED - Failed
1605 * RT_ERR_SMI - SMI access error
1606 * RT_ERR_INPUT - Invalid input parameters.
1607 * Note:
1608 * This function set ACL template.
1609 */
1610 rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate)
1611 {
1612 rtk_api_ret_t retVal;
1613 rtk_uint32 idxField;
1614 rtl8367c_acltemplate_t aclType;
1615
1616 /* Check initialization state */
1617 RTK_CHK_INIT_STATE();
1618
1619 if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE)
1620 return RT_ERR_INPUT;
1621
1622 for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++)
1623 {
1624 if(aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_DMAC_15_0 ||
1625 (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_CTAG && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV4_SIP_15_0 ) ||
1626 (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV4_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV6_SIP_15_0 ) ||
1627 (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV6_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_VIDRANGE ) ||
1628 (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_FIELD_VALID && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_FIELD_SELECT00 ) ||
1629 aclTemplate->fieldType[idxField] >= FILTER_FIELD_RAW_END)
1630 {
1631 return RT_ERR_INPUT;
1632 }
1633 }
1634
1635 for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++)
1636 {
1637 aclType.field[idxField] = aclTemplate->fieldType[idxField];
1638 }
1639
1640 if((retVal = rtl8367c_setAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK)
1641 return retVal;
1642
1643 return RT_ERR_OK;
1644 }
1645
1646 /* Function Name:
1647 * rtk_filter_igrAcl_template_get
1648 * Description:
1649 * Get template of ingress ACL.
1650 * Input:
1651 * template - Ingress ACL template
1652 * Output:
1653 * None
1654 * Return:
1655 * RT_ERR_OK - OK
1656 * RT_ERR_FAILED - Failed
1657 * RT_ERR_SMI - SMI access error
1658 * Note:
1659 * This function gets template of ACL.
1660 */
1661 rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate)
1662 {
1663 rtk_api_ret_t ret;
1664 rtk_uint32 idxField;
1665 rtl8367c_acltemplate_t aclType;
1666
1667 /* Check initialization state */
1668 RTK_CHK_INIT_STATE();
1669
1670 if(NULL == aclTemplate)
1671 return RT_ERR_NULL_POINTER;
1672
1673 if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE)
1674 return RT_ERR_INPUT;
1675
1676 if((ret = rtl8367c_getAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK)
1677 return ret;
1678
1679 for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField ++)
1680 {
1681 aclTemplate->fieldType[idxField] = aclType.field[idxField];
1682 }
1683
1684 return RT_ERR_OK;
1685 }
1686
1687 /* Function Name:
1688 * rtk_filter_igrAcl_field_sel_set
1689 * Description:
1690 * Set user defined field selectors in HSB
1691 * Input:
1692 * index - index of field selector 0-15
1693 * format - Format of field selector
1694 * offset - Retrieving data offset
1695 * Output:
1696 * None
1697 * Return:
1698 * RT_ERR_OK - OK
1699 * RT_ERR_FAILED - Failed
1700 * RT_ERR_SMI - SMI access error
1701 * Note:
1702 * System support 16 user defined field selctors.
1703 * Each selector can be enabled or disable.
1704 * User can defined retrieving 16-bits in many predefiend
1705 * standard l2/l3/l4 payload.
1706 */
1707 rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset)
1708 {
1709 rtk_api_ret_t ret;
1710
1711 /* Check initialization state */
1712 RTK_CHK_INIT_STATE();
1713
1714 if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER)
1715 return RT_ERR_OUT_OF_RANGE;
1716
1717 if(format >= FORMAT_END)
1718 return RT_ERR_OUT_OF_RANGE;
1719
1720 if(offset > RTL8367C_FIELDSEL_MAX_OFFSET)
1721 return RT_ERR_OUT_OF_RANGE;
1722
1723 if((ret = rtl8367c_setAsicFieldSelector(index, (rtk_uint32)format, offset)) != RT_ERR_OK)
1724 return ret;
1725
1726 return RT_ERR_OK;
1727 }
1728
1729 /* Function Name:
1730 * rtk_filter_igrAcl_field_sel_get
1731 * Description:
1732 * Get user defined field selectors in HSB
1733 * Input:
1734 * index - index of field selector 0-15
1735 * Output:
1736 * pFormat - Format of field selector
1737 * pOffset - Retrieving data offset
1738 * Return:
1739 * RT_ERR_OK - OK
1740 * RT_ERR_FAILED - Failed
1741 * RT_ERR_SMI - SMI access error
1742 * Note:
1743 * None.
1744 */
1745 rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset)
1746 {
1747 rtk_api_ret_t ret;
1748
1749 /* Check initialization state */
1750 RTK_CHK_INIT_STATE();
1751
1752 if(NULL == pFormat || NULL == pOffset)
1753 return RT_ERR_NULL_POINTER;
1754
1755 if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER)
1756 return RT_ERR_OUT_OF_RANGE;
1757
1758 if((ret = rtl8367c_getAsicFieldSelector(index, pFormat, pOffset)) != RT_ERR_OK)
1759 return ret;
1760
1761 return RT_ERR_OK;
1762 }
1763
1764 /* Function Name:
1765 * rtk_filter_iprange_set
1766 * Description:
1767 * Set IP Range check
1768 * Input:
1769 * index - index of IP Range 0-15
1770 * type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP
1771 * upperIp - The upper bound of IP range
1772 * lowerIp - The lower Bound of IP range
1773 * Output:
1774 * None.
1775 * Return:
1776 * RT_ERR_OK - OK
1777 * RT_ERR_FAILED - Failed
1778 * RT_ERR_SMI - SMI access error
1779 * RT_ERR_OUT_OF_RANGE - The parameter is out of range
1780 * RT_ERR_INPUT - Input error
1781 * Note:
1782 * upperIp must be larger or equal than lowerIp.
1783 */
1784 rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp)
1785 {
1786 rtk_api_ret_t ret;
1787
1788 /* Check initialization state */
1789 RTK_CHK_INIT_STATE();
1790
1791 if(index > RTL8367C_ACLRANGEMAX)
1792 return RT_ERR_OUT_OF_RANGE;
1793
1794 if(type >= IPRANGE_END)
1795 return RT_ERR_OUT_OF_RANGE;
1796
1797 if(lowerIp > upperIp)
1798 return RT_ERR_INPUT;
1799
1800 if((ret = rtl8367c_setAsicAclIpRange(index, type, upperIp, lowerIp)) != RT_ERR_OK)
1801 return ret;
1802
1803 return RT_ERR_OK;
1804 }
1805
1806 /* Function Name:
1807 * rtk_filter_iprange_get
1808 * Description:
1809 * Set IP Range check
1810 * Input:
1811 * index - index of IP Range 0-15
1812 * Output:
1813 * pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP
1814 * pUpperIp - The upper bound of IP range
1815 * pLowerIp - The lower Bound of IP range
1816 * Return:
1817 * RT_ERR_OK - OK
1818 * RT_ERR_FAILED - Failed
1819 * RT_ERR_SMI - SMI access error
1820 * RT_ERR_OUT_OF_RANGE - The parameter is out of range
1821 * Note:
1822 * None.
1823 */
1824 rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp)
1825 {
1826 rtk_api_ret_t ret;
1827
1828 /* Check initialization state */
1829 RTK_CHK_INIT_STATE();
1830
1831 if((NULL == pType) || (NULL == pUpperIp) || (NULL == pLowerIp))
1832 return RT_ERR_NULL_POINTER;
1833
1834 if(index > RTL8367C_ACLRANGEMAX)
1835 return RT_ERR_OUT_OF_RANGE;
1836
1837 if((ret = rtl8367c_getAsicAclIpRange(index, pType, pUpperIp, pLowerIp)) != RT_ERR_OK)
1838 return ret;
1839
1840 return RT_ERR_OK;
1841 }
1842
1843 /* Function Name:
1844 * rtk_filter_vidrange_set
1845 * Description:
1846 * Set VID Range check
1847 * Input:
1848 * index - index of VID Range 0-15
1849 * type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID
1850 * upperVid - The upper bound of VID range
1851 * lowerVid - The lower Bound of VID range
1852 * Output:
1853 * None.
1854 * Return:
1855 * RT_ERR_OK - OK
1856 * RT_ERR_FAILED - Failed
1857 * RT_ERR_SMI - SMI access error
1858 * RT_ERR_OUT_OF_RANGE - The parameter is out of range
1859 * RT_ERR_INPUT - Input error
1860 * Note:
1861 * upperVid must be larger or equal than lowerVid.
1862 */
1863 rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid)
1864 {
1865 rtk_api_ret_t ret;
1866
1867 /* Check initialization state */
1868 RTK_CHK_INIT_STATE();
1869
1870 if(index > RTL8367C_ACLRANGEMAX)
1871 return RT_ERR_OUT_OF_RANGE;
1872
1873 if(type >= VIDRANGE_END)
1874 return RT_ERR_OUT_OF_RANGE;
1875
1876 if(lowerVid > upperVid)
1877 return RT_ERR_INPUT;
1878
1879 if( (upperVid > RTL8367C_VIDMAX) || (lowerVid > RTL8367C_VIDMAX))
1880 return RT_ERR_OUT_OF_RANGE;
1881
1882 if((ret = rtl8367c_setAsicAclVidRange(index, type, upperVid, lowerVid)) != RT_ERR_OK)
1883 return ret;
1884
1885 return RT_ERR_OK;
1886 }
1887
1888 /* Function Name:
1889 * rtk_filter_vidrange_get
1890 * Description:
1891 * Get VID Range check
1892 * Input:
1893 * index - index of VID Range 0-15
1894 * Output:
1895 * pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID
1896 * pUpperVid - The upper bound of VID range
1897 * pLowerVid - The lower Bound of VID range
1898 * Return:
1899 * RT_ERR_OK - OK
1900 * RT_ERR_FAILED - Failed
1901 * RT_ERR_SMI - SMI access error
1902 * RT_ERR_OUT_OF_RANGE - The parameter is out of range
1903 * Note:
1904 * None.
1905 */
1906 rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid)
1907 {
1908 rtk_api_ret_t ret;
1909
1910 /* Check initialization state */
1911 RTK_CHK_INIT_STATE();
1912
1913 if((NULL == pType) || (NULL == pUpperVid) || (NULL == pLowerVid))
1914 return RT_ERR_NULL_POINTER;
1915
1916 if(index > RTL8367C_ACLRANGEMAX)
1917 return RT_ERR_OUT_OF_RANGE;
1918
1919 if((ret = rtl8367c_getAsicAclVidRange(index, pType, pUpperVid, pLowerVid)) != RT_ERR_OK)
1920 return ret;
1921
1922 return RT_ERR_OK;
1923 }
1924
1925 /* Function Name:
1926 * rtk_filter_portrange_set
1927 * Description:
1928 * Set Port Range check
1929 * Input:
1930 * index - index of Port Range 0-15
1931 * type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port
1932 * upperPort - The upper bound of Port range
1933 * lowerPort - The lower Bound of Port range
1934 * Output:
1935 * None.
1936 * Return:
1937 * RT_ERR_OK - OK
1938 * RT_ERR_FAILED - Failed
1939 * RT_ERR_SMI - SMI access error
1940 * RT_ERR_OUT_OF_RANGE - The parameter is out of range
1941 * RT_ERR_INPUT - Input error
1942 * Note:
1943 * upperPort must be larger or equal than lowerPort.
1944 */
1945 rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort)
1946 {
1947 rtk_api_ret_t ret;
1948
1949 /* Check initialization state */
1950 RTK_CHK_INIT_STATE();
1951
1952 if(index > RTL8367C_ACLRANGEMAX)
1953 return RT_ERR_OUT_OF_RANGE;
1954
1955 if(type >= PORTRANGE_END)
1956 return RT_ERR_OUT_OF_RANGE;
1957
1958 if(lowerPort > upperPort)
1959 return RT_ERR_INPUT;
1960
1961 if(upperPort > RTL8367C_ACL_PORTRANGEMAX)
1962 return RT_ERR_INPUT;
1963
1964 if(lowerPort > RTL8367C_ACL_PORTRANGEMAX)
1965 return RT_ERR_INPUT;
1966
1967 if((ret = rtl8367c_setAsicAclPortRange(index, type, upperPort, lowerPort)) != RT_ERR_OK)
1968 return ret;
1969
1970 return RT_ERR_OK;
1971 }
1972
1973 /* Function Name:
1974 * rtk_filter_portrange_get
1975 * Description:
1976 * Set Port Range check
1977 * Input:
1978 * index - index of Port Range 0-15
1979 * Output:
1980 * pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port
1981 * pUpperPort - The upper bound of Port range
1982 * pLowerPort - The lower Bound of Port range
1983 * Return:
1984 * RT_ERR_OK - OK
1985 * RT_ERR_FAILED - Failed
1986 * RT_ERR_SMI - SMI access error
1987 * RT_ERR_OUT_OF_RANGE - The parameter is out of range
1988 * RT_ERR_INPUT - Input error
1989 * Note:
1990 * None.
1991 */
1992 rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort)
1993 {
1994 rtk_api_ret_t ret;
1995
1996 /* Check initialization state */
1997 RTK_CHK_INIT_STATE();
1998
1999 if((NULL == pType) || (NULL == pUpperPort) || (NULL == pLowerPort))
2000 return RT_ERR_NULL_POINTER;
2001
2002 if(index > RTL8367C_ACLRANGEMAX)
2003 return RT_ERR_OUT_OF_RANGE;
2004
2005 if((ret = rtl8367c_getAsicAclPortRange(index, pType, pUpperPort, pLowerPort)) != RT_ERR_OK)
2006 return ret;
2007
2008 return RT_ERR_OK;
2009 }
2010
2011 /* Function Name:
2012 * rtk_filter_igrAclPolarity_set
2013 * Description:
2014 * Set ACL Goip control palarity
2015 * Input:
2016 * polarity - 1: High, 0: Low
2017 * Output:
2018 * None
2019 * Return:
2020 * RT_ERR_OK - Success
2021 * RT_ERR_SMI - SMI access error
2022 * Note:
2023 * none
2024 */
2025 rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity)
2026 {
2027 /* Check initialization state */
2028 RTK_CHK_INIT_STATE();
2029
2030 if(polarity > 1)
2031 return RT_ERR_OUT_OF_RANGE;
2032 return rtl8367c_setAsicAclGpioPolarity(polarity);
2033 }
2034 /* Function Name:
2035 * rtk_filter_igrAclPolarity_get
2036 * Description:
2037 * Get ACL Goip control palarity
2038 * Input:
2039 * pPolarity - 1: High, 0: Low
2040 * Output:
2041 * None
2042 * Return:
2043 * RT_ERR_OK - Success
2044 * RT_ERR_SMI - SMI access error
2045 * Note:
2046 * none
2047 */
2048 rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity)
2049 {
2050 /* Check initialization state */
2051 RTK_CHK_INIT_STATE();
2052
2053 if(NULL == pPolarity)
2054 return RT_ERR_NULL_POINTER;
2055
2056 return rtl8367c_getAsicAclGpioPolarity(pPolarity);
2057 }
2058
2059
2060
2061