tm_dump_mem.c (10054B)
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 * Diag CLI TMCheck command 8 */ 9 10 #include <soc/defs.h> 11 #if defined(BCM_TOMAHAWK3_SUPPORT) 12 13 #include <appl/diag/system.h> 14 #include <appl/diag/parse.h> 15 #include <shared/bsl.h> 16 #include <bcm/error.h> 17 18 #include <soc/tomahawk3.h> 19 20 #ifdef __KERNEL__ 21 #define atoi _shr_ctoi 22 #endif 23 24 char cmd_tm_dump_mem_usage[] = 25 "tmdumpmem [-index] <port/queue> <memory_name> <port> <queue> ...\n"; 26 27 STATIC int 28 th3_retrieve_port_mem_index (int unit, soc_mem_t mem, int port) { 29 int mem_index; 30 int mem_depth; 31 32 33 if (mem == MMU_RQE_DEVICE_TO_MMU_PORT_MAPPINGm) { 34 mem_index = port; 35 } else { 36 /* Index transformation for MMU memories based on port number */ 37 mem_depth = soc_mem_index_max(unit, mem) + 1; 38 if (mem_depth == SOC_TH3_MAX_DEV_PORTS_PER_PIPE) { 39 /* Mem indexed by local MMU port number */ 40 mem_index = SOC_TH3_MMU_LOCAL_PORT(unit, port); 41 } else if (mem_depth == SOC_TH3_MAX_NUM_PORTS) { 42 /* MMU mem indexed by MMU chip port number */ 43 mem_index = SOC_TH3_MMU_CHIP_PORT(unit, port); 44 } else { 45 mem_index = -1; 46 } 47 } 48 return mem_index; 49 } 50 51 52 STATIC int 53 th3_dump_port_based_mem (int unit, char* memory_name, int port, int print_index) 54 { 55 soc_mem_t *mem_list; 56 int mem_tot = 1, mem_idx, memory_index; 57 int copyno; 58 soc_mem_t mem = INVALIDm; 59 int block_info_index; 60 int rv; 61 uint32 entry[SOC_MAX_MEM_WORDS]; 62 63 /* Reserving array of length 64 for max combinations of EB/IPIPE in TH3 */ 64 mem_list = sal_alloc(64 * sizeof(soc_mem_t), "List of MMU logical views"); 65 if (mem_list == NULL) { 66 return SOC_E_MEMORY; 67 } 68 69 /* Checking validity of passed memory */ 70 if (parse_memory_name(unit, &mem, memory_name, ©no, 0) < 0) { 71 cli_out("ERROR: unknown table \"%s\"\n", memory_name); 72 sal_free(mem_list); 73 return SOC_E_PARAM; 74 } 75 block_info_index = SOC_MEM_BLOCK_ANY(unit, mem); 76 if ((SOC_BLOCK_TYPE(unit, block_info_index) != SOC_BLK_MMU_ITM) && 77 (SOC_BLOCK_TYPE(unit, block_info_index) != SOC_BLK_MMU_EB) && 78 (SOC_BLOCK_TYPE(unit, block_info_index) != SOC_BLK_MMU_GLB)) { 79 /* index transformation not applicable for non-MMU memories */ 80 cli_out("ERROR: Command used for non-MMU memory \"%s\"\n", memory_name); 81 sal_free(mem_list); 82 return SOC_E_PARAM; 83 } 84 85 86 if (copyno == COPYNO_ALL) { 87 copyno = SOC_MEM_BLOCK_ANY(unit, mem); 88 } 89 90 91 /* Expand based on port only if it is per-port memory */ 92 rv = soc_th3_retrieve_mmu_mem_list_for_port(unit, port, mem, -1, 93 mem_list, 64, &mem_tot); 94 if (rv) { 95 mem_list[0] = mem; 96 } 97 memory_index = th3_retrieve_port_mem_index(unit, mem_list[0], port); 98 if (memory_index == -1) { 99 sal_free(mem_list); 100 cli_out("Memory: \"%s\" is not port based \n", memory_name); 101 return SOC_E_PARAM; 102 } 103 for(mem_idx = 0; mem_idx < mem_tot; mem_idx++) { 104 mem = mem_list[mem_idx]; 105 if (mem != INVALIDm) { 106 if (!print_index) { 107 cli_out("%s.%s[%d]: ", 108 SOC_MEM_UFNAME(unit, mem), 109 SOC_BLOCK_NAME(unit, copyno), 110 memory_index); 111 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 112 } else { 113 cli_out("Memory: %s index: %d\n", SOC_MEM_UFNAME(unit, mem), 114 memory_index); 115 } 116 } 117 } 118 sal_free(mem_list); 119 return SOC_E_NONE; 120 } 121 122 STATIC int 123 th3_dump_queue_based_mem (int unit, char* memory_name, int port, int queue, 124 int print_index) 125 { 126 soc_mem_t *mem_list; 127 int mem_tot = 1, mem_idx; 128 int copyno; 129 soc_mem_t mem = INVALIDm; 130 int block_info_index; 131 int rv; 132 uint32 entry[SOC_MAX_MEM_WORDS]; 133 soc_info_t *si = &SOC_INFO(unit); 134 int mem_index; 135 int mem_depth; 136 137 /* Reserving array of length 64 for max combinations of EB/IPIPE in TH3 */ 138 mem_list = sal_alloc(64 * sizeof(soc_mem_t), "List of MMU logical views"); 139 if (mem_list == NULL) { 140 return SOC_E_MEMORY; 141 } 142 143 /* Checking validity of passed memory */ 144 if (parse_memory_name(unit, &mem, memory_name, ©no, 0) < 0) { 145 cli_out("ERROR: unknown table \"%s\"\n", memory_name); 146 sal_free(mem_list); 147 return SOC_E_PARAM; 148 } 149 block_info_index = SOC_MEM_BLOCK_ANY(unit, mem); 150 if ((SOC_BLOCK_TYPE(unit, block_info_index) != SOC_BLK_MMU_ITM) && 151 (SOC_BLOCK_TYPE(unit, block_info_index) != SOC_BLK_MMU_EB)) { 152 /* index transformation not applicable for non-MMU memories */ 153 cli_out("ERROR: Command used for unknown Queue based Memory \"%s\"\n", 154 memory_name); 155 sal_free(mem_list); 156 return SOC_E_PARAM; 157 } 158 if (copyno == COPYNO_ALL) { 159 copyno = SOC_MEM_BLOCK_ANY(unit, mem); 160 } 161 162 /* Expand based on port number for queu based memories */ 163 rv = soc_th3_retrieve_mmu_mem_list_for_port(unit, port, mem, -1, 164 mem_list, 64, &mem_tot); 165 if (rv) { 166 mem_list[0] = mem; 167 } 168 169 for(mem_idx = 0; mem_idx < mem_tot; mem_idx++) { 170 mem = mem_list[mem_idx]; 171 mem_depth = soc_mem_index_max(unit, mem) + 1; 172 173 /* 174 * Queue based memories in ITM have chip_q_number as index 175 * Memory depths vary as 1920, 1968, & 2080 176 * Queue memories which are pipe based have local queue number as index 177 * Memory depth for pipe-local queue memories is 276 178 */ 179 if (mem_depth == 1920 || mem_depth == 1968 || mem_depth == 2080) { 180 /* Memories indexed by chip_q_number (global) */ 181 mem_index = si->port_uc_cosq_base[port] + queue; 182 } else if (mem_depth == SOC_TH3_NUM_COS_QUEUES_PER_PIPE) { 183 /* Memories indexed by pipe local Queue number */ 184 mem_index = (si->port_l2i_mapping[port] * SOC_TH3_NUM_GP_QUEUES) 185 + queue; 186 } else { 187 /* Access meant for non-queue memory */ 188 cli_out("ERROR: Command used for unknown Queue based Memory: memory" 189 "depth not mtaching\"%s\"\n", 190 memory_name); 191 sal_free(mem_list); 192 return SOC_E_PARAM; 193 } 194 if (mem != INVALIDm) { 195 if (!print_index) { 196 cli_out("%s.%s[%d]: ", 197 SOC_MEM_UFNAME(unit, mem), 198 SOC_BLOCK_NAME(unit, copyno), 199 mem_index); 200 soc_mem_entry_dump(unit, mem, entry, BSL_LSS_CLI); 201 } else { 202 cli_out("Memory: %s index: %d\n", SOC_MEM_UFNAME(unit, mem), 203 mem_index); 204 } 205 } 206 } 207 sal_free(mem_list); 208 return SOC_E_NONE; 209 } 210 cmd_result_t 211 cmd_tm_dump_mem(int unit, args_t *arg) 212 { 213 char *index_type, *memory_name, *idx_param1, *idx_param2; 214 int port; 215 int rv = 0; 216 int queue, user_q; 217 int only_index = 0; 218 soc_info_t *si = &SOC_INFO(unit); 219 220 index_type = ARG_GET(arg); 221 if (index_type == NULL) { 222 return CMD_USAGE; 223 } 224 225 if (!sal_strcasecmp(index_type, "-index")) { 226 only_index = 1; 227 index_type = ARG_GET(arg); 228 } 229 230 memory_name = ARG_GET(arg); 231 if (memory_name == NULL) { 232 return CMD_USAGE; 233 } 234 if (!sal_strcasecmp(index_type, "port")) { 235 /* Accessing port based memories in MMU */ 236 idx_param1 = ARG_GET(arg); 237 port = sal_atoi(idx_param1); 238 if (SOC_PORT_VALID(unit, port)) { 239 rv = th3_dump_port_based_mem (unit, memory_name, port, only_index); 240 if (rv) { 241 cli_out("%s: ERROR: %s\n", ARG_CMD(arg), bcm_errmsg(rv)); 242 return CMD_FAIL; 243 } 244 } else { 245 cli_out("Invalid logical port number\n"); 246 return CMD_FAIL; 247 } 248 } else if (!sal_strcasecmp(index_type, "queue") || 249 !sal_strcasecmp(index_type, "uc_cos") || 250 !sal_strcasecmp(index_type, "mc_cos")) { 251 /* Accessing queue based memories in MMU */ 252 idx_param1 = ARG_GET(arg); 253 idx_param2 = ARG_GET(arg); 254 port = sal_atoi(idx_param1); 255 user_q = sal_atoi(idx_param2); 256 257 if (!SOC_PORT_VALID(unit, port) && (port != -1)) { 258 cli_out("Invalid logical port number\n"); 259 return CMD_FAIL; 260 } 261 /* 262 * Queue number retrieval and validation based on user input of 263 * queue/uc_cos/mc_cos 264 */ 265 if (!sal_strcasecmp(index_type, "queue")) { 266 queue = user_q; 267 } else if(!sal_strcasecmp(index_type, "uc_cos")) { 268 if ((IS_CPU_PORT(unit, port)) || (user_q > si->port_num_uc_cosq[1])) { 269 cli_out ("Invalid Uc_cos number provided \n"); 270 return CMD_FAIL; 271 } 272 queue = user_q; 273 } else { 274 if ((!IS_CPU_PORT(unit, port) && (user_q > si->port_num_cosq[1])) || 275 (IS_CPU_PORT(unit, port) && (user_q > si->port_num_cosq[0]))) { 276 cli_out ("Invalid mc_cos number provided \n"); 277 return CMD_FAIL; 278 } 279 queue = si->port_num_uc_cosq[1] + user_q; 280 } 281 282 if ((queue < 0) || 283 (IS_CPU_PORT(unit, port) && (queue >= SOC_TH3_NUM_CPU_QUEUES)) || 284 (!IS_CPU_PORT(unit, port) && (queue >= SOC_TH3_NUM_GP_QUEUES))) { 285 cli_out("Invalid Queue number\n"); 286 return CMD_FAIL; 287 } 288 289 rv = th3_dump_queue_based_mem (unit, memory_name, port, queue, 290 only_index); 291 if (rv) { 292 cli_out("%s: ERROR: %s\n", ARG_CMD(arg), bcm_errmsg(rv)); 293 return CMD_FAIL; 294 } 295 } else { 296 return CMD_USAGE; 297 } 298 299 return CMD_OK; 300 } 301 302 #endif /* BCM_TOMAHAWK3_SUPPORT */