qos.c (3750B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: qos.c 8 * Purpose: Katana2 QoS functions 9 */ 10 11 #include <soc/mem.h> 12 #include <bcm/error.h> 13 #include <bcm_int/esw/trx.h> 14 #include <bcm_int/esw/katana2.h> 15 16 #ifdef BCM_KATANA2_SUPPORT 17 18 #undef DSCP_CODE_POINT_CNT 19 #define DSCP_CODE_POINT_CNT 64 20 #undef DSCP_CODE_POINT_MAX 21 #define DSCP_CODE_POINT_MAX (DSCP_CODE_POINT_CNT - 1) 22 #define _BCM_QOS_MAP_CHUNK_DSCP 64 23 24 /* Function: 25 * bcm_kt2_port_dscp_map_set 26 * Purpose: 27 * Internal implementation for bcm_kt2_port_dscp_map_set 28 * Parameters: 29 * unit - switch device 30 * port - switch port or -1 for global table 31 * srccp - src code point or -1 32 * mapcp - mapped code point or -1 33 * prio - priority value for mapped code point 34 * -1 to use port default untagged priority 35 * BCM_PRIO_RED can be or'ed into the priority 36 * BCM_PRIO_YELLOW can be or'ed into the priority 37 * Returns: 38 * BCM_E_XXX 39 */ 40 41 int 42 bcm_kt2_port_dscp_map_set(int unit, bcm_port_t port, int srccp, 43 int mapcp, int prio, int cng) 44 { 45 port_tab_entry_t pent; 46 void *entries[2]; 47 uint32 old_profile_index = 0; 48 int index = 0; 49 int rv = BCM_E_NONE; 50 dscp_table_entry_t dscp_table[_BCM_QOS_MAP_CHUNK_DSCP]; 51 int offset = 0,i = 0; 52 void *entry; 53 54 /* Lock the port table */ 55 soc_mem_lock(unit, PORT_TABm); 56 57 /* Get profile index from port table. */ 58 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &pent); 59 if (BCM_FAILURE(rv)) { 60 soc_mem_unlock(unit, PORT_TABm); 61 return rv; 62 } 63 64 old_profile_index = 65 soc_mem_field32_get(unit, PORT_TABm, &pent, TRUST_DSCP_PTRf) 66 * DSCP_CODE_POINT_CNT; 67 68 sal_memset(dscp_table, 0, sizeof(dscp_table)); 69 70 /* Base index of table in hardware */ 71 72 entries[0] = &dscp_table; 73 74 rv = _bcm_dscp_table_entry_get(unit, old_profile_index, 75 _BCM_QOS_MAP_CHUNK_DSCP, entries); 76 offset = srccp; 77 /* Modify what's needed */ 78 79 if (offset < 0) { 80 for (i = 0; i <= DSCP_CODE_POINT_MAX; i++) { 81 entry = &dscp_table[i]; 82 soc_DSCP_TABLEm_field32_set(unit, entry, DSCPf, mapcp); 83 soc_DSCP_TABLEm_field32_set(unit, entry, PRIf, prio); 84 soc_DSCP_TABLEm_field32_set(unit, entry, CNGf, cng); 85 } 86 } else { 87 entry = &dscp_table[offset]; 88 soc_DSCP_TABLEm_field32_set(unit, entry, DSCPf, mapcp); 89 soc_DSCP_TABLEm_field32_set(unit, entry, PRIf, prio); 90 soc_DSCP_TABLEm_field32_set(unit, entry, CNGf, cng); 91 } 92 93 /* Add new chunk and store new HW index */ 94 95 rv = _bcm_dscp_table_entry_add(unit, entries, _BCM_QOS_MAP_CHUNK_DSCP, 96 (uint32 *)&index); 97 if (BCM_FAILURE(rv)) { 98 soc_mem_unlock(unit, PORT_TABm); 99 return rv; 100 } 101 102 if (index != old_profile_index) { 103 soc_mem_field32_set(unit, PORT_TABm, &pent, TRUST_DSCP_PTRf, 104 index / _BCM_QOS_MAP_CHUNK_DSCP); 105 rv = soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, 106 &pent); 107 if (BCM_FAILURE(rv)) { 108 soc_mem_unlock(unit, PORT_TABm); 109 return rv; 110 } 111 } 112 113 rv = _bcm_dscp_table_entry_delete(unit, old_profile_index); 114 /* Release port table lock */ 115 soc_mem_unlock(unit, PORT_TABm); 116 return rv; 117 } 118 119 #endif /* BCM_KATANA2_SUPPORT */ 120