openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

commit 134f6f88b5dde87c4d82543fcc495564f5548bfe
parent e66169ebf899aeb38a79b51cd164a378948abe6d
Author: Broadcom SDK Release <sdk.releases@broadcom.com>
Date:   Fri,  8 Mar 2019 13:45:49 -0800

SDK-172592: Fix gport tree to support changes in scheduler hierarchy

Devices: 56980_A0
Module: cosq

Symptom:
TH3: Remap scheduler cause bcm_cosq_stat_sync_get can't get correct stat

Diffstat:
Msdk-6.5.16/include/soc/tomahawk3.h | 3+++
Msdk-6.5.16/src/bcm/tomahawk3/cosq.c | 50+++++++++++++++++++++++++++++++++++---------------
Msdk-6.5.16/src/soc/esw/tomahawk3/traffic_manager.c | 48++++++++++++++++++++++++++++++++++++------------
3 files changed, 74 insertions(+), 27 deletions(-)

diff --git a/sdk-6.5.16/include/soc/tomahawk3.h b/sdk-6.5.16/include/soc/tomahawk3.h @@ -885,6 +885,9 @@ soc_th3_cosq_cpu_parent_get(int unit, int child_index, int child_level, int *parent_index); extern int +soc_th3_cosq_parent_get(int unit, int port, int child_index, int child_level, + int *parent_index); +extern int soc_tomahawk3_mem_sram_info_get(int unit, soc_mem_t mem, int index, _soc_ser_sram_info_t *sram_info); diff --git a/sdk-6.5.16/src/bcm/tomahawk3/cosq.c b/sdk-6.5.16/src/bcm/tomahawk3/cosq.c @@ -1342,17 +1342,21 @@ _bcm_th3_cosq_gport_add_attach(int unit, bcm_gport_t port, int numq, uint32 flag "SCHED add_attach port %d numq %d gport %d sched.numq %d\n"), port, numq, port_info->sched[numq].gport, port_info->sched[numq].numq)); } else { - id = th3_cosq_mmu_info[unit]->th3_port_info[local_port].L1[numq].children[0]->hw_index; + id = th3_cosq_mmu_info[unit]->th3_port_info[local_port].mmuq[numq].hw_index; if (_bcm_th3_queue_is_unicast(unit, id)) { - port_info->ucast[id].level = SOC_TH3_NODE_LVL_L1; - port_info->ucast[id].in_use = th3_cosq_mmu_info[unit]->th3_port_info[local_port].L1[numq].in_use; + port_info->ucast[id].level = SOC_TH3_NODE_LVL_L2; + port_info->ucast[id].in_use = + th3_cosq_mmu_info[unit]->th3_port_info[local_port].mmuq[numq].in_use; if (port_info->ucast[id].in_use) { - port_info->ucast[id].hw_index = th3_cosq_mmu_info[unit]->th3_port_info[local_port].L1[numq].hw_index; - port_info->ucast[id].cos = th3_cosq_mmu_info[unit]->th3_port_info[local_port].L1[numq].parent->cos; + port_info->ucast[id].hw_index = + th3_cosq_mmu_info[unit]->th3_port_info[local_port].mmuq[numq].hw_index; + port_info->ucast[id].cos = + th3_cosq_mmu_info[unit]->th3_port_info[local_port].mmuq[numq].parent->parent->cos; BCM_GPORT_UCAST_QUEUE_GROUP_SYSQID_SET(gport, local_port, id); port_info->ucast[id].gport = gport; port_info->ucast[id].numq = 1; - queue_num = th3_cosq_mmu_info[unit]->th3_port_info[local_port].L1[numq].parent->hw_index; + queue_num = + th3_cosq_mmu_info[unit]->th3_port_info[local_port].mmuq[numq].parent->parent->hw_index; sched_encap = (queue_num << 16) | local_port; BCM_GPORT_SCHEDULER_SET(parent_gport, sched_encap); port_info->ucast[id].parent_gport = parent_gport; @@ -1365,15 +1369,19 @@ _bcm_th3_cosq_gport_add_attach(int unit, bcm_gport_t port, int numq, uint32 flag } } else { id = id - _bcm_th3_get_num_ucq(unit); - port_info->mcast[id].level = SOC_TH3_NODE_LVL_L1; - port_info->mcast[id].in_use = th3_cosq_mmu_info[unit]->th3_port_info[local_port].L1[numq].in_use; + port_info->mcast[id].level = SOC_TH3_NODE_LVL_L2; + port_info->mcast[id].in_use = + th3_cosq_mmu_info[unit]->th3_port_info[local_port].mmuq[numq].in_use; if (port_info->mcast[id].in_use) { - port_info->mcast[id].hw_index = th3_cosq_mmu_info[unit]->th3_port_info[local_port].L1[numq].hw_index; - port_info->mcast[id].cos = th3_cosq_mmu_info[unit]->th3_port_info[local_port].L1[numq].parent->cos; + port_info->mcast[id].hw_index = + th3_cosq_mmu_info[unit]->th3_port_info[local_port].mmuq[numq].hw_index; + port_info->mcast[id].cos = + th3_cosq_mmu_info[unit]->th3_port_info[local_port].mmuq[numq].parent->parent->cos; BCM_GPORT_MCAST_QUEUE_GROUP_SYSQID_SET(gport, local_port, id); port_info->mcast[id].gport = gport; port_info->mcast[id].numq = 1; - queue_num = th3_cosq_mmu_info[unit]->th3_port_info[local_port].L1[numq].parent->hw_index; + queue_num = + th3_cosq_mmu_info[unit]->th3_port_info[local_port].mmuq[numq].parent->parent->hw_index; sched_encap = (queue_num << 16) | local_port; BCM_GPORT_SCHEDULER_SET(parent_gport, sched_encap); port_info->mcast[id].parent_gport = parent_gport; @@ -9085,10 +9093,12 @@ _bcm_th3_cosq_port_info_dump(int unit, bcm_port_t port) { _bcm_th3_cosq_port_info_t *port_info; _bcm_th3_cosq_node_t *node; + soc_th3_cosq_node_t *l1_node; int index, empty; soc_th3_sched_mode_e sched_mode = 0; int weight = 0; char *sched_modes[] = {"X", "SP", "WRR", "WERR"}; + int l1_parent = -1; if (!SOC_PORT_VALID(unit, port)) { return BCM_E_PORT; @@ -9146,9 +9156,13 @@ _bcm_th3_cosq_port_info_dump(int unit, bcm_port_t port) /* UC Queue */ int parent_id; node = &port_info->ucast[index]; + l1_node = + th3_cosq_mmu_info[unit]->th3_port_info[port].mmuq[index].parent; + BCM_IF_ERROR_RETURN(soc_th3_cosq_parent_get(unit, port, index, + node->level, &l1_parent)); BCM_IF_ERROR_RETURN( - soc_th3_cosq_sched_mode_get(unit, port, node->level, index, - &sched_mode, &weight, 0)); + soc_th3_cosq_sched_mode_get(unit, port, l1_node->level, + l1_parent, &sched_mode, &weight, 0)); BCM_IF_ERROR_RETURN( _bcm_th3_cosq_node_get(unit, node->parent_gport, NULL, NULL, &parent_id, NULL)); @@ -9162,9 +9176,15 @@ _bcm_th3_cosq_port_info_dump(int unit, bcm_port_t port) /* MC Queue */ int parent_id; node = &port_info->mcast[index]; + l1_node = + th3_cosq_mmu_info[unit]->th3_port_info[port].mmuq[(index + + _bcm_th3_get_num_ucq(unit))].parent; + BCM_IF_ERROR_RETURN(soc_th3_cosq_parent_get(unit, port, + (index + _bcm_th3_get_num_ucq(unit)), + node->level, &l1_parent)); BCM_IF_ERROR_RETURN( - soc_th3_cosq_sched_mode_get(unit, port, node->level, index, - &sched_mode, &weight, 1)); + soc_th3_cosq_sched_mode_get(unit, port, l1_node->level, + l1_parent, &sched_mode, &weight, 1)); BCM_IF_ERROR_RETURN( _bcm_th3_cosq_node_get(unit, node->parent_gport, NULL, NULL, &parent_id, NULL)); diff --git a/sdk-6.5.16/src/soc/esw/tomahawk3/traffic_manager.c b/sdk-6.5.16/src/soc/esw/tomahawk3/traffic_manager.c @@ -2288,7 +2288,7 @@ soc_cosq_struct_init(int unit) th3_cosq_mmu_info[unit]->th3_port_info[port_num]. mmuq[queue_num].level = 2; th3_cosq_mmu_info[unit]->th3_port_info[port_num]. - mmuq[queue_num].in_use = 0; + mmuq[queue_num].in_use = 1; th3_cosq_mmu_info[unit]->th3_port_info[port_num]. mmuq[queue_num].sched_policy = SOC_TH3_SCHED_MODE_WRR; th3_cosq_mmu_info[unit]->th3_port_info[port_num]. @@ -4217,20 +4217,44 @@ soc_th3_cosq_parent_get(int unit, int port, int child_index, int child_level, soc_reg_t reg = MMU_QSCH_PORT_CONFIGr; uint64 rval_64; uint32 mapping = 0; + soc_reg_t prof_reg = MMU_MTRO_MMUQ_SCHQ_CFGr; + soc_reg_t map_reg = MMU_MTRO_MMUQ_SCHQ_PROFILEr; + int port_profile = 0; + uint32 rval; + soc_field_t schedq_field[12] = { + SCH_Q_NUM_0f, SCH_Q_NUM_1f, + SCH_Q_NUM_2f, SCH_Q_NUM_3f, + SCH_Q_NUM_4f, SCH_Q_NUM_5f, + SCH_Q_NUM_6f, SCH_Q_NUM_7f, + SCH_Q_NUM_8f, SCH_Q_NUM_9f, + SCH_Q_NUM_10f, SCH_Q_NUM_11f, + }; - if (child_level != SOC_TH3_NODE_LVL_L1) { - /* Only child at L1 are allowed to move */ - return SOC_E_PARAM; - } - /* Set the L1 queue's parent to the given L0 node */ - SOC_IF_ERROR_RETURN - (soc_reg64_get(unit, reg, 0, port, &rval_64)); - mapping = soc_reg64_field32_get(unit, reg, rval_64, L1_TO_L0_MAPPINGf); - if ((mapping & (1 << child_index)) == 0) { - *parent_index = child_index; + if (child_level == SOC_TH3_NODE_LVL_L1) { + /* Set the L1 queue's parent to the given L0 node */ + SOC_IF_ERROR_RETURN + (soc_reg64_get(unit, reg, 0, port, &rval_64)); + mapping = soc_reg64_field32_get(unit, reg, rval_64, L1_TO_L0_MAPPINGf); + + if ((mapping & (1 << child_index)) == 0) { + *parent_index = child_index; + } else { + *parent_index = child_index+1; + } + } else if (child_level == SOC_TH3_NODE_LVL_L2) { + /* Retrieve schedq mapped to MMUQ*/ + rval = 0; + SOC_IF_ERROR_RETURN + (soc_reg32_get(unit, prof_reg, port, 0, &rval)); + port_profile = soc_reg_field_get(unit, prof_reg, rval, Q_PROFILE_SELf); + SOC_IF_ERROR_RETURN + (soc_reg64_get(unit, map_reg, REG_PORT_ANY, port_profile, &rval_64)); + *parent_index = soc_reg64_field32_get(unit, map_reg, rval_64, + schedq_field[child_index]); + } else { - *parent_index = child_index+1; + return SOC_E_PARAM; } return SOC_E_NONE;