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