| /****************************************************************************** |
| * |
| * <:copyright-BRCM:2016:DUAL/GPL:standard |
| * |
| * Copyright (c) 2016 Broadcom |
| * All Rights Reserved |
| * |
| * Unless you and Broadcom execute a separate written software license |
| * agreement governing use of this software, this software is licensed |
| * to you under the terms of the GNU General Public License version 2 |
| * (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| * with the following added to such license: |
| * |
| * As a special exception, the copyright holders of this software give |
| * you permission to link this software with independent modules, and |
| * to copy and distribute the resulting executable under terms of your |
| * choice, provided that you also meet, for each linked independent |
| * module, the terms and conditions of the license of that module. |
| * An independent module is a module which is not derived from this |
| * software. The special exception does not apply to any modifications |
| * of the software. |
| * |
| * Not withstanding the above, under no circumstances may you combine |
| * this software in any way with any other Broadcom software provided |
| * under a license other than the GPL, without Broadcom's express prior |
| * written consent. |
| * |
| * :> |
| * |
| *****************************************************************************/ |
| |
| /** |
| * @file bal_dpp_qos_map.c |
| * @brief BAL Switch Util QoS map management API |
| * |
| * This file contains the data structures and functions for |
| * configuring and managing the pcp bits translation services for |
| * DUNE Pack Processor (DPP). |
| * |
| * The pcp translation service is accomplished using ING ingress vlan translation API |
| * The API required a Qos map table for pcp translatin on a LIF. |
| * This file defines 15 pre-map tables for all known use cases. |
| * |
| * A set of utilities API are included for callers to determine which table to use |
| * |
| * ******************************************************************************** |
| * |
| */ |
| |
| /*@{*/ |
| #ifndef TEST_SW_UTIL_LOOPBACK |
| |
| #include <stdint.h> |
| |
| #include "bcm_dev_log.h" |
| #include "bcmos_errno.h" |
| #include "bal_dpp_qos_map.h" |
| |
| #include "bal_switch_util.h" /* for definition of log_id_sw_util */ |
| |
| #include "bcm/error.h" |
| #include "bcm/qos.h" |
| |
| #define BAL_BCM_PCP_MAP_NUM 15 |
| #define BAL_BCM_PCP_MAP_ENTRIES 8 |
| #define BAL_BCM_MAX_PCP_VALUE 7 |
| #define BAL_BCM_FIXED_PCP_MAP_NUM 8 |
| |
| |
| const int g_bal_bcm_qos_pcp_map[BAL_BCM_PCP_MAP_NUM][BAL_BCM_PCP_MAP_ENTRIES] = |
| { |
| {0, 0, 0, 0, 0, 0, 0, 0}, /* 0-7 --> 0 */ |
| {1, 1, 1, 1, 1, 1, 1, 1}, /* 0-7 --> 1 */ |
| {2, 2, 2, 2, 2, 2, 2, 2}, /* 0-7 --> 2 */ |
| {3, 3, 3, 3, 3, 3, 3, 3}, /* 0-7 --> 3 */ |
| {4, 4, 4, 4, 4, 4, 4, 4}, /* 0-7 --> 4 */ |
| {5, 5, 5, 5, 5, 5, 5, 5}, /* 0-7 --> 5 */ |
| {6, 6, 6, 6, 6, 6, 6, 6}, /* 0-7 --> 6 */ |
| {7, 7, 7, 7, 7, 7, 7, 7}, /* 0-7 --> 7 */ |
| {1, 2, 3, 4, 5, 6, 7, 0}, /* 0-6 --> 1-7, 7 ->0 offset = 1 or -7 */ |
| {2, 3, 4, 5, 6, 7, 0, 1}, /* 0-5 --> 2-7, 6-7->0-1 offset = 2 or -6 */ |
| {3, 4, 5, 6, 7, 0, 1, 2}, /* 0-4 --> 3-7, 5-7->0-2 offset = 3 or -5 */ |
| {4, 5, 6, 7, 0, 1, 2, 3}, /* 0-3 --> 4-7, 4-7->0-3 offset = 4 or -4 */ |
| {5, 6, 7, 0, 1, 2, 3, 4}, /* 0-2 --> 5-7, 3-7->0-4 offset = 5 or -3 */ |
| {6, 7, 0, 1, 2, 3, 4, 5}, /* 0-1 --> 6-7, 2-7->0-5 offset = 6 or -2 */ |
| {7, 0, 1, 2, 3, 4, 5, 6}, /* 0 --> 7, 1-7->0-6 offset = 7 or -1 */ |
| }; |
| |
| static int g_bal_bcm_pcp_remark_map_id[BAL_BCM_PCP_MAP_NUM]; |
| |
| /**************************************************************************/ |
| /** |
| * @brief Create the PCP remark mapping tables |
| * |
| * This function creates the mapping from PCP bits in the |
| * frames received by DPP to the internal priority in |
| * DPP. The created map id are used in the ingress vlan translation API |
| * to perform PCP bits replacement. |
| * |
| * |
| * @param unit SDK unit number |
| * |
| * @return bcmos_errno |
| * |
| **************************************************************************/ |
| bcmos_errno bal_sw_dpp_pcp_remark_maps_init(int unit) |
| { |
| bcm_error_t sdk_rc = BCM_E_NONE; |
| bcm_qos_map_t l2_in_map; |
| int map_id, pcp; |
| int32_t qos_map_id; |
| |
| |
| for(map_id=0; map_id < BAL_BCM_PCP_MAP_NUM; map_id++) |
| { |
| /* in case anything goes wrong */ |
| g_bal_bcm_pcp_remark_map_id[map_id] = BAL_BCM_INVALID_PCP_MAP_ID; |
| |
| /* Create a map object */ |
| sdk_rc = bcm_qos_map_create(unit, BCM_QOS_MAP_INGRESS| BCM_QOS_MAP_L2_VLAN_PCP, &qos_map_id); |
| if (sdk_rc != BCM_E_NONE) |
| { |
| /* Error */ |
| BCM_LOG(ERROR, log_id_sw_util, |
| "bcm_qos_map_create failed with %s\n", |
| bcm_errmsg(sdk_rc)); |
| |
| return BCM_ERR_INTERNAL; |
| } |
| |
| /* Create a mapping for each PCP bits value. */ |
| for (pcp = 0; pcp < BAL_BCM_PCP_MAP_ENTRIES; pcp++) |
| { |
| bcm_qos_map_t_init(&l2_in_map); |
| |
| /* Ingress PCP/CoS value */ |
| l2_in_map.pkt_pri = g_bal_bcm_qos_pcp_map[map_id][pcp]; |
| |
| /* Set internal priority for this ingress pri */ |
| l2_in_map.int_pri = pcp; |
| |
| /* Set color for this ingress Priority */ |
| l2_in_map.color = bcmColorGreen; |
| |
| sdk_rc = bcm_qos_map_add(unit, BCM_QOS_MAP_L2_OUTER_TAG|BCM_QOS_MAP_L2|BCM_QOS_MAP_L2_VLAN_PCP, &l2_in_map, qos_map_id); |
| if (sdk_rc != BCM_E_NONE) |
| { |
| /* Error */ |
| BCM_LOG(ERROR, log_id_sw_util, |
| "bcm_qos_map_add failed with %s, for pcp %d\n", |
| bcm_errmsg(sdk_rc), pcp); |
| |
| return BCM_ERR_INTERNAL; |
| } |
| |
| } |
| |
| g_bal_bcm_pcp_remark_map_id[map_id] = qos_map_id; |
| } |
| return BCM_ERR_OK; |
| } |
| |
| /**************************************************************************/ |
| /** |
| * @brief Retrieve PCP remark mapping table ID according to the translation |
| * |
| * This function retrieve the pre-created mapping table id associate with |
| * the translation. |
| * The created map id can be used in the ingress vlan translation API |
| * to perform PCP bits replacement. |
| * |
| * @param src_pcp the pcp value that need to be translated, or -1 for DONTCARE |
| * @param dst_pcp the translated pcp value |
| * @param p_map_id pointer for the retrieved id |
| * |
| * @return bcmos_errno |
| * |
| **************************************************************************/ |
| bcmos_errno bal_sw_dpp_pcp_remark_map_get(int src_pcp, int dst_pcp, int *p_map_id) |
| { |
| int offset; |
| unsigned int indx; |
| |
| if(dst_pcp < 0 || dst_pcp > BAL_BCM_MAX_PCP_VALUE) |
| { |
| BCM_LOG(ERROR, log_id_sw_util, |
| "%s(): invalid destination pcp = %d\n", __FUNCTION__, dst_pcp); |
| return BCM_ERR_PARM; |
| } |
| /* if source is DONTCARE, i.e map to a fixed PCP, use the first 8 map tables */ |
| if(src_pcp == -1) |
| { |
| *p_map_id = g_bal_bcm_pcp_remark_map_id[dst_pcp]; |
| } |
| else |
| { |
| if(src_pcp < 0 || src_pcp > BAL_BCM_MAX_PCP_VALUE) |
| { |
| BCM_LOG(ERROR, log_id_sw_util, |
| "%s(): invalid source pcp = %d\n", __FUNCTION__, src_pcp); |
| return BCM_ERR_PARM; |
| } |
| /* find out the offset between the src_pcp and dst_pcp */ |
| offset = dst_pcp - src_pcp; |
| if (offset == 0) |
| { |
| BCM_LOG(ERROR, log_id_sw_util, |
| "%s(): source pcp %d == destination pcp %d\n", __FUNCTION__, src_pcp, dst_pcp); |
| return BCM_ERR_NOT_SUPPORTED; |
| } |
| if (offset < 0) |
| { |
| /* see comments in the above map tables */ |
| offset += BAL_BCM_PCP_MAP_ENTRIES; |
| } |
| |
| indx = offset + BAL_BCM_FIXED_PCP_MAP_NUM - 1; |
| if(indx >= BAL_BCM_PCP_MAP_NUM) |
| { |
| BCM_LOG(ERROR, log_id_sw_util, |
| "%s(): something is wrong, invalid map index = %d\n", __FUNCTION__, indx); |
| return BCM_ERR_INTERNAL; |
| } |
| /* index is 0 based */ |
| *p_map_id = g_bal_bcm_pcp_remark_map_id[indx]; |
| |
| } |
| |
| BCM_LOG(INFO, log_id_sw_util, |
| "%s(): pbits translate %d -> %d using bal qos map table %d, id 0x%x\n", __FUNCTION__, src_pcp, dst_pcp, indx, *p_map_id); |
| return BCM_ERR_OK; |
| } |
| |
| #endif /* TEST_SW_UTIL_LOOPBACK */ |
| |
| /*@}*/ |