aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c')
-rw-r--r--target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c2061
1 files changed, 2061 insertions, 0 deletions
diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c
new file mode 100644
index 0000000000..75e5a5e740
--- /dev/null
+++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c
@@ -0,0 +1,2061 @@
+/*
+ * Copyright (C) 2013 Realtek Semiconductor Corp.
+ * All Rights Reserved.
+ *
+ * Unless you and Realtek execute a separate written software license
+ * agreement governing use of this software, this software is licensed
+ * to you under the terms of the GNU General Public License version 2,
+ * available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+ *
+ * $Revision: 76306 $
+ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $
+ *
+ * Purpose : RTK switch high-level API for RTL8367/RTL8367C
+ * Feature : Here is a list of all functions and variables in ACL module.
+ *
+ */
+
+#include <rtk_switch.h>
+#include <rtk_error.h>
+#include <acl.h>
+#include <vlan.h>
+#include <svlan.h>
+#include <rate.h>
+#include <string.h>
+
+#include <rtl8367c_asicdrv.h>
+#include <rtl8367c_asicdrv_acl.h>
+#include <rtl8367c_asicdrv_hsb.h>
+#include <rtl8367c_asicdrv_vlan.h>
+#include <rtl8367c_asicdrv_svlan.h>
+#include <rtl8367c_asicdrv_cputag.h>
+#include <rtl8367c_asicdrv_mib.h>
+
+CONST_T rtk_uint8 filter_templateField[RTL8367C_ACLTEMPLATENO][RTL8367C_ACLRULEFIELDNO] = {
+ {ACL_DMAC0, ACL_DMAC1, ACL_DMAC2, ACL_SMAC0, ACL_SMAC1, ACL_SMAC2, ACL_ETHERTYPE, ACL_FIELD_SELECT15},
+ {ACL_IP4SIP0, ACL_IP4SIP1, ACL_IP4DIP0, ACL_IP4DIP1, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT02, ACL_FIELD_SELECT15},
+ {ACL_IP6SIP0WITHIPV4, ACL_IP6SIP1WITHIPV4,ACL_FIELD_SELECT03, ACL_FIELD_SELECT04, ACL_FIELD_SELECT05, ACL_FIELD_SELECT06, ACL_FIELD_SELECT07, ACL_FIELD_SELECT08},
+ {ACL_IP6DIP0WITHIPV4, ACL_IP6DIP1WITHIPV4,ACL_FIELD_SELECT09, ACL_FIELD_SELECT10, ACL_FIELD_SELECT11, ACL_FIELD_SELECT12, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14},
+ {ACL_VIDRANGE, ACL_IPRANGE, ACL_PORTRANGE, ACL_CTAG, ACL_STAG, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT15}
+};
+
+CONST_T rtk_uint8 filter_advanceCaretagField[RTL8367C_ACLTEMPLATENO][2] = {
+ {TRUE, 7},
+ {TRUE, 7},
+ {FALSE, 0},
+ {FALSE, 0},
+ {TRUE, 7},
+};
+
+
+CONST_T rtk_uint8 filter_fieldTemplateIndex[FILTER_FIELD_END][RTK_FILTER_FIELD_USED_MAX] = {
+ {0x00, 0x01,0x02},
+ {0x03, 0x04,0x05},
+ {0x06},
+ {0x43},
+ {0x44},
+ {0x10, 0x11},
+ {0x12, 0x13},
+ {0x24},
+ {0x25},
+ {0x35},
+ {0x35},
+ {0x20, 0x21,0x22,0x23},
+ {0x30, 0x31,0x32,0x33},
+ {0x26},
+ {0x27},
+ {0x14},
+ {0x15},
+ {0x16},
+ {0x14},
+ {0x15},
+ {0x14},
+ {0x14},
+ {0x14},
+
+ {0x40},
+ {0x41},
+ {0x42},
+
+ {0x14},
+ {0x15},
+ {0x16},
+ {0x22},
+ {0x23},
+ {0x24},
+ {0x25},
+ {0x26},
+ {0x27},
+ {0x32},
+ {0x33},
+ {0x34},
+ {0x35},
+ {0x36},
+ {0x37},
+ {0x47},
+
+ {0xFF} /* Pattern Match */
+};
+
+CONST_T rtk_uint8 filter_fieldSize[FILTER_FIELD_END] = {
+ 3, 3, 1, 1, 1,
+ 2, 2, 1, 1, 1, 1, 4, 4, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 8
+};
+
+CONST_T rtk_uint16 field_selector[RTL8367C_FIELDSEL_FORMAT_NUMBER][2] =
+{
+ {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 0 */
+ {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 1 */
+ {FIELDSEL_FORMAT_IPPAYLOAD, 12}, /* Field Selector 2 */
+ {FIELDSEL_FORMAT_IPV6, 10}, /* Field Selector 3 */
+ {FIELDSEL_FORMAT_IPV6, 8}, /* Field Selector 4 */
+ {FIELDSEL_FORMAT_IPV4, 0}, /* Field Selector 5 */
+ {FIELDSEL_FORMAT_IPV4, 8}, /* Field Selector 6 */
+ {FIELDSEL_FORMAT_IPV6, 0}, /* Field Selector 7 */
+ {FIELDSEL_FORMAT_IPV6, 6}, /* Field Selector 8 */
+ {FIELDSEL_FORMAT_IPV6, 26}, /* Field Selector 9 */
+ {FIELDSEL_FORMAT_IPV6, 24}, /* Field Selector 10 */
+ {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 11 */
+ {FIELDSEL_FORMAT_IPV4, 6}, /* Field Selector 12 */
+ {FIELDSEL_FORMAT_IPPAYLOAD, 0}, /* Field Selector 13 */
+ {FIELDSEL_FORMAT_IPPAYLOAD, 2}, /* Field Selector 14 */
+ {FIELDSEL_FORMAT_DEFAULT, 0} /* Field Selector 15 */
+};
+
+
+static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr);
+
+
+/* Function Name:
+ * rtk_filter_igrAcl_init
+ * Description:
+ * ACL initialization function
+ * Input:
+ * None
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
+ * Note:
+ * This function enable and intialize ACL function
+ */
+rtk_api_ret_t rtk_filter_igrAcl_init(void)
+{
+ rtl8367c_acltemplate_t aclTemp;
+ rtk_uint32 i, j;
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if ((ret = rtk_filter_igrAcl_cfg_delAll()) != RT_ERR_OK)
+ return ret;
+
+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
+ {
+ for(j = 0; j < RTL8367C_ACLRULEFIELDNO;j++)
+ aclTemp.field[j] = filter_templateField[i][j];
+
+ if ((ret = rtl8367c_setAsicAclTemplate(i, &aclTemp)) != RT_ERR_OK)
+ return ret;
+ }
+
+ for(i = 0; i < RTL8367C_FIELDSEL_FORMAT_NUMBER; i++)
+ {
+ if ((ret = rtl8367c_setAsicFieldSelector(i, field_selector[i][0], field_selector[i][1])) != RT_ERR_OK)
+ return ret;
+ }
+
+ RTK_SCAN_ALL_PHY_PORTMASK(i)
+ {
+ if ((ret = rtl8367c_setAsicAcl(i, TRUE)) != RT_ERR_OK)
+ return ret;
+
+ if ((ret = rtl8367c_setAsicAclUnmatchedPermit(i, TRUE)) != RT_ERR_OK)
+ return ret;
+ }
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_field_add
+ * Description:
+ * Add comparison rule to an ACL configuration
+ * Input:
+ * pFilter_cfg - The ACL configuration that this function will add comparison rule
+ * pFilter_field - The comparison rule that will be added.
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
+ * RT_ERR_INPUT - Invalid input parameters.
+ * Note:
+ * This function add a comparison rule (*pFilter_field) to an ACL configuration (*pFilter_cfg).
+ * Pointer pFilter_cfg points to an ACL configuration structure, this structure keeps multiple ACL
+ * comparison rules by means of linked list. Pointer pFilter_field will be added to linked
+ * list keeped by structure that pFilter_cfg points to.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t* pFilter_cfg, rtk_filter_field_t* pFilter_field)
+{
+ rtk_uint32 i;
+ rtk_filter_field_t *tailPtr;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(NULL == pFilter_cfg || NULL == pFilter_field)
+ return RT_ERR_NULL_POINTER;
+
+ if(pFilter_field->fieldType >= FILTER_FIELD_END)
+ return RT_ERR_ENTRY_INDEX;
+
+
+ if(0 == pFilter_field->fieldTemplateNo)
+ {
+ pFilter_field->fieldTemplateNo = filter_fieldSize[pFilter_field->fieldType];
+
+ for(i = 0; i < pFilter_field->fieldTemplateNo; i++)
+ {
+ pFilter_field->fieldTemplateIdx[i] = filter_fieldTemplateIndex[pFilter_field->fieldType][i];
+ }
+ }
+
+ if(NULL == pFilter_cfg->fieldHead)
+ {
+ pFilter_cfg->fieldHead = pFilter_field;
+ }
+ else
+ {
+ if (pFilter_cfg->fieldHead->next == NULL)
+ {
+ pFilter_cfg->fieldHead->next = pFilter_field;
+ }
+ else
+ {
+ tailPtr = pFilter_cfg->fieldHead->next;
+ while( tailPtr->next != NULL)
+ {
+ tailPtr = tailPtr->next;
+ }
+ tailPtr->next = pFilter_field;
+ }
+ }
+
+ return RT_ERR_OK;
+}
+
+static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr)
+{
+ rtk_uint32 i, tempIdx,fieldIdx, ipValue, ipMask;
+ rtk_uint32 ip6addr[RTK_IPV6_ADDR_WORD_LENGTH];
+ rtk_uint32 ip6mask[RTK_IPV6_ADDR_WORD_LENGTH];
+
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+
+ aclRule[tempIdx].valid = TRUE;
+ }
+
+ switch (fieldPtr->fieldType)
+ {
+ /* use DMAC structure as representative for mac structure */
+ case FILTER_FIELD_DMAC:
+ case FILTER_FIELD_SMAC:
+
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ 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);
+ 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);
+ }
+ break;
+ case FILTER_FIELD_ETHERTYPE:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.value;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.mask;
+ }
+ break;
+ case FILTER_FIELD_IPV4_SIP:
+ case FILTER_FIELD_IPV4_DIP:
+
+ ipValue = fieldPtr->filter_pattern_union.sip.value;
+ ipMask = fieldPtr->filter_pattern_union.sip.mask;
+
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = (0xFFFF & (ipValue >> (i*16)));
+ aclRule[tempIdx].care_bits.field[fieldIdx] = (0xFFFF & (ipMask >> (i*16)));
+ }
+ break;
+ case FILTER_FIELD_IPV4_TOS:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.value & 0xFF;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.mask & 0xFF;
+ }
+ break;
+ case FILTER_FIELD_IPV4_PROTOCOL:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.value & 0xFF;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.mask & 0xFF;
+ }
+ break;
+ case FILTER_FIELD_IPV6_SIPV6:
+ case FILTER_FIELD_IPV6_DIPV6:
+ for(i = 0; i < RTK_IPV6_ADDR_WORD_LENGTH; i++)
+ {
+ ip6addr[i] = fieldPtr->filter_pattern_union.sipv6.value.addr[i];
+ ip6mask[i] = fieldPtr->filter_pattern_union.sipv6.mask.addr[i];
+ }
+
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ if(i < 2)
+ {
+ aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[0] & (0xFFFF << (i * 16))) >> (i * 16));
+ aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[0] & (0xFFFF << (i * 16))) >> (i * 16));
+ }
+ else
+ {
+ /*default acl template for ipv6 address supports MSB 32-bits and LSB 32-bits only*/
+ aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16));
+ aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16));
+ }
+ }
+
+ break;
+ case FILTER_FIELD_CTAG:
+ case FILTER_FIELD_STAG:
+
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ 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;
+ 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;
+ }
+ break;
+ case FILTER_FIELD_IPV4_FLAG:
+
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x1FFF;
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.value << 15);
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.value << 14);
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.value << 13);
+
+ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x1FFF;
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.mask << 15);
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.mask << 14);
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.mask << 13);
+ }
+
+ break;
+ case FILTER_FIELD_IPV4_OFFSET:
+
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xE000;
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.value;
+
+ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xE000;
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.mask;
+ }
+
+ break;
+
+ case FILTER_FIELD_IPV6_TRAFFIC_CLASS:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.value << 4)&0x0FF0;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.mask << 4)&0x0FF0;
+ }
+ break;
+ case FILTER_FIELD_IPV6_NEXT_HEADER:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value << 8;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask << 8;
+ }
+ break;
+ case FILTER_FIELD_TCP_SPORT:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.value;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.mask;
+ }
+ break;
+ case FILTER_FIELD_TCP_DPORT:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.value;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.mask;
+ }
+ break;
+ case FILTER_FIELD_TCP_FLAG:
+
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.value << 7);
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.value << 6);
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.value << 5);
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.value << 4);
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.value << 3);
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.value << 2);
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.value << 1);
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.value;
+
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.mask << 7);
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.mask << 6);
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.mask << 5);
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.mask << 4);
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.mask << 3);
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.mask << 2);
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.mask << 1);
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.mask;
+ }
+ break;
+ case FILTER_FIELD_UDP_SPORT:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.value;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.mask;
+ }
+ break;
+ case FILTER_FIELD_UDP_DPORT:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.value;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.mask;
+ }
+ break;
+ case FILTER_FIELD_ICMP_CODE:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xFF00;
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.value;
+ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xFF00;
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.mask;
+ }
+ break;
+ case FILTER_FIELD_ICMP_TYPE:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x00FF;
+ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.value << 8);
+ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x00FF;
+ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.mask << 8);
+ }
+ break;
+ case FILTER_FIELD_IGMP_TYPE:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.value << 8);
+ aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.mask << 8);
+ }
+ break;
+ case FILTER_FIELD_PATTERN_MATCH:
+ for(i = 0; i < fieldPtr->fieldTemplateNo; i++)
+ {
+ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.value[i/2] >> (16 * (i%2))) & 0x0000FFFF );
+ aclRule[tempIdx].care_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.mask[i/2] >> (16 * (i%2))) & 0x0000FFFF );
+ }
+ break;
+ case FILTER_FIELD_VID_RANGE:
+ case FILTER_FIELD_IP_RANGE:
+ case FILTER_FIELD_PORT_RANGE:
+ default:
+ tempIdx = (fieldPtr->fieldTemplateIdx[0] & 0xF0) >> 4;
+ fieldIdx = fieldPtr->fieldTemplateIdx[0] & 0x0F;
+
+ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value;
+ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask;
+ break;
+ }
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_cfg_add
+ * Description:
+ * Add an ACL configuration to ASIC
+ * Input:
+ * filter_id - Start index of ACL configuration.
+ * pFilter_cfg - The ACL configuration that this function will add comparison rule
+ * pFilter_action - Action(s) of ACL configuration.
+ * Output:
+ * ruleNum - number of rules written in acl table
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_NULL_POINTER - Pointer pFilter_field or pFilter_cfg point to NULL.
+ * RT_ERR_INPUT - Invalid input parameters.
+ * RT_ERR_ENTRY_INDEX - Invalid filter_id .
+ * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL.
+ * RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT - Action is not supported in this chip.
+ * RT_ERR_FILTER_INACL_RULE_NOT_SUPPORT - Rule is not supported.
+ * Note:
+ * This function store pFilter_cfg, pFilter_action into ASIC. The starting
+ * index(es) is filter_id.
+ */
+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)
+{
+ rtk_api_ret_t retVal;
+ rtk_uint32 careTagData, careTagMask;
+ rtk_uint32 i,vidx, svidx, actType, ruleId;
+ rtk_uint32 aclActCtrl;
+ rtk_uint32 cpuPort;
+ rtk_filter_field_t* fieldPtr;
+ rtl8367c_aclrule aclRule[RTL8367C_ACLTEMPLATENO];
+ rtl8367c_aclrule tempRule;
+ rtl8367c_acl_act_t aclAct;
+ rtk_uint32 noRulesAdd;
+ rtk_uint32 portmask;
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(filter_id > RTL8367C_ACLRULEMAX )
+ return RT_ERR_ENTRY_INDEX;
+
+ if((NULL == pFilter_cfg) || (NULL == pFilter_action) || (NULL == ruleNum))
+ return RT_ERR_NULL_POINTER;
+
+ fieldPtr = pFilter_cfg->fieldHead;
+
+ /* init RULE */
+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
+ {
+ memset(&aclRule[i], 0, sizeof(rtl8367c_aclrule));
+
+ aclRule[i].data_bits.type= i;
+ aclRule[i].care_bits.type= 0x7;
+ }
+
+ while(NULL != fieldPtr)
+ {
+ _rtk_filter_igrAcl_writeDataField(aclRule, fieldPtr);
+
+ fieldPtr = fieldPtr->next;
+ }
+
+ /*set care tag mask in User Defined Field 15*/
+ /*Follow care tag should not be used while ACL template and User defined fields are fully control by system designer*/
+ /*those advanced packet type care tag is used in default template design structure only*/
+ careTagData = 0;
+ careTagMask = 0;
+
+ for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++)
+ {
+ if(pFilter_cfg->careTag.tagType[i].mask)
+ careTagMask = careTagMask | (1 << (i-CARE_TAG_TCP));
+
+ if(pFilter_cfg->careTag.tagType[i].value)
+ careTagData = careTagData | (1 << (i-CARE_TAG_TCP));
+ }
+
+ if(careTagData || careTagMask)
+ {
+ i = 0;
+ while(i < RTL8367C_ACLTEMPLATENO)
+ {
+ if(aclRule[i].valid == 1 && filter_advanceCaretagField[i][0] == TRUE)
+ {
+
+ aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF;
+ aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF;
+ break;
+ }
+ i++;
+ }
+ /*none of previous used template containing field 15*/
+ if(i == RTL8367C_ACLTEMPLATENO)
+ {
+ i = 0;
+ while(i < RTL8367C_ACLTEMPLATENO)
+ {
+ if(filter_advanceCaretagField[i][0] == TRUE)
+ {
+ aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF;
+ aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF;
+ aclRule[i].valid = 1;
+ break;
+ }
+ i++;
+ }
+ }
+ }
+
+ /*Check rule number*/
+ noRulesAdd = 0;
+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
+ {
+ if(1 == aclRule[i].valid)
+ {
+ noRulesAdd ++;
+ }
+ }
+
+ *ruleNum = noRulesAdd;
+
+ if((filter_id + noRulesAdd - 1) > RTL8367C_ACLRULEMAX)
+ {
+ return RT_ERR_ENTRY_INDEX;
+ }
+
+ /*set care tag mask in TAG Indicator*/
+ careTagData = 0;
+ careTagMask = 0;
+
+ for(i = 0; i <= CARE_TAG_IPV6;i++)
+ {
+ if(0 == pFilter_cfg->careTag.tagType[i].mask )
+ {
+ careTagMask &= ~(1 << i);
+ }
+ else
+ {
+ careTagMask |= (1 << i);
+ if(0 == pFilter_cfg->careTag.tagType[i].value )
+ careTagData &= ~(1 << i);
+ else
+ careTagData |= (1 << i);
+ }
+ }
+
+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
+ {
+ aclRule[i].data_bits.tag_exist = (careTagData) & ACL_RULE_CARETAG_MASK;
+ aclRule[i].care_bits.tag_exist = (careTagMask) & ACL_RULE_CARETAG_MASK;
+ }
+
+ RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.value);
+ RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.mask);
+
+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
+ {
+ if(TRUE == aclRule[i].valid)
+ {
+ if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.value, &portmask) != RT_ERR_OK)
+ return RT_ERR_PORT_MASK;
+
+ aclRule[i].data_bits.active_portmsk = portmask;
+
+ if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.mask, &portmask) != RT_ERR_OK)
+ return RT_ERR_PORT_MASK;
+
+ aclRule[i].care_bits.active_portmsk = portmask;
+ }
+ }
+
+ if(pFilter_cfg->invert >= FILTER_INVERT_END )
+ return RT_ERR_INPUT;
+
+
+ /*Last action gets high priority if actions are the same*/
+ memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t));
+ aclActCtrl = 0;
+ for(actType = 0; actType < FILTER_ENACT_END; actType ++)
+ {
+ if(pFilter_action->actEnable[actType])
+ {
+ switch (actType)
+ {
+ case FILTER_ENACT_CVLAN_INGRESS:
+ if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX)
+ return RT_ERR_INPUT;
+
+ if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK)
+ {
+ return retVal;
+ }
+ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
+ aclAct.cvidx_cact = vidx;
+
+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
+ {
+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
+ }
+ else
+ {
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
+ }
+
+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
+ break;
+ case FILTER_ENACT_CVLAN_EGRESS:
+ if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX)
+ return RT_ERR_INPUT;
+
+ if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK)
+ return retVal;
+
+ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
+ aclAct.cvidx_cact = vidx;
+
+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
+ {
+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
+ }
+ else
+ {
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
+ }
+
+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
+ break;
+ case FILTER_ENACT_CVLAN_SVID:
+
+ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
+
+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
+ {
+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
+ }
+ else
+ {
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
+ }
+
+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
+ break;
+ case FILTER_ENACT_POLICING_1:
+ if(pFilter_action->filterPolicingIdx[1] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
+ return RT_ERR_INPUT;
+
+ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType);
+ aclAct.cvidx_cact = pFilter_action->filterPolicingIdx[1];
+
+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
+ {
+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY)
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
+ }
+ else
+ {
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY;
+ }
+
+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
+ break;
+
+ case FILTER_ENACT_SVLAN_INGRESS:
+ case FILTER_ENACT_SVLAN_EGRESS:
+
+ if((retVal = rtk_svlan_checkAndCreateMbr(pFilter_action->filterSvlanVid, &svidx)) != RT_ERR_OK)
+ return retVal;
+
+ aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType);
+ aclAct.svidx_sact = svidx;
+ aclActCtrl |= FILTER_ENACT_SVLAN_MASK;
+ break;
+ case FILTER_ENACT_SVLAN_CVID:
+
+ aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType);
+ aclActCtrl |= FILTER_ENACT_SVLAN_MASK;
+ break;
+ case FILTER_ENACT_POLICING_2:
+ if(pFilter_action->filterPolicingIdx[2] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
+ return RT_ERR_INPUT;
+
+ aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType);
+ aclAct.svidx_sact = pFilter_action->filterPolicingIdx[2];
+ aclActCtrl |= FILTER_ENACT_SVLAN_MASK;
+ break;
+ case FILTER_ENACT_POLICING_0:
+ if(pFilter_action->filterPolicingIdx[0] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
+ return RT_ERR_INPUT;
+
+ aclAct.aclmeteridx = pFilter_action->filterPolicingIdx[0];
+ aclActCtrl |= FILTER_ENACT_POLICING_MASK;
+ break;
+ case FILTER_ENACT_PRIORITY:
+ case FILTER_ENACT_1P_REMARK:
+ if(pFilter_action->filterPriority > RTL8367C_PRIMAX)
+ return RT_ERR_INPUT;
+
+ aclAct.priact = FILTER_ENACT_PRI_TYPE(actType);
+ aclAct.pridx = pFilter_action->filterPriority;
+ aclActCtrl |= FILTER_ENACT_PRIORITY_MASK;
+ break;
+ case FILTER_ENACT_DSCP_REMARK:
+ if(pFilter_action->filterPriority > RTL8367C_DSCPMAX)
+ return RT_ERR_INPUT;
+
+ aclAct.priact = FILTER_ENACT_PRI_TYPE(actType);
+ aclAct.pridx = pFilter_action->filterPriority;
+ aclActCtrl |= FILTER_ENACT_PRIORITY_MASK;
+ break;
+ case FILTER_ENACT_POLICING_3:
+ if(pFilter_action->filterPriority >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM))
+ return RT_ERR_INPUT;
+
+ aclAct.priact = FILTER_ENACT_PRI_TYPE(actType);
+ aclAct.pridx = pFilter_action->filterPolicingIdx[3];
+ aclActCtrl |= FILTER_ENACT_PRIORITY_MASK;
+ break;
+ case FILTER_ENACT_DROP:
+
+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_REDIRECT);
+ aclAct.fwdact_ext = FALSE;
+
+ aclAct.fwdpmask = 0;
+ aclActCtrl |= FILTER_ENACT_FWD_MASK;
+ break;
+ case FILTER_ENACT_REDIRECT:
+ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
+
+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
+ aclAct.fwdact_ext = FALSE;
+
+ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
+ return RT_ERR_PORT_MASK;
+ aclAct.fwdpmask = portmask;
+
+ aclActCtrl |= FILTER_ENACT_FWD_MASK;
+ break;
+
+ case FILTER_ENACT_ADD_DSTPORT:
+ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
+
+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
+ aclAct.fwdact_ext = FALSE;
+
+ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
+ return RT_ERR_PORT_MASK;
+ aclAct.fwdpmask = portmask;
+
+ aclActCtrl |= FILTER_ENACT_FWD_MASK;
+ break;
+ case FILTER_ENACT_MIRROR:
+ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
+
+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
+ aclAct.cact_ext = FALSE;
+
+ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
+ return RT_ERR_PORT_MASK;
+ aclAct.fwdpmask = portmask;
+
+ aclActCtrl |= FILTER_ENACT_FWD_MASK;
+ break;
+ case FILTER_ENACT_TRAP_CPU:
+
+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType);
+ aclAct.fwdact_ext = FALSE;
+
+ aclActCtrl |= FILTER_ENACT_FWD_MASK;
+ break;
+ case FILTER_ENACT_COPY_CPU:
+ if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK)
+ return retVal;
+
+ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_MIRROR);
+ aclAct.fwdact_ext = FALSE;
+
+ aclAct.fwdpmask = 1 << cpuPort;
+ aclActCtrl |= FILTER_ENACT_FWD_MASK;
+ break;
+ case FILTER_ENACT_ISOLATION:
+ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask);
+
+ aclAct.fwdact_ext = TRUE;
+
+ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK)
+ return RT_ERR_PORT_MASK;
+ aclAct.fwdpmask = portmask;
+
+ aclActCtrl |= FILTER_ENACT_FWD_MASK;
+ break;
+
+ case FILTER_ENACT_INTERRUPT:
+
+ aclAct.aclint = TRUE;
+ aclActCtrl |= FILTER_ENACT_INTGPIO_MASK;
+ break;
+ case FILTER_ENACT_GPO:
+
+ aclAct.gpio_en = TRUE;
+ aclAct.gpio_pin = pFilter_action->filterPin;
+ aclActCtrl |= FILTER_ENACT_INTGPIO_MASK;
+ break;
+ case FILTER_ENACT_EGRESSCTAG_TAG:
+
+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
+ {
+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
+ }
+ else
+ {
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
+ }
+ aclAct.tag_fmt = FILTER_CTAGFMT_TAG;
+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
+ break;
+ case FILTER_ENACT_EGRESSCTAG_UNTAG:
+
+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
+ {
+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
+ }
+ else
+ {
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
+ }
+ aclAct.tag_fmt = FILTER_CTAGFMT_UNTAG;
+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
+ break;
+ case FILTER_ENACT_EGRESSCTAG_KEEP:
+
+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
+ {
+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
+ }
+ else
+ {
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
+ }
+ aclAct.tag_fmt = FILTER_CTAGFMT_KEEP;
+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
+ break;
+ case FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK:
+
+ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK))
+ {
+ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY)
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG;
+ }
+ else
+ {
+ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY;
+ }
+ aclAct.tag_fmt = FILTER_CTAGFMT_KEEP1PRMK;
+ aclActCtrl |= FILTER_ENACT_CVLAN_MASK;
+ break;
+ default:
+ return RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT;
+ }
+ }
+ }
+
+
+ /*check if free ACL rules are enough*/
+ for(i = filter_id; i < (filter_id + noRulesAdd); i++)
+ {
+ if((retVal = rtl8367c_getAsicAclRule(i, &tempRule)) != RT_ERR_OK )
+ return retVal;
+
+ if(tempRule.valid == TRUE)
+ {
+ return RT_ERR_TBL_FULL;
+ }
+ }
+
+ ruleId = 0;
+ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++)
+ {
+ if(aclRule[i].valid == TRUE)
+ {
+ /* write ACL action control */
+ if((retVal = rtl8367c_setAsicAclActCtrl(filter_id + ruleId, aclActCtrl)) != RT_ERR_OK )
+ return retVal;
+ /* write ACL action */
+ if((retVal = rtl8367c_setAsicAclAct(filter_id + ruleId, &aclAct)) != RT_ERR_OK )
+ return retVal;
+
+ /* write ACL not */
+ if((retVal = rtl8367c_setAsicAclNot(filter_id + ruleId, pFilter_cfg->invert)) != RT_ERR_OK )
+ return retVal;
+ /* write ACL rule */
+ if((retVal = rtl8367c_setAsicAclRule(filter_id + ruleId, &aclRule[i])) != RT_ERR_OK )
+ return retVal;
+
+ /* only the first rule will be written with input action control, aclActCtrl of other rules will be zero */
+ aclActCtrl = 0;
+ memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t));
+
+ ruleId ++;
+ }
+ }
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_cfg_del
+ * Description:
+ * Delete an ACL configuration from ASIC
+ * Input:
+ * filter_id - Start index of ACL configuration.
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_FILTER_ENTRYIDX - Invalid filter_id.
+ * Note:
+ * This function delete a group of ACL rules starting from filter_id.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id)
+{
+ rtl8367c_aclrule initRule;
+ rtl8367c_acl_act_t initAct;
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(filter_id > RTL8367C_ACLRULEMAX )
+ return RT_ERR_FILTER_ENTRYIDX;
+
+ memset(&initRule, 0, sizeof(rtl8367c_aclrule));
+ memset(&initAct, 0, sizeof(rtl8367c_acl_act_t));
+
+ if((ret = rtl8367c_setAsicAclRule(filter_id, &initRule)) != RT_ERR_OK)
+ return ret;
+ if((ret = rtl8367c_setAsicAclActCtrl(filter_id, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK)
+ return ret;
+ if((ret = rtl8367c_setAsicAclAct(filter_id, &initAct)) != RT_ERR_OK)
+ return ret;
+ if((ret = rtl8367c_setAsicAclNot(filter_id, DISABLED)) != RT_ERR_OK )
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_cfg_delAll
+ * Description:
+ * Delete all ACL entries from ASIC
+ * Input:
+ * None
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * Note:
+ * This function delete all ACL configuration from ASIC.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void)
+{
+ rtk_uint32 i;
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ for(i = 0; i < RTL8367C_ACLRULENO; i++)
+ {
+ if((ret = rtl8367c_setAsicAclActCtrl(i, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK)
+ return ret;
+ if((ret = rtl8367c_setAsicAclNot(i, DISABLED)) != RT_ERR_OK )
+ return ret;
+ }
+
+ return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_RESET_CFG, RTL8367C_ACL_RESET_CFG_OFFSET, TRUE);;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_cfg_get
+ * Description:
+ * Get one ingress acl configuration from ASIC.
+ * Input:
+ * filter_id - Start index of ACL configuration.
+ * Output:
+ * pFilter_cfg - buffer pointer of ingress acl data
+ * pFilter_action - buffer pointer of ingress acl action
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_NULL_POINTER - Pointer pFilter_action or pFilter_cfg point to NULL.
+ * RT_ERR_FILTER_ENTRYIDX - Invalid entry index.
+ * Note:
+ * This function get configuration from ASIC.
+ */
+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)
+{
+ rtk_api_ret_t retVal;
+ rtk_uint32 i, tmp;
+ rtl8367c_aclrule aclRule;
+ rtl8367c_acl_act_t aclAct;
+ rtk_uint32 cpuPort;
+ rtl8367c_acltemplate_t type;
+ rtl8367c_svlan_memconf_t svlan_cfg;
+ rtl8367c_vlanconfiguser vlanMC;
+ rtk_uint32 phyPmask;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(NULL == pFilter_cfg || NULL == pAction)
+ return RT_ERR_NULL_POINTER;
+
+ if(filter_id > RTL8367C_ACLRULEMAX)
+ return RT_ERR_ENTRY_INDEX;
+
+ if ((retVal = rtl8367c_getAsicAclRule(filter_id, &aclRule)) != RT_ERR_OK)
+ return retVal;
+
+ /* Check valid */
+ if(aclRule.valid == 0)
+ {
+ pFilter_cfg->valid = DISABLED;
+ return RT_ERR_OK;
+ }
+
+ phyPmask = aclRule.data_bits.active_portmsk;
+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.value)) != RT_ERR_OK)
+ return RT_ERR_FAILED;
+
+ phyPmask = aclRule.care_bits.active_portmsk;
+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.mask)) != RT_ERR_OK)
+ return RT_ERR_FAILED;
+
+ for(i = 0; i <= CARE_TAG_IPV6; i++)
+ {
+ if(aclRule.data_bits.tag_exist & (1 << i))
+ pFilter_cfg->careTag.tagType[i].value = 1;
+ else
+ pFilter_cfg->careTag.tagType[i].value = 0;
+
+ if (aclRule.care_bits.tag_exist & (1 << i))
+ pFilter_cfg->careTag.tagType[i].mask = 1;
+ else
+ pFilter_cfg->careTag.tagType[i].mask = 0;
+ }
+
+ if(filter_advanceCaretagField[aclRule.data_bits.type][0] == TRUE)
+ {
+ /* Advanced Care tag setting */
+ for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++)
+ {
+ if(aclRule.data_bits.field[filter_advanceCaretagField[aclRule.data_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) )
+ pFilter_cfg->careTag.tagType[i].value = 1;
+ else
+ pFilter_cfg->careTag.tagType[i].value = 0;
+
+ if(aclRule.care_bits.field[filter_advanceCaretagField[aclRule.care_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) )
+ pFilter_cfg->careTag.tagType[i].mask = 1;
+ else
+ pFilter_cfg->careTag.tagType[i].mask = 0;
+ }
+ }
+
+ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++)
+ {
+ pFilter_cfg->careFieldRaw[i] = aclRule.care_bits.field[i];
+ pFilter_cfg->dataFieldRaw[i] = aclRule.data_bits.field[i];
+ }
+
+ if ((retVal = rtl8367c_getAsicAclNot(filter_id, &tmp))!= RT_ERR_OK)
+ return retVal;
+
+ pFilter_cfg->invert = tmp;
+
+ pFilter_cfg->valid = aclRule.valid;
+
+ memset(pAction, 0, sizeof(rtk_filter_action_t));
+
+ if ((retVal = rtl8367c_getAsicAclActCtrl(filter_id, &tmp))!= RT_ERR_OK)
+ return retVal;
+
+ if ((retVal = rtl8367c_getAsicAclAct(filter_id, &aclAct)) != RT_ERR_OK)
+ return retVal;
+
+ if(tmp & FILTER_ENACT_FWD_MASK)
+ {
+ if(TRUE == aclAct.fwdact_ext)
+ {
+ pAction->actEnable[FILTER_ENACT_ISOLATION] = TRUE;
+
+ phyPmask = aclAct.fwdpmask;
+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
+ return RT_ERR_FAILED;
+ }
+ else if(aclAct.fwdact == RTL8367C_ACL_FWD_TRAP)
+ {
+ pAction->actEnable[FILTER_ENACT_TRAP_CPU] = TRUE;
+ }
+ else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRRORFUNTION )
+ {
+ pAction->actEnable[FILTER_ENACT_MIRROR] = TRUE;
+
+ phyPmask = aclAct.fwdpmask;
+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
+ return RT_ERR_FAILED;
+ }
+ else if (aclAct.fwdact == RTL8367C_ACL_FWD_REDIRECT)
+ {
+ if(aclAct.fwdpmask == 0 )
+ pAction->actEnable[FILTER_ENACT_DROP] = TRUE;
+ else
+ {
+ pAction->actEnable[FILTER_ENACT_REDIRECT] = TRUE;
+
+ phyPmask = aclAct.fwdpmask;
+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
+ return RT_ERR_FAILED;
+ }
+ }
+ else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRROR)
+ {
+ if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK)
+ return retVal;
+ if (aclAct.fwdpmask == (1 << cpuPort))
+ {
+ pAction->actEnable[FILTER_ENACT_COPY_CPU] = TRUE;
+ }
+ else
+ {
+ pAction->actEnable[FILTER_ENACT_ADD_DSTPORT] = TRUE;
+
+ phyPmask = aclAct.fwdpmask;
+ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK)
+ return RT_ERR_FAILED;
+ }
+ }
+ else
+ {
+ return RT_ERR_FAILED;
+ }
+ }
+
+ if(tmp & FILTER_ENACT_POLICING_MASK)
+ {
+ pAction->actEnable[FILTER_ENACT_POLICING_0] = TRUE;
+ pAction->filterPolicingIdx[0] = aclAct.aclmeteridx;
+ }
+
+ if(tmp & FILTER_ENACT_PRIORITY_MASK)
+ {
+ if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_PRIORITY))
+ {
+ pAction->actEnable[FILTER_ENACT_PRIORITY] = TRUE;
+ pAction->filterPriority = aclAct.pridx;
+ }
+ else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_1P_REMARK))
+ {
+ pAction->actEnable[FILTER_ENACT_1P_REMARK] = TRUE;
+ pAction->filterPriority = aclAct.pridx;
+ }
+ else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_DSCP_REMARK))
+ {
+ pAction->actEnable[FILTER_ENACT_DSCP_REMARK] = TRUE;
+ pAction->filterPriority = aclAct.pridx;
+ }
+ else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_POLICING_3))
+ {
+ pAction->actEnable[FILTER_ENACT_POLICING_3] = TRUE;
+ pAction->filterPolicingIdx[3] = aclAct.pridx;
+ }
+ }
+
+ if(tmp & FILTER_ENACT_SVLAN_MASK)
+ {
+ if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_INGRESS))
+ {
+ if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK)
+ return retVal;
+
+ pAction->actEnable[FILTER_ENACT_SVLAN_INGRESS] = TRUE;
+ pAction->filterSvlanIdx = aclAct.svidx_sact;
+ pAction->filterSvlanVid = svlan_cfg.vs_svid;
+ }
+ else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_EGRESS))
+ {
+ if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK)
+ return retVal;
+
+ pAction->actEnable[FILTER_ENACT_SVLAN_EGRESS] = TRUE;
+ pAction->filterSvlanIdx = aclAct.svidx_sact;
+ pAction->filterSvlanVid = svlan_cfg.vs_svid;
+ }
+ else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_CVID))
+ pAction->actEnable[FILTER_ENACT_SVLAN_CVID] = TRUE;
+ else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_POLICING_2))
+ {
+ pAction->actEnable[FILTER_ENACT_POLICING_2] = TRUE;
+ pAction->filterPolicingIdx[2] = aclAct.svidx_sact;
+ }
+ }
+
+
+ if(tmp & FILTER_ENACT_CVLAN_MASK)
+ {
+ if(FILTER_ENACT_CACTEXT_TAGONLY == aclAct.cact_ext ||
+ FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext )
+ {
+ if(FILTER_CTAGFMT_UNTAG == aclAct.tag_fmt)
+ {
+ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_UNTAG] = TRUE;
+ }
+ else if(FILTER_CTAGFMT_TAG == aclAct.tag_fmt)
+ {
+ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_TAG] = TRUE;
+ }
+ else if(FILTER_CTAGFMT_KEEP == aclAct.tag_fmt)
+ {
+ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEP] = TRUE;
+ }
+ else if(FILTER_CTAGFMT_KEEP1PRMK== aclAct.tag_fmt)
+ {
+ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK] = TRUE;
+ }
+
+ }
+
+ if(FILTER_ENACT_CACTEXT_VLANONLY == aclAct.cact_ext ||
+ FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext )
+ {
+ if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_INGRESS))
+ {
+ if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK)
+ return retVal;
+
+ pAction->actEnable[FILTER_ENACT_CVLAN_INGRESS] = TRUE;
+ pAction->filterCvlanIdx = aclAct.cvidx_cact;
+ pAction->filterCvlanVid = vlanMC.evid;
+ }
+ else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_EGRESS))
+ {
+ if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK)
+ return retVal;
+
+ pAction->actEnable[FILTER_ENACT_CVLAN_EGRESS] = TRUE;
+ pAction->filterCvlanIdx = aclAct.cvidx_cact;
+ pAction->filterCvlanVid = vlanMC.evid;
+ }
+ else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_SVID))
+ {
+ pAction->actEnable[FILTER_ENACT_CVLAN_SVID] = TRUE;
+ }
+ else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_POLICING_1))
+ {
+ pAction->actEnable[FILTER_ENACT_POLICING_1] = TRUE;
+ pAction->filterPolicingIdx[1] = aclAct.cvidx_cact;
+ }
+ }
+ }
+
+ if(tmp & FILTER_ENACT_INTGPIO_MASK)
+ {
+ if(TRUE == aclAct.aclint)
+ {
+ pAction->actEnable[FILTER_ENACT_INTERRUPT] = TRUE;
+ }
+
+ if(TRUE == aclAct.gpio_en)
+ {
+ pAction->actEnable[FILTER_ENACT_GPO] = TRUE;
+ pAction->filterPin = aclAct.gpio_pin;
+ }
+ }
+
+ /* Get field type of RAW data */
+ if ((retVal = rtl8367c_getAsicAclTemplate(aclRule.data_bits.type, &type))!= RT_ERR_OK)
+ return retVal;
+
+ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++)
+ {
+ pFilter_cfg->fieldRawType[i] = type.field[i];
+ }/* end of for(i...) */
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_unmatchAction_set
+ * Description:
+ * Set action to packets when no ACL configuration match
+ * Input:
+ * port - Port id.
+ * action - Action.
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PORT_ID - Invalid port id.
+ * RT_ERR_INPUT - Invalid input parameters.
+ * Note:
+ * This function sets action of packets when no ACL configruation matches.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ /* Check port valid */
+ RTK_CHK_PORT_VALID(port);
+
+ if(action >= FILTER_UNMATCH_END)
+ return RT_ERR_INPUT;
+
+ if((ret = rtl8367c_setAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), action)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_unmatchAction_get
+ * Description:
+ * Get action to packets when no ACL configuration match
+ * Input:
+ * port - Port id.
+ * Output:
+ * pAction - Action.
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PORT_ID - Invalid port id.
+ * RT_ERR_INPUT - Invalid input parameters.
+ * Note:
+ * This function gets action of packets when no ACL configruation matches.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* pAction)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(NULL == pAction)
+ return RT_ERR_NULL_POINTER;
+
+ /* Check port valid */
+ RTK_CHK_PORT_VALID(port);
+
+ if((ret = rtl8367c_getAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), pAction)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_state_set
+ * Description:
+ * Set state of ingress ACL.
+ * Input:
+ * port - Port id.
+ * state - Ingress ACL state.
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PORT_ID - Invalid port id.
+ * RT_ERR_INPUT - Invalid input parameters.
+ * Note:
+ * This function gets action of packets when no ACL configruation matches.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ /* Check port valid */
+ RTK_CHK_PORT_VALID(port);
+
+ if(state >= RTK_ENABLE_END)
+ return RT_ERR_INPUT;
+
+ if((ret = rtl8367c_setAsicAcl(rtk_switch_port_L2P_get(port), state)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_state_get
+ * Description:
+ * Get state of ingress ACL.
+ * Input:
+ * port - Port id.
+ * Output:
+ * pState - Ingress ACL state.
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_PORT_ID - Invalid port id.
+ * RT_ERR_INPUT - Invalid input parameters.
+ * Note:
+ * This function gets action of packets when no ACL configruation matches.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* pState)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(NULL == pState)
+ return RT_ERR_NULL_POINTER;
+
+ /* Check port valid */
+ RTK_CHK_PORT_VALID(port);
+
+ if((ret = rtl8367c_getAsicAcl(rtk_switch_port_L2P_get(port), pState)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+/* Function Name:
+ * rtk_filter_igrAcl_template_set
+ * Description:
+ * Set template of ingress ACL.
+ * Input:
+ * template - Ingress ACL template
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_INPUT - Invalid input parameters.
+ * Note:
+ * This function set ACL template.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate)
+{
+ rtk_api_ret_t retVal;
+ rtk_uint32 idxField;
+ rtl8367c_acltemplate_t aclType;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE)
+ return RT_ERR_INPUT;
+
+ for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++)
+ {
+ if(aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_DMAC_15_0 ||
+ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_CTAG && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV4_SIP_15_0 ) ||
+ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV4_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV6_SIP_15_0 ) ||
+ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV6_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_VIDRANGE ) ||
+ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_FIELD_VALID && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_FIELD_SELECT00 ) ||
+ aclTemplate->fieldType[idxField] >= FILTER_FIELD_RAW_END)
+ {
+ return RT_ERR_INPUT;
+ }
+ }
+
+ for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++)
+ {
+ aclType.field[idxField] = aclTemplate->fieldType[idxField];
+ }
+
+ if((retVal = rtl8367c_setAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK)
+ return retVal;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_template_get
+ * Description:
+ * Get template of ingress ACL.
+ * Input:
+ * template - Ingress ACL template
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * Note:
+ * This function gets template of ACL.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate)
+{
+ rtk_api_ret_t ret;
+ rtk_uint32 idxField;
+ rtl8367c_acltemplate_t aclType;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(NULL == aclTemplate)
+ return RT_ERR_NULL_POINTER;
+
+ if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE)
+ return RT_ERR_INPUT;
+
+ if((ret = rtl8367c_getAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK)
+ return ret;
+
+ for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField ++)
+ {
+ aclTemplate->fieldType[idxField] = aclType.field[idxField];
+ }
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_field_sel_set
+ * Description:
+ * Set user defined field selectors in HSB
+ * Input:
+ * index - index of field selector 0-15
+ * format - Format of field selector
+ * offset - Retrieving data offset
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * Note:
+ * System support 16 user defined field selctors.
+ * Each selector can be enabled or disable.
+ * User can defined retrieving 16-bits in many predefiend
+ * standard l2/l3/l4 payload.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if(format >= FORMAT_END)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if(offset > RTL8367C_FIELDSEL_MAX_OFFSET)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if((ret = rtl8367c_setAsicFieldSelector(index, (rtk_uint32)format, offset)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAcl_field_sel_get
+ * Description:
+ * Get user defined field selectors in HSB
+ * Input:
+ * index - index of field selector 0-15
+ * Output:
+ * pFormat - Format of field selector
+ * pOffset - Retrieving data offset
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * Note:
+ * None.
+ */
+rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(NULL == pFormat || NULL == pOffset)
+ return RT_ERR_NULL_POINTER;
+
+ if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if((ret = rtl8367c_getAsicFieldSelector(index, pFormat, pOffset)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_iprange_set
+ * Description:
+ * Set IP Range check
+ * Input:
+ * index - index of IP Range 0-15
+ * type - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP
+ * upperIp - The upper bound of IP range
+ * lowerIp - The lower Bound of IP range
+ * Output:
+ * None.
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range
+ * RT_ERR_INPUT - Input error
+ * Note:
+ * upperIp must be larger or equal than lowerIp.
+ */
+rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(index > RTL8367C_ACLRANGEMAX)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if(type >= IPRANGE_END)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if(lowerIp > upperIp)
+ return RT_ERR_INPUT;
+
+ if((ret = rtl8367c_setAsicAclIpRange(index, type, upperIp, lowerIp)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_iprange_get
+ * Description:
+ * Set IP Range check
+ * Input:
+ * index - index of IP Range 0-15
+ * Output:
+ * pType - IP Range check type, 0:Delete a entry, 1: IPv4_SIP, 2: IPv4_DIP, 3:IPv6_SIP, 4:IPv6_DIP
+ * pUpperIp - The upper bound of IP range
+ * pLowerIp - The lower Bound of IP range
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range
+ * Note:
+ * None.
+ */
+rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if((NULL == pType) || (NULL == pUpperIp) || (NULL == pLowerIp))
+ return RT_ERR_NULL_POINTER;
+
+ if(index > RTL8367C_ACLRANGEMAX)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if((ret = rtl8367c_getAsicAclIpRange(index, pType, pUpperIp, pLowerIp)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_vidrange_set
+ * Description:
+ * Set VID Range check
+ * Input:
+ * index - index of VID Range 0-15
+ * type - IP Range check type, 0:Delete a entry, 1: CVID, 2: SVID
+ * upperVid - The upper bound of VID range
+ * lowerVid - The lower Bound of VID range
+ * Output:
+ * None.
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range
+ * RT_ERR_INPUT - Input error
+ * Note:
+ * upperVid must be larger or equal than lowerVid.
+ */
+rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(index > RTL8367C_ACLRANGEMAX)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if(type >= VIDRANGE_END)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if(lowerVid > upperVid)
+ return RT_ERR_INPUT;
+
+ if( (upperVid > RTL8367C_VIDMAX) || (lowerVid > RTL8367C_VIDMAX))
+ return RT_ERR_OUT_OF_RANGE;
+
+ if((ret = rtl8367c_setAsicAclVidRange(index, type, upperVid, lowerVid)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_vidrange_get
+ * Description:
+ * Get VID Range check
+ * Input:
+ * index - index of VID Range 0-15
+ * Output:
+ * pType - IP Range check type, 0:Unused, 1: CVID, 2: SVID
+ * pUpperVid - The upper bound of VID range
+ * pLowerVid - The lower Bound of VID range
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range
+ * Note:
+ * None.
+ */
+rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if((NULL == pType) || (NULL == pUpperVid) || (NULL == pLowerVid))
+ return RT_ERR_NULL_POINTER;
+
+ if(index > RTL8367C_ACLRANGEMAX)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if((ret = rtl8367c_getAsicAclVidRange(index, pType, pUpperVid, pLowerVid)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_portrange_set
+ * Description:
+ * Set Port Range check
+ * Input:
+ * index - index of Port Range 0-15
+ * type - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port
+ * upperPort - The upper bound of Port range
+ * lowerPort - The lower Bound of Port range
+ * Output:
+ * None.
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range
+ * RT_ERR_INPUT - Input error
+ * Note:
+ * upperPort must be larger or equal than lowerPort.
+ */
+rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(index > RTL8367C_ACLRANGEMAX)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if(type >= PORTRANGE_END)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if(lowerPort > upperPort)
+ return RT_ERR_INPUT;
+
+ if(upperPort > RTL8367C_ACL_PORTRANGEMAX)
+ return RT_ERR_INPUT;
+
+ if(lowerPort > RTL8367C_ACL_PORTRANGEMAX)
+ return RT_ERR_INPUT;
+
+ if((ret = rtl8367c_setAsicAclPortRange(index, type, upperPort, lowerPort)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_portrange_get
+ * Description:
+ * Set Port Range check
+ * Input:
+ * index - index of Port Range 0-15
+ * Output:
+ * pType - IP Range check type, 0:Delete a entry, 1: Source Port, 2: Destnation Port
+ * pUpperPort - The upper bound of Port range
+ * pLowerPort - The lower Bound of Port range
+ * Return:
+ * RT_ERR_OK - OK
+ * RT_ERR_FAILED - Failed
+ * RT_ERR_SMI - SMI access error
+ * RT_ERR_OUT_OF_RANGE - The parameter is out of range
+ * RT_ERR_INPUT - Input error
+ * Note:
+ * None.
+ */
+rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort)
+{
+ rtk_api_ret_t ret;
+
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if((NULL == pType) || (NULL == pUpperPort) || (NULL == pLowerPort))
+ return RT_ERR_NULL_POINTER;
+
+ if(index > RTL8367C_ACLRANGEMAX)
+ return RT_ERR_OUT_OF_RANGE;
+
+ if((ret = rtl8367c_getAsicAclPortRange(index, pType, pUpperPort, pLowerPort)) != RT_ERR_OK)
+ return ret;
+
+ return RT_ERR_OK;
+}
+
+/* Function Name:
+ * rtk_filter_igrAclPolarity_set
+ * Description:
+ * Set ACL Goip control palarity
+ * Input:
+ * polarity - 1: High, 0: Low
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+ * RT_ERR_SMI - SMI access error
+ * Note:
+ * none
+ */
+rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity)
+{
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(polarity > 1)
+ return RT_ERR_OUT_OF_RANGE;
+ return rtl8367c_setAsicAclGpioPolarity(polarity);
+}
+/* Function Name:
+ * rtk_filter_igrAclPolarity_get
+ * Description:
+ * Get ACL Goip control palarity
+ * Input:
+ * pPolarity - 1: High, 0: Low
+ * Output:
+ * None
+ * Return:
+ * RT_ERR_OK - Success
+ * RT_ERR_SMI - SMI access error
+ * Note:
+ * none
+ */
+rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity)
+{
+ /* Check initialization state */
+ RTK_CHK_INIT_STATE();
+
+ if(NULL == pPolarity)
+ return RT_ERR_NULL_POINTER;
+
+ return rtl8367c_getAsicAclGpioPolarity(pPolarity);
+}
+
+
+
+