dma.c (20865B)
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: dma.c 8 * Purpose: Commands for low-level DMA-able memory control 9 */ 10 11 #include <sal/types.h> 12 13 #include <soc/cm.h> 14 #include <soc/dma.h> 15 #include <soc/error.h> 16 #include <shared/bsl.h> 17 #include <appl/diag/parse.h> 18 #include <appl/diag/system.h> 19 20 #define CMD_ESW_DMA_LADDR "dma_laddr" 21 #define CMD_ESW_DMA_PADDR "dma_paddr" 22 #define CMD_ESW_DMA_SIZE "dma_size" 23 #define CMD_ESW_DMA_COUNT "dma_count" 24 #define CMD_ESW_DMA_BYTES "dma_bytes" 25 #define CMD_ESW_DMA_SHORTS "dma_shorts" 26 #define CMD_ESW_DMA_WORDS "dma_words" 27 #define CMD_ESW_DMA_DV "dma_dv_laddr" 28 #define CMD_ESW_DMA_DCB "dma_dcb_laddr" 29 #define CMD_ESW_DMA_DCB_COUNT "dma_dcb_count" 30 #define CMD_ESW_DMA_DCB_SIZE "dma_dcb_size" 31 32 char cmd_esw_dma_usage[] = 33 #ifdef COMPILER_STRING_CONST_LIMIT 34 "Usage: dma <option> [args...]\n" 35 #else 36 "Usages:\n\t" 37 "\n\t" 38 " dma alloc [b|h|w] <count> [name]\n\t" 39 " Allocate DMA-able memory (you can add region name)\n\t" 40 " dma free [<laddr>]\n\t" 41 " Free DMA-able memory\n\t" 42 " dma l2p [<laddr>]\n\t" 43 " Convert logical (CPU) address into a physical (bus) address\n\t" 44 " dma p2l [<paddr>]\n\t" 45 " Convert physical (bus) address into a logical (CPU) address\n\t" 46 " dma flush [b|h|w] [<laddr> [<count>]]\n\t" 47 " Flush the cache corresponding to the DMA-able memory region\n\t" 48 " dma inval [b|h|w] [<laddr> [<count>]]\n\t" 49 " Invalidate the cache corresponding to the DMA-able memory region\n\t" 50 " dma load <laddr> <hex data>\n\t" 51 " Fill DMA-able memory with provided hex data\n\t" 52 " dma fill [b|h|w] <laddr> <count> <value>\n\t" 53 " Fill DMA-able memory with provided value\n\t" 54 " dma edit [b|h|w] [<laddr>]\n\t" 55 " Interactive memory editing\n\t" 56 " dma dvalloc [r|t] <dcb_count>\n\t" 57 " Allocate a DMA Vector (DV) with dcb_count DCBs\n\t" 58 " dma dvfree dv_addr\n\t" 59 " Free a DV together with the allocated DCBs\n\t" 60 " dma addrx <dv_laddr> <buf_laddr> <bytes>\n\t" 61 " Add an RX DCB to the DV chain\n\t" 62 " dma dcbdump [r|t] $dcb_laddr\n\t" 63 " Dump the memory as a DCB\n\t" 64 "\nNote:\n\t" 65 "The following variables contain the results of the subcommands and\n\t" 66 "be used as default arguments:\n\t\t" 67 "$" CMD_ESW_DMA_LADDR "\t -- the logical address of DMA-able memory\n\t\t" 68 "$" CMD_ESW_DMA_PADDR "\t -- the physical address of DMA-able memory\n\t\t" 69 "$" CMD_ESW_DMA_SIZE "\t -- the size of the element (b, h, or w)\n\t\t" 70 "$" CMD_ESW_DMA_COUNT "\t -- the number of elements (bytes, shorts, words)\n\t\t" 71 "$" CMD_ESW_DMA_BYTES "\t -- number of bytes in the allocated region\n\t\t" 72 "$" CMD_ESW_DMA_SHORTS"\t -- number of shorts in the allocated region\n\t\t" 73 "$" CMD_ESW_DMA_WORDS "\t -- number of words in the allocated region\n\t\t" 74 "$" CMD_ESW_DMA_DV "\t -- the logical address of the allocated \n\t\t" 75 "\t\t DMA vector (DV)\n\t\t" 76 "$" CMD_ESW_DMA_DCB "\t -- the logical address of allocated DCB chain\n\t\t" 77 "$" CMD_ESW_DMA_DCB_COUNT "\t -- number of DCBs in the allocated chain\n\t\t" 78 "$" CMD_ESW_DMA_DCB_SIZE "\t -- the size of a single DCB in bytes\n" 79 "\n" 80 #endif 81 ; 82 83 STATIC cmd_result_t 84 cmd_esw_dma_get_size(int unit, args_t *a, int *size) 85 { 86 char *sz; 87 88 if (size == NULL) { 89 return CMD_FAIL; 90 } 91 92 if ((sz = ARG_GET(a)) != NULL) { 93 switch (sz[0]) { 94 case 'b': case 'B': *size = 1; return CMD_OK; 95 case 'h': case 'H': *size = 2; return CMD_OK; 96 case 'w': case 'W': *size = 4; return CMD_OK; 97 default: ARG_PREV(a); 98 } 99 } 100 101 if ((sz = var_get(CMD_ESW_DMA_SIZE)) == NULL) { 102 *size = 1; /* Default are bytes */ 103 return CMD_OK; 104 } else { 105 switch (sz[0]) { 106 case 'b': case 'B': *size = 1; return CMD_OK; 107 case 'h': case 'H': *size = 2; return CMD_OK; 108 case 'w': case 'W': *size = 4; return CMD_OK; 109 default: 110 cli_out("Incorrect size specification <%s>\n", sz); 111 return CMD_FAIL; 112 } 113 } 114 115 return CMD_FAIL; 116 } 117 118 STATIC cmd_result_t 119 cmd_esw_dma_get_count(int unit, args_t *a, int *count) 120 { 121 char *arg; 122 123 if (count == NULL) { 124 return CMD_FAIL; 125 } 126 127 /* Parse the number of bytes to allocate */ 128 if ((arg = ARG_GET(a)) == NULL && 129 (arg = var_get(CMD_ESW_DMA_COUNT)) == NULL) { 130 return CMD_FAIL; 131 } 132 133 *count = parse_integer(arg); 134 135 return CMD_OK; 136 } 137 138 STATIC void 139 cmd_esw_dma_set_count_size(uint32 count, uint32 size) 140 { 141 142 var_unset(CMD_ESW_DMA_BYTES, TRUE, FALSE, FALSE); 143 var_unset(CMD_ESW_DMA_SHORTS, TRUE, FALSE, FALSE); 144 var_unset(CMD_ESW_DMA_WORDS, TRUE, FALSE, FALSE); 145 146 switch (size) { 147 case 1: 148 var_set(CMD_ESW_DMA_SIZE, "b", TRUE, FALSE); 149 var_set_integer(CMD_ESW_DMA_BYTES, count, TRUE, FALSE); 150 break; 151 case 2: 152 var_set(CMD_ESW_DMA_SIZE, "h", TRUE, FALSE); 153 var_set_integer(CMD_ESW_DMA_SHORTS, count, TRUE, FALSE); 154 break; 155 case 4: 156 var_set(CMD_ESW_DMA_SIZE, "w", TRUE, FALSE); 157 var_set_integer(CMD_ESW_DMA_WORDS, count, TRUE, FALSE); 158 break; 159 default: 160 var_set(CMD_ESW_DMA_SIZE, "?", TRUE, FALSE); 161 break; 162 } 163 164 } 165 166 STATIC cmd_result_t 167 cmd_esw_dma_get_laddr(int unit, args_t *a, void **laddr) 168 { 169 char *arg; 170 171 if (laddr == NULL) { 172 return CMD_FAIL; 173 } 174 175 /* Parse the logical address */ 176 if ((arg = ARG_GET(a)) == NULL && 177 (arg = var_get(CMD_ESW_DMA_LADDR)) == NULL) { 178 return CMD_FAIL; 179 } 180 181 *laddr = (void *)parse_address(arg); 182 183 return CMD_OK; 184 } 185 186 STATIC void 187 cmd_esw_dma_set_laddr(void *laddr) 188 { 189 char buf[20]; 190 191 sal_sprintf(buf, "%p", laddr); 192 var_set(CMD_ESW_DMA_LADDR, buf, TRUE, FALSE); 193 } 194 195 STATIC cmd_result_t 196 cmd_esw_dma_get_paddr(int unit, args_t *a, uint32 *paddr) 197 { 198 char *arg; 199 200 if (paddr == NULL) { 201 return CMD_FAIL; 202 } 203 204 /* Parse the logical address */ 205 if ((arg = ARG_GET(a)) == NULL && 206 (arg = var_get(CMD_ESW_DMA_PADDR)) == NULL) { 207 return CMD_FAIL; 208 } 209 210 *paddr = parse_address(arg); 211 212 return CMD_OK; 213 } 214 215 STATIC void 216 cmd_esw_dma_set_paddr(uint32 paddr) 217 { 218 char buf[20]; 219 220 sal_sprintf(buf, "0x%08x", paddr); 221 var_set(CMD_ESW_DMA_PADDR, buf, TRUE, FALSE); 222 } 223 224 STATIC cmd_result_t 225 cmd_esw_dma_get_dcb_count(int unit, args_t *a, int *dcb_count) 226 { 227 char *arg; 228 229 if (dcb_count == NULL) { 230 return CMD_FAIL; 231 } 232 233 /* Parse the number of bytes to allocate */ 234 if ((arg = ARG_GET(a)) == NULL && 235 (arg = var_get(CMD_ESW_DMA_DCB_COUNT)) == NULL) { 236 return CMD_FAIL; 237 } 238 239 *dcb_count = parse_integer(arg); 240 241 return CMD_OK; 242 } 243 244 STATIC cmd_result_t 245 cmd_esw_dma_get_dv(int unit, args_t *a, dv_t **laddr) 246 { 247 char *arg; 248 249 if (laddr == NULL) { 250 return CMD_FAIL; 251 } 252 253 /* Parse the logical address */ 254 if ((arg = ARG_GET(a)) == NULL && 255 (arg = var_get(CMD_ESW_DMA_DV)) == NULL) { 256 return CMD_FAIL; 257 } 258 259 *laddr = (void *)parse_address(arg); 260 261 return CMD_OK; 262 } 263 264 STATIC void 265 cmd_esw_dma_set_dv(dv_t *dv, int dcb_size) 266 { 267 char buf[20]; 268 269 sal_sprintf(buf, "%p", (void *)dv); 270 var_set(CMD_ESW_DMA_DV, buf, TRUE, FALSE); 271 272 sal_sprintf(buf, "%p", dv->dv_dcb); 273 var_set(CMD_ESW_DMA_DCB, buf, TRUE, FALSE); 274 275 var_set_integer(CMD_ESW_DMA_DCB_COUNT, dv->dv_cnt, TRUE, FALSE); 276 var_set_integer(CMD_ESW_DMA_DCB_SIZE, dcb_size, TRUE, FALSE); 277 } 278 279 /* 280 * Subcommands 281 */ 282 283 STATIC cmd_result_t 284 cmd_esw_dma_alloc(int unit, args_t *a) 285 { 286 char *arg; 287 int size; 288 int count; 289 int alloc_count; 290 void *laddr; 291 292 if (!sh_check_attached(ARG_CMD(a), unit)) { 293 return CMD_FAIL; 294 } 295 296 if (cmd_esw_dma_get_size(unit, a, &size) != CMD_OK) { 297 return CMD_USAGE; 298 } 299 300 301 if (cmd_esw_dma_get_count(unit, a, &count) != CMD_OK || count == 0) { 302 return CMD_USAGE; 303 } 304 305 /* Get the region name if provided */ 306 arg = ARG_GET(a); 307 308 /* Allocate DMA-able memory */ 309 alloc_count = size * count; 310 laddr = soc_cm_salloc(unit, alloc_count, arg == NULL ? "diag-shell" : arg); 311 if (laddr == NULL) { 312 cli_out("Failed to allocate %d bytes of DMA-able memory\n", alloc_count); 313 return CMD_FAIL; 314 } 315 316 /* Print the results and set the variable for others to reference */ 317 cli_out("Allocated %d bytes of DMA-able memory at address %p\n", 318 alloc_count, laddr); 319 320 cmd_esw_dma_set_laddr(laddr); 321 cmd_esw_dma_set_count_size(count, size); 322 323 return CMD_OK; 324 } 325 326 STATIC cmd_result_t 327 cmd_esw_dma_free(int unit, args_t *a) 328 { 329 void *laddr = NULL; 330 331 if (!sh_check_attached(ARG_CMD(a), unit)) { 332 return CMD_FAIL; 333 } 334 335 if (cmd_esw_dma_get_laddr(unit, a, &laddr) != CMD_OK) 336 if (laddr == NULL) { 337 return CMD_FAIL; 338 } 339 340 soc_cm_sfree(unit, laddr); 341 342 return CMD_OK; 343 } 344 345 STATIC cmd_result_t 346 cmd_esw_dma_l2p(int unit, args_t *a) 347 { 348 void *laddr; 349 uint32 paddr; 350 351 if (!sh_check_attached(ARG_CMD(a), unit)) { 352 return CMD_FAIL; 353 } 354 355 if (cmd_esw_dma_get_laddr(unit, a, &laddr) != CMD_OK) { 356 return CMD_USAGE; 357 } 358 359 paddr = soc_cm_l2p(unit, laddr); 360 361 cli_out("l2p(%p) = 0x%08x\n", laddr, paddr); 362 363 cmd_esw_dma_set_paddr(paddr); 364 365 return CMD_OK; 366 } 367 368 STATIC cmd_result_t 369 cmd_esw_dma_p2l(int unit, args_t *a) 370 { 371 uint32 paddr; 372 void *laddr; 373 374 if (!sh_check_attached(ARG_CMD(a), unit)) { 375 return CMD_FAIL; 376 } 377 378 if (cmd_esw_dma_get_paddr(unit, a, &paddr) != CMD_OK) { 379 return CMD_USAGE; 380 } 381 382 laddr = soc_cm_p2l(unit, paddr); 383 384 cli_out("p2l(0x%08x) = %p\n", paddr, laddr); 385 386 cmd_esw_dma_set_laddr(laddr); 387 388 return CMD_OK; 389 } 390 391 STATIC cmd_result_t 392 cmd_esw_dma_flush(int unit, args_t *a) 393 { 394 int size; 395 int count; 396 void *laddr; 397 int flush_count; 398 int rv; 399 400 if (!sh_check_attached(ARG_CMD(a), unit)) { 401 return CMD_FAIL; 402 } 403 404 if (cmd_esw_dma_get_size(unit, a, &size) != CMD_OK) { 405 return CMD_USAGE; 406 } 407 408 if (cmd_esw_dma_get_laddr(unit, a, &laddr) != CMD_OK) { 409 return CMD_USAGE; 410 } 411 412 if (cmd_esw_dma_get_count(unit, a, &count) != CMD_OK) { 413 return CMD_USAGE; 414 } 415 416 flush_count = size * count; 417 418 rv = soc_cm_sflush(unit, laddr, flush_count); 419 cli_out("Flushing %d bytes starting at %p: %s\n", 420 flush_count, laddr, soc_errmsg(rv)); 421 if (SOC_FAILURE(rv)) { 422 return CMD_FAIL; 423 } 424 425 return CMD_OK; 426 } 427 428 STATIC cmd_result_t 429 cmd_esw_dma_inval(int unit, args_t *a) 430 { 431 int size; 432 int count; 433 void *laddr; 434 int inval_count; 435 int rv; 436 437 if (!sh_check_attached(ARG_CMD(a), unit)) { 438 return CMD_FAIL; 439 } 440 441 if (cmd_esw_dma_get_size(unit, a, &size) != CMD_OK) { 442 return CMD_USAGE; 443 } 444 445 if (cmd_esw_dma_get_laddr(unit, a, &laddr) != CMD_OK) { 446 return CMD_USAGE; 447 } 448 449 if (cmd_esw_dma_get_count(unit, a, &count) != CMD_OK) { 450 return CMD_USAGE; 451 } 452 453 inval_count = size * count; 454 455 rv = soc_cm_sinval(unit, laddr, inval_count); 456 cli_out("Invalidating %d bytes starting at %p: %s\n", 457 inval_count, laddr, soc_errmsg(rv)); 458 if (SOC_FAILURE(rv)) { 459 return CMD_FAIL; 460 } 461 462 return CMD_OK; 463 } 464 465 STATIC cmd_result_t 466 cmd_esw_dma_load(int unit, args_t *a) 467 { 468 void *laddr_v; 469 uint8 *laddr; 470 char *cp; 471 472 473 if (cmd_esw_dma_get_laddr(unit, a, &laddr_v) != CMD_OK) { 474 return CMD_USAGE; 475 } 476 477 laddr = (uint8 *)laddr_v; 478 479 while ((cp = ARG_GET(a)) != NULL) { 480 while (*cp) { 481 if (isspace((int)(*cp))) { 482 cp++; 483 } else { 484 if (!isxdigit((unsigned)*cp) || 485 !isxdigit((unsigned)*(cp+1))) { 486 cli_out("%s: Invalid character\n", ARG_CMD(a)); 487 return(CMD_FAIL); 488 } 489 490 *laddr++ = (xdigit2i(*cp) << 4) | xdigit2i(*(cp + 1)); 491 cp += 2; 492 } 493 } 494 } 495 496 return CMD_OK; 497 } 498 499 STATIC cmd_result_t 500 cmd_esw_dma_fill(int unit, args_t *a) 501 { 502 char *arg; 503 int size; 504 void *laddr; 505 int count; 506 uint32 val; 507 int i; 508 509 if (cmd_esw_dma_get_size(unit, a, &size) != CMD_OK) { 510 cli_out("Incorrect size specification\n"); 511 return CMD_USAGE; 512 } 513 514 if (cmd_esw_dma_get_laddr(unit, a, &laddr) != CMD_OK) { 515 cli_out("Invalid logical address specified\n"); 516 return CMD_USAGE; 517 } 518 519 if (cmd_esw_dma_get_count(unit, a, &count) != CMD_OK) { 520 cli_out("Invalid count specified\n"); 521 return CMD_USAGE; 522 } 523 524 if ((arg = ARG_GET(a)) == NULL) { 525 cli_out("No fill value specified\n"); 526 return CMD_USAGE; 527 } 528 529 val = parse_integer(arg); 530 531 switch (size) { 532 case 1: 533 sal_memset(laddr, val, count); 534 break; 535 case 2: 536 for(i=0; i < count; i++) { 537 ((uint16 *)laddr)[i] = (uint16)val; 538 } 539 break; 540 case 4: 541 for(i=0; i < count; i++) { 542 ((uint32 *)laddr)[i] = val; 543 } 544 break; 545 default: 546 return CMD_USAGE; 547 } 548 549 return CMD_OK; 550 } 551 552 STATIC cmd_result_t 553 cmd_esw_dma_edit(int unit, args_t *a) 554 { 555 void *laddr_v; 556 uint8 *laddr; 557 int size; 558 uint32 val; 559 char prompt[40]; 560 char dfl_str[40]; 561 562 if (cmd_esw_dma_get_size(unit, a, &size) != CMD_OK) { 563 return CMD_USAGE; 564 } 565 566 if (cmd_esw_dma_get_laddr(unit, a, &laddr_v) != CMD_OK) { 567 return CMD_USAGE; 568 } 569 570 cli_out("Editing memory starting at %p\n", laddr_v); 571 cli_out("Available commands:\n" 572 "\t'.', 'q' -- Exit\n" 573 "\t'-' -- Go to the previous byte/word/halfword\n" 574 "\t'<ENTER> -- Go to the next byte/word/halfword\n" 575 "\t'b' -- Edit bytes\n" 576 "\t'h' == Edit half-words\n" 577 "\t'w' -- Edit words\n\n"); 578 579 laddr = laddr_v; 580 581 for (;;) { 582 sal_sprintf(prompt, "%p ", (void *)laddr); 583 switch (size) { 584 case 1: 585 val = *(uint8 *)laddr; 586 sal_sprintf(dfl_str, "0x%02x", val); 587 break; 588 case 2: 589 val = *(uint16 *)laddr; 590 sal_sprintf(dfl_str, "0x%04x", val); 591 break; 592 case 4: 593 val = *(uint32 *)laddr; 594 sal_sprintf(dfl_str, "0x%08x", val); 595 break; 596 } 597 598 if (sal_readline(prompt, prompt, sizeof(prompt), dfl_str) == 0 || 599 prompt[0] == 0) { 600 cli_out("Aborted\n"); 601 break; 602 } 603 604 if (prompt[0] == '.' || prompt[0] == 'Q' || prompt[0] == 'q') { 605 break; 606 } 607 608 switch (prompt[0]) { 609 case '-': 610 laddr -= size; 611 continue; 612 break; 613 case 'W': 614 case 'w': 615 size = 4; 616 continue; 617 break; 618 case 'H': 619 case 'h': 620 size = 2; 621 continue; 622 break; 623 case 'B': 624 case 'b': 625 size = 1; 626 continue; 627 break; 628 default: 629 val = parse_integer(prompt); 630 break; 631 } 632 633 switch (size) { 634 case 1: 635 *(uint8 *)laddr = val; 636 break; 637 case 2: 638 *(uint16 *)laddr = val; 639 break; 640 case 4: 641 *(uint32 *)laddr = val; 642 break; 643 } 644 645 laddr += size; 646 } 647 648 return CMD_OK; 649 } 650 651 cmd_result_t 652 cmd_esw_dma_dv_alloc(int unit, args_t *a) 653 { 654 char *arg; 655 dvt_t op; 656 int dcb_count; 657 dv_t *dv; 658 659 if (!sh_check_attached(ARG_CMD(a), unit)) { 660 return CMD_FAIL; 661 } 662 663 if ((arg = ARG_GET(a)) == NULL) { 664 cli_out("DMA Vector (DV) type is not specified.\n"); 665 return CMD_USAGE; 666 } else { 667 switch (arg[0]) { 668 case 'r': case 'R': 669 op = DV_RX; 670 break; 671 case 't': case 'T': 672 op = DV_TX; 673 break; 674 default: 675 cli_out("Incorrect DV type <%s>. [r|t] expected.\n", arg); 676 return CMD_USAGE; 677 } 678 } 679 680 if (cmd_esw_dma_get_dcb_count(unit, a, &dcb_count) != CMD_OK) { 681 return CMD_USAGE; 682 } 683 684 dv = soc_dma_dv_alloc(unit, op, dcb_count); 685 if (dv == NULL) { 686 cli_out("Failed to allocate a DMA Vector (DV) with %d DCBs\n", 687 dcb_count); 688 return CMD_FAIL; 689 } else { 690 /* coverity[noescape] */ 691 cli_out("Allocated DMA Vector (DV) at %p. " 692 "%d DCBs (start %p, %d bytes)\n", 693 (void *)dv, dv->dv_cnt, (void *)dv->dv_dcb, SOC_DCB_SIZE(unit)); 694 cmd_esw_dma_set_dv(dv, SOC_DCB_SIZE(unit)); 695 } 696 697 return CMD_OK; 698 } 699 700 cmd_result_t 701 cmd_esw_dma_dcb_dump(int unit, args_t *a) 702 { 703 char *arg; 704 #if defined(BROADCOM_DEBUG) 705 dvt_t op; 706 #endif 707 dcb_t *dcb_laddr; 708 709 if (!sh_check_attached(ARG_CMD(a), unit)) { 710 return CMD_FAIL; 711 } 712 713 if ((arg = ARG_GET(a)) == NULL) { 714 cli_out("DCB type is not specified.\n"); 715 return CMD_USAGE; 716 } else { 717 switch (arg[0]) { 718 case 'r': case 'R': 719 #if defined(BROADCOM_DEBUG) 720 op = DV_RX; 721 #endif 722 break; 723 case 't': case 'T': 724 #if defined(BROADCOM_DEBUG) 725 op = DV_TX; 726 #endif 727 break; 728 default: 729 cli_out("Incorrect DCB type <%s>. [r|t] expected.\n", arg); 730 return CMD_USAGE; 731 } 732 } 733 734 if (cmd_esw_dma_get_laddr(unit, a, &dcb_laddr) != CMD_OK) { 735 cli_out("Cannot get DCB address\n"); 736 return CMD_FAIL; 737 } 738 739 #ifdef BROADCOM_DEBUG 740 cli_out("Dumping DCB at address %p:\n", dcb_laddr); 741 SOC_DCB_DUMP(unit, dcb_laddr, "", (op == DV_TX) ? 1 : 0); 742 #endif 743 744 return CMD_OK; 745 } 746 747 cmd_result_t 748 cmd_esw_dma_dv_free(int unit, args_t *a) 749 { 750 dv_t *dv; 751 752 if (!sh_check_attached(ARG_CMD(a), unit)) { 753 return CMD_FAIL; 754 } 755 756 if (cmd_esw_dma_get_dv(unit, a, &dv) != CMD_OK) { 757 return CMD_FAIL; 758 } 759 760 soc_dma_dv_free(unit, dv); 761 762 return CMD_OK; 763 } 764 765 cmd_result_t 766 cmd_esw_dma_addrx(int unit, args_t *a) 767 { 768 void *laddr; 769 dv_t *dv; 770 int count; 771 int rv; 772 773 if (!sh_check_attached(ARG_CMD(a), unit)) { 774 return CMD_FAIL; 775 } 776 777 if (cmd_esw_dma_get_dv(unit, a, &dv) != CMD_OK) { 778 cli_out("Cannot get DV address\n"); 779 return CMD_FAIL; 780 } 781 782 783 if (cmd_esw_dma_get_laddr(unit, a, &laddr) != CMD_OK) { 784 cli_out("Cannot get buffer address\n"); 785 return CMD_FAIL; 786 } 787 788 if (cmd_esw_dma_get_count(unit, a, &count) != CMD_OK) { 789 cli_out("Cannot get buffer size\n"); 790 return CMD_FAIL; 791 } 792 793 rv = SOC_DCB_ADDRX(unit, dv, (sal_vaddr_t)laddr, count, 0); 794 795 cli_out("Added DCB to RX DV. %d DCB remaining\n", rv); 796 797 return CMD_OK; 798 } 799 cmd_result_t 800 cmd_esw_dma(int unit, args_t *a) 801 { 802 char *subcmd; 803 804 if ((subcmd = ARG_GET(a)) == NULL) { 805 return CMD_USAGE; 806 } 807 808 if (sal_strcasecmp(subcmd, "alloc") == 0) { 809 return cmd_esw_dma_alloc(unit, a); 810 } else if (sal_strcasecmp(subcmd, "free") == 0) { 811 return cmd_esw_dma_free(unit, a); 812 } else if (sal_strcasecmp(subcmd, "l2p") == 0) { 813 return cmd_esw_dma_l2p(unit, a); 814 } else if (sal_strcasecmp(subcmd, "p2l") == 0) { 815 return cmd_esw_dma_p2l(unit, a); 816 } else if (sal_strcasecmp(subcmd, "flush") == 0) { 817 return cmd_esw_dma_flush(unit, a); 818 } else if (sal_strcasecmp(subcmd, "inval") == 0) { 819 return cmd_esw_dma_inval(unit, a); 820 } else if (sal_strcasecmp(subcmd, "fill") == 0) { 821 return cmd_esw_dma_fill(unit, a); 822 } else if (sal_strcasecmp(subcmd, "load") == 0) { 823 return cmd_esw_dma_load(unit, a); 824 } else if (sal_strcasecmp(subcmd, "edit") == 0) { 825 return cmd_esw_dma_edit(unit, a); 826 } else if (sal_strcasecmp(subcmd, "dvalloc") == 0) { 827 return cmd_esw_dma_dv_alloc(unit, a); 828 } else if (sal_strcasecmp(subcmd, "dvfree") == 0) { 829 return cmd_esw_dma_dv_free(unit, a); 830 } else if (sal_strcasecmp(subcmd, "dcbdump") == 0) { 831 return cmd_esw_dma_dcb_dump(unit, a); 832 } else if (sal_strcasecmp(subcmd, "addrx") == 0) { 833 return cmd_esw_dma_addrx(unit, a); 834 } 835 836 cli_out("Unrecognized subcommand <%s>\n", subcmd); 837 838 return CMD_USAGE; 839 }