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