| /* |
| * Copyright (c) 2016-2017, 2020, 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 "hppe_trunk_reg.h" |
| #include "hppe_trunk.h" |
| #include "adpt.h" |
| #include "hppe_fdb_reg.h" |
| #include "hppe_fdb.h" |
| |
| sw_error_t |
| adpt_hppe_trunk_fail_over_en_get(a_uint32_t dev_id, a_bool_t * fail_over) |
| { |
| union l2_global_conf_u l2_global_conf; |
| |
| memset(&l2_global_conf, 0, sizeof(l2_global_conf)); |
| ADPT_DEV_ID_CHECK(dev_id); |
| ADPT_NULL_POINT_CHECK(fail_over); |
| |
| SW_RTN_ON_ERROR(hppe_l2_global_conf_get(dev_id, &l2_global_conf)); |
| |
| *fail_over = l2_global_conf.bf.failover_en; |
| |
| return SW_OK; |
| } |
| |
| sw_error_t |
| adpt_hppe_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) |
| { |
| union trunk_hash_field_reg_u trunk_hash_field; |
| |
| memset(&trunk_hash_field, 0, sizeof(trunk_hash_field)); |
| ADPT_DEV_ID_CHECK(dev_id); |
| ADPT_NULL_POINT_CHECK(hash_mode); |
| |
| SW_RTN_ON_ERROR(hppe_trunk_hash_field_reg_get(dev_id, &trunk_hash_field)); |
| |
| *hash_mode = 0; |
| |
| if (trunk_hash_field.bf.mac_da_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_DA; |
| |
| if (trunk_hash_field.bf.mac_sa_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_SA; |
| |
| if (trunk_hash_field.bf.src_ip_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_SIP; |
| |
| if (trunk_hash_field.bf.dst_ip_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_DIP; |
| |
| if (trunk_hash_field.bf.src_port_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_SRC_PORT; |
| |
| if (trunk_hash_field.bf.l4_src_port_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_L4_SRC_PORT; |
| |
| if (trunk_hash_field.bf.l4_dst_port_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_L4_DST_PORT; |
| |
| if (trunk_hash_field.bf.udf0_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_UDF0; |
| |
| if (trunk_hash_field.bf.udf1_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_UDF1; |
| |
| if (trunk_hash_field.bf.udf2_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_UDF2; |
| |
| if (trunk_hash_field.bf.udf3_incl) |
| *hash_mode |= FAL_TRUNK_HASH_KEY_UDF3; |
| |
| return SW_OK; |
| } |
| |
| sw_error_t |
| adpt_hppe_trunk_group_get(a_uint32_t dev_id, a_uint32_t trunk_id, |
| a_bool_t * enable, fal_pbmp_t * member) |
| { |
| union trunk_filter_u trunk_filter; |
| union port_trunk_id_u port_trunk_id; |
| a_uint32_t port_id; |
| |
| memset(&trunk_filter, 0, sizeof(trunk_filter)); |
| memset(&port_trunk_id, 0, sizeof(port_trunk_id)); |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| ADPT_NULL_POINT_CHECK(enable); |
| ADPT_NULL_POINT_CHECK(member); |
| |
| *enable = A_FALSE; |
| for (port_id = 0; port_id < FAL_MAX_PORT_NUMBER; port_id ++) |
| { |
| SW_RTN_ON_ERROR(hppe_port_trunk_id_get(dev_id, port_id, &port_trunk_id)); |
| if ((trunk_id == port_trunk_id.bf.trunk_id) && (A_TRUE == port_trunk_id.bf.trunk_en)) |
| { |
| *enable = A_TRUE; |
| break; |
| } |
| } |
| |
| SW_RTN_ON_ERROR(hppe_trunk_filter_get(dev_id, trunk_id, &trunk_filter)); |
| |
| *member = trunk_filter.bf.mem_bitmap; |
| |
| return SW_OK; |
| } |
| |
| sw_error_t |
| adpt_hppe_trunk_group_set(a_uint32_t dev_id, a_uint32_t trunk_id, |
| a_bool_t enable, fal_pbmp_t member) |
| { |
| union trunk_filter_u trunk_filter; |
| union port_trunk_id_u port_trunk_id; |
| union trunk_member_u trunk_member; |
| a_uint32_t i, j, cnt = 0, data[FAL_MAX_PORT_NUMBER] = {0}; |
| |
| memset(&trunk_filter, 0, sizeof(trunk_filter)); |
| memset(&port_trunk_id, 0, sizeof(port_trunk_id)); |
| memset(&trunk_member, 0, sizeof(trunk_member)); |
| |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| if (trunk_id >= TRUNK_FILTER_MAX_ENTRY) |
| { |
| return SW_OUT_OF_RANGE; |
| } |
| |
| if(enable == A_TRUE && member == 0) |
| { |
| SSDK_ERROR("trunk member cannot be 0 when trunk group was enabled\n"); |
| return SW_BAD_PARAM; |
| } |
| |
| if (A_TRUE == enable) |
| { |
| for (i = 0; i < FAL_MAX_PORT_NUMBER; i++) |
| { |
| if (member & (0x1 << i)) |
| { |
| if (FAL_TRUNK_GROUP_MAX_MEMEBER <= cnt) |
| { |
| return SW_BAD_PARAM; |
| } |
| data[cnt] = i; |
| cnt++; |
| } |
| } |
| } |
| |
| for (i = 0; i < FAL_MAX_PORT_NUMBER; i++) |
| { |
| SW_RTN_ON_ERROR(hppe_port_trunk_id_get(dev_id, i, &port_trunk_id)); |
| if (port_trunk_id.bf.trunk_id == trunk_id) { |
| port_trunk_id.bf.trunk_en = A_FALSE; |
| SW_RTN_ON_ERROR(hppe_port_trunk_id_set(dev_id, i, &port_trunk_id)); |
| } |
| } |
| |
| for (j = 0; j < FAL_MAX_PORT_NUMBER; j++) |
| { |
| if (member & (0x1 << j)) |
| { |
| port_trunk_id.bf.trunk_en = enable; |
| port_trunk_id.bf.trunk_id = trunk_id; |
| SW_RTN_ON_ERROR(hppe_port_trunk_id_set(dev_id, j, &port_trunk_id)); |
| } |
| } |
| |
| if (A_TRUE == enable) |
| trunk_filter.bf.mem_bitmap = member; |
| else |
| trunk_filter.bf.mem_bitmap = 0; |
| |
| SW_RTN_ON_ERROR(hppe_trunk_filter_set(dev_id, trunk_id, &trunk_filter)); |
| |
| if (A_TRUE == enable) |
| { |
| for(i = SSDK_PHYSICAL_PORT0; i <= SSDK_PHYSICAL_PORT7; i+=cnt) |
| { |
| for(j = 0; j < cnt; j++) |
| { |
| if((i+j) < FAL_MAX_PORT_NUMBER) |
| { |
| data[i+j] = data[j]; |
| } |
| } |
| } |
| } |
| trunk_member.bf.member_0_port_id = data[0]; |
| trunk_member.bf.member_1_port_id = data[1]; |
| trunk_member.bf.member_2_port_id = data[2]; |
| trunk_member.bf.member_3_port_id = data[3]; |
| trunk_member.bf.member_4_port_id = data[4]; |
| trunk_member.bf.member_5_port_id = data[5]; |
| trunk_member.bf.member_6_port_id = data[6]; |
| trunk_member.bf.member_7_port_id = data[7]; |
| |
| SW_RTN_ON_ERROR(hppe_trunk_member_set(dev_id, trunk_id, &trunk_member)); |
| |
| return SW_OK; |
| } |
| sw_error_t |
| adpt_hppe_trunk_fail_over_en_set(a_uint32_t dev_id, a_bool_t fail_over) |
| { |
| union l2_global_conf_u l2_global_conf; |
| |
| memset(&l2_global_conf, 0, sizeof(l2_global_conf)); |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| SW_RTN_ON_ERROR(hppe_l2_global_conf_get(dev_id, &l2_global_conf)); |
| |
| l2_global_conf.bf.failover_en = fail_over; |
| |
| SW_RTN_ON_ERROR(hppe_l2_global_conf_set(dev_id, &l2_global_conf)); |
| |
| return SW_OK; |
| } |
| sw_error_t |
| adpt_hppe_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) |
| { |
| union trunk_hash_field_reg_u trunk_hash_field; |
| |
| memset(&trunk_hash_field, 0, sizeof(trunk_hash_field)); |
| ADPT_DEV_ID_CHECK(dev_id); |
| |
| if (FAL_TRUNK_HASH_KEY_DA & hash_mode) |
| trunk_hash_field.bf.mac_da_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_SA & hash_mode) |
| trunk_hash_field.bf.mac_sa_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_DIP & hash_mode) |
| trunk_hash_field.bf.dst_ip_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_SIP & hash_mode) |
| trunk_hash_field.bf.src_ip_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_SRC_PORT & hash_mode) |
| trunk_hash_field.bf.src_port_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_L4_SRC_PORT & hash_mode) |
| trunk_hash_field.bf.l4_src_port_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_L4_DST_PORT & hash_mode) |
| trunk_hash_field.bf.l4_dst_port_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_UDF0 & hash_mode) |
| trunk_hash_field.bf.udf0_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_UDF1 & hash_mode) |
| trunk_hash_field.bf.udf1_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_UDF2 & hash_mode) |
| trunk_hash_field.bf.udf2_incl = 1; |
| |
| if (FAL_TRUNK_HASH_KEY_UDF3 & hash_mode) |
| trunk_hash_field.bf.udf3_incl = 1; |
| |
| SW_RTN_ON_ERROR(hppe_trunk_hash_field_reg_set(dev_id, &trunk_hash_field)); |
| |
| return SW_OK; |
| } |
| |
| void adpt_hppe_trunk_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_trunk_func_bitmap = ((1 << FUNC_TRUNK_GROUP_SET) | |
| (1 << FUNC_TRUNK_GROUP_GET) | |
| (1 << FUNC_TRUNK_HASH_MODE_SET) | |
| (1 << FUNC_TRUNK_HASH_MODE_GET) | |
| (1 << FUNC_TRUNK_FAILOVER_ENABLE) | |
| (1 << FUNC_TRUNK_FAILOVER_STATUS_GET)); |
| |
| return; |
| } |
| |
| static void adpt_hppe_trunk_func_unregister(a_uint32_t dev_id, adpt_api_t *p_adpt_api) |
| { |
| if(p_adpt_api == NULL) |
| return; |
| |
| p_adpt_api->adpt_trunk_fail_over_en_get = NULL; |
| p_adpt_api->adpt_trunk_hash_mode_get = NULL; |
| p_adpt_api->adpt_trunk_group_get = NULL; |
| p_adpt_api->adpt_trunk_group_set = NULL; |
| p_adpt_api->adpt_trunk_fail_over_en_set = NULL; |
| p_adpt_api->adpt_trunk_hash_mode_set = NULL; |
| |
| return; |
| } |
| |
| sw_error_t adpt_hppe_trunk_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 SW_FAIL; |
| |
| adpt_hppe_trunk_func_unregister(dev_id, p_adpt_api); |
| |
| if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_FAILOVER_STATUS_GET)) |
| p_adpt_api->adpt_trunk_fail_over_en_get = adpt_hppe_trunk_fail_over_en_get; |
| if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_HASH_MODE_GET)) |
| p_adpt_api->adpt_trunk_hash_mode_get = adpt_hppe_trunk_hash_mode_get; |
| if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_GROUP_GET)) |
| p_adpt_api->adpt_trunk_group_get = adpt_hppe_trunk_group_get; |
| if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_GROUP_SET)) |
| p_adpt_api->adpt_trunk_group_set = adpt_hppe_trunk_group_set; |
| if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_FAILOVER_ENABLE)) |
| p_adpt_api->adpt_trunk_fail_over_en_set = adpt_hppe_trunk_fail_over_en_set; |
| if (p_adpt_api->adpt_trunk_func_bitmap & (1 << FUNC_TRUNK_HASH_MODE_SET)) |
| p_adpt_api->adpt_trunk_hash_mode_set = adpt_hppe_trunk_hash_mode_set; |
| |
| return SW_OK; |
| } |
| |
| /** |
| * @} |
| */ |