| /* |
| * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all copies. |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT |
| * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| |
| /** |
| * @defgroup |
| * @{ |
| */ |
| #include "sw.h" |
| #include "adpt.h" |
| #include "adpt_hppe.h" |
| #include "hppe_acl_reg.h" |
| #include "hppe_acl.h" |
| #include <linux/list.h> |
| |
| #define ADPT_ACL_HPPE_MAC_DA_RULE 0 |
| #define ADPT_ACL_HPPE_MAC_SA_RULE 1 |
| #define ADPT_ACL_HPPE_VLAN_RULE 2 |
| #define ADPT_ACL_HPPE_L2_MISC_RULE 3 |
| #define ADPT_ACL_HPPE_IPV4_DIP_RULE 4 |
| #define ADPT_ACL_HPPE_IPV4_SIP_RULE 5 |
| #define ADPT_ACL_HPPE_IPV6_DIP0_RULE 6 |
| #define ADPT_ACL_HPPE_IPV6_DIP1_RULE 7 |
| #define ADPT_ACL_HPPE_IPV6_DIP2_RULE 8 |
| #define ADPT_ACL_HPPE_IPV6_SIP0_RULE 9 |
| #define ADPT_ACL_HPPE_IPV6_SIP1_RULE 10 |
| #define ADPT_ACL_HPPE_IPV6_SIP2_RULE 11 |
| #define ADPT_ACL_HPPE_IPMISC_RULE 12 |
| #define ADPT_ACL_HPPE_UDF0_RULE 13 |
| #define ADPT_ACL_HPPE_UDF1_RULE 14 |
| #define ADPT_ACL_HPPE_RULE_TYPE_NUM 15 |
| |
| |
| #define ADPT_ACL_SW_LIST_NUM 512 |
| #define ADPT_ACL_HW_LIST_NUM 64 |
| #define ADPT_ACL_RULE_NUM_PER_LIST 8 /* can change this MACRO to support more rules per ACL list */ |
| #define ADPT_ACL_ENTRY_NUM_PER_LIST 8 |
| |
| typedef struct{ |
| struct list_head list; |
| a_uint16_t rule_id; |
| a_uint8_t rule_type; |
| a_uint8_t rule_hw_entry; |
| a_uint8_t rule_hw_list_id; |
| a_uint8_t ext1_val; |
| a_uint8_t ext2_val; |
| a_uint8_t ext4_val; |
| }ADPT_HPPE_ACL_SW_RULE; |
| |
| typedef struct{ |
| struct list_head list; |
| struct list_head list_sw_rule; |
| a_uint32_t list_pri; |
| a_uint16_t list_id; |
| }ADPT_HPPE_ACL_SW_LIST; |
| |
| typedef struct{ |
| struct list_head list_sw_list; |
| }ADPT_HPPE_ACL_SW_LIST_HEAD; |
| |
| typedef struct{ |
| a_bool_t hw_list_valid; |
| a_uint8_t hw_list_id; |
| a_uint8_t free_hw_entry_bitmap; |
| a_uint8_t free_hw_entry_count; |
| }ADPT_HPPE_ACL_HW_LIST; |
| |
| typedef struct{ |
| a_uint8_t mac[6]; |
| a_uint32_t is_ip:1; |
| a_uint32_t is_ipv6:1; |
| a_uint32_t is_ethernet:1; |
| a_uint32_t is_snap:1; |
| a_uint32_t is_fake_mac_header:1; |
| }ADPT_HPPE_ACL_MAC_RULE; |
| typedef struct{ |
| a_uint8_t mac_mask[6]; |
| a_uint32_t is_ip_mask:1; |
| a_uint32_t is_ipv6_mask:1; |
| a_uint32_t is_ethernet_mask:1; |
| a_uint32_t is_snap_mask:1; |
| a_uint32_t is_fake_mac_header_mask:1; |
| }ADPT_HPPE_ACL_MAC_RULE_MASK; |
| |
| typedef struct{ |
| a_uint32_t cvid:12;/*it is min cvid when range is enable*/ |
| a_uint32_t reserved:4; |
| a_uint32_t cpcp:3; |
| a_uint32_t cdei:1; |
| a_uint32_t svid:12; |
| a_uint32_t spcp:3; |
| a_uint32_t sdei:1; |
| a_uint32_t ctag_fmt:3; |
| a_uint32_t stag_fmt:3; |
| a_uint32_t vsi:5; |
| a_uint32_t vsi_valid:1; |
| a_uint32_t is_ip:1; |
| a_uint32_t is_ipv6:1; |
| a_uint32_t is_ethernet:1; |
| a_uint32_t is_snap:1; |
| a_uint32_t is_fake_mac_header:1; |
| }ADPT_HPPE_ACL_VLAN_RULE; |
| |
| typedef struct{ |
| a_uint32_t cvid_mask:12;/*it is max cvid when range is enable*/ |
| a_uint32_t reserved:4; |
| a_uint32_t cpcp_mask:3; |
| a_uint32_t cdei_mask:1; |
| a_uint32_t svid_mask:12; |
| a_uint32_t spcp_mask:3; |
| a_uint32_t sdei_mask:1; |
| a_uint32_t ctag_fmt_mask:3; |
| a_uint32_t stag_fmt_mask:3; |
| a_uint32_t vsi_mask:5; |
| a_uint32_t vsi_valid_mask:1; |
| a_uint32_t is_ip_mask:1; |
| a_uint32_t is_ipv6_mask:1; |
| a_uint32_t is_ethernet_mask:1; |
| a_uint32_t is_snap_mask:1; |
| a_uint32_t is_fake_mac_header_mask:1; |
| }ADPT_HPPE_ACL_VLAN_RULE_MASK; |
| |
| typedef struct{ |
| a_uint32_t svid:12;/*it is min svid when range is enable*/ |
| a_uint32_t reserved:4; |
| a_uint32_t l2prot:16; |
| a_uint32_t pppoe_sessionid:16; |
| a_uint32_t is_ip:1; |
| a_uint32_t is_ipv6:1; |
| a_uint32_t is_ethernet:1; |
| a_uint32_t is_snap:1; |
| a_uint32_t is_fake_mac_header:1; |
| }ADPT_HPPE_ACL_L2MISC_RULE; |
| |
| typedef struct{ |
| a_uint32_t svid_mask:12;/*it is max svid when range is enable*/ |
| a_uint32_t reserved:4; |
| a_uint32_t l2prot_mask:16; |
| a_uint32_t pppoe_sessionid_mask:16; |
| a_uint32_t is_ip_mask:1; |
| a_uint32_t is_ipv6_mask:1; |
| a_uint32_t is_ethernet_mask:1; |
| a_uint32_t is_snap_mask:1; |
| a_uint32_t is_fake_mac_header_mask:1; |
| }ADPT_HPPE_ACL_L2MISC_RULE_MASK; |
| |
| typedef struct{ |
| a_uint32_t l4_port:16;/*it is min dport when range is enable*/ |
| a_uint32_t ip_0:16; |
| a_uint32_t ip_1:16; |
| a_uint32_t l3_fragment:1; |
| a_uint32_t l3_packet_type:3; |
| a_uint32_t is_ip:1; |
| a_uint32_t reserved:11; |
| }ADPT_HPPE_ACL_IPV4_RULE; |
| |
| typedef struct{ |
| a_uint32_t l4_port_mask:16;/*it is min dport when range is enable*/ |
| a_uint32_t ip_mask_0:16; |
| a_uint32_t ip_mask_1:16; |
| a_uint32_t l3_fragment_mask:1; |
| a_uint32_t l3_packet_type_mask:3; |
| a_uint32_t is_ip_mask:1; |
| a_uint32_t reserved:11; |
| }ADPT_HPPE_ACL_IPV4_RULE_MASK; |
| |
| typedef struct{ |
| a_uint32_t udf0:16; |
| a_uint32_t udf1:16; |
| a_uint32_t udf2:16; |
| a_uint32_t udf0_valid:1; |
| a_uint32_t udf1_valid:1; |
| a_uint32_t udf2_valid:1; |
| a_uint32_t is_ipv6:1; |
| a_uint32_t is_ip:1; |
| }ADPT_HPPE_ACL_UDF_RULE; |
| |
| typedef struct{ |
| a_uint32_t udf0_mask:16; |
| a_uint32_t udf1_mask:16; |
| a_uint32_t udf2_mask:16; |
| a_uint32_t udf0_valid:1; |
| a_uint32_t udf1_valid:1; |
| a_uint32_t udf2_valid:1; |
| a_uint32_t is_ipv6:1; |
| a_uint32_t is_ip:1; |
| }ADPT_HPPE_ACL_UDF_RULE_MASK; |
| |
| |
| typedef struct{ |
| a_uint32_t ip_port:16; /*it is port when DIP_2_RULE or SIP_2_RULE*/ |
| a_uint32_t ip_ext_1:16; |
| a_uint32_t ip_ext_2:16; |
| a_uint32_t l3_fragment:1; |
| a_uint32_t l3_packet_type:3; |
| a_uint32_t reserved:1; |
| }ADPT_HPPE_ACL_IPV6_RULE; |
| |
| typedef struct{ |
| a_uint32_t ip_port_mask:16; /*it is port when DIP_2_RULE or SIP_2_RULE*/ |
| a_uint32_t ip_ext_1_mask:16; |
| a_uint32_t ip_ext_2_mask:16; |
| a_uint32_t l3_fragment_mask:1; |
| a_uint32_t l3_packet_type_mask:3; |
| a_uint32_t reserved:1; |
| }ADPT_HPPE_ACL_IPV6_RULE_MASK; |
| |
| typedef struct{ |
| a_uint32_t l3_length:16;/*it is min length when range is enable*/ |
| a_uint32_t l3_prot:8; /*ipv4 protocol or ipv6 next header*/ |
| a_uint32_t l3_dscp_tc:8; |
| a_uint32_t first_fragment:1; |
| a_uint32_t tcp_flags:6; |
| a_uint32_t ipv4_option_state:1; |
| a_uint32_t l3_ttl:2; /*ipv4 ttl, ipv6 hop limit*/ |
| a_uint32_t ah_header:1; |
| a_uint32_t esp_header:1; |
| a_uint32_t mobility_header:1; |
| a_uint32_t fragment_header:1; |
| a_uint32_t other_header:1; |
| a_uint32_t reserved0:1; |
| a_uint32_t l3_fragment:1; |
| a_uint32_t is_ipv6:1; |
| a_uint32_t reserved1:3; |
| }ADPT_HPPE_ACL_IPMISC_RULE; |
| |
| typedef struct{ |
| a_uint32_t l3_length_mask:16;/*it is max length when range is enable*/ |
| a_uint32_t l3_prot_mask:8; /*ipv4 protocol or ipv6 next header*/ |
| a_uint32_t l3_dscp_tc_mask:8; |
| a_uint32_t first_fragment_mask:1; |
| a_uint32_t tcp_flags_mask:6; |
| a_uint32_t ipv4_option_state_mask:1; |
| a_uint32_t l3_ttl_mask:2; /*ipv4 ttl, ipv6 hop limit*/ |
| a_uint32_t ah_header_mask:1; |
| a_uint32_t esp_header_mask:1; |
| a_uint32_t mobility_header_mask:1; |
| a_uint32_t fragment_header_mask:1; |
| a_uint32_t other_header_mask:1; |
| a_uint32_t reserved0:1; |
| a_uint32_t l3_fragment_mask:1; |
| a_uint32_t is_ipv6_mask:1; |
| a_uint32_t reserved1:3; |
| }ADPT_HPPE_ACL_IPMISC_RULE_MASK; |
| |
| static ADPT_HPPE_ACL_SW_LIST_HEAD g_acl_sw_list[SW_MAX_NR_DEV]; |
| static ADPT_HPPE_ACL_HW_LIST g_acl_hw_list[SW_MAX_NR_DEV][ADPT_ACL_HW_LIST_NUM]; |
| static aos_lock_t hppe_acl_lock[SW_MAX_NR_DEV]; |
| |
| const a_uint8_t s_acl_ext2[7][2] = { |
| {0,1},{2,3},{4,5},{6,7},{0,2},{4,6},{0,4} |
| }; |
| typedef struct |
| { |
| a_uint8_t num; |
| a_uint8_t ext_1; |
| a_uint8_t ext_2; |
| a_uint8_t ext_4; |
| a_uint8_t entries; |
| }ADPT_HPPE_ACL_ENTRY_EXTEND_INFO; |
| const ADPT_HPPE_ACL_ENTRY_EXTEND_INFO s_acl_entries[] = { |
| /*num ext_1 ext_2 ext_4 entries*/ |
| {1, 0, 0, 0, 0x2}, |
| {1, 0, 0, 0, 0x8}, |
| {1, 0, 0, 0, 0x20}, |
| {1, 0, 0, 0, 0x80}, |
| {1, 0, 0, 0, 0x1}, |
| {1, 0, 0, 0, 0x4}, |
| {1, 0, 0, 0, 0x10}, |
| {1, 0, 0, 0, 0x40}, |
| {2, 0x1, 0, 0, 0x3}, |
| {2, 0x2, 0, 0, 0xc}, |
| {2, 0x4, 0, 0, 0x30}, |
| {2, 0x8, 0, 0, 0xc0}, |
| {2, 0, 0x1, 0, 0x5}, |
| {2, 0, 0x2, 0, 0x50}, |
| {2, 0, 0, 0x1, 0x11}, |
| {3, 0x1, 0x1, 0x0, 0x7}, |
| {3, 0x1, 0x0, 0x1, 0x13}, |
| {3, 0x2, 0x1, 0x0, 0xd}, |
| {3, 0x4, 0x2, 0x0, 0x70}, |
| {3, 0x4, 0x0, 0x1, 0x31}, |
| {3, 0x8, 0x2, 0x0, 0xd0}, |
| {3, 0x0, 0x1, 0x1, 0x15}, |
| {3, 0x0, 0x2, 0x1, 0x51}, |
| {4, 0x3, 0x1, 0x0, 0xf}, |
| {4, 0x5, 0x0, 0x1, 0x33}, |
| {4, 0x2, 0x1, 0x1, 0x1d}, |
| {4, 0xc, 0x2, 0x0, 0xf0}, |
| {4, 0x4, 0x1, 0x1, 0x35}, |
| {4, 0x8, 0x2, 0x1, 0xd1}, |
| {4, 0x0, 0x3, 0x1, 0x55}, |
| {5, 0x3, 0x1, 0x1, 0x1f}, |
| {5, 0x6, 0x1, 0x1, 0x3d}, |
| {5, 0xc, 0x2, 0x1, 0xf1}, |
| {5, 0x8, 0x3, 0x1, 0xd5}, |
| {6, 0x7, 0x1, 0x1, 0x3f}, |
| {6, 0x6, 0x3, 0x1, 0x7d}, |
| {6, 0xc, 0x3, 0x1, 0xf5}, |
| {7, 0x7, 0x3, 0x1, 0x7f}, |
| {7, 0xe, 0x3, 0x1, 0xfd}, |
| {8, 0xf, 0x3, 0x1, 0xff}, |
| }; |
| |
| static void _adpt_acl_reg_dump(a_uint8_t *reg, a_uint32_t len) |
| { |
| a_int32_t i = 0; |
| |
| for(i = 0; i < len; i++) |
| { |
| printk(KERN_CONT "%02x ", reg[i]); |
| if((i+1)%32 == 0 || (i == len-1)) |
| printk(KERN_CONT "\n"); |
| } |
| |
| return; |
| } |
| |
| /*type = 0, count all; type = 1 count odd; type = 2 count even*/ |
| static a_uint32_t _acl_bits_count(a_uint32_t bits, a_uint32_t max, a_uint32_t type) |
| { |
| a_uint32_t i = 0, count = 0; |
| while(i < max) |
| { |
| if((bits >> i) &0x1) |
| { |
| if(type == 1) |
| { |
| if(i%2!=0) |
| count++; |
| } |
| else if(type == 2) |
| { |
| if(i%2==0) |
| count++; |
| } |
| else |
| count++; |
| } |
| i++; |
| } |
| return count; |
| } |
| |
| /*type = 0, count all; type = 1 count odd; type = 2 count even*/ |
| static a_uint32_t _acl_bit_index(a_uint32_t bits, a_uint32_t max, a_uint32_t type) |
| { |
| a_uint32_t i = 0; |
| while(i < max) |
| { |
| if((bits >> i) &0x1) |
| { |
| if(type == 1)/*odd*/ |
| { |
| if(i%2!=0) |
| break; |
| } |
| else if(type == 2)/*even*/ |
| { |
| if(i%2==0) |
| break; |
| } |
| else |
| break; |
| } |
| i++; |
| } |
| if(i<max) |
| return i; |
| return 0xff; |
| } |
| |
| static a_bool_t |
| _adpt_acl_zero_addr(const fal_mac_addr_t addr) |
| { |
| a_uint32_t i; |
| |
| for (i = 0; i < 6; i++) |
| { |
| if (addr.uc[i]) |
| { |
| return A_FALSE; |
| } |
| } |
| return A_TRUE; |
| } |
| |
| #if 0 |
| static void _acl_print_extend_slices(a_uint8_t extend,a_uint8_t extend_slices, u_int8_t slice_count) |
| { |
| a_uint32_t i; |
| a_uint32_t ext_1=0, ext_2=0, ext_4=0; |
| for(i = 0; i < 8; i++) |
| { |
| if(extend & (1<<i)) |
| { |
| if(i==6) |
| ext_4 = 0x1; |
| else if(i<4) |
| ext_1 |= (1<<i); |
| else |
| ext_2 |= (1<<(i%4)); |
| } |
| } |
| printk("\n{%d, 0x%x, 0x%x, 0x%x, 0x%x},\n", slice_count, ext_1, ext_2, ext_4, extend_slices); |
| } |
| static void _acl_slice_ext_bitmap_gen(a_uint32_t ext_n) |
| { |
| a_uint32_t i, j; |
| a_uint8_t extend = 0; |
| a_uint8_t full_extend = 0; |
| a_uint8_t extend_slices = 0; |
| a_uint8_t extend_count = 0; |
| |
| printk("########ext_n = %d\n", ext_n); |
| |
| for(i = 0; i < 7; i++) |
| { |
| extend = (1 << i); |
| extend_slices = (1<<s_acl_ext2[i][0])|(1<<s_acl_ext2[i][1]); |
| extend_count = 2; |
| full_extend = 0; |
| for(j = i+1; j < 7; j++) |
| { |
| int k; |
| if((extend & (1<<j))||(full_extend & (1<<j))) |
| { |
| //printk("extend = %x, full_extend = %x\n", extend, full_extend); |
| continue; |
| } |
| for(k = 0; k < extend_count; k++) |
| { |
| if(extend_slices &(1<<s_acl_ext2[j][0])) |
| { |
| extend |= (1<<j); |
| extend_slices |= (1<<s_acl_ext2[j][1]); |
| extend_count++; |
| break; |
| } |
| else if(extend_slices &(1<<s_acl_ext2[j][1])) |
| { |
| extend |= (1<<j); |
| extend_slices |= (1<<s_acl_ext2[j][0]); |
| extend_count++; |
| break; |
| } |
| } |
| if(extend_count == ext_n) |
| { |
| _acl_print_extend_slices(extend, extend_slices, extend_count); |
| full_extend |= extend; |
| extend_count = 2; |
| extend = (1 << i); |
| extend_slices = (1<<s_acl_ext2[i][0])|(1<<s_acl_ext2[i][1]); |
| j=i; |
| } |
| if(k < extend_count) |
| { |
| j=i; |
| } |
| } |
| } |
| } |
| #endif |
| |
| enum{ |
| HPPE_ACL_TYPE_PORTBITMAP = 0, |
| HPPE_ACL_TYPE_PORT, |
| HPPE_ACL_TYPE_SERVICE_CODE, |
| HPPE_ACL_TYPE_L3_IF, |
| HPPE_ACL_TYPE_INVALID, |
| }; |
| |
| enum{ |
| HPPE_ACL_ACTION_FWD = 0, |
| HPPE_ACL_ACTION_DROP, |
| HPPE_ACL_ACTION_COPYCPU, |
| HPPE_ACL_ACTION_RDTCPU, |
| }; |
| |
| enum{ |
| HPPE_ACL_DEST_INVALID = 0, |
| HPPE_ACL_DEST_NEXTHOP, |
| HPPE_ACL_DEST_PORT_ID, |
| HPPE_ACL_DEST_PORT_BMP, |
| }; |
| |
| #define HPPE_ACL_DEST_INFO(type,value) (((type)<<12)|((value)&0xfff)) |
| #define HPPE_ACL_DEST_TYPE(dest) (((dest)>>12)&0x3) |
| #define HPPE_ACL_DEST_VALUE(dest) ((dest)&0xfff) |
| |
| static a_uint32_t _adpt_hppe_acl_srctype_to_hw(fal_acl_bind_obj_t obj_t) |
| { |
| a_uint32_t src_type = HPPE_ACL_TYPE_INVALID; |
| |
| switch(obj_t) |
| { |
| case FAL_ACL_BIND_PORTBITMAP: |
| src_type = HPPE_ACL_TYPE_PORTBITMAP; |
| break; |
| case FAL_ACL_BIND_PORT: |
| src_type = HPPE_ACL_TYPE_PORT; |
| break; |
| case FAL_ACL_BIND_SERVICE_CODE: |
| src_type = HPPE_ACL_TYPE_SERVICE_CODE; |
| break; |
| case FAL_ACL_BIND_L3_IF: |
| src_type = HPPE_ACL_TYPE_L3_IF; |
| break; |
| } |
| return src_type; |
| } |
| |
| static sw_error_t |
| _adpt_hppe_acl_rule_bind(a_uint32_t dev_id, a_uint32_t list_id, ADPT_HPPE_ACL_SW_RULE *rule_entry, |
| fal_acl_direc_t direc, fal_acl_bind_obj_t obj_t, a_uint32_t obj_idx) |
| { |
| a_uint32_t hw_index = 0, hw_entries = 0, hw_srctype = 0, hw_list_id = 0; |
| union ipo_rule_reg_u hw_reg = {0}; |
| |
| hw_entries = rule_entry->rule_hw_entry; |
| hw_list_id = rule_entry->rule_hw_list_id; |
| /* msg for debug */ |
| SSDK_DEBUG("ACL bind rule: list_id=%d, rule_id=%d, hw_entries=0x%x, hw_list_id=%d\n", |
| list_id, rule_entry->rule_id, hw_entries, hw_list_id); |
| |
| while(hw_entries != 0) |
| { |
| hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); |
| if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) |
| { |
| break; |
| } |
| |
| hppe_ipo_rule_reg_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, |
| &hw_reg); |
| |
| if(obj_t == FAL_ACL_BIND_PORT && obj_idx < SSDK_MAX_PORT_NUM) |
| { |
| /*convert port to bitmap if it is physical port*/ |
| obj_t = FAL_ACL_BIND_PORTBITMAP; |
| obj_idx = (1<<obj_idx); |
| } |
| |
| hw_srctype = _adpt_hppe_acl_srctype_to_hw(obj_t); |
| |
| if(hw_srctype == HPPE_ACL_TYPE_INVALID) |
| { |
| SSDK_ERROR("Invalid source type %d\n", obj_t); |
| return SW_BAD_PARAM; |
| } |
| else if(hw_srctype == HPPE_ACL_TYPE_PORTBITMAP && |
| hw_reg.bf.src_type == HPPE_ACL_TYPE_PORTBITMAP) |
| { |
| hw_reg.bf.src_0 |= obj_idx&0x7; |
| hw_reg.bf.src_1 |= (obj_idx>>3)&0x1f; |
| } |
| else |
| { |
| hw_reg.bf.src_0 = obj_idx&0x7; |
| hw_reg.bf.src_1 = (obj_idx>>3)&0x1f; |
| } |
| hw_reg.bf.src_type = hw_srctype; |
| |
| hppe_ipo_rule_reg_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, |
| &hw_reg); |
| SSDK_DEBUG("ACL bind entry %d source type %d, source value 0x%x\n", |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, obj_t, obj_idx); |
| hw_entries &= (~(1<<hw_index)); |
| } |
| |
| return SW_OK; |
| } |
| |
| static ADPT_HPPE_ACL_SW_LIST * |
| _adpt_hppe_acl_list_entry_get(a_uint32_t dev_id, a_uint32_t list_id) |
| { |
| ADPT_HPPE_ACL_SW_LIST *list_entry = NULL; |
| struct list_head *list_pos = NULL; |
| |
| list_for_each(list_pos, &g_acl_sw_list[dev_id].list_sw_list) |
| { |
| list_entry = list_entry(list_pos, ADPT_HPPE_ACL_SW_LIST, list); |
| if(list_entry->list_id == list_id) |
| { |
| break; |
| } |
| } |
| if(list_pos == &g_acl_sw_list[dev_id].list_sw_list) |
| { |
| return NULL; |
| } |
| else |
| { |
| return list_entry; |
| } |
| } |
| |
| sw_error_t |
| adpt_hppe_acl_list_bind(a_uint32_t dev_id, a_uint32_t list_id, fal_acl_direc_t direc, |
| fal_acl_bind_obj_t obj_t, a_uint32_t obj_idx) |
| { |
| struct list_head *rule_pos = NULL; |
| ADPT_HPPE_ACL_SW_RULE *rule_bind_entry = NULL; |
| ADPT_HPPE_ACL_SW_LIST *list_bind_entry = NULL; |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| if(list_id >= ADPT_ACL_SW_LIST_NUM) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| aos_lock_bh(&hppe_acl_lock[dev_id]); |
| list_bind_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); |
| if(list_bind_entry == NULL) |
| { |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_NOT_FOUND; |
| } |
| |
| list_for_each(rule_pos, &list_bind_entry->list_sw_rule) |
| { |
| rule_bind_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); |
| if(rule_bind_entry->rule_hw_entry) |
| { |
| sw_error_t rc; |
| rc = _adpt_hppe_acl_rule_bind(dev_id, list_id, rule_bind_entry, |
| direc, obj_t, obj_idx); |
| if(rc != SW_OK) |
| { |
| SSDK_ERROR("rule %d bind fail\n", rule_bind_entry->rule_id); |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_FAIL; |
| } |
| } |
| } |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_mac_rule_hw_2_sw(a_uint32_t is_mac_da, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask, fal_acl_rule_t * rule) |
| { |
| ADPT_HPPE_ACL_MAC_RULE *macrule = (ADPT_HPPE_ACL_MAC_RULE *)hw_reg; |
| ADPT_HPPE_ACL_MAC_RULE_MASK *macrule_mask = (ADPT_HPPE_ACL_MAC_RULE_MASK *)hw_mask; |
| |
| if(is_mac_da) |
| { |
| rule->dest_mac_val.uc[0] = macrule->mac[5]; |
| rule->dest_mac_val.uc[1] = macrule->mac[4]; |
| rule->dest_mac_val.uc[2] = macrule->mac[3]; |
| rule->dest_mac_val.uc[3] = macrule->mac[2]; |
| rule->dest_mac_val.uc[4] = macrule->mac[1]; |
| rule->dest_mac_val.uc[5] = macrule->mac[0]; |
| rule->dest_mac_mask.uc[0] = macrule_mask->mac_mask[5]; |
| rule->dest_mac_mask.uc[1] = macrule_mask->mac_mask[4]; |
| rule->dest_mac_mask.uc[2] = macrule_mask->mac_mask[3]; |
| rule->dest_mac_mask.uc[3] = macrule_mask->mac_mask[2]; |
| rule->dest_mac_mask.uc[4] = macrule_mask->mac_mask[1]; |
| rule->dest_mac_mask.uc[5] = macrule_mask->mac_mask[0]; |
| } |
| else |
| { |
| rule->src_mac_val.uc[0] = macrule->mac[5]; |
| rule->src_mac_val.uc[1] = macrule->mac[4]; |
| rule->src_mac_val.uc[2] = macrule->mac[3]; |
| rule->src_mac_val.uc[3] = macrule->mac[2]; |
| rule->src_mac_val.uc[4] = macrule->mac[1]; |
| rule->src_mac_val.uc[5] = macrule->mac[0]; |
| rule->src_mac_mask.uc[0] = macrule_mask->mac_mask[5]; |
| rule->src_mac_mask.uc[1] = macrule_mask->mac_mask[4]; |
| rule->src_mac_mask.uc[2] = macrule_mask->mac_mask[3]; |
| rule->src_mac_mask.uc[3] = macrule_mask->mac_mask[2]; |
| rule->src_mac_mask.uc[4] = macrule_mask->mac_mask[1]; |
| rule->src_mac_mask.uc[5] = macrule_mask->mac_mask[0]; |
| } |
| if(A_FALSE == _adpt_acl_zero_addr(rule->dest_mac_mask)) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_DA); |
| } |
| if(A_FALSE == _adpt_acl_zero_addr(rule->src_mac_mask)) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_SA); |
| } |
| |
| if(macrule_mask->is_ip_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); |
| rule->is_ip_val = macrule->is_ip; |
| } |
| |
| if(macrule_mask->is_ipv6_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); |
| rule->is_ipv6_val = macrule->is_ipv6; |
| } |
| |
| if(macrule_mask->is_ethernet_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_ETHERNET); |
| rule->is_ethernet_val = macrule->is_ethernet; |
| } |
| |
| if(macrule_mask->is_snap_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_SNAP); |
| rule->is_snap_val = macrule->is_snap; |
| } |
| |
| if(macrule_mask->is_fake_mac_header_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER); |
| rule->is_fake_mac_header_val = macrule->is_fake_mac_header; |
| } |
| |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_vlan_rule_hw_2_sw(union ipo_rule_reg_u *hw_reg, |
| union ipo_mask_reg_u *hw_mask, fal_acl_rule_t * rule) |
| { |
| ADPT_HPPE_ACL_VLAN_RULE * vlanrule = (ADPT_HPPE_ACL_VLAN_RULE *)hw_reg; |
| ADPT_HPPE_ACL_VLAN_RULE_MASK *vlanrule_mask = (ADPT_HPPE_ACL_VLAN_RULE_MASK *)hw_mask; |
| |
| /*ctag*/ |
| if(vlanrule_mask->cvid_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID); |
| rule->ctag_vid_mask = vlanrule_mask->cvid_mask; |
| } |
| if(hw_reg->bf.range_en) |
| { |
| if(vlanrule->cvid == 0) |
| { |
| rule->ctag_vid_op = FAL_ACL_FIELD_LE; |
| rule->ctag_vid_val = vlanrule_mask->cvid_mask; |
| } |
| else if(vlanrule_mask->cvid_mask == 0xfff) |
| { |
| rule->ctag_vid_op = FAL_ACL_FIELD_GE; |
| rule->ctag_vid_val = vlanrule->cvid; |
| } |
| else |
| { |
| rule->ctag_vid_op = FAL_ACL_FIELD_RANGE; |
| rule->ctag_vid_val = vlanrule->cvid; |
| } |
| |
| } |
| else |
| { |
| rule->ctag_vid_op = FAL_ACL_FIELD_MASK; |
| rule->ctag_vid_val = vlanrule->cvid; |
| } |
| |
| if(vlanrule_mask->cpcp_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI); |
| rule->ctag_pri_val = vlanrule->cpcp; |
| rule->ctag_pri_mask = vlanrule_mask->cpcp_mask; |
| } |
| |
| if(vlanrule_mask->cdei_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI); |
| rule->ctag_cfi_val = vlanrule->cdei; |
| rule->ctag_cfi_mask = vlanrule_mask->cdei_mask; |
| } |
| |
| if(vlanrule_mask->ctag_fmt_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_CTAGGED); |
| rule->ctagged_val = vlanrule->ctag_fmt; |
| rule->ctagged_mask = vlanrule_mask->ctag_fmt_mask; |
| } |
| |
| /*stag*/ |
| if(vlanrule_mask->svid_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID); |
| rule->stag_vid_val = vlanrule->svid; |
| rule->stag_vid_mask = vlanrule_mask->svid_mask; |
| } |
| if(vlanrule_mask->spcp_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI); |
| rule->stag_pri_val = vlanrule->spcp; |
| rule->stag_pri_mask = vlanrule_mask->spcp_mask; |
| } |
| if(vlanrule_mask->sdei_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI); |
| rule->stag_dei_val = vlanrule->sdei; |
| rule->stag_dei_mask = vlanrule_mask->sdei_mask; |
| } |
| if(vlanrule_mask->stag_fmt_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAGGED); |
| rule->stagged_val = vlanrule->stag_fmt; |
| rule->stagged_mask = vlanrule_mask->stag_fmt_mask; |
| } |
| /*vsi*/ |
| if(vlanrule_mask->vsi_valid_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_VSI_VALID); |
| rule->vsi_valid = vlanrule->vsi_valid; |
| rule->vsi_valid_mask = vlanrule_mask->vsi_valid_mask; |
| } |
| if(vlanrule_mask->vsi_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_VSI); |
| rule->vsi = vlanrule->vsi; |
| rule->vsi_mask = vlanrule_mask->vsi_mask; |
| } |
| |
| if(vlanrule_mask->is_ip_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); |
| rule->is_ip_val = vlanrule->is_ip; |
| } |
| |
| if(vlanrule_mask->is_ipv6_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); |
| rule->is_ipv6_val = vlanrule->is_ipv6; |
| } |
| |
| if(vlanrule_mask->is_ethernet_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_ETHERNET); |
| rule->is_ethernet_val = vlanrule->is_ethernet; |
| } |
| |
| if(vlanrule_mask->is_snap_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_SNAP); |
| rule->is_snap_val = vlanrule->is_snap; |
| } |
| |
| if(vlanrule_mask->is_fake_mac_header_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER); |
| rule->is_fake_mac_header_val = vlanrule->is_fake_mac_header; |
| } |
| |
| return SW_OK; |
| } |
| static sw_error_t _adpt_hppe_acl_l2_misc_rule_hw_2_sw(union ipo_rule_reg_u *hw_reg, |
| union ipo_mask_reg_u *hw_mask, fal_acl_rule_t * rule) |
| { |
| ADPT_HPPE_ACL_L2MISC_RULE * l2misc_rule = (ADPT_HPPE_ACL_L2MISC_RULE *)hw_reg; |
| ADPT_HPPE_ACL_L2MISC_RULE_MASK *l2misc_mask = (ADPT_HPPE_ACL_L2MISC_RULE_MASK *)hw_mask; |
| |
| /*stag*/ |
| if(l2misc_mask->svid_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID); |
| rule->stag_vid_mask = l2misc_mask->svid_mask; |
| } |
| if(hw_reg->bf.range_en) |
| { |
| if(l2misc_rule->svid == 0) |
| { |
| rule->stag_vid_op = FAL_ACL_FIELD_LE; |
| rule->stag_vid_val = l2misc_mask->svid_mask; |
| } |
| else if(l2misc_mask->svid_mask == 0xfff) |
| { |
| rule->stag_vid_op = FAL_ACL_FIELD_GE; |
| rule->stag_vid_val = l2misc_rule->svid; |
| } |
| else |
| { |
| rule->stag_vid_op = FAL_ACL_FIELD_RANGE; |
| rule->stag_vid_val = l2misc_rule->svid; |
| } |
| |
| } |
| else |
| { |
| rule->stag_vid_op = FAL_ACL_FIELD_MASK; |
| rule->stag_vid_val = l2misc_rule->svid; |
| } |
| |
| if(l2misc_mask->l2prot_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE); |
| rule->ethtype_val = l2misc_rule->l2prot; |
| rule->ethtype_mask = l2misc_mask->l2prot_mask; |
| } |
| |
| if(l2misc_mask->pppoe_sessionid_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_PPPOE_SESSIONID); |
| rule->pppoe_sessionid = l2misc_rule->pppoe_sessionid; |
| rule->pppoe_sessionid_mask = l2misc_mask->pppoe_sessionid_mask; |
| } |
| |
| if(l2misc_mask->is_ip_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); |
| rule->is_ip_val = l2misc_rule->is_ip; |
| } |
| |
| if(l2misc_mask->is_ipv6_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); |
| rule->is_ipv6_val = l2misc_rule->is_ipv6; |
| } |
| |
| if(l2misc_mask->is_ethernet_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_ETHERNET); |
| rule->is_ethernet_val = l2misc_rule->is_ethernet; |
| } |
| |
| if(l2misc_mask->is_snap_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_SNAP); |
| rule->is_snap_val = l2misc_rule->is_snap; |
| } |
| |
| if(l2misc_mask->is_fake_mac_header_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER); |
| rule->is_fake_mac_header_val = l2misc_rule->is_fake_mac_header; |
| } |
| |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_ipv4_rule_hw_2_sw(a_uint32_t is_ip_da, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask, fal_acl_rule_t *rule) |
| { |
| ADPT_HPPE_ACL_IPV4_RULE * ipv4rule = (ADPT_HPPE_ACL_IPV4_RULE *)hw_reg; |
| ADPT_HPPE_ACL_IPV4_RULE_MASK *ipv4rule_mask = (ADPT_HPPE_ACL_IPV4_RULE_MASK *)hw_mask; |
| |
| if(is_ip_da) |
| { |
| if(ipv4rule_mask->ip_mask_0 || ipv4rule_mask->ip_mask_1) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP4_DIP); |
| rule->dest_ip4_val = ipv4rule->ip_1<<16|ipv4rule->ip_0; |
| rule->dest_ip4_mask = (ipv4rule_mask->ip_mask_1<<16)|ipv4rule_mask->ip_mask_0; |
| } |
| if(ipv4rule_mask->l4_port_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L4_DPORT); |
| rule->dest_l4port_mask = ipv4rule_mask->l4_port_mask; |
| } |
| if(hw_reg->bf.range_en) |
| { |
| if(ipv4rule->l4_port == 0) |
| { |
| rule->dest_l4port_op = FAL_ACL_FIELD_LE; |
| rule->dest_l4port_val = ipv4rule_mask->l4_port_mask; |
| } |
| else if(ipv4rule_mask->l4_port_mask == 0xffff) |
| { |
| rule->dest_l4port_op = FAL_ACL_FIELD_GE; |
| rule->dest_l4port_val = ipv4rule->l4_port; |
| } |
| else |
| { |
| rule->dest_l4port_op = FAL_ACL_FIELD_RANGE; |
| rule->dest_l4port_val = ipv4rule->l4_port; |
| } |
| } |
| else |
| { |
| rule->dest_l4port_op = FAL_ACL_FIELD_MASK; |
| rule->dest_l4port_val = ipv4rule->l4_port; |
| } |
| } |
| else |
| { |
| if(ipv4rule_mask->ip_mask_0 || ipv4rule_mask->ip_mask_1) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP4_SIP); |
| rule->src_ip4_val = ipv4rule->ip_1<<16|ipv4rule->ip_0; |
| rule->src_ip4_mask = ipv4rule_mask->ip_mask_1<<16|ipv4rule_mask->ip_mask_0; |
| } |
| if(ipv4rule_mask->l4_port_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L4_SPORT); |
| rule->src_l4port_mask = ipv4rule_mask->l4_port_mask; |
| } |
| if(hw_reg->bf.range_en) |
| { |
| if(ipv4rule->l4_port == 0) |
| { |
| rule->src_l4port_op = FAL_ACL_FIELD_LE; |
| rule->src_l4port_val = ipv4rule_mask->l4_port_mask; |
| } |
| else if(ipv4rule_mask->l4_port_mask == 0xffff) |
| { |
| rule->src_l4port_op = FAL_ACL_FIELD_GE; |
| rule->src_l4port_val = ipv4rule->l4_port; |
| } |
| else |
| { |
| rule->src_l4port_op = FAL_ACL_FIELD_RANGE; |
| rule->src_l4port_val = ipv4rule->l4_port; |
| } |
| } |
| else |
| { |
| rule->src_l4port_op = FAL_ACL_FIELD_MASK; |
| rule->src_l4port_val = ipv4rule->l4_port; |
| } |
| } |
| |
| if(ipv4rule_mask->is_ip_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); |
| rule->is_ip_val = ipv4rule->is_ip; |
| } |
| if(ipv4rule_mask->l3_fragment_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT); |
| rule->is_fragement_val = ipv4rule->l3_fragment; |
| rule->is_fragement_mask = ipv4rule_mask->l3_fragment_mask; |
| } |
| if(ipv4rule_mask->l3_packet_type_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE); |
| rule->l3_pkt_type = ipv4rule->l3_packet_type; |
| rule->l3_pkt_type_mask = ipv4rule_mask->l3_packet_type_mask; |
| } |
| |
| return SW_OK; |
| } |
| |
| /*ip_bit_range: 0 mean DIP0 or SIP0, 1 mean DIP1 or SIP1, 2 mean DIP2 or SIP2,*/ |
| static sw_error_t _adpt_hppe_acl_ipv6_rule_hw_2_sw(a_uint32_t is_ip_da, a_uint32_t ip_bit_range, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask, fal_acl_rule_t *rule) |
| { |
| ADPT_HPPE_ACL_IPV6_RULE * ipv6rule = (ADPT_HPPE_ACL_IPV6_RULE *)hw_reg; |
| ADPT_HPPE_ACL_IPV6_RULE_MASK *ipv6rule_mask = (ADPT_HPPE_ACL_IPV6_RULE_MASK *)hw_mask; |
| |
| if(is_ip_da) |
| { |
| if(ip_bit_range == 0) |
| { |
| if(ipv6rule_mask->ip_port_mask |
| || ipv6rule_mask->ip_ext_1_mask |
| || ipv6rule_mask->ip_ext_2_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_DIP); |
| } |
| |
| rule->dest_ip6_val.ul[3] = ipv6rule->ip_ext_1<<16|ipv6rule->ip_port; |
| rule->dest_ip6_val.ul[2] |= (ipv6rule->ip_ext_2)&0xffff; |
| rule->dest_ip6_mask.ul[3] = |
| ipv6rule_mask->ip_ext_1_mask<<16|ipv6rule_mask->ip_port_mask; |
| rule->dest_ip6_mask.ul[2] |= (ipv6rule_mask->ip_ext_2_mask)&0xffff; |
| } |
| else if(ip_bit_range == 1) |
| { |
| if(ipv6rule_mask->ip_port_mask |
| || ipv6rule_mask->ip_ext_1_mask |
| || ipv6rule_mask->ip_ext_2_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_DIP); |
| } |
| rule->dest_ip6_val.ul[2] |= (ipv6rule->ip_port<<16)&0xffff0000; |
| rule->dest_ip6_val.ul[1] = ipv6rule->ip_ext_2<<16|ipv6rule->ip_ext_1; |
| rule->dest_ip6_mask.ul[2] |= (ipv6rule_mask->ip_port_mask<<16)&0xffff0000; |
| rule->dest_ip6_mask.ul[1] = |
| ipv6rule_mask->ip_ext_2_mask<<16|ipv6rule_mask->ip_ext_1_mask; |
| } |
| else if(ip_bit_range == 2) |
| { |
| if(ipv6rule_mask->ip_ext_1_mask |
| || ipv6rule_mask->ip_ext_2_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_DIP); |
| rule->dest_ip6_val.ul[0] = |
| ipv6rule->ip_ext_2<<16|ipv6rule->ip_ext_1; |
| rule->dest_ip6_mask.ul[0] = ipv6rule_mask->ip_ext_2_mask<<16| |
| ipv6rule_mask->ip_ext_1_mask; |
| } |
| if(ipv6rule_mask->ip_port_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L4_DPORT); |
| rule->dest_l4port_mask = ipv6rule_mask->ip_port_mask; |
| } |
| if(hw_reg->bf.range_en) |
| { |
| if(ipv6rule->ip_port == 0) |
| { |
| rule->dest_l4port_op = FAL_ACL_FIELD_LE; |
| rule->dest_l4port_val = ipv6rule_mask->ip_port_mask; |
| } |
| else if(ipv6rule_mask->ip_port_mask == 0xffff) |
| { |
| rule->dest_l4port_op = FAL_ACL_FIELD_GE; |
| rule->dest_l4port_val= ipv6rule->ip_port; |
| } |
| else |
| { |
| rule->dest_l4port_op = FAL_ACL_FIELD_RANGE; |
| rule->dest_l4port_val= ipv6rule->ip_port; |
| } |
| } |
| else |
| { |
| rule->dest_l4port_op = FAL_ACL_FIELD_MASK; |
| rule->dest_l4port_val = ipv6rule->ip_port; |
| } |
| |
| } |
| } |
| else |
| { |
| if(ip_bit_range == 0) |
| { |
| if(ipv6rule_mask->ip_port_mask |
| || ipv6rule_mask->ip_ext_1_mask |
| || ipv6rule_mask->ip_ext_2_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_SIP); |
| } |
| rule->src_ip6_val.ul[3] = ipv6rule->ip_ext_1<<16|ipv6rule->ip_port; |
| rule->src_ip6_val.ul[2] |= (ipv6rule->ip_ext_2)&0xffff; |
| rule->src_ip6_mask.ul[3] = |
| ipv6rule_mask->ip_ext_1_mask<<16|ipv6rule_mask->ip_port_mask; |
| rule->src_ip6_mask.ul[2] |= (ipv6rule_mask->ip_ext_2_mask)&0xffff; |
| } |
| else if(ip_bit_range == 1) |
| { |
| if(ipv6rule_mask->ip_port_mask |
| || ipv6rule_mask->ip_ext_1_mask |
| || ipv6rule_mask->ip_ext_2_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_SIP); |
| } |
| rule->src_ip6_val.ul[2] |= (ipv6rule->ip_port<<16)&0xffff0000; |
| rule->src_ip6_val.ul[1] = ipv6rule->ip_ext_2<<16|ipv6rule->ip_ext_1; |
| rule->src_ip6_mask.ul[2] |= (ipv6rule_mask->ip_port_mask<<16)&0xffff0000; |
| rule->src_ip6_mask.ul[1] = |
| ipv6rule_mask->ip_ext_2_mask<<16|ipv6rule_mask->ip_ext_1_mask; |
| } |
| else if(ip_bit_range == 2) |
| { |
| if(ipv6rule_mask->ip_ext_1_mask |
| || ipv6rule_mask->ip_ext_2_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP6_SIP); |
| rule->src_ip6_val.ul[0] = ipv6rule->ip_ext_2<<16|ipv6rule->ip_ext_1; |
| rule->src_ip6_mask.ul[0] = ipv6rule_mask->ip_ext_2_mask<<16| |
| ipv6rule_mask->ip_ext_1_mask; |
| } |
| if(ipv6rule_mask->ip_port_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L4_SPORT); |
| rule->src_l4port_mask = ipv6rule_mask->ip_port_mask; |
| } |
| if(hw_reg->bf.range_en) |
| { |
| if(ipv6rule->ip_port == 0) |
| { |
| rule->src_l4port_op = FAL_ACL_FIELD_LE; |
| rule->src_l4port_val = ipv6rule_mask->ip_port_mask; |
| } |
| else if(ipv6rule_mask->ip_port_mask == 0xffff) |
| { |
| rule->src_l4port_op = FAL_ACL_FIELD_GE; |
| rule->src_l4port_val= ipv6rule->ip_port; |
| } |
| else |
| { |
| rule->src_l4port_op = FAL_ACL_FIELD_RANGE; |
| rule->src_l4port_val= ipv6rule->ip_port; |
| } |
| } |
| else |
| { |
| rule->src_l4port_op = FAL_ACL_FIELD_MASK; |
| rule->src_l4port_val = ipv6rule->ip_port; |
| } |
| |
| } |
| } |
| |
| if(ipv6rule_mask->l3_fragment_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT); |
| rule->is_fragement_val = ipv6rule->l3_fragment; |
| rule->is_fragement_mask = ipv6rule_mask->l3_fragment_mask; |
| } |
| if(ipv6rule_mask->l3_packet_type_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE); |
| rule->l3_pkt_type = ipv6rule->l3_packet_type; |
| rule->l3_pkt_type_mask = ipv6rule_mask->l3_packet_type_mask; |
| } |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_ipmisc_rule_hw_2_sw(union ipo_rule_reg_u *hw_reg, |
| union ipo_mask_reg_u *hw_mask, fal_acl_rule_t *rule) |
| { |
| ADPT_HPPE_ACL_IPMISC_RULE * ipmisc_rule = (ADPT_HPPE_ACL_IPMISC_RULE *)hw_reg; |
| ADPT_HPPE_ACL_IPMISC_RULE_MASK *ipmisc_mask = (ADPT_HPPE_ACL_IPMISC_RULE_MASK *)hw_mask; |
| |
| if(ipmisc_mask->l3_length_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_LENGTH); |
| rule->l3_length_mask = ipmisc_mask->l3_length_mask; |
| } |
| if(hw_reg->bf.range_en) |
| { |
| if(ipmisc_rule->l3_length == 0) |
| { |
| rule->l3_length_op = FAL_ACL_FIELD_LE; |
| rule->l3_length = ipmisc_mask->l3_length_mask; |
| } |
| else if(ipmisc_mask->l3_length_mask == 0xffff) |
| { |
| rule->l3_length_op = FAL_ACL_FIELD_GE; |
| rule->l3_length = ipmisc_rule->l3_length; |
| } |
| else |
| { |
| rule->l3_length_op = FAL_ACL_FIELD_RANGE; |
| rule->l3_length = ipmisc_rule->l3_length; |
| } |
| } |
| else |
| { |
| rule->l3_length_op = FAL_ACL_FIELD_MASK; |
| rule->l3_length = ipmisc_rule->l3_length; |
| } |
| |
| if(ipmisc_mask->l3_prot_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP_PROTO); |
| rule->ip_proto_val = ipmisc_rule->l3_prot; |
| rule->ip_proto_mask = ipmisc_mask->l3_prot_mask; |
| } |
| if(ipmisc_mask->l3_dscp_tc_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP_DSCP); |
| rule->ip_dscp_val = ipmisc_rule->l3_dscp_tc; |
| rule->ip_dscp_mask = ipmisc_mask->l3_dscp_tc_mask; |
| } |
| |
| if(ipmisc_mask->first_fragment_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT); |
| rule->is_first_frag_val = ipmisc_rule->first_fragment; |
| } |
| if(ipmisc_mask->tcp_flags_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_TCP_FLAG); |
| rule->tcp_flag_val = ipmisc_rule->tcp_flags; |
| rule->tcp_flag_mask = ipmisc_mask->tcp_flags_mask; |
| } |
| if(ipmisc_mask->ipv4_option_state_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV4_OPTION); |
| rule->is_ipv4_option_val = ipmisc_rule->ipv4_option_state; |
| } |
| if(ipmisc_mask->l3_ttl_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_TTL); |
| rule->l3_ttl = ipmisc_rule->l3_ttl; |
| rule->l3_ttl_mask = ipmisc_mask->l3_ttl_mask; |
| } |
| if(ipmisc_mask->ah_header_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_AH_HEADER); |
| rule->is_ah_header_val = ipmisc_rule->ah_header; |
| } |
| if(ipmisc_mask->esp_header_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_ESP_HEADER); |
| rule->is_esp_header_val = ipmisc_rule->esp_header; |
| } |
| if(ipmisc_mask->mobility_header_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_MOBILITY_HEADER); |
| rule->is_mobility_header_val = ipmisc_rule->mobility_header; |
| } |
| if(ipmisc_mask->fragment_header_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_FRAGMENT_HEADER); |
| rule->is_fragment_header_val = ipmisc_rule->fragment_header; |
| } |
| if(ipmisc_mask->other_header_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_OTHER_EXT_HEADER); |
| rule->is_other_header_val = ipmisc_rule->other_header; |
| } |
| if(ipmisc_mask->is_ipv6_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); |
| rule->is_ipv6_val = ipmisc_rule->is_ipv6; |
| } |
| if(ipmisc_mask->l3_fragment_mask) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT); |
| rule->is_fragement_val = ipmisc_rule->l3_fragment; |
| } |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_udf_rule_hw_2_sw(union ipo_rule_reg_u *hw_reg, a_uint32_t is_win1, |
| union ipo_mask_reg_u *hw_mask, fal_acl_rule_t *rule) |
| { |
| ADPT_HPPE_ACL_UDF_RULE * udfrule = (ADPT_HPPE_ACL_UDF_RULE *)hw_reg; |
| ADPT_HPPE_ACL_UDF_RULE_MASK *udfrule_mask = (ADPT_HPPE_ACL_UDF_RULE_MASK *)hw_mask; |
| |
| if(is_win1) |
| { |
| if(udfrule->udf2_valid == 1) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF3); |
| rule->udf3_val = udfrule->udf2; |
| rule->udf3_mask = udfrule_mask->udf2_mask; |
| } |
| if(udfrule->udf1_valid == 1) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF2); |
| rule->udf2_val = udfrule->udf1; |
| rule->udf2_mask = udfrule_mask->udf1_mask; |
| } |
| if(udfrule->udf0_valid == 1) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF1); |
| if(hw_reg->bf.range_en == 1) |
| { |
| if(udfrule->udf0 == 0) |
| { |
| rule->udf1_op = FAL_ACL_FIELD_LE; |
| rule->udf1_val = udfrule_mask->udf0_mask; |
| } |
| else if(rule->udf1_mask == 0xffff) |
| { |
| rule->udf1_op = FAL_ACL_FIELD_GE; |
| rule->udf1_val = udfrule->udf0; |
| } |
| else |
| { |
| rule->udf1_op = FAL_ACL_FIELD_RANGE; |
| rule->udf1_val = udfrule->udf0; |
| rule->udf1_mask = udfrule_mask->udf0_mask; |
| } |
| } |
| else |
| { |
| rule->udf1_op = FAL_ACL_FIELD_MASK; |
| rule->udf1_val = udfrule->udf0; |
| rule->udf1_mask = udfrule_mask->udf0_mask; |
| } |
| |
| } |
| } |
| else |
| { |
| if(udfrule->udf2_valid == 1) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF2); |
| rule->udf2_val = udfrule->udf2; |
| rule->udf2_mask = udfrule_mask->udf2_mask; |
| } |
| if(udfrule->udf1_valid == 1) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF1); |
| rule->udf1_val = udfrule->udf1; |
| rule->udf1_mask = udfrule_mask->udf1_mask; |
| } |
| if(udfrule->udf0_valid == 1) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_UDF0); |
| if(hw_reg->bf.range_en == 1) |
| { |
| if(udfrule->udf0 == 0) |
| { |
| rule->udf0_op = FAL_ACL_FIELD_LE; |
| rule->udf0_val = udfrule_mask->udf0_mask; |
| } |
| else if(rule->udf0_mask == 0xffff) |
| { |
| rule->udf0_op = FAL_ACL_FIELD_GE; |
| rule->udf0_val = udfrule->udf0; |
| } |
| else |
| { |
| rule->udf0_op = FAL_ACL_FIELD_RANGE; |
| rule->udf0_val = udfrule->udf0; |
| rule->udf0_mask = udfrule_mask->udf0_mask; |
| } |
| } |
| else |
| { |
| rule->udf0_op = FAL_ACL_FIELD_MASK; |
| rule->udf0_val = udfrule->udf0; |
| rule->udf0_mask = udfrule_mask->udf0_mask; |
| } |
| |
| } |
| } |
| |
| if(udfrule_mask->is_ip) |
| { |
| rule->is_ip_val = udfrule->is_ip; |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IP); |
| } |
| if(udfrule_mask->is_ipv6) |
| { |
| udfrule->is_ipv6= rule->is_ipv6_val; |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_IPV6); |
| } |
| return SW_OK; |
| } |
| |
| static sw_error_t |
| _adpt_hppe_acl_action_hw_2_sw(a_uint32_t dev_id,union ipo_action_u *hw_act, fal_acl_rule_t *rule) |
| { |
| if(hw_act->bf.dest_info_change_en) |
| { |
| a_uint32_t dest_type = HPPE_ACL_DEST_TYPE(hw_act->bf.dest_info); |
| a_uint32_t dest_val = HPPE_ACL_DEST_VALUE(hw_act->bf.dest_info); |
| SSDK_DEBUG("hw_act->bf.dest_info = %x\n", hw_act->bf.dest_info); |
| if(dest_type == HPPE_ACL_DEST_NEXTHOP) /*nexthop*/ |
| { |
| rule->ports = FAL_ACL_DEST_OFFSET(FAL_ACL_DEST_NEXTHOP, |
| dest_val); |
| } |
| else if(dest_type == HPPE_ACL_DEST_PORT_ID) /*vp or trunk*/ |
| { |
| rule->ports = FAL_ACL_DEST_OFFSET(FAL_ACL_DEST_PORT_ID, |
| dest_val); |
| } |
| else if(dest_type == HPPE_ACL_DEST_PORT_BMP) /*bitmap*/ |
| { |
| rule->ports = FAL_ACL_DEST_OFFSET(FAL_ACL_DEST_PORT_BMP, |
| dest_val); |
| } |
| if(rule->ports != 0) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REDPT); |
| } |
| else if(hw_act->bf.fwd_cmd == HPPE_ACL_ACTION_RDTCPU) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_RDTCPU); |
| } |
| else if(hw_act->bf.fwd_cmd == HPPE_ACL_ACTION_COPYCPU) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_CPYCPU); |
| } |
| else if(hw_act->bf.fwd_cmd == HPPE_ACL_ACTION_DROP) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_DENY); |
| } |
| else if(hw_act->bf.fwd_cmd == HPPE_ACL_ACTION_FWD) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_PERMIT); |
| } |
| } |
| |
| if(hw_act->bf.mirror_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_MIRROR); |
| } |
| if(hw_act->bf.bypass_bitmap_0 != 0 || |
| hw_act->bf.bypass_bitmap_1 != 0) |
| { |
| rule->bypass_bitmap = (hw_act->bf.bypass_bitmap_1<<14)|hw_act->bf.bypass_bitmap_0; |
| } |
| if(hw_act->bf.svid_change_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID); |
| rule->stag_fmt = hw_act->bf.stag_fmt; |
| rule->stag_vid = hw_act->bf.svid; |
| } |
| if(hw_act->bf.stag_pcp_change_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI); |
| rule->stag_pri = hw_act->bf.stag_pcp; |
| } |
| if(hw_act->bf.stag_dei_change_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI); |
| rule->stag_dei = hw_act->bf.stag_dei; |
| } |
| if(hw_act->bf.cvid_change_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID); |
| rule->ctag_fmt = hw_act->bf.ctag_fmt; |
| rule->ctag_vid = hw_act->bf.cvid; |
| } |
| if(hw_act->bf.ctag_pcp_change_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI); |
| rule->ctag_pri = (hw_act->bf.ctag_pcp_1<<2)|hw_act->bf.ctag_pcp_0; |
| } |
| if(hw_act->bf.ctag_dei_change_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI); |
| rule->ctag_cfi = hw_act->bf.ctag_dei; |
| } |
| if(hw_act->bf.dscp_tc_change_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_DSCP); |
| rule->dscp = hw_act->bf.dscp_tc; |
| #if defined(CPPE) |
| if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) |
| { |
| rule->dscp_mask = hw_act->bf.dscp_tc_mask; |
| } |
| #endif |
| } |
| if(hw_act->bf.int_dp_change_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_INT_DP); |
| rule->int_dp = hw_act->bf.int_dp; |
| } |
| if(hw_act->bf.policer_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_POLICER_EN); |
| rule->policer_ptr = hw_act->bf.policer_index; |
| } |
| if(hw_act->bf.qid_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_REMARK_QUEUE); |
| rule->queue = hw_act->bf.qid; |
| } |
| if(hw_act->bf.enqueue_pri_change_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_ENQUEUE_PRI); |
| rule->enqueue_pri = hw_act->bf.enqueue_pri; |
| } |
| if(hw_act->bf.service_code_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_SERVICE_CODE); |
| rule->service_code = (hw_act->bf.service_code_1<<1)|hw_act->bf.service_code_0; |
| } |
| if(hw_act->bf.syn_toggle) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_SYN_TOGGLE); |
| } |
| if(hw_act->bf.cpu_code_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_CPU_CODE); |
| rule->cpu_code = hw_act->bf.cpu_code; |
| } |
| if(hw_act->bf.metadata_en == 1) |
| { |
| FAL_ACTION_FLG_SET(rule->action_flg, FAL_ACL_ACTION_METADATA_EN); |
| } |
| #if defined(CPPE) |
| if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) |
| { |
| rule->qos_res_prec = hw_act->bf.qos_res_prec; |
| } |
| #endif |
| return SW_OK; |
| } |
| sw_error_t |
| adpt_hppe_acl_rule_query(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, |
| fal_acl_rule_t * rule) |
| { |
| sw_error_t rv = 0; |
| a_uint32_t hw_index = 0, hw_entries = 0, hw_list_id = 0; |
| union ipo_rule_reg_u hw_reg = {0}; |
| union ipo_mask_reg_u hw_mask = {0}; |
| union ipo_action_u hw_act = {0}; |
| union ipo_cnt_tbl_u hw_match = {0}; |
| struct list_head *rule_pos = NULL; |
| ADPT_HPPE_ACL_SW_RULE *rule_query_entry = NULL; |
| ADPT_HPPE_ACL_SW_LIST *list_query_entry = NULL; |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| ADPT_NULL_POINT_CHECK(rule); |
| |
| if(list_id >= ADPT_ACL_SW_LIST_NUM) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| if(rule_id >= ADPT_ACL_RULE_NUM_PER_LIST) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| aos_lock_bh(&hppe_acl_lock[dev_id]); |
| list_query_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); |
| if(list_query_entry == NULL) |
| { |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_NOT_FOUND; |
| } |
| |
| list_for_each(rule_pos, &list_query_entry->list_sw_rule) |
| { |
| rule_query_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); |
| if((rule_query_entry->rule_id == rule_id) && (rule_query_entry->rule_hw_entry != 0)) |
| { |
| rule->rule_type = rule_query_entry->rule_type; |
| hw_entries = rule_query_entry->rule_hw_entry; |
| hw_list_id = rule_query_entry->rule_hw_list_id; |
| break; |
| } |
| } |
| if(rule_pos == &list_query_entry->list_sw_rule) |
| { |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_NOT_FOUND; |
| } |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| |
| hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); |
| if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) |
| { |
| return SW_FAIL; |
| } |
| hppe_ipo_cnt_tbl_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, &hw_match); |
| |
| rule->match_cnt = hw_match.bf.hit_pkt_cnt; |
| rule->match_bytes = hw_match.bf.hit_byte_cnt_1; |
| rule->match_bytes = rule->match_bytes<<32|hw_match.bf.hit_byte_cnt_0; |
| while(hw_entries != 0) |
| { |
| hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); |
| if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) |
| { |
| break; |
| } |
| rv |= hppe_ipo_rule_reg_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, |
| &hw_reg); |
| rv |= hppe_ipo_mask_reg_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, |
| &hw_mask); |
| rv |= hppe_ipo_action_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, |
| &hw_act); |
| rule->post_routing = hw_reg.bf.post_routing_en; |
| rule->acl_pool = hw_reg.bf.res_chain; |
| rule->pri = hw_reg.bf.pri&0x7; |
| |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_MAC_DA_RULE) |
| { |
| _adpt_hppe_acl_mac_rule_hw_2_sw(1, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_MAC_SA_RULE) |
| { |
| _adpt_hppe_acl_mac_rule_hw_2_sw(0, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_VLAN_RULE) |
| { |
| _adpt_hppe_acl_vlan_rule_hw_2_sw(&hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_L2_MISC_RULE) |
| { |
| _adpt_hppe_acl_l2_misc_rule_hw_2_sw(&hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV4_DIP_RULE) |
| { |
| _adpt_hppe_acl_ipv4_rule_hw_2_sw(1, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV4_SIP_RULE) |
| { |
| _adpt_hppe_acl_ipv4_rule_hw_2_sw(0, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_DIP0_RULE) |
| { |
| _adpt_hppe_acl_ipv6_rule_hw_2_sw(1, 0, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_DIP1_RULE) |
| { |
| _adpt_hppe_acl_ipv6_rule_hw_2_sw(1, 1, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_DIP2_RULE) |
| { |
| _adpt_hppe_acl_ipv6_rule_hw_2_sw(1, 2, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_SIP0_RULE) |
| { |
| _adpt_hppe_acl_ipv6_rule_hw_2_sw(0, 0, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_SIP1_RULE) |
| { |
| _adpt_hppe_acl_ipv6_rule_hw_2_sw(0, 1, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPV6_SIP2_RULE) |
| { |
| _adpt_hppe_acl_ipv6_rule_hw_2_sw(0, 2, &hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_IPMISC_RULE) |
| { |
| _adpt_hppe_acl_ipmisc_rule_hw_2_sw(&hw_reg, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_UDF0_RULE) |
| { |
| _adpt_hppe_acl_udf_rule_hw_2_sw(&hw_reg, 0, &hw_mask, rule); |
| } |
| if(hw_reg.bf.rule_type == ADPT_ACL_HPPE_UDF1_RULE) |
| { |
| _adpt_hppe_acl_udf_rule_hw_2_sw(&hw_reg, 1, &hw_mask, rule); |
| } |
| |
| if(hw_reg.bf.inverse_en == 1) |
| { |
| FAL_FIELD_FLG_SET(rule->field_flg, FAL_ACL_FIELD_INVERSE_ALL); |
| } |
| |
| _adpt_hppe_acl_action_hw_2_sw(dev_id,&hw_act, rule); |
| hw_entries &= (~(1<<hw_index)); |
| } |
| |
| return SW_OK; |
| } |
| static sw_error_t |
| _adpt_hppe_acl_rule_unbind(a_uint32_t dev_id, a_uint32_t list_id, ADPT_HPPE_ACL_SW_RULE *rule_entry, |
| fal_acl_direc_t direc, fal_acl_bind_obj_t obj_t, a_uint32_t obj_idx) |
| { |
| a_uint32_t hw_index = 0, hw_entries = 0, hw_list_id = 0; |
| union ipo_rule_reg_u hw_reg = {0}; |
| |
| hw_entries = rule_entry->rule_hw_entry; |
| hw_list_id = rule_entry->rule_hw_list_id; |
| /* msg for debug */ |
| SSDK_DEBUG("ACL unbind rule: list_id=%d, rule_id=%d, hw_entries=0x%x, hw_list_id=%d\n", |
| list_id, rule_entry->rule_id, hw_entries, hw_list_id); |
| |
| while(hw_entries != 0) |
| { |
| hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); |
| if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) |
| { |
| break; |
| } |
| |
| hppe_ipo_rule_reg_get(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, |
| &hw_reg); |
| |
| if(obj_t == FAL_ACL_BIND_PORT && obj_idx < SSDK_MAX_PORT_NUM) |
| { |
| /*convert port to bitmap if it is physical port*/ |
| obj_t = FAL_ACL_BIND_PORTBITMAP; |
| obj_idx = (1<<obj_idx); |
| } |
| |
| if(hw_reg.bf.src_type != _adpt_hppe_acl_srctype_to_hw(obj_t)) |
| { |
| SSDK_ERROR("ACL unbind fail obj_t %d\n", obj_t); |
| return SW_NOT_FOUND; |
| } |
| if(hw_reg.bf.src_type == HPPE_ACL_TYPE_PORTBITMAP) |
| { |
| hw_reg.bf.src_0 &= ((~obj_idx)&0x7); |
| hw_reg.bf.src_1 &= ((~(obj_idx>>3))&0x1f); |
| } |
| else |
| { |
| hw_reg.bf.src_type = HPPE_ACL_TYPE_PORTBITMAP; |
| hw_reg.bf.src_0 = 0; |
| hw_reg.bf.src_1 = 0; |
| } |
| hppe_ipo_rule_reg_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, |
| &hw_reg); |
| SSDK_DEBUG("ACL unbind entry %d source type %d, source value 0x%x\n", |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, obj_t, obj_idx); |
| hw_entries &= (~(1<<hw_index)); |
| } |
| |
| return SW_OK; |
| } |
| |
| sw_error_t |
| adpt_hppe_acl_list_unbind(a_uint32_t dev_id, a_uint32_t list_id, fal_acl_direc_t direc, |
| fal_acl_bind_obj_t obj_t, a_uint32_t obj_idx) |
| { |
| struct list_head *rule_pos = NULL; |
| ADPT_HPPE_ACL_SW_RULE *rule_unbind_entry = NULL; |
| ADPT_HPPE_ACL_SW_LIST *list_unbind_entry = NULL; |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| if(list_id >= ADPT_ACL_SW_LIST_NUM) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| aos_lock_bh(&hppe_acl_lock[dev_id]); |
| list_unbind_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); |
| if(list_unbind_entry != NULL) |
| { |
| list_for_each(rule_pos, &list_unbind_entry->list_sw_rule) |
| { |
| rule_unbind_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); |
| if(rule_unbind_entry->rule_hw_entry) |
| { |
| _adpt_hppe_acl_rule_unbind(dev_id, list_id, rule_unbind_entry, |
| direc, obj_t, obj_idx); |
| } |
| } |
| } |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_OK; |
| } |
| sw_error_t |
| adpt_hppe_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, |
| a_uint32_t rule_id, a_uint32_t rule_nr) |
| { |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| return SW_NOT_SUPPORTED; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_rule_range_match(a_uint32_t dev_id, a_uint32_t hw_list_index, |
| a_uint32_t rule_id, a_uint32_t rule_nr, fal_acl_rule_t * rule, a_uint8_t entries) |
| { |
| a_uint8_t rangecount = 0, even_entry_count = 0; |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) |
| { |
| if (FAL_ACL_FIELD_MASK != rule->stag_vid_op) |
| { |
| rangecount++; |
| } |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) |
| { |
| if (FAL_ACL_FIELD_MASK != rule->ctag_vid_op) |
| { |
| rangecount++; |
| } |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_DPORT)) |
| { |
| if (FAL_ACL_FIELD_MASK != rule->dest_l4port_op) |
| { |
| rangecount++; |
| } |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT)) |
| { |
| if (FAL_ACL_FIELD_MASK != rule->src_l4port_op) |
| { |
| rangecount++; |
| } |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_LENGTH)) |
| { |
| if (FAL_ACL_FIELD_MASK != rule->l3_length_op) |
| { |
| rangecount++; |
| } |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF0)) |
| { |
| if (FAL_ACL_FIELD_MASK != rule->udf0_op) |
| { |
| rangecount++; |
| } |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF1)) |
| { |
| if (FAL_ACL_FIELD_MASK != rule->udf1_op) |
| { |
| rangecount++; |
| } |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) |
| { |
| if (FAL_ACL_FIELD_MASK != rule->icmp_type_code_op) |
| { |
| rangecount++; |
| } |
| } |
| |
| even_entry_count = _acl_bits_count(entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 2); |
| |
| if(rangecount <= even_entry_count) |
| { |
| return SW_OK; |
| } |
| return SW_NO_RESOURCE; |
| } |
| sw_error_t _adpt_hppe_acl_alloc_entries(a_uint32_t dev_id, a_uint32_t *hw_list_index, |
| a_uint32_t rule_id, a_uint32_t rule_nr, fal_acl_rule_t * rule, |
| a_uint32_t rule_type_map, a_uint32_t rule_type_count, a_uint32_t *index) |
| { |
| a_uint8_t free_hw_entry_bitmap = 0, free_hw_entry_count = 0, i = 0; |
| a_uint32_t j = 0; |
| a_uint8_t map_info_count = sizeof(s_acl_entries)/sizeof(ADPT_HPPE_ACL_ENTRY_EXTEND_INFO); |
| |
| for(j = 0 ; j < ADPT_ACL_HW_LIST_NUM; j++) |
| { |
| free_hw_entry_bitmap = g_acl_hw_list[dev_id][j].free_hw_entry_bitmap; |
| free_hw_entry_count = g_acl_hw_list[dev_id][j].free_hw_entry_count; |
| /* msg for debug */ |
| SSDK_DEBUG("_adpt_hppe_acl_alloc_entries():hw_list_index=%d, hw_list_id=%d, " |
| "free_hw_entry_bitmap=0x%x, free_hw_entry_count=%d\n", j, |
| g_acl_hw_list[dev_id][j].hw_list_id, free_hw_entry_bitmap, |
| free_hw_entry_count); |
| if(free_hw_entry_count < rule_type_count) |
| { |
| continue; |
| } |
| for(i = 0; i < map_info_count; i++) |
| { |
| if((rule_type_count == s_acl_entries[i].num) && |
| ((free_hw_entry_bitmap & s_acl_entries[i].entries) == |
| s_acl_entries[i].entries)) |
| { |
| if(SW_OK == _adpt_hppe_acl_rule_range_match(dev_id, j, |
| rule_id, rule_nr, rule, s_acl_entries[i].entries)) |
| { |
| SSDK_DEBUG("\n{%d, 0x%x, 0x%x, 0x%x, 0x%x},\n", |
| s_acl_entries[i].num, s_acl_entries[i].ext_1, |
| s_acl_entries[i].ext_2, s_acl_entries[i].ext_4, |
| s_acl_entries[i].entries); |
| *index = i; |
| *hw_list_index = j; |
| return SW_OK; |
| } |
| } |
| } |
| } |
| return SW_NO_RESOURCE; |
| } |
| |
| static sw_error_t |
| _adpt_hppe_acl_l2_fields_check(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, a_uint32_t rule_nr, |
| fal_acl_rule_t * rule, a_uint32_t *rule_type_map) |
| { |
| a_uint32_t l2_rule_type_map = 0; |
| SSDK_DEBUG("fields[0] = 0x%x, fields[1] = 0x%x\n", rule->field_flg[0], rule->field_flg[1]); |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_DA)) |
| { |
| SSDK_DEBUG("select MAC DA rule\n"); |
| l2_rule_type_map |= (1<<ADPT_ACL_HPPE_MAC_DA_RULE); |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_SA)) |
| { |
| SSDK_DEBUG("select MAC SA rule\n"); |
| l2_rule_type_map |= (1<<ADPT_ACL_HPPE_MAC_SA_RULE); |
| } |
| if((FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI_VALID))) |
| { |
| SSDK_DEBUG("select VLAN rule\n"); |
| l2_rule_type_map |= (1<<ADPT_ACL_HPPE_VLAN_RULE); |
| } |
| |
| if((FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_PPPOE_SESSIONID)) || |
| ((FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) && |
| (rule->stag_vid_op != FAL_ACL_FIELD_MASK))) |
| { |
| SSDK_DEBUG("select L2 MISC rule\n"); |
| l2_rule_type_map |= (1<<ADPT_ACL_HPPE_L2_MISC_RULE); |
| } |
| |
| if(!((l2_rule_type_map & (1<<ADPT_ACL_HPPE_VLAN_RULE))|| |
| (l2_rule_type_map & (1<<ADPT_ACL_HPPE_L2_MISC_RULE)))) |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) |
| { |
| SSDK_DEBUG("select VLAN rule\n"); |
| l2_rule_type_map |= (1<<ADPT_ACL_HPPE_VLAN_RULE); |
| } |
| } |
| |
| if(l2_rule_type_map == 0) |
| { |
| if((FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_SNAP)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ETHERNET)) || |
| (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER))) |
| { |
| SSDK_DEBUG("select MAC DA rule\n"); |
| l2_rule_type_map |= (1<<ADPT_ACL_HPPE_MAC_DA_RULE); |
| } |
| } |
| |
| *rule_type_map |= l2_rule_type_map; |
| SSDK_DEBUG("rule_type_map = 0x%x\n", *rule_type_map); |
| |
| return SW_OK; |
| } |
| static sw_error_t |
| _adpt_hppe_acl_ipv4_fields_check(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, a_uint32_t rule_nr, |
| fal_acl_rule_t * rule, a_uint32_t *rule_type_map) |
| { |
| SSDK_DEBUG("fields[0] = 0x%x, fields[1] = 0x%x\n", |
| rule->field_flg[0], rule->field_flg[1]); |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_SIP) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_CODE)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV4_SIP_RULE); |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_DPORT) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_DIP)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV4_DIP_RULE); |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_LENGTH) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_DSCP) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_TCP_FLAG) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV4_OPTION) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_TTL) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_AH_HEADER) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ESP_HEADER) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PROTO)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPMISC_RULE); |
| } |
| if((!(*rule_type_map & (1<<ADPT_ACL_HPPE_IPV4_DIP_RULE))) && |
| (!(*rule_type_map & (1<<ADPT_ACL_HPPE_IPV4_SIP_RULE)))) |
| {/*both dip and sip rule are not selected, but ip_pkt_type field selected*/ |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV4_DIP_RULE); |
| } |
| } |
| if(*rule_type_map == 0) |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV4_DIP_RULE); |
| } |
| } |
| |
| SSDK_DEBUG("rule_type_map = 0x%x\n", *rule_type_map); |
| return SW_OK; |
| } |
| |
| static sw_error_t |
| _adpt_hppe_acl_ipv6_fields_check(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, a_uint32_t rule_nr, |
| fal_acl_rule_t * rule, a_uint32_t *rule_type_map) |
| { |
| SSDK_DEBUG("fields[0] = 0x%x, fields[1] = 0x%x\n", |
| rule->field_flg[0], rule->field_flg[1]); |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_CODE)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_SIP2_RULE); |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP6_SIP)) |
| { |
| if(rule->src_ip6_mask.ul[3] != 0 || rule->src_ip6_mask.ul[2]&0x0000ffff) |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_SIP0_RULE); |
| if(rule->src_ip6_mask.ul[1] != 0 || rule->src_ip6_mask.ul[2]&0xffff0000) |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_SIP1_RULE); |
| if(rule->src_ip6_mask.ul[0] != 0 ) |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_SIP2_RULE); |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_DPORT)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_DIP2_RULE); |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP6_DIP)) |
| { |
| if(rule->dest_ip6_mask.ul[3] != 0 || rule->dest_ip6_mask.ul[2]&0x0000ffff) |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_DIP0_RULE); |
| if(rule->dest_ip6_mask.ul[1] != 0 || rule->dest_ip6_mask.ul[2]&0xffff0000) |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_DIP1_RULE); |
| if(rule->dest_ip6_mask.ul[0] != 0 ) |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_DIP2_RULE); |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_LENGTH) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_DSCP) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_TCP_FLAG) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_TTL) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)|| |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ESP_HEADER) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MOBILITY_HEADER) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FRAGMENT_HEADER)|| |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_OTHER_EXT_HEADER)|| |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_AH_HEADER) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PROTO)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPMISC_RULE); |
| } |
| |
| if((!(*rule_type_map & (1<<ADPT_ACL_HPPE_IPV6_DIP0_RULE))) && |
| (!(*rule_type_map & (1<<ADPT_ACL_HPPE_IPV6_DIP1_RULE))) && |
| (!(*rule_type_map & (1<<ADPT_ACL_HPPE_IPV6_DIP2_RULE))) && |
| (!(*rule_type_map & (1<<ADPT_ACL_HPPE_IPV6_SIP0_RULE))) && |
| (!(*rule_type_map & (1<<ADPT_ACL_HPPE_IPV6_SIP1_RULE))) && |
| (!(*rule_type_map & (1<<ADPT_ACL_HPPE_IPV6_SIP2_RULE)))) |
| {/*both dip and sip rule are not selected, but ip_pkt_type field selected*/ |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_DIP0_RULE); |
| } |
| } |
| |
| if(*rule_type_map == 0) |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_IPV6_DIP0_RULE); |
| } |
| } |
| |
| SSDK_DEBUG("rule_type_map = 0x%x\n", *rule_type_map); |
| |
| return SW_OK; |
| } |
| |
| static sw_error_t |
| _adpt_hppe_acl_udf_fields_check(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, a_uint32_t rule_nr, |
| fal_acl_rule_t * rule, a_uint32_t *rule_type_map) |
| { |
| SSDK_DEBUG("fields[0] = 0x%x, fields[1] = 0x%x\n", |
| rule->field_flg[0], rule->field_flg[1]); |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF0)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_UDF0_RULE); |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF3)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_UDF1_RULE); |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF1) && |
| rule->udf1_op != FAL_ACL_FIELD_MASK) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_UDF1_RULE); |
| } |
| |
| if(*rule_type_map == 0) |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF1) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF2)) |
| { |
| *rule_type_map |= (1<<ADPT_ACL_HPPE_UDF0_RULE); |
| } |
| } |
| |
| SSDK_DEBUG("rule_type_map = 0x%x\n", *rule_type_map); |
| |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_mac_rule_sw_2_hw(fal_acl_rule_t *rule, a_uint32_t is_mac_da, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) |
| { |
| ADPT_HPPE_ACL_MAC_RULE * macrule = (ADPT_HPPE_ACL_MAC_RULE *)hw_reg; |
| ADPT_HPPE_ACL_MAC_RULE_MASK *macrule_mask = (ADPT_HPPE_ACL_MAC_RULE_MASK *)hw_mask; |
| |
| if(is_mac_da) |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_DA)) |
| { |
| macrule->mac[5] = rule->dest_mac_val.uc[0]; |
| macrule->mac[4] = rule->dest_mac_val.uc[1]; |
| macrule->mac[3] = rule->dest_mac_val.uc[2]; |
| macrule->mac[2] = rule->dest_mac_val.uc[3]; |
| macrule->mac[1] = rule->dest_mac_val.uc[4]; |
| macrule->mac[0] = rule->dest_mac_val.uc[5]; |
| macrule_mask->mac_mask[5] = rule->dest_mac_mask.uc[0]; |
| macrule_mask->mac_mask[4] = rule->dest_mac_mask.uc[1]; |
| macrule_mask->mac_mask[3] = rule->dest_mac_mask.uc[2]; |
| macrule_mask->mac_mask[2] = rule->dest_mac_mask.uc[3]; |
| macrule_mask->mac_mask[1] = rule->dest_mac_mask.uc[4]; |
| macrule_mask->mac_mask[0] = rule->dest_mac_mask.uc[5]; |
| } |
| } |
| else |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_SA)) |
| { |
| macrule->mac[5] = rule->src_mac_val.uc[0]; |
| macrule->mac[4] = rule->src_mac_val.uc[1]; |
| macrule->mac[3] = rule->src_mac_val.uc[2]; |
| macrule->mac[2] = rule->src_mac_val.uc[3]; |
| macrule->mac[1] = rule->src_mac_val.uc[4]; |
| macrule->mac[0] = rule->src_mac_val.uc[5]; |
| macrule_mask->mac_mask[5] = rule->src_mac_mask.uc[0]; |
| macrule_mask->mac_mask[4] = rule->src_mac_mask.uc[1]; |
| macrule_mask->mac_mask[3] = rule->src_mac_mask.uc[2]; |
| macrule_mask->mac_mask[2] = rule->src_mac_mask.uc[3]; |
| macrule_mask->mac_mask[1] = rule->src_mac_mask.uc[4]; |
| macrule_mask->mac_mask[0] = rule->src_mac_mask.uc[5]; |
| } |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) |
| { |
| macrule->is_ip = rule->is_ip_val; |
| macrule_mask->is_ip_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) |
| { |
| macrule->is_ipv6 = rule->is_ipv6_val; |
| macrule_mask->is_ipv6_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ETHERNET)) |
| { |
| macrule->is_ethernet = rule->is_ethernet_val; |
| macrule_mask->is_ethernet_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_SNAP)) |
| { |
| macrule->is_snap = rule->is_snap_val; |
| macrule_mask->is_snap_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER)) |
| { |
| macrule->is_fake_mac_header = rule->is_fake_mac_header_val; |
| macrule_mask->is_fake_mac_header_mask = 1; |
| } |
| |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_vlan_rule_sw_2_hw(fal_acl_rule_t *rule, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) |
| { |
| ADPT_HPPE_ACL_VLAN_RULE * vlanrule = (ADPT_HPPE_ACL_VLAN_RULE *)hw_reg; |
| ADPT_HPPE_ACL_VLAN_RULE_MASK *vlanrule_mask = (ADPT_HPPE_ACL_VLAN_RULE_MASK *)hw_mask; |
| |
| /*ctag*/ |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_VID)) |
| { |
| if(FAL_ACL_FIELD_MASK == rule->ctag_vid_op) |
| { |
| vlanrule->cvid = rule->ctag_vid_val; |
| vlanrule_mask->cvid_mask = rule->ctag_vid_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->ctag_vid_op) |
| { |
| min = 0; |
| max = rule->ctag_vid_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->ctag_vid_op) |
| { |
| min = rule->ctag_vid_val; |
| max = 0xfff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->ctag_vid_op) |
| { |
| min = rule->ctag_vid_val; |
| max = rule->ctag_vid_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| vlanrule->cvid = min; |
| vlanrule_mask->cvid_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_PRI)) |
| { |
| vlanrule->cpcp = rule->ctag_pri_val; |
| vlanrule_mask->cpcp_mask = rule->ctag_pri_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAG_CFI)) |
| { |
| vlanrule->cdei = rule->ctag_cfi_val; |
| vlanrule_mask->cdei_mask = rule->ctag_cfi_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_CTAGGED)) |
| { |
| vlanrule->ctag_fmt = rule->ctagged_val; |
| vlanrule_mask->ctag_fmt_mask = rule->ctagged_mask; |
| } |
| /*stag*/ |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID) && |
| (rule->stag_vid_op == FAL_ACL_FIELD_MASK)) |
| { |
| vlanrule->svid = rule->stag_vid_val; |
| vlanrule_mask->svid_mask = rule->stag_vid_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_PRI)) |
| { |
| vlanrule->spcp = rule->stag_pri_val; |
| vlanrule_mask->spcp_mask = rule->stag_pri_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_DEI)) |
| { |
| vlanrule->sdei = rule->stag_dei_val; |
| vlanrule_mask->sdei_mask = rule->stag_dei_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAGGED)) |
| { |
| vlanrule->stag_fmt = rule->stagged_val; |
| vlanrule_mask->stag_fmt_mask = rule->stagged_mask; |
| } |
| /*vsi*/ |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI_VALID)) |
| { |
| vlanrule->vsi_valid= rule->vsi_valid; |
| vlanrule_mask->vsi_valid_mask = rule->vsi_valid_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_VSI)) |
| { |
| vlanrule->vsi= rule->vsi; |
| vlanrule_mask->vsi_mask = rule->vsi_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) |
| { |
| vlanrule->is_ip = rule->is_ip_val; |
| vlanrule_mask->is_ip_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) |
| { |
| vlanrule->is_ipv6 = rule->is_ipv6_val; |
| vlanrule_mask->is_ipv6_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ETHERNET)) |
| { |
| vlanrule->is_ethernet = rule->is_ethernet_val; |
| vlanrule_mask->is_ethernet_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_SNAP)) |
| { |
| vlanrule->is_snap = rule->is_snap_val; |
| vlanrule_mask->is_snap_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER)) |
| { |
| vlanrule->is_fake_mac_header = rule->is_fake_mac_header_val; |
| vlanrule_mask->is_fake_mac_header_mask = 1; |
| } |
| |
| return SW_OK; |
| } |
| |
| |
| static sw_error_t _adpt_hppe_acl_l2_misc_rule_sw_2_hw(fal_acl_rule_t *rule, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) |
| { |
| ADPT_HPPE_ACL_L2MISC_RULE * l2misc_rule = (ADPT_HPPE_ACL_L2MISC_RULE *)hw_reg; |
| ADPT_HPPE_ACL_L2MISC_RULE_MASK *l2misc_mask = (ADPT_HPPE_ACL_L2MISC_RULE_MASK *)hw_mask; |
| |
| /*stag*/ |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_STAG_VID)) |
| { |
| if(FAL_ACL_FIELD_MASK == rule->stag_vid_op) |
| { |
| l2misc_rule->svid = rule->stag_vid_val; |
| l2misc_mask->svid_mask = rule->stag_vid_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->stag_vid_op) |
| { |
| min = 0; |
| max = rule->stag_vid_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->stag_vid_op) |
| { |
| min = rule->stag_vid_val; |
| max = 0xfff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->stag_vid_op) |
| { |
| min = rule->stag_vid_val; |
| max = rule->stag_vid_mask; |
| } |
| else |
| { |
| return SW_NOT_SUPPORTED; |
| } |
| l2misc_rule->svid = min; |
| l2misc_mask->svid_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MAC_ETHTYPE)) |
| { |
| l2misc_rule->l2prot = rule->ethtype_val; |
| l2misc_mask->l2prot_mask = rule->ethtype_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_PPPOE_SESSIONID)) |
| { |
| l2misc_rule->pppoe_sessionid = rule->pppoe_sessionid; |
| l2misc_mask->pppoe_sessionid_mask = rule->pppoe_sessionid_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) |
| { |
| l2misc_rule->is_ip = rule->is_ip_val; |
| l2misc_mask->is_ip_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) |
| { |
| l2misc_rule->is_ipv6 = rule->is_ipv6_val; |
| l2misc_mask->is_ipv6_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ETHERNET)) |
| { |
| l2misc_rule->is_ethernet = rule->is_ethernet_val; |
| l2misc_mask->is_ethernet_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_SNAP)) |
| { |
| l2misc_rule->is_snap = rule->is_snap_val; |
| l2misc_mask->is_snap_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FAKE_MAC_HEADER)) |
| { |
| l2misc_rule->is_fake_mac_header = rule->is_fake_mac_header_val; |
| l2misc_mask->is_fake_mac_header_mask = 1; |
| } |
| |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_ipv4_rule_sw_2_hw(fal_acl_rule_t *rule, a_uint32_t is_ip_da, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) |
| { |
| ADPT_HPPE_ACL_IPV4_RULE * ipv4rule = (ADPT_HPPE_ACL_IPV4_RULE *)hw_reg; |
| ADPT_HPPE_ACL_IPV4_RULE_MASK *ipv4rule_mask = (ADPT_HPPE_ACL_IPV4_RULE_MASK *)hw_mask; |
| |
| if(is_ip_da) |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_DIP)) |
| { |
| ipv4rule->ip_0 = rule->dest_ip4_val&0xffff; |
| ipv4rule->ip_1 = (rule->dest_ip4_val>>16)&0xffff; |
| ipv4rule_mask->ip_mask_0 = rule->dest_ip4_mask&0xffff; |
| ipv4rule_mask->ip_mask_1 = (rule->dest_ip4_mask)>>16&0xffff; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_DPORT)) |
| { |
| if(FAL_ACL_FIELD_MASK == rule->dest_l4port_op) |
| { |
| ipv4rule->l4_port = rule->dest_l4port_val; |
| ipv4rule_mask->l4_port_mask = rule->dest_l4port_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->dest_l4port_op) |
| { |
| min = 0; |
| max = rule->dest_l4port_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->dest_l4port_op) |
| { |
| min = rule->dest_l4port_val; |
| max = 0xffff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->dest_l4port_op) |
| { |
| min = rule->dest_l4port_val; |
| max = rule->dest_l4port_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| ipv4rule->l4_port = min; |
| ipv4rule_mask->l4_port_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| } |
| else |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP4_SIP)) |
| { |
| ipv4rule->ip_0 = rule->src_ip4_val&0xffff; |
| ipv4rule->ip_1 = (rule->src_ip4_val>>16)&0xffff; |
| ipv4rule_mask->ip_mask_0 = rule->src_ip4_mask&0xffff; |
| ipv4rule_mask->ip_mask_1 = (rule->src_ip4_mask>>16)&0xffff; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT)) |
| { |
| if(FAL_ACL_FIELD_MASK == rule->src_l4port_op) |
| { |
| ipv4rule->l4_port = rule->src_l4port_val; |
| ipv4rule_mask->l4_port_mask = rule->src_l4port_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->src_l4port_op) |
| { |
| min = 0; |
| max = rule->src_l4port_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->src_l4port_op) |
| { |
| min = rule->src_l4port_val; |
| max = 0xffff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->src_l4port_op) |
| { |
| min = rule->src_l4port_val; |
| max = rule->src_l4port_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| ipv4rule->l4_port = min; |
| ipv4rule_mask->l4_port_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_CODE) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) |
| { |
| if(FAL_ACL_FIELD_MASK == rule->icmp_type_code_op) |
| { |
| ipv4rule->l4_port = (rule->icmp_type_val<<8)|rule->icmp_code_val; |
| ipv4rule_mask->l4_port_mask = (rule->icmp_type_mask<<8)|rule->icmp_code_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->icmp_type_code_op) |
| { |
| min = 0; |
| max = (rule->icmp_type_val<<8)|rule->icmp_code_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->icmp_type_code_op) |
| { |
| min = (rule->icmp_type_val<<8)|rule->icmp_code_val; |
| max = 0xffff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->icmp_type_code_op) |
| { |
| min = (rule->icmp_type_val<<8)|rule->icmp_code_val; |
| max = (rule->icmp_type_mask<<8)|rule->icmp_code_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| ipv4rule->l4_port = min; |
| ipv4rule_mask->l4_port_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) |
| { |
| ipv4rule->is_ip = rule->is_ip_val; |
| ipv4rule_mask->is_ip_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) |
| { |
| ipv4rule->l3_fragment = rule->is_fragement_val; |
| ipv4rule_mask->l3_fragment_mask = rule->is_fragement_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE)) |
| { |
| ipv4rule->l3_packet_type = rule->l3_pkt_type; |
| ipv4rule_mask->l3_packet_type_mask = rule->l3_pkt_type_mask; |
| } |
| |
| return SW_OK; |
| } |
| |
| /*ip_bit_range: 0 mean DIP0 or SIP0, 1 mean DIP1 or SIP1, 2 mean DIP2 or SIP2,*/ |
| static sw_error_t _adpt_hppe_acl_ipv6_rule_sw_2_hw(fal_acl_rule_t *rule, a_uint32_t is_ip_da, a_uint32_t ip_bit_range, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) |
| { |
| ADPT_HPPE_ACL_IPV6_RULE * ipv6rule = (ADPT_HPPE_ACL_IPV6_RULE *)hw_reg; |
| ADPT_HPPE_ACL_IPV6_RULE_MASK *ipv6rule_mask = (ADPT_HPPE_ACL_IPV6_RULE_MASK *)hw_mask; |
| |
| if(is_ip_da) |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP6_DIP)) |
| { |
| if(ip_bit_range == 0) |
| { |
| ipv6rule->ip_port = rule->dest_ip6_val.ul[3]&0xffff; |
| ipv6rule->ip_ext_1 = (rule->dest_ip6_val.ul[3]>>16)&0xffff; |
| ipv6rule->ip_ext_2 = (rule->dest_ip6_val.ul[2])&0xffff; |
| ipv6rule_mask->ip_port_mask = rule->dest_ip6_mask.ul[3]&0xffff; |
| ipv6rule_mask->ip_ext_1_mask = (rule->dest_ip6_mask.ul[3]>>16)&0xffff; |
| ipv6rule_mask->ip_ext_2_mask = (rule->dest_ip6_mask.ul[2])&0xffff; |
| } |
| else if(ip_bit_range == 1) |
| { |
| ipv6rule->ip_port = (rule->dest_ip6_val.ul[2]>>16)&0xffff; |
| ipv6rule->ip_ext_1 = (rule->dest_ip6_val.ul[1])&0xffff; |
| ipv6rule->ip_ext_2 = (rule->dest_ip6_val.ul[1]>>16)&0xffff; |
| ipv6rule_mask->ip_port_mask = (rule->dest_ip6_mask.ul[2]>>16)&0xffff; |
| ipv6rule_mask->ip_ext_1_mask = (rule->dest_ip6_mask.ul[1])&0xffff; |
| ipv6rule_mask->ip_ext_2_mask = (rule->dest_ip6_mask.ul[1]>>16)&0xffff; |
| } |
| else if(ip_bit_range == 2) |
| { |
| ipv6rule->ip_ext_1 = (rule->dest_ip6_val.ul[0])&0xffff; |
| ipv6rule->ip_ext_2 = (rule->dest_ip6_val.ul[0]>>16)&0xffff; |
| ipv6rule_mask->ip_ext_1_mask = (rule->dest_ip6_mask.ul[0])&0xffff; |
| ipv6rule_mask->ip_ext_2_mask = (rule->dest_ip6_mask.ul[0]>>16)&0xffff; |
| } |
| } |
| if((ip_bit_range == 2) && (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_DPORT))) |
| { |
| if(FAL_ACL_FIELD_MASK == rule->dest_l4port_op) |
| { |
| ipv6rule->ip_port = rule->dest_l4port_val; |
| ipv6rule_mask->ip_port_mask = rule->dest_l4port_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->dest_l4port_op) |
| { |
| min = 0; |
| max = rule->dest_l4port_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->dest_l4port_op) |
| { |
| min = rule->dest_l4port_val; |
| max = 0xffff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->dest_l4port_op) |
| { |
| min = rule->dest_l4port_val; |
| max = rule->dest_l4port_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| ipv6rule->ip_port = min; |
| ipv6rule_mask->ip_port_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| } |
| else |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP6_SIP)) |
| { |
| if(ip_bit_range == 0) |
| { |
| ipv6rule->ip_port = rule->src_ip6_val.ul[3]&0xffff; |
| ipv6rule->ip_ext_1 = (rule->src_ip6_val.ul[3]>>16)&0xffff; |
| ipv6rule->ip_ext_2 = (rule->src_ip6_val.ul[2])&0xffff; |
| ipv6rule_mask->ip_port_mask = rule->src_ip6_mask.ul[3]&0xffff; |
| ipv6rule_mask->ip_ext_1_mask = (rule->src_ip6_mask.ul[3]>>16)&0xffff; |
| ipv6rule_mask->ip_ext_2_mask = (rule->src_ip6_mask.ul[2])&0xffff; |
| } |
| else if(ip_bit_range == 1) |
| { |
| ipv6rule->ip_port = (rule->src_ip6_val.ul[2]>>16)&0xffff; |
| ipv6rule->ip_ext_1 = (rule->src_ip6_val.ul[1])&0xffff; |
| ipv6rule->ip_ext_2 = (rule->src_ip6_val.ul[1]>>16)&0xffff; |
| ipv6rule_mask->ip_port_mask = (rule->src_ip6_mask.ul[2]>>16)&0xffff; |
| ipv6rule_mask->ip_ext_1_mask = (rule->src_ip6_mask.ul[1])&0xffff; |
| ipv6rule_mask->ip_ext_2_mask = (rule->src_ip6_mask.ul[1]>>16)&0xffff; |
| } |
| else if(ip_bit_range == 2) |
| { |
| ipv6rule->ip_ext_1 = (rule->src_ip6_val.ul[0])&0xffff; |
| ipv6rule->ip_ext_2 = (rule->src_ip6_val.ul[0]>>16)&0xffff; |
| ipv6rule_mask->ip_ext_1_mask = (rule->src_ip6_mask.ul[0])&0xffff; |
| ipv6rule_mask->ip_ext_2_mask = (rule->src_ip6_mask.ul[0]>>16)&0xffff; |
| } |
| } |
| if((ip_bit_range == 2) && (FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L4_SPORT))) |
| { |
| if(FAL_ACL_FIELD_MASK == rule->src_l4port_op) |
| { |
| ipv6rule->ip_port = rule->src_l4port_val; |
| ipv6rule_mask->ip_port_mask = rule->src_l4port_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->src_l4port_op) |
| { |
| min = 0; |
| max = rule->src_l4port_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->src_l4port_op) |
| { |
| min = rule->src_l4port_val; |
| max = 0xffff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->src_l4port_op) |
| { |
| min = rule->src_l4port_val; |
| max = rule->src_l4port_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| ipv6rule->ip_port = min; |
| ipv6rule_mask->ip_port_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_CODE) || |
| FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ICMP_TYPE)) |
| { |
| if(FAL_ACL_FIELD_MASK == rule->icmp_type_code_op) |
| { |
| ipv6rule->ip_port = (rule->icmp_type_val<<8)|rule->icmp_code_val; |
| ipv6rule_mask->ip_port_mask = (rule->icmp_type_mask<<8)|rule->icmp_code_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->icmp_type_code_op) |
| { |
| min = 0; |
| max = (rule->icmp_type_val<<8)|rule->icmp_code_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->icmp_type_code_op) |
| { |
| min = (rule->icmp_type_val<<8)|rule->icmp_code_val; |
| max = 0xffff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->icmp_type_code_op) |
| { |
| min = (rule->icmp_type_val<<8)|rule->icmp_code_val; |
| max = (rule->icmp_type_mask<<8)|rule->icmp_code_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| ipv6rule->ip_port = min; |
| ipv6rule_mask->ip_port_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) |
| { |
| ipv6rule->l3_fragment = rule->is_fragement_val; |
| ipv6rule_mask->l3_fragment_mask = rule->is_fragement_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PKT_TYPE)) |
| { |
| ipv6rule->l3_packet_type = rule->l3_pkt_type; |
| ipv6rule_mask->l3_packet_type_mask = rule->l3_pkt_type_mask; |
| } |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_ipmisc_rule_sw_2_hw(fal_acl_rule_t *rule, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) |
| { |
| ADPT_HPPE_ACL_IPMISC_RULE * ipmisc_rule = (ADPT_HPPE_ACL_IPMISC_RULE *)hw_reg; |
| ADPT_HPPE_ACL_IPMISC_RULE_MASK *ipmisc_mask = (ADPT_HPPE_ACL_IPMISC_RULE_MASK *)hw_mask; |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_LENGTH)) |
| { |
| if(FAL_ACL_FIELD_MASK == rule->l3_length_op) |
| { |
| ipmisc_rule->l3_length = rule->l3_length; |
| ipmisc_mask->l3_length_mask = rule->l3_length_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->l3_length_op) |
| { |
| min = 0; |
| max = rule->l3_length; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->l3_length_op) |
| { |
| min = rule->l3_length; |
| max = 0xffff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->l3_length_op) |
| { |
| min = rule->l3_length; |
| max = rule->l3_length_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| ipmisc_rule->l3_length = min; |
| ipmisc_mask->l3_length_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_PROTO)) |
| { |
| ipmisc_rule->l3_prot = rule->ip_proto_val; |
| ipmisc_mask->l3_prot_mask = rule->ip_proto_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP_DSCP)) |
| { |
| ipmisc_rule->l3_dscp_tc = rule->ip_dscp_val; |
| ipmisc_mask->l3_dscp_tc_mask = rule->ip_dscp_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FIRST_FRAGMENT)) |
| { |
| ipmisc_rule->first_fragment = rule->is_first_frag_val; |
| ipmisc_mask->first_fragment_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_TCP_FLAG)) |
| { |
| ipmisc_rule->tcp_flags = rule->tcp_flag_val; |
| ipmisc_mask->tcp_flags_mask = rule->tcp_flag_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV4_OPTION)) |
| { |
| ipmisc_rule->ipv4_option_state = rule->is_ipv4_option_val; |
| ipmisc_mask->ipv4_option_state_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_TTL)) |
| { |
| ipmisc_rule->l3_ttl = rule->l3_ttl; |
| ipmisc_mask->l3_ttl_mask = rule->l3_ttl_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_AH_HEADER)) |
| { |
| ipmisc_rule->ah_header = rule->is_ah_header_val; |
| ipmisc_mask->ah_header_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_ESP_HEADER)) |
| { |
| ipmisc_rule->esp_header = rule->is_esp_header_val; |
| ipmisc_mask->esp_header_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_MOBILITY_HEADER)) |
| { |
| ipmisc_rule->mobility_header = rule->is_mobility_header_val; |
| ipmisc_mask->mobility_header_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_FRAGMENT_HEADER)) |
| { |
| ipmisc_rule->fragment_header = rule->is_fragment_header_val; |
| ipmisc_mask->fragment_header_mask= 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_OTHER_EXT_HEADER)) |
| { |
| ipmisc_rule->other_header = rule->is_other_header_val; |
| ipmisc_mask->other_header_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) |
| { |
| ipmisc_rule->is_ipv6 = rule->is_ipv6_val; |
| ipmisc_mask->is_ipv6_mask = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_L3_FRAGMENT)) |
| { |
| ipmisc_rule->l3_fragment = rule->is_fragement_val; |
| ipmisc_mask->l3_fragment_mask = 1; |
| } |
| return SW_OK; |
| } |
| |
| static sw_error_t _adpt_hppe_acl_udf_rule_sw_2_hw(fal_acl_rule_t *rule, a_uint32_t is_win1, |
| union ipo_rule_reg_u *hw_reg, union ipo_mask_reg_u *hw_mask) |
| { |
| ADPT_HPPE_ACL_UDF_RULE * udfrule = (ADPT_HPPE_ACL_UDF_RULE *)hw_reg; |
| ADPT_HPPE_ACL_UDF_RULE_MASK *udfrule_mask = (ADPT_HPPE_ACL_UDF_RULE_MASK *)hw_mask; |
| |
| if(is_win1) |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF3)) |
| { |
| udfrule->udf2_valid = 1; |
| udfrule->udf2 = rule->udf3_val; |
| udfrule_mask->udf2_valid = 1; |
| udfrule_mask->udf2_mask = rule->udf3_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF2)) |
| { |
| udfrule->udf1_valid = 1; |
| udfrule->udf1 = rule->udf2_val; |
| udfrule_mask->udf1_valid = 1; |
| udfrule_mask->udf1_mask = rule->udf2_mask; |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF1)) |
| { |
| udfrule->udf0_valid = 1; |
| udfrule_mask->udf0_valid = 1; |
| if(FAL_ACL_FIELD_MASK == rule->udf1_op) |
| { |
| udfrule->udf0 = rule->udf1_val; |
| udfrule_mask->udf0_mask = rule->udf1_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->udf1_op) |
| { |
| min = 0; |
| max = rule->udf1_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->udf1_op) |
| { |
| min = rule->udf1_val; |
| max = 0xffff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->udf1_op) |
| { |
| min = rule->udf1_val; |
| max = rule->udf1_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| udfrule->udf0 = min; |
| udfrule_mask->udf0_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| } |
| else |
| { |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF1) && |
| FAL_ACL_FIELD_MASK == rule->udf1_op) |
| { |
| udfrule->udf1_valid = 1; |
| udfrule->udf1 = rule->udf1_val; |
| udfrule_mask->udf1_valid = 1; |
| udfrule_mask->udf1_mask = rule->udf1_mask; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF2)) |
| { |
| udfrule->udf2_valid = 1; |
| udfrule->udf2 = rule->udf2_val; |
| udfrule_mask->udf2_valid = 1; |
| udfrule_mask->udf2_mask = rule->udf2_mask; |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_UDF0)) |
| { |
| udfrule->udf0_valid = 1; |
| udfrule_mask->udf0_valid = 1; |
| if(FAL_ACL_FIELD_MASK == rule->udf0_op) |
| { |
| udfrule->udf0 = rule->udf0_val; |
| udfrule_mask->udf0_mask = rule->udf0_mask; |
| } |
| else |
| { |
| a_uint16_t min, max; |
| if(FAL_ACL_FIELD_LE == rule->udf0_op) |
| { |
| min = 0; |
| max = rule->udf0_val; |
| } |
| else if(FAL_ACL_FIELD_GE == rule->udf0_op) |
| { |
| min = rule->udf0_val; |
| max = 0xffff; |
| } |
| else if(FAL_ACL_FIELD_RANGE == rule->udf0_op) |
| { |
| min = rule->udf0_val; |
| max = rule->udf0_mask; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| udfrule->udf0 = min; |
| udfrule_mask->udf0_mask = max; |
| hw_reg->bf.range_en = 1; |
| } |
| } |
| } |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IP)) |
| { |
| udfrule->is_ip = rule->is_ip_val; |
| udfrule_mask->is_ip = 1; |
| } |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_IPV6)) |
| { |
| udfrule->is_ipv6= rule->is_ipv6_val; |
| udfrule_mask->is_ipv6 = 1; |
| } |
| return SW_OK; |
| } |
| static sw_error_t |
| _adpt_hppe_acl_action_sw_2_hw(a_uint32_t dev_id,fal_acl_rule_t *rule, union ipo_action_u *hw_act) |
| { |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REDPT)) |
| { |
| a_uint32_t dest_type = FAL_ACL_DEST_TYPE(rule->ports); |
| a_uint32_t dest_val = FAL_ACL_DEST_VALUE(rule->ports); |
| |
| SSDK_DEBUG("rule->ports = %x\n", rule->ports); |
| |
| hw_act->bf.dest_info_change_en = 1; |
| if(dest_type == FAL_ACL_DEST_NEXTHOP) /*nexthop*/ |
| { |
| hw_act->bf.dest_info = |
| HPPE_ACL_DEST_INFO(HPPE_ACL_DEST_NEXTHOP, dest_val); |
| } |
| else if(FAL_ACL_DEST_TYPE(rule->ports) == FAL_ACL_DEST_PORT_ID)/*vp*/ |
| { |
| hw_act->bf.dest_info = |
| HPPE_ACL_DEST_INFO(HPPE_ACL_DEST_PORT_ID, dest_val); |
| } |
| else if(FAL_ACL_DEST_TYPE(rule->ports) == FAL_ACL_DEST_PORT_BMP)/*bitmap*/ |
| { |
| hw_act->bf.dest_info = |
| HPPE_ACL_DEST_INFO(HPPE_ACL_DEST_PORT_BMP, dest_val); |
| } |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_PERMIT)) |
| { |
| hw_act->bf.dest_info_change_en = 1; |
| hw_act->bf.fwd_cmd = 0;/*forward*/ |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_DENY)) |
| { |
| hw_act->bf.dest_info_change_en = 1; |
| hw_act->bf.fwd_cmd = 1;/*drop*/ |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_CPYCPU)) |
| { |
| hw_act->bf.dest_info_change_en = 1; |
| hw_act->bf.fwd_cmd = 2;/*copy to cpu*/ |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_RDTCPU)) |
| { |
| hw_act->bf.dest_info_change_en = 1; |
| hw_act->bf.fwd_cmd = 3;/*redirect to cpu*/ |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_MIRROR)) |
| { |
| hw_act->bf.mirror_en= 1; |
| } |
| hw_act->bf.bypass_bitmap_0 = rule->bypass_bitmap & 0x3fff; |
| hw_act->bf.bypass_bitmap_1 = (rule->bypass_bitmap>>14) & 0x3ffff; |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_VID)) |
| { |
| hw_act->bf.svid_change_en = 1; |
| hw_act->bf.stag_fmt = rule->stag_fmt; |
| hw_act->bf.svid = rule->stag_vid; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_PRI)) |
| { |
| hw_act->bf.stag_pcp_change_en = 1; |
| hw_act->bf.stag_pcp = rule->stag_pri; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_STAG_DEI)) |
| { |
| hw_act->bf.stag_dei_change_en = 1; |
| hw_act->bf.stag_dei = rule->stag_dei; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_VID)) |
| { |
| hw_act->bf.cvid_change_en = 1; |
| hw_act->bf.ctag_fmt = rule->ctag_fmt; |
| hw_act->bf.cvid = rule->ctag_vid; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_PRI)) |
| { |
| hw_act->bf.ctag_pcp_change_en = 1; |
| hw_act->bf.ctag_pcp_0 = rule->ctag_pri&0x3; |
| hw_act->bf.ctag_pcp_1 = (rule->ctag_pri>>2)&0x1; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_CTAG_CFI)) |
| { |
| hw_act->bf.ctag_dei_change_en = 1; |
| hw_act->bf.ctag_dei = rule->ctag_cfi; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_DSCP)) |
| { |
| hw_act->bf.dscp_tc_change_en = 1; |
| hw_act->bf.dscp_tc = rule->dscp; |
| #if defined(CPPE) |
| if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) |
| { |
| hw_act->bf.dscp_tc_mask = rule->dscp_mask; |
| } |
| #endif |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_INT_DP)) |
| { |
| hw_act->bf.int_dp_change_en = 1; |
| hw_act->bf.int_dp = rule->int_dp; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_POLICER_EN)) |
| { |
| hw_act->bf.policer_en = 1; |
| hw_act->bf.policer_index = rule->policer_ptr; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_REMARK_QUEUE)) |
| { |
| hw_act->bf.qid_en = 1; |
| hw_act->bf.qid = rule->queue; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_ENQUEUE_PRI)) |
| { |
| hw_act->bf.enqueue_pri_change_en = 1; |
| hw_act->bf.enqueue_pri = rule->enqueue_pri; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_SERVICE_CODE)) |
| { |
| hw_act->bf.service_code_en = 1; |
| hw_act->bf.service_code_0 = rule->service_code&0x1; |
| hw_act->bf.service_code_1 = (rule->service_code>>1)&0x7f; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_SYN_TOGGLE)) |
| { |
| hw_act->bf.syn_toggle = 1; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_CPU_CODE)) |
| { |
| hw_act->bf.cpu_code_en = 1; |
| hw_act->bf.cpu_code = rule->cpu_code; |
| } |
| if(FAL_ACTION_FLG_TST(rule->action_flg, FAL_ACL_ACTION_METADATA_EN)) |
| { |
| hw_act->bf.metadata_en = 1; |
| } |
| #if defined(CPPE) |
| if(adpt_hppe_chip_revision_get(dev_id) == CPPE_REVISION) |
| { |
| hw_act->bf.qos_res_prec = rule->qos_res_prec; |
| } |
| #endif |
| return SW_OK; |
| } |
| |
| sw_error_t |
| _adpt_hppe_acl_rule_hw_add(a_uint32_t dev_id, ADPT_HPPE_ACL_SW_LIST *list_entry, |
| a_uint32_t hw_list_id, a_uint32_t rule_id, a_uint32_t rule_nr, |
| fal_acl_rule_t * rule, a_uint32_t rule_type_map, a_uint32_t allocated_entries) |
| { |
| union ipo_rule_reg_u hw_reg = {0}; |
| union ipo_mask_reg_u hw_mask = {0}; |
| union ipo_action_u hw_act = {0}; |
| sw_error_t rv = 0; |
| a_uint32_t hw_entry = 0; |
| a_uint32_t i = 0; |
| |
| hw_reg.bf.post_routing_en = rule->post_routing; |
| hw_reg.bf.res_chain = rule->acl_pool; |
| hw_reg.bf.pri = ((list_entry->list_pri)<<3)|rule->pri; |
| |
| for( i = 0; i < ADPT_ACL_HPPE_RULE_TYPE_NUM; i++) |
| { |
| if(!((1<<i)&rule_type_map)) |
| { |
| continue; |
| } |
| hw_reg.bf.rule_field_0 = 0; |
| hw_reg.bf.rule_field_1 = 0; |
| |
| memset(&hw_mask, 0, sizeof(hw_mask)); |
| memset(&hw_act, 0, sizeof(hw_act)); |
| |
| if(i == ADPT_ACL_HPPE_VLAN_RULE) |
| { |
| hw_reg.bf.rule_type = 2; |
| _adpt_hppe_acl_vlan_rule_sw_2_hw(rule, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_MAC_DA_RULE) |
| { |
| hw_reg.bf.rule_type = 0; |
| _adpt_hppe_acl_mac_rule_sw_2_hw(rule, 1, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_MAC_SA_RULE) |
| { |
| hw_reg.bf.rule_type = 1; |
| _adpt_hppe_acl_mac_rule_sw_2_hw(rule, 0, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_L2_MISC_RULE) |
| { |
| hw_reg.bf.rule_type = 3; |
| _adpt_hppe_acl_l2_misc_rule_sw_2_hw(rule, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_IPV4_DIP_RULE) |
| { |
| hw_reg.bf.rule_type = 4; |
| _adpt_hppe_acl_ipv4_rule_sw_2_hw(rule, 1, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_IPV4_SIP_RULE) |
| { |
| hw_reg.bf.rule_type = 5; |
| _adpt_hppe_acl_ipv4_rule_sw_2_hw(rule, 0, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_IPV6_DIP0_RULE) |
| { |
| hw_reg.bf.rule_type = 6; |
| _adpt_hppe_acl_ipv6_rule_sw_2_hw(rule, 1, 0, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_IPV6_DIP1_RULE) |
| { |
| hw_reg.bf.rule_type = 7; |
| _adpt_hppe_acl_ipv6_rule_sw_2_hw(rule, 1, 1, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_IPV6_DIP2_RULE) |
| { |
| hw_reg.bf.rule_type = 8; |
| _adpt_hppe_acl_ipv6_rule_sw_2_hw(rule, 1, 2, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_IPV6_SIP0_RULE) |
| { |
| hw_reg.bf.rule_type = 9; |
| _adpt_hppe_acl_ipv6_rule_sw_2_hw(rule, 0, 0, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_IPV6_SIP1_RULE) |
| { |
| hw_reg.bf.rule_type = 10; |
| _adpt_hppe_acl_ipv6_rule_sw_2_hw(rule, 0, 1, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_IPV6_SIP2_RULE) |
| { |
| hw_reg.bf.rule_type = 11; |
| _adpt_hppe_acl_ipv6_rule_sw_2_hw(rule, 0, 2, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_IPMISC_RULE) |
| { |
| hw_reg.bf.rule_type = 12; |
| _adpt_hppe_acl_ipmisc_rule_sw_2_hw(rule, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_UDF0_RULE) |
| { |
| hw_reg.bf.rule_type = 13; |
| _adpt_hppe_acl_udf_rule_sw_2_hw(rule, 0, &hw_reg, &hw_mask); |
| } |
| else if(i == ADPT_ACL_HPPE_UDF1_RULE) |
| { |
| hw_reg.bf.rule_type = 14; |
| _adpt_hppe_acl_udf_rule_sw_2_hw(rule, 1, &hw_reg, &hw_mask); |
| } |
| |
| if(!hw_reg.bf.range_en) |
| { |
| hw_entry = _acl_bit_index(allocated_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 1); |
| } |
| if(hw_entry == 0xff || hw_reg.bf.range_en) |
| { |
| hw_entry = _acl_bit_index(allocated_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 2); |
| } |
| if(hw_entry == 0xff) |
| { |
| printk("%s, %d, fail find hw_entry in 0x%x\n", |
| __FUNCTION__, __LINE__, allocated_entries); |
| return SW_NO_RESOURCE; |
| } |
| allocated_entries &= (~(1<<hw_entry)); |
| |
| if(FAL_FIELD_FLG_TST(rule->field_flg, FAL_ACL_FIELD_INVERSE_ALL)) |
| { |
| hw_reg.bf.inverse_en = 1; |
| } |
| |
| SSDK_DEBUG("rule and mask set hw_entry = %d\n", |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_entry); |
| SSDK_DEBUG("post_route %d, chain %d, pri %d, src_1 %d, src_0 %d, src_type %d " |
| "rule_type %d, inverse %d, range %d\n", hw_reg.bf.post_routing_en, |
| hw_reg.bf.res_chain, hw_reg.bf.pri, hw_reg.bf.src_1, hw_reg.bf.src_0, |
| hw_reg.bf.src_type, hw_reg.bf.rule_type, hw_reg.bf.inverse_en, |
| hw_reg.bf.range_en); |
| /*_adpt_acl_reg_dump((a_uint8_t *)&hw_reg, sizeof(hw_reg));*/ |
| rv |= hppe_ipo_rule_reg_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_entry, |
| &hw_reg); |
| /*_adpt_acl_reg_dump((a_uint8_t *)&hw_mask, sizeof(hw_mask));*/ |
| rv |= hppe_ipo_mask_reg_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_entry, |
| &hw_mask); |
| _adpt_hppe_acl_action_sw_2_hw(dev_id,rule, &hw_act); |
| /*_adpt_acl_reg_dump((a_uint8_t *)&hw_act, sizeof(hw_act));*/ |
| rv |= hppe_ipo_action_set(dev_id, hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_entry, |
| &hw_act); |
| |
| if(rv != SW_OK) |
| { |
| return rv; |
| } |
| } |
| |
| return SW_OK; |
| } |
| |
| static sw_error_t |
| _adpt_hppe_acl_hw_list_resort(a_uint32_t dev_id, a_uint32_t hw_list_index, a_bool_t move_up) |
| { |
| a_uint32_t i = 0; |
| ADPT_HPPE_ACL_HW_LIST temp = {0}; |
| |
| if(hw_list_index >= ADPT_ACL_HW_LIST_NUM) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| if(move_up) |
| { |
| temp.hw_list_id = g_acl_hw_list[dev_id][hw_list_index].hw_list_id; |
| temp.free_hw_entry_bitmap = |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap; |
| temp.free_hw_entry_count = |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count; |
| for(i = hw_list_index; i > 0; i--) |
| { |
| if(temp.free_hw_entry_count < |
| g_acl_hw_list[dev_id][i-1].free_hw_entry_count) |
| { |
| g_acl_hw_list[dev_id][i].hw_list_id = |
| g_acl_hw_list[dev_id][i-1].hw_list_id; |
| g_acl_hw_list[dev_id][i].free_hw_entry_bitmap = |
| g_acl_hw_list[dev_id][i-1].free_hw_entry_bitmap; |
| g_acl_hw_list[dev_id][i].free_hw_entry_count = |
| g_acl_hw_list[dev_id][i-1].free_hw_entry_count; |
| } |
| else |
| { |
| break; |
| } |
| } |
| g_acl_hw_list[dev_id][i].hw_list_id = temp.hw_list_id; |
| g_acl_hw_list[dev_id][i].free_hw_entry_bitmap = temp.free_hw_entry_bitmap; |
| g_acl_hw_list[dev_id][i].free_hw_entry_count = temp.free_hw_entry_count; |
| } |
| else |
| { |
| temp.hw_list_id = g_acl_hw_list[dev_id][hw_list_index].hw_list_id; |
| temp.free_hw_entry_bitmap = |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap; |
| temp.free_hw_entry_count = |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count; |
| for(i = hw_list_index; i < ADPT_ACL_HW_LIST_NUM-1; i++) |
| { |
| if(temp.free_hw_entry_count > |
| g_acl_hw_list[dev_id][i+1].free_hw_entry_count) |
| { |
| g_acl_hw_list[dev_id][i].hw_list_id = |
| g_acl_hw_list[dev_id][i+1].hw_list_id; |
| g_acl_hw_list[dev_id][i].free_hw_entry_bitmap = |
| g_acl_hw_list[dev_id][i+1].free_hw_entry_bitmap; |
| g_acl_hw_list[dev_id][i].free_hw_entry_count = |
| g_acl_hw_list[dev_id][i+1].free_hw_entry_count; |
| } |
| else |
| { |
| break; |
| } |
| } |
| g_acl_hw_list[dev_id][i].hw_list_id = temp.hw_list_id; |
| g_acl_hw_list[dev_id][i].free_hw_entry_bitmap = temp.free_hw_entry_bitmap; |
| g_acl_hw_list[dev_id][i].free_hw_entry_count = temp.free_hw_entry_count; |
| } |
| return SW_OK; |
| } |
| |
| sw_error_t |
| adpt_hppe_acl_rule_add(a_uint32_t dev_id, a_uint32_t list_id, |
| a_uint32_t rule_id, a_uint32_t rule_nr, fal_acl_rule_t * rule) |
| { |
| a_uint32_t rule_type_map = 0; |
| a_uint32_t rule_type_count = 0; |
| a_uint32_t index = 0, hw_list_index = 0, hw_list_id = 0; |
| sw_error_t rv = 0; |
| union rule_ext_1_reg_u ext_1 = {0}; |
| union rule_ext_2_reg_u ext_2 = {0}; |
| union rule_ext_4_reg_u ext_4 = {0}; |
| struct list_head *rule_pos = NULL; |
| ADPT_HPPE_ACL_SW_RULE *rule_exist_entry = NULL, *rule_add_entry = NULL; |
| ADPT_HPPE_ACL_SW_LIST *list_find_entry = NULL; |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| ADPT_NULL_POINT_CHECK(rule); |
| |
| if(list_id >= ADPT_ACL_SW_LIST_NUM) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| if(rule_id >= ADPT_ACL_RULE_NUM_PER_LIST) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| aos_lock_bh(&hppe_acl_lock[dev_id]); |
| list_find_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); |
| if(list_find_entry == NULL) |
| { |
| SSDK_ERROR("List %d not create, no resource to insert rules into it\n", list_id); |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_NO_RESOURCE; |
| } |
| |
| list_for_each(rule_pos, &list_find_entry->list_sw_rule) |
| { |
| rule_exist_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); |
| if((rule_exist_entry->rule_id == rule_id) && (rule_exist_entry->rule_hw_entry != 0)) |
| { |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_ALREADY_EXIST; |
| } |
| } |
| |
| SSDK_DEBUG("fields[0] = 0x%x, fields[1] = 0x%x\n", |
| rule->field_flg[0], rule->field_flg[1]); |
| if(rule->rule_type == FAL_ACL_RULE_IP4)/*input ipv4 type*/ |
| { |
| _adpt_hppe_acl_ipv4_fields_check(dev_id, list_id, rule_id, rule_nr, rule, |
| &rule_type_map); |
| } |
| else if(rule->rule_type == FAL_ACL_RULE_IP6)/*input ipv6 type*/ |
| { |
| _adpt_hppe_acl_ipv6_fields_check(dev_id, list_id, rule_id, rule_nr, rule, |
| &rule_type_map); |
| } |
| _adpt_hppe_acl_udf_fields_check(dev_id, list_id, rule_id, rule_nr, rule, &rule_type_map); |
| _adpt_hppe_acl_l2_fields_check(dev_id, list_id, rule_id, rule_nr, rule, &rule_type_map); |
| |
| if(rule_type_map == 0) |
| { |
| rule_type_map |= (1<<ADPT_ACL_HPPE_MAC_DA_RULE); |
| } |
| |
| SSDK_DEBUG("rule_type_map = 0x%x\n", rule_type_map); |
| |
| rule_type_count = _acl_bits_count(rule_type_map, ADPT_ACL_HPPE_RULE_TYPE_NUM, 0); |
| SSDK_DEBUG("rule_type_count = %d\n", rule_type_count); |
| |
| if(rule_type_count == 0 || rule_type_count > ADPT_ACL_ENTRY_NUM_PER_LIST) |
| { |
| SSDK_ERROR("rule_type_count = %d\n", rule_type_count); |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_NOT_SUPPORTED; |
| } |
| |
| rv = _adpt_hppe_acl_alloc_entries(dev_id, &hw_list_index, rule_id, rule_nr, rule, |
| rule_type_map, rule_type_count, &index); |
| if(rv != SW_OK) |
| { |
| SSDK_ERROR("Alloc hw entries fail for rule %d\n", rule_id); |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return rv; |
| } |
| /* msg for debug */ |
| SSDK_DEBUG("ACL rule add before:list_id=%d, hw_list_index=%d, hw_list_id=%d, " |
| "free_hw_entry_bitmap=0x%x, free_hw_entry_count=%d\n", list_id, hw_list_index, |
| g_acl_hw_list[dev_id][hw_list_index].hw_list_id, |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap, |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count); |
| |
| hw_list_id = g_acl_hw_list[dev_id][hw_list_index].hw_list_id; |
| rv = _adpt_hppe_acl_rule_hw_add(dev_id, list_find_entry, hw_list_id, rule_id, rule_nr, rule, |
| rule_type_map, s_acl_entries[index].entries); |
| if(rv != SW_OK) |
| { |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return rv; |
| } |
| |
| if(s_acl_entries[index].ext_1 != 0) |
| { |
| rv |= hppe_rule_ext_1_reg_get(dev_id, hw_list_id, &ext_1); |
| ext_1.val |= s_acl_entries[index].ext_1; |
| SSDK_DEBUG("ext_1.val = 0x%x\n", ext_1.val); |
| rv |= hppe_rule_ext_1_reg_set(dev_id, hw_list_id, &ext_1); |
| } |
| if(s_acl_entries[index].ext_2 != 0) |
| { |
| rv |= hppe_rule_ext_2_reg_get(dev_id, hw_list_id, &ext_2); |
| ext_2.val |= s_acl_entries[index].ext_2; |
| SSDK_DEBUG("ext_2.val = 0x%x\n", ext_2.val); |
| rv |= hppe_rule_ext_2_reg_set(dev_id, hw_list_id, &ext_2); |
| } |
| if(s_acl_entries[index].ext_4 != 0) |
| { |
| rv |= hppe_rule_ext_4_reg_get(dev_id, hw_list_id, &ext_4); |
| ext_4.val |= s_acl_entries[index].ext_4; |
| SSDK_DEBUG("ext_4.val = 0x%x\n", ext_4.val); |
| rv |= hppe_rule_ext_4_reg_set(dev_id, hw_list_id, &ext_4); |
| } |
| |
| /*record sw info and insert the sw rule entry to the sw list entry*/ |
| rule_add_entry = (ADPT_HPPE_ACL_SW_RULE*)aos_mem_alloc(sizeof(ADPT_HPPE_ACL_SW_RULE)); |
| if(rule_add_entry == NULL) |
| { |
| SSDK_ERROR("%s, %d:malloc fail for rule add entry\n", __FUNCTION__, __LINE__); |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_FAIL; |
| } |
| rule_add_entry->rule_id = rule_id; |
| rule_add_entry->rule_type = rule->rule_type; |
| rule_add_entry->rule_hw_entry = s_acl_entries[index].entries; |
| rule_add_entry->rule_hw_list_id = hw_list_id; |
| rule_add_entry->ext1_val = s_acl_entries[index].ext_1; |
| rule_add_entry->ext2_val = s_acl_entries[index].ext_2; |
| rule_add_entry->ext4_val = s_acl_entries[index].ext_4; |
| list_add(&rule_add_entry->list, &list_find_entry->list_sw_rule); |
| |
| /*update hw list info */ |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap &= |
| (~(s_acl_entries[index].entries)); |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count -= s_acl_entries[index].num; |
| |
| /* msg for debug */ |
| SSDK_DEBUG("ACL rule add after:list_id=%d, hw_list_index=%d, hw_list_id=%d, " |
| "free_hw_entry_bitmap=0x%x, free_hw_entry_count=%d\n", list_id, hw_list_index, |
| hw_list_id, g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap, |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count); |
| /*resort hw list */ |
| _adpt_hppe_acl_hw_list_resort(dev_id, hw_list_index, A_TRUE); |
| |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_OK; |
| } |
| |
| static sw_error_t |
| _adpt_hppe_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, |
| ADPT_HPPE_ACL_SW_RULE *rule_entry, a_uint32_t rule_nr) |
| { |
| sw_error_t rv = 0; |
| a_uint32_t hw_index = 0, hw_entries = 0, hw_list_id = 0, hw_list_index = 0, i = 0; |
| union ipo_rule_reg_u hw_reg = {0}; |
| union ipo_mask_reg_u hw_mask = {0}; |
| union ipo_action_u hw_act = {0}; |
| union rule_ext_1_reg_u ext_1 = {0}; |
| union rule_ext_2_reg_u ext_2 = {0}; |
| union rule_ext_4_reg_u ext_4 = {0}; |
| |
| hw_entries = rule_entry->rule_hw_entry; |
| hw_list_id = rule_entry->rule_hw_list_id; |
| /* msg for debug */ |
| SSDK_DEBUG("ACL delete rule entry before:list_id=%d, rule_id=%d, " |
| "hw_entries=0x%x, hw_list_id=%d\n", list_id, |
| rule_entry->rule_id, rule_entry->rule_hw_entry, |
| rule_entry->rule_hw_list_id); |
| while(hw_entries != 0) |
| { |
| union ipo_cnt_tbl_u counters = {0}; |
| hw_index = _acl_bit_index(hw_entries, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); |
| if(hw_index >= ADPT_ACL_ENTRY_NUM_PER_LIST) |
| { |
| break; |
| } |
| |
| rv |= hppe_ipo_rule_reg_set(dev_id, |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, &hw_reg); |
| rv |= hppe_ipo_mask_reg_set(dev_id, |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, &hw_mask); |
| rv |= hppe_ipo_action_set(dev_id, |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, &hw_act); |
| SSDK_DEBUG("ACL destroy entry %d\n", |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index); |
| hw_entries &= (~(1<<hw_index)); |
| |
| /*clean counters*/ |
| hppe_ipo_cnt_tbl_set(dev_id, |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+hw_index, &counters); |
| } |
| |
| if(rule_entry->ext1_val) |
| { |
| rv |= hppe_rule_ext_1_reg_get(dev_id, hw_list_id, &ext_1); |
| ext_1.val &= (~rule_entry->ext1_val); |
| SSDK_DEBUG("ext_1.val = 0x%x\n", ext_1.val); |
| rv |= hppe_rule_ext_1_reg_set(dev_id, hw_list_id, &ext_1); |
| } |
| if(rule_entry->ext2_val) |
| { |
| rv |= hppe_rule_ext_2_reg_get(dev_id, hw_list_id, &ext_2); |
| ext_2.val &= (~rule_entry->ext2_val); |
| SSDK_DEBUG("ext_2.val = 0x%x\n", ext_2.val); |
| rv |= hppe_rule_ext_2_reg_set(dev_id, hw_list_id, &ext_2); |
| } |
| if(rule_entry->ext4_val) |
| { |
| rv |= hppe_rule_ext_4_reg_get(dev_id, hw_list_id, &ext_4); |
| ext_4.val &= (~rule_entry->ext4_val); |
| SSDK_DEBUG("ext_4.val = 0x%x\n", ext_4.val); |
| rv |= hppe_rule_ext_4_reg_set(dev_id, hw_list_id, &ext_4); |
| } |
| |
| /*find hw_list_index*/ |
| for(i = 0; i < ADPT_ACL_HW_LIST_NUM; i++) |
| { |
| if(g_acl_hw_list[dev_id][i].hw_list_id == hw_list_id) |
| { |
| hw_list_index = i; |
| break; |
| } |
| } |
| |
| /*update hw list info and resort hw list*/ |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap |= rule_entry->rule_hw_entry; |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count += |
| _acl_bits_count(rule_entry->rule_hw_entry, ADPT_ACL_ENTRY_NUM_PER_LIST, 0); |
| /* msg for debug */ |
| SSDK_DEBUG("ACL delete rule entry after:hw_list_index=%d, list_id=%d, " |
| "rule_id=%d, hw_entries=0x%x, hw_list_id=%d\n", hw_list_index, |
| list_id, rule_entry->rule_id, rule_entry->rule_hw_entry, |
| rule_entry->rule_hw_list_id); |
| _adpt_hppe_acl_hw_list_resort(dev_id, hw_list_index, A_FALSE); |
| |
| /*delete rule entry from the sw list*/ |
| list_del(&rule_entry->list); |
| aos_mem_free(rule_entry); |
| rule_entry = NULL; |
| |
| return rv; |
| } |
| |
| sw_error_t |
| adpt_hppe_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, |
| a_uint32_t rule_id, a_uint32_t rule_nr) |
| { |
| struct list_head *rule_pos = NULL; |
| ADPT_HPPE_ACL_SW_RULE *rule_delete_entry = NULL; |
| ADPT_HPPE_ACL_SW_LIST *list_find_entry = NULL; |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| if(list_id >= ADPT_ACL_SW_LIST_NUM) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| if(rule_id >= ADPT_ACL_RULE_NUM_PER_LIST) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| aos_lock_bh(&hppe_acl_lock[dev_id]); |
| list_find_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); |
| if(list_find_entry != NULL) |
| { |
| list_for_each(rule_pos, &list_find_entry->list_sw_rule) |
| { |
| rule_delete_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); |
| if(rule_delete_entry->rule_id == rule_id) |
| { |
| _adpt_hppe_acl_rule_delete(dev_id, list_id, |
| rule_delete_entry, rule_nr); |
| break; |
| } |
| } |
| } |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_OK; |
| } |
| |
| static sw_error_t |
| _adpt_hppe_acl_rule_dump(a_uint32_t dev_id, a_uint32_t list_id, ADPT_HPPE_ACL_SW_RULE *rule_entry) |
| { |
| a_uint8_t i = 0; |
| a_uint8_t hw_entries = rule_entry->rule_hw_entry; |
| a_uint32_t hw_list_id = rule_entry->rule_hw_list_id; |
| union ipo_rule_reg_u hw_reg = {0}; |
| union ipo_mask_reg_u hw_mask = {0}; |
| union ipo_action_u hw_act = {0}; |
| |
| if(hw_entries != 0) |
| { |
| printk("######list_id %d, rule_id %d, hw_list_id %d\n", list_id, |
| rule_entry->rule_id, hw_list_id); |
| for(i = 0; i < ADPT_ACL_ENTRY_NUM_PER_LIST; i++) |
| { |
| if((1<<i) & hw_entries) |
| { |
| hppe_ipo_rule_reg_get(dev_id, |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+i, &hw_reg); |
| hppe_ipo_mask_reg_get(dev_id, |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+i, &hw_mask); |
| hppe_ipo_action_get(dev_id, |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+i, &hw_act); |
| printk("hw_entry %d\n", hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+i); |
| _adpt_acl_reg_dump((u_int8_t *)&hw_reg, sizeof(hw_reg)); |
| printk("hw_entry_mask %d\n", |
| hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+i); |
| _adpt_acl_reg_dump((u_int8_t *)&hw_mask, sizeof(hw_mask)); |
| printk("hw_action %d\n", hw_list_id*ADPT_ACL_ENTRY_NUM_PER_LIST+i); |
| _adpt_acl_reg_dump((u_int8_t *)&hw_act, sizeof(hw_act)); |
| } |
| } |
| } |
| |
| return SW_OK; |
| } |
| |
| sw_error_t |
| adpt_hppe_acl_rule_dump(a_uint32_t dev_id) |
| { |
| a_uint8_t hw_list_index = 0; |
| struct list_head *list_pos = NULL, *rule_pos = NULL; |
| ADPT_HPPE_ACL_SW_LIST *list_dump_entry = NULL; |
| ADPT_HPPE_ACL_SW_RULE *rule_dump_entry = NULL; |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| /*dump the hw list status for debug*/ |
| for(hw_list_index = 0; hw_list_index < ADPT_ACL_HW_LIST_NUM; hw_list_index++) |
| { |
| SSDK_DEBUG("hw_list_index=%d, hw_list_valid=%d, hw_list_id=%d, " |
| "free_hw_entry_bitmap=0x%x, free_hw_entry_count=%d\n", hw_list_index, |
| g_acl_hw_list[dev_id][ hw_list_index].hw_list_valid, |
| g_acl_hw_list[dev_id][ hw_list_index].hw_list_id, |
| g_acl_hw_list[dev_id][ hw_list_index].free_hw_entry_bitmap, |
| g_acl_hw_list[dev_id][ hw_list_index].free_hw_entry_count); |
| } |
| |
| aos_lock_bh(&hppe_acl_lock[dev_id]); |
| list_for_each(list_pos, &g_acl_sw_list[dev_id].list_sw_list) |
| { |
| list_dump_entry = list_entry(list_pos, ADPT_HPPE_ACL_SW_LIST, list); |
| list_for_each(rule_pos, &list_dump_entry->list_sw_rule) |
| { |
| rule_dump_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); |
| _adpt_hppe_acl_rule_dump(dev_id, list_dump_entry->list_id, rule_dump_entry); |
| } |
| } |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_OK; |
| } |
| |
| sw_error_t |
| adpt_hppe_acl_list_dump(a_uint32_t dev_id) |
| { |
| adpt_hppe_acl_rule_dump(dev_id); |
| |
| return SW_OK; |
| } |
| |
| |
| sw_error_t |
| adpt_hppe_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri) |
| { |
| ADPT_HPPE_ACL_SW_LIST *list_create_entry = NULL; |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| if(list_id >= ADPT_ACL_SW_LIST_NUM) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| aos_lock_bh(&hppe_acl_lock[dev_id]); |
| list_create_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); |
| if(list_create_entry != NULL) |
| { |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_ALREADY_EXIST; |
| } |
| |
| list_create_entry = (ADPT_HPPE_ACL_SW_LIST*)aos_mem_alloc(sizeof(ADPT_HPPE_ACL_SW_LIST)); |
| if(list_create_entry == NULL) |
| { |
| SSDK_ERROR("%s, %d:malloc fail for list create entry\n", __FUNCTION__, __LINE__); |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_FAIL; |
| } |
| INIT_LIST_HEAD(&list_create_entry->list_sw_rule); |
| list_create_entry->list_id = list_id; |
| list_create_entry->list_pri = list_pri; |
| list_add(&list_create_entry->list, &g_acl_sw_list[dev_id].list_sw_list); |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_OK; |
| } |
| |
| sw_error_t |
| adpt_hppe_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) |
| { |
| struct list_head *rule_pos=NULL, *rule_pos_temp = NULL; |
| ADPT_HPPE_ACL_SW_RULE *rule_delete_entry = NULL; |
| ADPT_HPPE_ACL_SW_LIST *list_destroy_entry = NULL; |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| if(list_id >= ADPT_ACL_SW_LIST_NUM) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| aos_lock_bh(&hppe_acl_lock[dev_id]); |
| list_destroy_entry = _adpt_hppe_acl_list_entry_get(dev_id, list_id); |
| if(list_destroy_entry != NULL) |
| { |
| list_for_each_safe(rule_pos, rule_pos_temp, &list_destroy_entry->list_sw_rule) |
| { |
| rule_delete_entry = list_entry(rule_pos, ADPT_HPPE_ACL_SW_RULE, list); |
| _adpt_hppe_acl_rule_delete(dev_id, list_id, rule_delete_entry, 1); |
| } |
| list_del(&list_destroy_entry->list); |
| aos_mem_free(list_destroy_entry); |
| list_destroy_entry = NULL; |
| } |
| aos_unlock_bh(&hppe_acl_lock[dev_id]); |
| return SW_OK; |
| } |
| |
| typedef sw_error_t (*hppe_acl_udp_set_func)(a_uint32_t dev_id, union udf_ctrl_reg_u *udf_ctrl); |
| typedef sw_error_t (*hppe_acl_udp_get_func)(a_uint32_t dev_id, union udf_ctrl_reg_u *udf_ctrl); |
| |
| hppe_acl_udp_set_func g_udf_set_func[FAL_ACL_UDF_BUTT][4] = { |
| {hppe_non_ip_udf0_ctrl_reg_set, hppe_non_ip_udf1_ctrl_reg_set, |
| hppe_non_ip_udf2_ctrl_reg_set, hppe_non_ip_udf3_ctrl_reg_set}, |
| {hppe_ipv4_udf0_ctrl_reg_set, hppe_ipv4_udf1_ctrl_reg_set, hppe_ipv4_udf2_ctrl_reg_set, |
| hppe_ipv4_udf3_ctrl_reg_set}, |
| {hppe_ipv6_udf0_ctrl_reg_set, hppe_ipv6_udf1_ctrl_reg_set, hppe_ipv6_udf2_ctrl_reg_set, |
| hppe_ipv6_udf3_ctrl_reg_set}, |
| }; |
| |
| hppe_acl_udp_get_func g_udf_get_func[FAL_ACL_UDF_BUTT][4] = { |
| {hppe_non_ip_udf0_ctrl_reg_get, hppe_non_ip_udf1_ctrl_reg_get, |
| hppe_non_ip_udf2_ctrl_reg_get, hppe_non_ip_udf3_ctrl_reg_get}, |
| {hppe_ipv4_udf0_ctrl_reg_get, hppe_ipv4_udf1_ctrl_reg_get, hppe_ipv4_udf2_ctrl_reg_get, |
| hppe_ipv4_udf3_ctrl_reg_get}, |
| {hppe_ipv6_udf0_ctrl_reg_get, hppe_ipv6_udf1_ctrl_reg_get, hppe_ipv6_udf2_ctrl_reg_get, |
| hppe_ipv6_udf3_ctrl_reg_get}, |
| }; |
| |
| sw_error_t |
| adpt_hppe_acl_udf_profile_get(a_uint32_t dev_id, fal_acl_udf_pkt_type_t pkt_type,a_uint32_t udf_idx, |
| fal_acl_udf_type_t *udf_type, a_uint32_t *offset) |
| { |
| union udf_ctrl_reg_u udf_ctrl = {0}; |
| sw_error_t rv = SW_OK; |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| ADPT_NULL_POINT_CHECK(udf_type); |
| ADPT_NULL_POINT_CHECK(offset); |
| |
| rv = g_udf_get_func[pkt_type][udf_idx](dev_id, &udf_ctrl); |
| |
| if(rv != SW_OK) |
| return rv; |
| |
| if(udf_ctrl.bf.udf_base == 0) |
| { |
| *udf_type = FAL_ACL_UDF_TYPE_L2; |
| } |
| else if(udf_ctrl.bf.udf_base == 1) |
| { |
| *udf_type = FAL_ACL_UDF_TYPE_L3; |
| } |
| else if(udf_ctrl.bf.udf_base == 2) |
| { |
| *udf_type = FAL_ACL_UDF_TYPE_L4; |
| } |
| |
| *offset = udf_ctrl.bf.udf_offset*2; |
| |
| return SW_OK; |
| } |
| |
| |
| sw_error_t |
| adpt_hppe_acl_udf_profile_set(a_uint32_t dev_id, fal_acl_udf_pkt_type_t pkt_type,a_uint32_t udf_idx, |
| fal_acl_udf_type_t udf_type, a_uint32_t offset) |
| { |
| union udf_ctrl_reg_u udf_ctrl = {0}; |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| if(udf_type == FAL_ACL_UDF_TYPE_L2) |
| { |
| udf_ctrl.bf.udf_base = 0; |
| } |
| else if(udf_type == FAL_ACL_UDF_TYPE_L3) |
| { |
| udf_ctrl.bf.udf_base = 1; |
| } |
| else if(udf_type == FAL_ACL_UDF_TYPE_L4) |
| { |
| udf_ctrl.bf.udf_base = 2; |
| } |
| else |
| return SW_NOT_SUPPORTED; |
| |
| if(offset % 2)/*only support even data*/ |
| return SW_BAD_VALUE; |
| udf_ctrl.bf.udf_offset = offset/2; |
| |
| return g_udf_set_func[pkt_type][udf_idx](dev_id, &udf_ctrl); |
| } |
| |
| void adpt_hppe_acl_func_bitmap_init(a_uint32_t dev_id) |
| { |
| adpt_api_t *p_adpt_api = NULL; |
| |
| p_adpt_api = adpt_api_ptr_get(dev_id); |
| |
| if(p_adpt_api == NULL) |
| return; |
| |
| p_adpt_api->adpt_acl_func_bitmap = ((1<<FUNC_ACL_LIST_CREAT)| |
| (1<<FUNC_ACL_LIST_DESTROY)| |
| (1<<FUNC_ACL_RULE_ADD)| |
| (1<<FUNC_ACL_RULE_DELETE)| |
| (1<<FUNC_ACL_RULE_QUERY)| |
| (1<<FUNC_ACL_RULE_DUMP)| |
| (1<<FUNC_ACL_LIST_BIND)| |
| (1<<FUNC_ACL_LIST_UNBIND)| |
| (1<<FUNC_ACL_UDF_PROFILE_SET)| |
| (1<<FUNC_ACL_UDF_PROFILE_GET)); |
| return; |
| } |
| |
| static void adpt_hppe_acl_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) |
| { |
| if(p_adpt_api == NULL) |
| return; |
| |
| p_adpt_api->adpt_acl_list_creat = NULL; |
| p_adpt_api->adpt_acl_list_destroy = NULL; |
| p_adpt_api->adpt_acl_rule_add = NULL; |
| p_adpt_api->adpt_acl_rule_delete = NULL; |
| p_adpt_api->adpt_acl_rule_query = NULL; |
| p_adpt_api->adpt_acl_rule_dump = NULL; |
| p_adpt_api->adpt_acl_list_dump = NULL; |
| p_adpt_api->adpt_acl_list_bind = NULL; |
| p_adpt_api->adpt_acl_list_unbind = NULL; |
| p_adpt_api->adpt_acl_udf_profile_set = NULL; |
| p_adpt_api->adpt_acl_udf_profile_get = NULL; |
| |
| return; |
| } |
| |
| sw_error_t adpt_hppe_acl_init(a_uint32_t dev_id) |
| { |
| adpt_api_t *p_adpt_api = NULL; |
| a_uint8_t hw_list_index = 0; |
| p_adpt_api = adpt_api_ptr_get(dev_id); |
| |
| if(p_adpt_api == NULL) |
| { |
| return SW_FAIL; |
| } |
| |
| for(hw_list_index = 0; hw_list_index < ADPT_ACL_HW_LIST_NUM; hw_list_index++) |
| { |
| if(g_acl_hw_list[dev_id][hw_list_index].hw_list_valid == A_FALSE) |
| { |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_bitmap = 0xff; |
| g_acl_hw_list[dev_id][hw_list_index].free_hw_entry_count = |
| ADPT_ACL_ENTRY_NUM_PER_LIST; |
| g_acl_hw_list[dev_id][hw_list_index].hw_list_id = |
| ADPT_ACL_HW_LIST_NUM - 1 - hw_list_index; |
| g_acl_hw_list [dev_id][hw_list_index].hw_list_valid = A_TRUE; |
| INIT_LIST_HEAD(&g_acl_sw_list[dev_id].list_sw_list); |
| } |
| } |
| |
| adpt_hppe_acl_func_unregister(dev_id, p_adpt_api); |
| |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_LIST_BIND)) |
| { |
| p_adpt_api->adpt_acl_list_bind = adpt_hppe_acl_list_bind; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_LIST_DUMP)) |
| { |
| p_adpt_api->adpt_acl_list_dump = adpt_hppe_acl_list_dump; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_RULE_QUERY)) |
| { |
| p_adpt_api->adpt_acl_rule_query = adpt_hppe_acl_rule_query; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_LIST_UNBIND)) |
| { |
| p_adpt_api->adpt_acl_list_unbind = adpt_hppe_acl_list_unbind; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_RULE_ADD)) |
| { |
| p_adpt_api->adpt_acl_rule_add = adpt_hppe_acl_rule_add; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_RULE_DELETE)) |
| { |
| p_adpt_api->adpt_acl_rule_delete = adpt_hppe_acl_rule_delete; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_RULE_DUMP)) |
| { |
| p_adpt_api->adpt_acl_rule_dump = adpt_hppe_acl_rule_dump; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_LIST_CREAT)) |
| { |
| p_adpt_api->adpt_acl_list_creat = adpt_hppe_acl_list_creat; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_LIST_DESTROY)) |
| { |
| p_adpt_api->adpt_acl_list_destroy = adpt_hppe_acl_list_destroy; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_UDF_PROFILE_SET)) |
| { |
| p_adpt_api->adpt_acl_udf_profile_set = adpt_hppe_acl_udf_profile_set; |
| } |
| if(p_adpt_api->adpt_acl_func_bitmap & (1<<FUNC_ACL_UDF_PROFILE_GET)) |
| { |
| p_adpt_api->adpt_acl_udf_profile_get = adpt_hppe_acl_udf_profile_get; |
| } |
| |
| aos_lock_init(&hppe_acl_lock[dev_id]); |
| |
| return SW_OK; |
| } |
| |
| /** |
| * @} |
| */ |