preemption.c (12499B)
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 #include <soc/drv.h> 8 #include <soc/monterey.h> 9 #include <bcm/error.h> 10 #include <bcm_int/esw/port.h> 11 #include <bcm/types.h> 12 #if defined(BCM_PREEMPTION_SUPPORT) 13 #include <bcm_int/esw/preemption.h> 14 #endif 15 #if defined(BCM_MONTEREY_SUPPORT) 16 17 int bcm_mn_preemption_edb_init(int unit) { 18 19 20 int preemption_start[128]={4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 21 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 22 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 23 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 24 4,4,4,5,4,4,4,5,4,4,4,5,4,4,4,5, 25 6,6,6,6,6,6,6,6,6,6,6,5,6,6,6,6, 26 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 27 6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,6 28 }; 29 int preemption_terminate[512]={ 30 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 31 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 32 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 33 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 34 8,8,8,8,8,8,8,8,8,0xd,8,0xd,8,0xd,8,0xd, 35 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 36 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 37 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 38 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 39 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 40 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 41 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 42 8,8,8,8,8,8,8,8,8,0xd,8,0xd,8,0xd,8,0xd, 43 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 44 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 45 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 46 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 47 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 48 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 49 8,8,8,8,8,8,8,8,8,8,8,0xd,8,8,8,0xd, 50 8,8,8,8,8,8,8,8,8,0xd,8,0xd,8,0xd,8,0xd, 51 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 52 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 53 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 54 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 55 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 56 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 57 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 58 8,8,8,8,8,8,8,8,8,0xd,8,0xd,8,0xd,8,0xd, 59 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 60 8,8,8,8,8,8,8,8,8,0xa,8,0xd,8,0xa,8,0xd, 61 8,8,8,8,8,8,8,8,8,0xa,8,8,8,0xa,8,8, 62 }; 63 64 static const soc_mem_t preemption_start_mem[16]={ 65 EGR_FLEX_PREEMPT_START_LOOKUP0m, 66 EGR_FLEX_PREEMPT_START_LOOKUP1m, 67 EGR_FLEX_PREEMPT_START_LOOKUP2m, 68 EGR_FLEX_PREEMPT_START_LOOKUP3m, 69 EGR_FLEX_PREEMPT_START_LOOKUP4m, 70 EGR_FLEX_PREEMPT_START_LOOKUP5m, 71 EGR_FLEX_PREEMPT_START_LOOKUP6m, 72 EGR_FLEX_PREEMPT_START_LOOKUP7m, 73 EGR_FLEX_PREEMPT_START_LOOKUP8m, 74 EGR_FLEX_PREEMPT_START_LOOKUP9m, 75 EGR_FLEX_PREEMPT_START_LOOKUP10m, 76 EGR_FLEX_PREEMPT_START_LOOKUP11m, 77 EGR_FLEX_PREEMPT_START_LOOKUP12m, 78 EGR_FLEX_PREEMPT_START_LOOKUP13m, 79 EGR_FLEX_PREEMPT_START_LOOKUP14m, 80 EGR_FLEX_PREEMPT_START_LOOKUP15m, 81 }; 82 static const soc_mem_t preemption_terminate_mem[16]={ 83 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP0m, 84 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP1m, 85 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP2m, 86 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP3m, 87 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP4m, 88 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP5m, 89 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP6m, 90 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP7m, 91 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP8m, 92 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP9m, 93 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP10m, 94 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP11m, 95 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP12m, 96 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP13m, 97 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP14m, 98 EGR_FLEX_PREEMPT_TERMINATE_LOOKUP15m, 99 }; 100 uint32 entry0[SOC_MAX_MEM_WORDS]; 101 uint32 entry1[SOC_MAX_MEM_WORDS]; 102 103 int port_macro_index, row_index, entry_index, absoulte_entry_index; 104 105 #define NUM_PORT_MACRO 16 106 #define NUM_ROW 32 107 #define NUM_START_ENTRY_PER_ROW 4 108 #define NUM_TERMINATE_ENTRY_PER_ROW 16 109 110 for(port_macro_index = 0 ; port_macro_index < NUM_PORT_MACRO; port_macro_index++) { 111 for (row_index = 0; row_index < NUM_ROW; row_index++) { 112 for (entry_index = 0 ; entry_index < NUM_START_ENTRY_PER_ROW ; entry_index++) { 113 absoulte_entry_index = NUM_START_ENTRY_PER_ROW * row_index + entry_index; 114 sal_memset(entry0, 0, (sizeof(uint32) * SOC_MAX_MEM_WORDS)); 115 soc_mem_field32_set(unit,preemption_start_mem[port_macro_index], 116 entry0, STARTf,preemption_start[absoulte_entry_index]); 117 SOC_IF_ERROR_RETURN( 118 soc_mem_write(unit,preemption_start_mem[port_macro_index] , 119 MEM_BLOCK_ANY, absoulte_entry_index, &entry0)); 120 } 121 for (entry_index = 0 ; entry_index < NUM_TERMINATE_ENTRY_PER_ROW ; entry_index++) { 122 absoulte_entry_index = NUM_TERMINATE_ENTRY_PER_ROW * row_index + entry_index; 123 sal_memset(entry1, 0, (sizeof(uint32) * SOC_MAX_MEM_WORDS)); 124 soc_mem_field32_set(unit,preemption_terminate_mem[port_macro_index], 125 entry1, TERMINATEf,preemption_terminate[absoulte_entry_index]); 126 SOC_IF_ERROR_RETURN( 127 soc_mem_write(unit,preemption_terminate_mem[port_macro_index], 128 MEM_BLOCK_ANY, absoulte_entry_index, &entry1)); 129 } 130 } 131 } 132 return BCM_E_NONE; 133 } 134 135 int 136 bcmi_mn_preemption_init(int unit) { 137 138 BCM_IF_ERROR_RETURN(bcm_mn_preemption_edb_init(unit)); 139 return BCM_E_NONE; 140 } 141 142 STATIC int 143 bcmi_mn_preemption_port_check(int unit, bcm_port_t port) 144 { 145 return TRUE; 146 } 147 148 int 149 bcmi_mn_preemption_capability_set(int unit, bcm_port_t port, 150 uint32 arg) 151 { 152 153 BCM_IF_ERROR_RETURN(bcmi_mn_preemption_port_check(unit, port)); 154 BCM_IF_ERROR_RETURN( 155 soc_reg_field32_modify(unit, 156 HSP_SCHED_PORT_PREEMPT_CONFIGr, 157 port, 158 PORT_PREEMPTABLEf, 159 arg ? 1 : 0)); 160 return BCM_E_NONE; 161 } 162 163 int 164 bcmi_mn_preemption_queue_bitmap_set(int unit, bcm_port_t port, 165 uint32 arg) 166 { 167 BCM_IF_ERROR_RETURN(bcmi_mn_preemption_port_check(unit, port)); 168 BCM_IF_ERROR_RETURN( 169 soc_reg_field_validate(unit, 170 HSP_SCHED_PORT_PREEMPT_CONFIGr, 171 COS_PREEMPTABLEf, 172 arg)); 173 BCM_IF_ERROR_RETURN( 174 soc_reg_field32_modify(unit, 175 HSP_SCHED_PORT_PREEMPT_CONFIGr, 176 port, 177 COS_PREEMPTABLEf, 178 arg)); 179 return BCM_E_NONE; 180 } 181 182 183 184 int 185 bcmi_mn_preemption_capability_get(int unit, bcm_port_t port, 186 uint32* arg) 187 { 188 uint32 regval; 189 if (NULL == arg) { 190 return SOC_E_PARAM; 191 } 192 BCM_IF_ERROR_RETURN(bcmi_mn_preemption_port_check(unit, port)); 193 BCM_IF_ERROR_RETURN( 194 READ_HSP_SCHED_PORT_PREEMPT_CONFIGr(unit, port, 195 ®val)); 196 *arg = soc_reg_field_get(unit, 197 HSP_SCHED_PORT_PREEMPT_CONFIGr, 198 regval, PORT_PREEMPTABLEf); 199 return BCM_E_NONE; 200 } 201 202 int 203 bcmi_mn_preemption_queue_bitmap_get(int unit, bcm_port_t port, 204 uint32* arg) 205 { 206 uint32 regval; 207 if (NULL == arg) { 208 return SOC_E_PARAM; 209 } 210 BCM_IF_ERROR_RETURN(bcmi_mn_preemption_port_check(unit, port)); 211 BCM_IF_ERROR_RETURN( 212 READ_HSP_SCHED_PORT_PREEMPT_CONFIGr(unit, port, 213 ®val)); 214 *arg = soc_reg_field_get(unit, 215 HSP_SCHED_PORT_PREEMPT_CONFIGr, 216 regval, COS_PREEMPTABLEf); 217 return BCM_E_NONE; 218 } 219 int 220 bcmi_mn_preemption_frag_config_tx_set(int unit, bcm_port_t port, 221 int is_final, 222 uint32 value) 223 { 224 uint32 entry[SOC_MAX_MEM_WORDS], hw_value; 225 soc_info_t *si; 226 int phy_port; 227 228 si = &SOC_INFO(unit); 229 phy_port = si->port_l2p_mapping[port]; 230 BCM_IF_ERROR_RETURN(bcmi_mn_preemption_port_check(unit, port)); 231 232 /* Min final frag size should be in range 64-128 and 233 min non-final frag size shoudl be in range 64-512 */ 234 if(value > 512 || value < 64) { 235 return BCM_E_PARAM; 236 } 237 if (is_final && (value > 128)) { 238 return BCM_E_PARAM; 239 } 240 hw_value = value / 8; 241 242 BCM_IF_ERROR_RETURN 243 (READ_EGR_PORT_MNFS_MFS_CONFIGm(unit, MEM_BLOCK_ALL, 244 phy_port, entry)); 245 soc_mem_field32_set(unit, EGR_PORT_MNFS_MFS_CONFIGm, 246 entry, (is_final ? MFSf : MNFSf), hw_value); 247 BCM_IF_ERROR_RETURN 248 (WRITE_EGR_PORT_MNFS_MFS_CONFIGm(unit, MEM_BLOCK_ALL, 249 phy_port, entry)); 250 return BCM_E_NONE; 251 } 252 int 253 bcmi_mn_preemption_frag_config_tx_get(int unit, bcm_port_t port, 254 int is_final, 255 uint32* value) 256 { 257 uint32 entry[SOC_MAX_MEM_WORDS], hw_value; 258 soc_info_t *si; 259 int phy_port; 260 261 si = &SOC_INFO(unit); 262 phy_port = si->port_l2p_mapping[port]; 263 264 if (NULL == value) { 265 return SOC_E_PARAM; 266 } 267 268 BCM_IF_ERROR_RETURN(bcmi_mn_preemption_port_check(unit, port)); 269 270 BCM_IF_ERROR_RETURN 271 (READ_EGR_PORT_MNFS_MFS_CONFIGm(unit, MEM_BLOCK_ALL, 272 phy_port, entry)); 273 hw_value = soc_mem_field32_get(unit, EGR_PORT_MNFS_MFS_CONFIGm, 274 entry, (is_final ? MFSf : MNFSf)); 275 *value = hw_value * 8; 276 return BCM_E_NONE; 277 } 278 279 #endif /* BCM_MONTEREY_SUPPORT */