1/* 2 * Copyright (c) 2014, 2015, The Linux Foundation. All rights reserved. 3 * Permission to use, copy, modify, and/or distribute this software for 4 * any purpose with or without fee is hereby granted, provided that the 5 * above copyright notice and this permission notice appear in all copies. 6 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 7 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 8 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 9 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 10 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 11 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 12 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 13 */ 14 15 16/** 17 * @defgroup dess_fdb DESS_FDB 18 * @{ 19 */ 20#include "sw.h" 21#include "hsl.h" 22#include "hsl_dev.h" 23#include "hsl_port_prop.h" 24#include "dess_fdb.h" 25#include "dess_reg.h" 26#include "dess_fdb_prv.h" 27 28static sw_error_t 29_dess_wl_feature_check(a_uint32_t dev_id) 30{ 31 sw_error_t rv; 32 a_uint32_t entry; 33 34 HSL_REG_FIELD_GET(rv, dev_id, MASK_CTL, 0, DEVICE_ID, 35 (a_uint8_t *) (&entry), sizeof (a_uint32_t)); 36 SW_RTN_ON_ERROR(rv); 37 38 if (DESS_DEVICE_ID == entry) 39 { 40 return SW_OK; 41 } 42 else 43 { 44 return SW_NOT_SUPPORTED; 45 } 46} 47 48static a_bool_t 49_dess_fdb_is_zeroaddr(fal_mac_addr_t addr) 50{ 51 a_uint32_t i; 52 53 for (i = 0; i < 6; i++) 54 { 55 if (addr.uc[i]) 56 { 57 return A_FALSE; 58 } 59 } 60 61 return A_TRUE; 62} 63 64static void 65_dess_fdb_fill_addr(fal_mac_addr_t addr, a_uint32_t * reg0, a_uint32_t * reg1) 66{ 67 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE0, addr.uc[0], *reg1); 68 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_ADDR_BYTE1, addr.uc[1], *reg1); 69 70 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE2, addr.uc[2], *reg0); 71 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE3, addr.uc[3], *reg0); 72 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE4, addr.uc[4], *reg0); 73 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC0, AT_ADDR_BYTE5, addr.uc[5], *reg0); 74 75 return; 76} 77 78static sw_error_t 79_dess_atu_sw_to_hw(a_uint32_t dev_id, const fal_fdb_entry_t * entry, 80 a_uint32_t reg[]) 81{ 82 a_uint32_t port; 83 sw_error_t rv; 84 85 if (A_TRUE == entry->white_list_en) 86 { 87 rv = _dess_wl_feature_check(dev_id); 88 SW_RTN_ON_ERROR(rv); 89 90 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, WL_EN, 1, reg[2]); 91 } 92 93 if (FAL_SVL_FID == entry->fid) 94 { 95 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); 96 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); 97 } 98 else if (DESS_MAX_FID >= entry->fid) 99 { 100 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, (entry->fid), reg[2]); 101 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); 102 } 103 else 104 { 105 return SW_BAD_PARAM; 106 } 107 108 if (A_FALSE == entry->portmap_en) 109 { 110 if (A_TRUE != 111 hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) 112 { 113 return SW_BAD_PARAM; 114 } 115 116 port = 0x1UL << entry->port.id; 117 } 118 else 119 { 120 if (A_FALSE == 121 hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) 122 { 123 return SW_BAD_PARAM; 124 } 125 126 port = entry->port.map; 127 } 128 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, DES_PORT, port, reg[1]); 129 130 if (FAL_MAC_CPY_TO_CPU == entry->dacmd) 131 { 132 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, COPY_TO_CPU, 1, reg[2]); 133 } 134 else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) 135 { 136 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, 1, reg[2]); 137 } 138 else if (FAL_MAC_FRWRD != entry->dacmd) 139 { 140 return SW_NOT_SUPPORTED; 141 } 142 143 if (A_TRUE == entry->leaky_en) 144 { 145 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 1, reg[2]); 146 } 147 else 148 { 149 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LEAKY_EN, 0, reg[2]); 150 } 151 152 if (A_TRUE == entry->static_en) 153 { 154 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 15, reg[2]); 155 } 156 else 157 { 158 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 7, reg[2]); 159 } 160 161 if (FAL_MAC_DROP == entry->sacmd) 162 { 163 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, SA_DROP_EN, 1, reg[1]); 164 } 165 else if (FAL_MAC_FRWRD != entry->sacmd) 166 { 167 return SW_NOT_SUPPORTED; 168 } 169 170 if (A_TRUE == entry->mirror_en) 171 { 172 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, MIRROR_EN, 1, reg[1]); 173 } 174 175 if (A_TRUE == entry->cross_pt_state) 176 { 177 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, CROSS_PT, 1, reg[1]); 178 } 179 else 180 { 181 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, CROSS_PT, 0, reg[1]); 182 } 183 184 if (A_TRUE == entry->da_pri_en) 185 { 186 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI_EN, 1, reg[1]); 187 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI, (entry->da_queue & 0x7), 188 reg[1]); 189 } 190 else 191 { 192 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_PRI_EN, 0, reg[1]); 193 } 194 195 if (A_TRUE == entry->load_balance_en) 196 { 197 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LOAD_BALANCE_EN, 1, reg[2]); 198 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LOAD_BALANCE, 199 (entry->load_balance & 0x3), reg[2]); 200 } 201 else 202 { 203 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, LOAD_BALANCE_EN, 0, reg[2]); 204 } 205 206 _dess_fdb_fill_addr(entry->addr, ®[0], ®[1]); 207 return SW_OK; 208} 209 210static void 211_dess_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) 212{ 213 a_uint32_t i, data; 214 215 aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); 216 217 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_SVL_EN, data, reg[1]); 218 if (data) 219 { 220 entry->fid = FAL_SVL_FID; 221 } 222 else 223 { 224 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_VID, data, reg[2]); 225 entry->fid = data; 226 } 227 228 entry->dacmd = FAL_MAC_FRWRD; 229 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, COPY_TO_CPU, data, reg[2]); 230 if (1 == data) 231 { 232 entry->dacmd = FAL_MAC_CPY_TO_CPU; 233 } 234 235 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, REDRCT_TO_CPU, data, reg[2]); 236 if (1 == data) 237 { 238 entry->dacmd = FAL_MAC_RDT_TO_CPU; 239 } 240 241 entry->sacmd = FAL_MAC_FRWRD; 242 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, SA_DROP_EN, data, reg[1]); 243 if (1 == data) 244 { 245 entry->sacmd = FAL_MAC_DROP; 246 } 247 248 entry->leaky_en = A_FALSE; 249 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LEAKY_EN, data, reg[2]); 250 if (1 == data) 251 { 252 entry->leaky_en = A_TRUE; 253 } 254 255 entry->static_en = A_FALSE; 256 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, data, reg[2]); 257 if (0xf == data) 258 { 259 entry->static_en = A_TRUE; 260 } 261 262 entry->mirror_en = A_FALSE; 263 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, MIRROR_EN, data, reg[1]); 264 if (1 == data) 265 { 266 entry->mirror_en = A_TRUE; 267 } 268 269 entry->da_pri_en = A_FALSE; 270 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_PRI_EN, data, reg[1]); 271 if (1 == data) 272 { 273 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, AT_PRI, data, reg[1]); 274 entry->da_pri_en = A_TRUE; 275 entry->da_queue = data & 0x7; 276 } 277 278 entry->cross_pt_state = A_FALSE; 279 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, CROSS_PT, data, reg[1]); 280 if (1 == data) 281 { 282 entry->cross_pt_state = A_TRUE; 283 } 284 285 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, DES_PORT, data, reg[1]); 286 entry->portmap_en = A_TRUE; 287 entry->port.map = data; 288 289 for (i = 2; i < 6; i++) 290 { 291 entry->addr.uc[i] = (reg[0] >> ((5 - i) << 3)) & 0xff; 292 } 293 294 for (i = 0; i < 2; i++) 295 { 296 entry->addr.uc[i] = (reg[1] >> ((1 - i) << 3)) & 0xff; 297 } 298 299 entry->white_list_en = A_FALSE; 300 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, WL_EN, data, reg[2]); 301 if (1 == data) 302 { 303 entry->white_list_en = A_TRUE; 304 } 305 306 entry->load_balance_en = A_FALSE; 307 entry->load_balance = 0; 308 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LOAD_BALANCE_EN, data, reg[2]); 309 if (1 == data) 310 { 311 entry->load_balance_en = A_TRUE; 312 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, LOAD_BALANCE, data, reg[2]); 313 entry->load_balance = data; 314 } 315 316 return; 317} 318 319static sw_error_t 320_dess_atu_down_to_hw(a_uint32_t dev_id, a_uint32_t reg[]) 321{ 322 sw_error_t rv; 323 324 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, 325 (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); 326 SW_RTN_ON_ERROR(rv); 327 328 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, 329 (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); 330 SW_RTN_ON_ERROR(rv); 331 332 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, 333 (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); 334 SW_RTN_ON_ERROR(rv); 335 336 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, 337 (a_uint8_t *) (®[3]), sizeof (a_uint32_t)); 338 return rv; 339} 340 341static sw_error_t 342_dess_atu_up_to_sw(a_uint32_t dev_id, a_uint32_t reg[]) 343{ 344 sw_error_t rv; 345 346 HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC0, 0, 347 (a_uint8_t *) (®[0]), sizeof (a_uint32_t)); 348 SW_RTN_ON_ERROR(rv); 349 350 HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, 351 (a_uint8_t *) (®[1]), sizeof (a_uint32_t)); 352 SW_RTN_ON_ERROR(rv); 353 354 HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC2, 0, 355 (a_uint8_t *) (®[2]), sizeof (a_uint32_t)); 356 SW_RTN_ON_ERROR(rv); 357 358 HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, 359 (a_uint8_t *) (®[3]), sizeof (a_uint32_t)); 360 return rv; 361} 362 363static sw_error_t 364_dess_fdb_commit(a_uint32_t dev_id, a_uint32_t op) 365{ 366 sw_error_t rv; 367 a_uint32_t busy = 1; 368 a_uint32_t full_vio; 369 a_uint32_t i = 2000; 370 a_uint32_t entry; 371 a_uint32_t hwop = op; 372 373 while (busy && --i) 374 { 375 HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, 376 (a_uint8_t *) (&entry), sizeof (a_uint32_t)); 377 SW_RTN_ON_ERROR(rv); 378 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_BUSY, busy, entry); 379 } 380 381 if (0 == i) 382 { 383 return SW_BUSY; 384 } 385 386 if (ARL_FIRST_ENTRY == op) 387 { 388 hwop = ARL_NEXT_ENTRY; 389 } 390 391 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_BUSY, 1, entry); 392 393 if (ARL_FLUSH_PORT_AND_STATIC == hwop) 394 { 395 hwop = ARL_FLUSH_PORT_UNICAST; 396 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, FLUSH_ST_EN, 1, entry); 397 } 398 399 if (ARL_FLUSH_PORT_NO_STATIC == hwop) 400 { 401 hwop = ARL_FLUSH_PORT_UNICAST; 402 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, FLUSH_ST_EN, 0, entry); 403 } 404 405 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_FUNC, hwop, entry); 406 407 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, 408 (a_uint8_t *) (&entry), sizeof (a_uint32_t)); 409 SW_RTN_ON_ERROR(rv); 410 411 busy = 1; 412 i = 2000; 413 while (busy && --i) 414 { 415 HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC3, 0, 416 (a_uint8_t *) (&entry), sizeof (a_uint32_t)); 417 SW_RTN_ON_ERROR(rv); 418 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_BUSY, busy, entry); 419 } 420 421 if (0 == i) 422 { 423 return SW_FAIL; 424 } 425 426 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC3, AT_FULL_VIO, full_vio, entry); 427 428 if (full_vio) 429 { 430 /* must clear AT_FULL_VOI bit */ 431 entry = 0x1000; 432 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, 433 (a_uint8_t *) (&entry), sizeof (a_uint32_t)); 434 SW_RTN_ON_ERROR(rv); 435 436 if (ARL_LOAD_ENTRY == hwop) 437 { 438 return SW_FULL; 439 } 440 else if ((ARL_PURGE_ENTRY == hwop) 441 || (ARL_FLUSH_PORT_UNICAST == hwop)) 442 { 443 return SW_NOT_FOUND; 444 } 445 else 446 { 447 return SW_FAIL; 448 } 449 } 450 451 return SW_OK; 452} 453 454static sw_error_t 455_dess_fdb_get(a_uint32_t dev_id, fal_fdb_op_t * option, fal_fdb_entry_t * entry, 456 a_uint32_t hwop) 457{ 458 sw_error_t rv; 459 a_uint32_t i, port = 0, status, reg[4] = { 0 }; 460 461 HSL_DEV_ID_CHECK(dev_id); 462 463 if (A_TRUE == option->port_en) 464 { 465 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_EN, 1, reg[3]); 466 if (A_FALSE == entry->portmap_en) 467 { 468 if (A_TRUE != 469 hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) 470 { 471 return SW_BAD_PARAM; 472 } 473 port = entry->port.id; 474 } 475 else 476 { 477 if (A_FALSE == 478 hsl_mports_prop_check(dev_id, entry->port.map, 479 HSL_PP_INCL_CPU)) 480 { 481 return SW_BAD_PARAM; 482 } 483 484 status = 0; 485 for (i = 0; i < SW_MAX_NR_PORT; i++) 486 { 487 if ((entry->port.map) & (0x1UL << i)) 488 { 489 if (status) 490 { 491 return SW_BAD_PARAM; 492 } 493 port = i; 494 status = 1; 495 } 496 } 497 } 498 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, port, reg[3]); 499 } 500 501 if (A_TRUE == option->fid_en) 502 { 503 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_VID_EN, 1, reg[3]); 504 } 505 506 if (A_TRUE == option->multicast_en) 507 { 508 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_MULTI_EN, 1, reg[3]); 509 } 510 511 if (FAL_SVL_FID == entry->fid) 512 { 513 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); 514 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); 515 } 516 else if (DESS_MAX_FID >= entry->fid) 517 { 518 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, entry->fid, reg[2]); 519 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); 520 } 521 else 522 { 523 return SW_BAD_PARAM; 524 } 525 526 if (ARL_FIRST_ENTRY != hwop) 527 { 528 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_STATUS, 0xf, reg[2]); 529 } 530 531 _dess_fdb_fill_addr(entry->addr, ®[0], ®[1]); 532 533 rv = _dess_atu_down_to_hw(dev_id, reg); 534 SW_RTN_ON_ERROR(rv); 535 536 rv = _dess_fdb_commit(dev_id, hwop); 537 SW_RTN_ON_ERROR(rv); 538 539 rv = _dess_atu_up_to_sw(dev_id, reg); 540 SW_RTN_ON_ERROR(rv); 541 542 _dess_atu_hw_to_sw(reg, entry); 543 544 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC2, AT_STATUS, status, reg[2]); 545 if ((A_TRUE == _dess_fdb_is_zeroaddr(entry->addr)) 546 && (0 == status)) 547 { 548 if (ARL_NEXT_ENTRY == hwop) 549 { 550 return SW_NO_MORE; 551 } 552 else 553 { 554 return SW_NOT_FOUND; 555 } 556 } 557 else 558 { 559 return SW_OK; 560 } 561 562 return SW_OK; 563} 564 565static sw_error_t 566_dess_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) 567{ 568 sw_error_t rv; 569 a_uint32_t reg[4] = { 0 }; 570 571 HSL_DEV_ID_CHECK(dev_id); 572 573 rv = _dess_atu_sw_to_hw(dev_id, entry, reg); 574 SW_RTN_ON_ERROR(rv); 575 576 rv = _dess_atu_down_to_hw(dev_id, reg); 577 SW_RTN_ON_ERROR(rv); 578 579 rv = _dess_fdb_commit(dev_id, ARL_LOAD_ENTRY); 580 return rv; 581} 582 583static sw_error_t 584_dess_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) 585{ 586 sw_error_t rv; 587 588 HSL_DEV_ID_CHECK(dev_id); 589 590 if (FAL_FDB_DEL_STATIC & flag) 591 { 592 rv = _dess_fdb_commit(dev_id, ARL_FLUSH_ALL); 593 } 594 else 595 { 596 rv = _dess_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); 597 } 598 599 return rv; 600} 601 602static sw_error_t 603_dess_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) 604{ 605 sw_error_t rv; 606 a_uint32_t reg = 0; 607 608 HSL_DEV_ID_CHECK(dev_id); 609 610 if (A_FALSE == hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 611 { 612 return SW_BAD_PARAM; 613 } 614 615 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, port_id, reg); 616 617 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC3, 0, (a_uint8_t *) (®), 618 sizeof (a_uint32_t)); 619 SW_RTN_ON_ERROR(rv); 620 621 if (FAL_FDB_DEL_STATIC & flag) 622 { 623 rv = _dess_fdb_commit(dev_id, ARL_FLUSH_PORT_AND_STATIC); 624 } 625 else 626 { 627 rv = _dess_fdb_commit(dev_id, ARL_FLUSH_PORT_NO_STATIC); 628 } 629 630 return rv; 631} 632 633static sw_error_t 634_dess_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) 635{ 636 sw_error_t rv; 637 a_uint32_t reg0 = 0, reg1 = 0, reg2 = 0; 638 639 HSL_DEV_ID_CHECK(dev_id); 640 641 _dess_fdb_fill_addr(entry->addr, ®0, ®1); 642 643 if (FAL_SVL_FID == entry->fid) 644 { 645 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg2); 646 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg1); 647 } 648 else if (DESS_MAX_FID >= entry->fid) 649 { 650 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, (entry->fid), reg2); 651 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg1); 652 } 653 else 654 { 655 return SW_BAD_PARAM; 656 } 657 658 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC2, 0, (a_uint8_t *) (®2), 659 sizeof (a_uint32_t)); 660 SW_RTN_ON_ERROR(rv); 661 662 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, (a_uint8_t *) (®1), 663 sizeof (a_uint32_t)); 664 SW_RTN_ON_ERROR(rv); 665 666 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC0, 0, (a_uint8_t *) (®0), 667 sizeof (a_uint32_t)); 668 SW_RTN_ON_ERROR(rv); 669 670 rv = _dess_fdb_commit(dev_id, ARL_PURGE_ENTRY); 671 return rv; 672} 673 674static sw_error_t 675_dess_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) 676{ 677 sw_error_t rv; 678 fal_fdb_op_t option; 679 680 aos_mem_zero(&option, sizeof (fal_fdb_op_t)); 681 rv = _dess_fdb_get(dev_id, &option, entry, ARL_FIND_ENTRY); 682 return rv; 683} 684 685static sw_error_t 686_dess_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * option, 687 fal_fdb_entry_t * entry) 688{ 689 sw_error_t rv; 690 691 rv = _dess_fdb_get(dev_id, option, entry, ARL_NEXT_ENTRY); 692 return rv; 693} 694 695static sw_error_t 696_dess_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, 697 fal_fdb_entry_t * entry) 698{ 699 sw_error_t rv; 700 701 rv = _dess_fdb_get(dev_id, option, entry, ARL_FIRST_ENTRY); 702 return rv; 703} 704 705static sw_error_t 706_dess_fdb_transfer(a_uint32_t dev_id, fal_port_t old_port, fal_port_t new_port, 707 a_uint32_t fid, fal_fdb_op_t * option) 708{ 709 sw_error_t rv; 710 a_uint32_t reg[4] = { 0 }; 711 712 if (A_TRUE == option->port_en) 713 { 714 return SW_NOT_SUPPORTED; 715 } 716 717 if (A_TRUE == option->fid_en) 718 { 719 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_VID_EN, 1, reg[3]); 720 } 721 722 if (A_TRUE == option->multicast_en) 723 { 724 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_MULTI_EN, 1, reg[3]); 725 } 726 727 if (FAL_SVL_FID == fid) 728 { 729 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, 0, reg[2]); 730 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 1, reg[1]); 731 } 732 else if (DESS_MAX_FID >= fid) 733 { 734 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC2, AT_VID, fid, reg[2]); 735 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, AT_SVL_EN, 0, reg[1]); 736 } 737 else 738 { 739 return SW_BAD_PARAM; 740 } 741 742 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, AT_PORT_NUM, old_port, reg[3]); 743 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC3, NEW_PORT_NUM, new_port, reg[3]); 744 745 rv = _dess_atu_down_to_hw(dev_id, reg); 746 SW_RTN_ON_ERROR(rv); 747 748 rv = _dess_fdb_commit(dev_id, ARL_TRANSFER_ENTRY); 749 return rv; 750} 751 752static sw_error_t 753_dess_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) 754{ 755 a_uint32_t data; 756 sw_error_t rv; 757 758 HSL_DEV_ID_CHECK(dev_id); 759 760 if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 761 { 762 return SW_BAD_PARAM; 763 } 764 765 if (A_TRUE == enable) 766 { 767 data = 1; 768 } 769 else if (A_FALSE == enable) 770 { 771 data = 0; 772 } 773 else 774 { 775 return SW_BAD_PARAM; 776 } 777 778 HSL_REG_FIELD_SET(rv, dev_id, PORT_LOOKUP_CTL, port_id, LEARN_EN, 779 (a_uint8_t *) (&data), sizeof (a_uint32_t)); 780 return rv; 781} 782 783static sw_error_t 784_dess_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, 785 a_bool_t * enable) 786{ 787 a_uint32_t data; 788 sw_error_t rv; 789 790 HSL_DEV_ID_CHECK(dev_id); 791 792 if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 793 { 794 return SW_BAD_PARAM; 795 } 796 797 HSL_REG_FIELD_GET(rv, dev_id, PORT_LOOKUP_CTL, port_id, LEARN_EN, 798 (a_uint8_t *) (&data), sizeof (a_uint32_t)); 799 SW_RTN_ON_ERROR(rv); 800 801 if (1 == data) 802 { 803 *enable = A_TRUE; 804 } 805 else 806 { 807 *enable = A_FALSE; 808 } 809 810 return SW_OK; 811} 812 813static sw_error_t 814_dess_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) 815{ 816 a_uint32_t data; 817 sw_error_t rv; 818 819 HSL_DEV_ID_CHECK(dev_id); 820 821 if (A_TRUE == enable) 822 { 823 data = 1; 824 } 825 else if (A_FALSE == enable) 826 { 827 data = 0; 828 } 829 else 830 { 831 return SW_BAD_PARAM; 832 } 833 834 HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, 835 (a_uint8_t *) (&data), sizeof (a_uint32_t)); 836 return rv; 837} 838 839static sw_error_t 840_dess_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode) 841{ 842 a_uint32_t data; 843 sw_error_t rv; 844 845 HSL_DEV_ID_CHECK(dev_id); 846 847 data = smode; 848 849 HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, ARL_INI_EN, 850 (a_uint8_t *) (&data), sizeof (a_uint32_t)); 851 return rv; 852} 853 854static sw_error_t 855_dess_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode* smode) 856{ 857 a_uint32_t data; 858 sw_error_t rv; 859 860 HSL_DEV_ID_CHECK(dev_id); 861 862 HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, ARL_INI_EN, 863 (a_uint8_t *) (&data), sizeof (a_uint32_t)); 864 865 *smode = data; 866 867 return rv; 868} 869 870 871 872static sw_error_t 873_dess_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) 874{ 875 a_uint32_t data; 876 sw_error_t rv; 877 878 HSL_DEV_ID_CHECK(dev_id); 879 880 HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_EN, 881 (a_uint8_t *) (&data), sizeof (a_uint32_t)); 882 SW_RTN_ON_ERROR(rv); 883 884 if (1 == data) 885 { 886 *enable = A_TRUE; 887 } 888 else 889 { 890 *enable = A_FALSE; 891 } 892 893 return SW_OK; 894} 895 896static sw_error_t 897_dess_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) 898{ 899 a_uint32_t data; 900 sw_error_t rv; 901 902 HSL_DEV_ID_CHECK(dev_id); 903 904 if ((65535 * 7 < *time) || (7 > *time)) 905 { 906 return SW_BAD_PARAM; 907 } 908 data = *time / 7; 909 *time = data * 7; 910 HSL_REG_FIELD_SET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, 911 (a_uint8_t *) (&data), sizeof (a_uint32_t)); 912 return rv; 913} 914 915static sw_error_t 916_dess_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time) 917{ 918 a_uint32_t data; 919 sw_error_t rv; 920 921 HSL_DEV_ID_CHECK(dev_id); 922 923 HSL_REG_FIELD_GET(rv, dev_id, ADDR_TABLE_CTL, 0, AGE_TIME, 924 (a_uint8_t *) (&data), sizeof (a_uint32_t)); 925 SW_RTN_ON_ERROR(rv); 926 927 *time = data * 7; 928 return SW_OK; 929} 930 931static sw_error_t 932_dess_port_fdb_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, 933 a_bool_t enable, a_uint32_t cnt) 934{ 935 sw_error_t rv; 936 a_uint32_t reg; 937 938 HSL_DEV_ID_CHECK(dev_id); 939 940 if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 941 { 942 return SW_BAD_PARAM; 943 } 944 945 HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, 946 (a_uint8_t *) (®), sizeof (a_uint32_t)); 947 SW_RTN_ON_ERROR(rv); 948 949 if (A_TRUE == enable) 950 { 951 if (DESS_MAX_PORT_LEARN_LIMIT_CNT < cnt) 952 { 953 return SW_BAD_PARAM; 954 } 955 SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, 1, reg); 956 SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, cnt, reg); 957 } 958 else if (A_FALSE == enable) 959 { 960 SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, 0, reg); 961 SW_SET_REG_BY_FIELD(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, 0, reg); 962 } 963 else 964 { 965 return SW_BAD_PARAM; 966 } 967 968 HSL_REG_ENTRY_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, 969 (a_uint8_t *) (®), sizeof (a_uint32_t)); 970 return rv; 971} 972 973static sw_error_t 974_dess_port_fdb_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, 975 a_bool_t * enable, a_uint32_t * cnt) 976{ 977 sw_error_t rv; 978 a_uint32_t data, reg; 979 980 HSL_DEV_ID_CHECK(dev_id); 981 982 if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 983 { 984 return SW_BAD_PARAM; 985 } 986 987 HSL_REG_ENTRY_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, 988 (a_uint8_t *) (®), sizeof (a_uint32_t)); 989 SW_RTN_ON_ERROR(rv); 990 991 SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, SA_LEARN_LIMIT_EN, data, reg); 992 if (data) 993 { 994 SW_GET_FIELD_BY_REG(PORT_LEARN_LIMIT_CTL, SA_LEARN_CNT, data, reg); 995 *enable = A_TRUE; 996 *cnt = data; 997 } 998 else 999 { 1000 *enable = A_FALSE; 1001 *cnt = 0; 1002 } 1003 1004 return SW_OK; 1005} 1006 1007static sw_error_t 1008_dess_port_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_port_t port_id, 1009 fal_fwd_cmd_t cmd) 1010{ 1011 sw_error_t rv; 1012 a_uint32_t data = 0; 1013 1014 HSL_DEV_ID_CHECK(dev_id); 1015 1016 if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 1017 { 1018 return SW_BAD_PARAM; 1019 } 1020 1021 if (FAL_MAC_DROP == cmd) 1022 { 1023 data = 1; 1024 } 1025 else if (FAL_MAC_RDT_TO_CPU == cmd) 1026 { 1027 data = 0; 1028 } 1029 else 1030 { 1031 return SW_NOT_SUPPORTED; 1032 } 1033 1034 HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, 1035 SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), 1036 sizeof (a_uint32_t)); 1037 return rv; 1038} 1039 1040static sw_error_t 1041_dess_port_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_port_t port_id, 1042 fal_fwd_cmd_t * cmd) 1043{ 1044 sw_error_t rv; 1045 a_uint32_t data = 0; 1046 1047 HSL_DEV_ID_CHECK(dev_id); 1048 1049 if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 1050 { 1051 return SW_BAD_PARAM; 1052 } 1053 1054 HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, 1055 SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), 1056 sizeof (a_uint32_t)); 1057 SW_RTN_ON_ERROR(rv); 1058 1059 if (data) 1060 { 1061 *cmd = FAL_MAC_DROP; 1062 } 1063 else 1064 { 1065 *cmd = FAL_MAC_RDT_TO_CPU; 1066 } 1067 1068 return SW_OK; 1069} 1070 1071static sw_error_t 1072_dess_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt) 1073{ 1074 sw_error_t rv; 1075 a_uint32_t reg; 1076 1077 HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, 1078 (a_uint8_t *) (®), sizeof (a_uint32_t)); 1079 SW_RTN_ON_ERROR(rv); 1080 1081 if (A_TRUE == enable) 1082 { 1083 if (DESS_MAX_LEARN_LIMIT_CNT < cnt) 1084 { 1085 return SW_BAD_PARAM; 1086 } 1087 SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, 1, 1088 reg); 1089 SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, cnt, reg); 1090 } 1091 else if (A_FALSE == enable) 1092 { 1093 SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, 0, 1094 reg); 1095 SW_SET_REG_BY_FIELD(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, 0, reg); 1096 } 1097 else 1098 { 1099 return SW_BAD_PARAM; 1100 } 1101 1102 HSL_REG_ENTRY_SET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, 1103 (a_uint8_t *) (®), sizeof (a_uint32_t)); 1104 return rv; 1105} 1106 1107static sw_error_t 1108_dess_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, 1109 a_uint32_t * cnt) 1110{ 1111 sw_error_t rv; 1112 a_uint32_t data, reg; 1113 1114 HSL_REG_ENTRY_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, 1115 (a_uint8_t *) (®), sizeof (a_uint32_t)); 1116 SW_RTN_ON_ERROR(rv); 1117 1118 SW_GET_FIELD_BY_REG(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_LIMIT_EN, data, 1119 reg); 1120 if (data) 1121 { 1122 SW_GET_FIELD_BY_REG(GLOBAL_LEARN_LIMIT_CTL, GOL_SA_LEARN_CNT, data, 1123 reg); 1124 *enable = A_TRUE; 1125 *cnt = data; 1126 } 1127 else 1128 { 1129 *enable = A_FALSE; 1130 *cnt = 0; 1131 } 1132 1133 return SW_OK; 1134} 1135 1136static sw_error_t 1137_dess_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) 1138{ 1139 sw_error_t rv; 1140 a_uint32_t data = 0; 1141 1142 HSL_DEV_ID_CHECK(dev_id); 1143 1144 if (FAL_MAC_DROP == cmd) 1145 { 1146 data = 1; 1147 } 1148 else if (FAL_MAC_RDT_TO_CPU == cmd) 1149 { 1150 data = 0; 1151 } 1152 else 1153 { 1154 return SW_NOT_SUPPORTED; 1155 } 1156 1157 HSL_REG_FIELD_SET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, 1158 GOL_SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), 1159 sizeof (a_uint32_t)); 1160 return rv; 1161} 1162 1163static sw_error_t 1164_dess_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) 1165{ 1166 sw_error_t rv; 1167 a_uint32_t data = 0; 1168 1169 HSL_DEV_ID_CHECK(dev_id); 1170 1171 HSL_REG_FIELD_GET(rv, dev_id, GLOBAL_LEARN_LIMIT_CTL, 0, 1172 GOL_SA_LEARN_LIMIT_DROP_EN, (a_uint8_t *) (&data), 1173 sizeof (a_uint32_t)); 1174 SW_RTN_ON_ERROR(rv); 1175 1176 if (data) 1177 { 1178 *cmd = FAL_MAC_DROP; 1179 } 1180 else 1181 { 1182 *cmd = FAL_MAC_RDT_TO_CPU; 1183 } 1184 1185 return SW_OK; 1186} 1187 1188#define DESS_RESV_ADDR_NUM 32 1189#define RESV_ADDR_TBL0_ADDR 0x3c000 1190#define RESV_ADDR_TBL1_ADDR 0x3c004 1191#define RESV_ADDR_TBL2_ADDR 0x3c008 1192 1193static void 1194_dess_resv_addr_parse(const a_uint32_t reg[], fal_mac_addr_t * addr) 1195{ 1196 a_uint32_t i; 1197 1198 for (i = 2; i < 6; i++) 1199 { 1200 addr->uc[i] = (reg[0] >> ((5 - i) << 3)) & 0xff; 1201 } 1202 1203 for (i = 0; i < 2; i++) 1204 { 1205 addr->uc[i] = (reg[1] >> ((1 - i) << 3)) & 0xff; 1206 } 1207} 1208 1209static sw_error_t 1210_dess_resv_atu_sw_to_hw(a_uint32_t dev_id, fal_fdb_entry_t * entry, 1211 a_uint32_t reg[]) 1212{ 1213 a_uint32_t port; 1214 1215 if (A_FALSE == entry->portmap_en) 1216 { 1217 if (A_TRUE != 1218 hsl_port_prop_check(dev_id, entry->port.id, HSL_PP_INCL_CPU)) 1219 { 1220 return SW_BAD_PARAM; 1221 } 1222 port = 0x1UL << entry->port.id; 1223 } 1224 else 1225 { 1226 if (A_FALSE == 1227 hsl_mports_prop_check(dev_id, entry->port.map, HSL_PP_INCL_CPU)) 1228 { 1229 return SW_BAD_PARAM; 1230 } 1231 port = entry->port.map; 1232 } 1233 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_DES_PORT, port, reg[1]); 1234 1235 if (FAL_MAC_CPY_TO_CPU == entry->dacmd) 1236 { 1237 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_COPY_TO_CPU, 1, reg[1]); 1238 } 1239 else if (FAL_MAC_RDT_TO_CPU == entry->dacmd) 1240 { 1241 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_REDRCT_TO_CPU, 1, reg[1]); 1242 } 1243 else if (FAL_MAC_FRWRD != entry->dacmd) 1244 { 1245 return SW_NOT_SUPPORTED; 1246 } 1247 1248 if (FAL_MAC_FRWRD != entry->sacmd) 1249 { 1250 return SW_NOT_SUPPORTED; 1251 } 1252 1253 if (A_TRUE == entry->leaky_en) 1254 { 1255 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_LEAKY_EN, 1, reg[1]); 1256 } 1257 else 1258 { 1259 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_LEAKY_EN, 0, reg[1]); 1260 } 1261 1262 if (A_TRUE != entry->static_en) 1263 { 1264 return SW_NOT_SUPPORTED; 1265 } 1266 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL2, RESV_STATUS, 1, reg[2]); 1267 1268 if (A_TRUE == entry->mirror_en) 1269 { 1270 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_MIRROR_EN, 1, reg[1]); 1271 } 1272 1273 if (A_TRUE == entry->cross_pt_state) 1274 { 1275 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_CROSS_PT, 1, reg[1]); 1276 } 1277 1278 if (A_TRUE == entry->da_pri_en) 1279 { 1280 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_PRI_EN, 1, reg[1]); 1281 SW_SET_REG_BY_FIELD(RESV_ADDR_TBL1, RESV_PRI, (entry->da_queue & 0x7), 1282 reg[1]); 1283 } 1284 1285 _dess_fdb_fill_addr(entry->addr, ®[0], ®[1]); 1286 return SW_OK; 1287} 1288 1289static void 1290_dess_resv_atu_hw_to_sw(const a_uint32_t reg[], fal_fdb_entry_t * entry) 1291{ 1292 a_uint32_t data; 1293 1294 aos_mem_zero(entry, sizeof (fal_fdb_entry_t)); 1295 1296 entry->fid = FAL_SVL_FID; 1297 1298 entry->dacmd = FAL_MAC_FRWRD; 1299 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_COPY_TO_CPU, data, reg[1]); 1300 if (1 == data) 1301 { 1302 entry->dacmd = FAL_MAC_CPY_TO_CPU; 1303 } 1304 1305 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_REDRCT_TO_CPU, data, reg[1]); 1306 if (1 == data) 1307 { 1308 entry->dacmd = FAL_MAC_RDT_TO_CPU; 1309 } 1310 1311 entry->sacmd = FAL_MAC_FRWRD; 1312 1313 entry->leaky_en = A_FALSE; 1314 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_LEAKY_EN, data, reg[1]); 1315 if (1 == data) 1316 { 1317 entry->leaky_en = A_TRUE; 1318 } 1319 1320 entry->static_en = A_TRUE; 1321 1322 entry->mirror_en = A_FALSE; 1323 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_MIRROR_EN, data, reg[1]); 1324 if (1 == data) 1325 { 1326 entry->mirror_en = A_TRUE; 1327 } 1328 1329 entry->da_pri_en = A_FALSE; 1330 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_PRI_EN, data, reg[1]); 1331 if (1 == data) 1332 { 1333 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_PRI, data, reg[1]); 1334 entry->da_pri_en = A_TRUE; 1335 entry->da_queue = data & 0x7; 1336 } 1337 1338 entry->cross_pt_state = A_FALSE; 1339 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_CROSS_PT, data, reg[1]); 1340 if (1 == data) 1341 { 1342 entry->cross_pt_state = A_TRUE; 1343 } 1344 1345 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL1, RESV_DES_PORT, data, reg[1]); 1346 entry->portmap_en = A_TRUE; 1347 entry->port.map = data; 1348 1349 _dess_resv_addr_parse(reg, &(entry->addr)); 1350 return; 1351} 1352 1353static sw_error_t 1354_dess_fdb_resv_commit(a_uint32_t dev_id, fal_fdb_entry_t * entry, a_uint32_t op, 1355 a_uint32_t * empty) 1356{ 1357 a_uint32_t index, addr, data, tbl[3] = { 0 }; 1358 sw_error_t rv; 1359 fal_mac_addr_t mac_tmp; 1360 1361 *empty = DESS_RESV_ADDR_NUM; 1362 for (index = 0; index < DESS_RESV_ADDR_NUM; index++) 1363 { 1364 addr = RESV_ADDR_TBL2_ADDR + (index << 4); 1365 HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), 1366 (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); 1367 SW_RTN_ON_ERROR(rv); 1368 1369 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL2, RESV_STATUS, data, tbl[2]); 1370 if (data) 1371 { 1372 addr = RESV_ADDR_TBL0_ADDR + (index << 4); 1373 HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), 1374 (a_uint8_t *) (&(tbl[0])), 1375 sizeof (a_uint32_t)); 1376 SW_RTN_ON_ERROR(rv); 1377 1378 addr = RESV_ADDR_TBL1_ADDR + (index << 4); 1379 HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), 1380 (a_uint8_t *) (&(tbl[1])), 1381 sizeof (a_uint32_t)); 1382 SW_RTN_ON_ERROR(rv); 1383 1384 _dess_resv_addr_parse(tbl, &mac_tmp); 1385 if (!aos_mem_cmp 1386 ((void *) &(entry->addr), (void *) &mac_tmp, 1387 sizeof (fal_mac_addr_t))) 1388 { 1389 if (ARL_PURGE_ENTRY == op) 1390 { 1391 addr = RESV_ADDR_TBL2_ADDR + (index << 4); 1392 tbl[2] = 0; 1393 HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), 1394 (a_uint8_t *) (&(tbl[2])), 1395 sizeof (a_uint32_t)); 1396 return rv; 1397 } 1398 else if (ARL_LOAD_ENTRY == op) 1399 { 1400 return SW_ALREADY_EXIST; 1401 } 1402 else if (ARL_FIND_ENTRY == op) 1403 { 1404 _dess_resv_atu_hw_to_sw(tbl, entry); 1405 return SW_OK; 1406 } 1407 } 1408 } 1409 else 1410 { 1411 *empty = index; 1412 } 1413 } 1414 1415 return SW_NOT_FOUND; 1416} 1417 1418static sw_error_t 1419_dess_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) 1420{ 1421 sw_error_t rv; 1422 a_uint32_t i, empty, addr, tbl[3] = { 0 }; 1423 1424 rv = _dess_resv_atu_sw_to_hw(dev_id, entry, tbl); 1425 SW_RTN_ON_ERROR(rv); 1426 1427 rv = _dess_fdb_resv_commit(dev_id, entry, ARL_LOAD_ENTRY, &empty); 1428 if (SW_ALREADY_EXIST == rv) 1429 { 1430 return rv; 1431 } 1432 1433 if (DESS_RESV_ADDR_NUM == empty) 1434 { 1435 return SW_NO_RESOURCE; 1436 } 1437 1438 for (i = 0; i < 3; i++) 1439 { 1440 addr = RESV_ADDR_TBL0_ADDR + (empty << 4) + (i << 2); 1441 HSL_REG_ENTRY_GEN_SET(rv, dev_id, addr, sizeof (a_uint32_t), 1442 (a_uint8_t *) (&(tbl[i])), sizeof (a_uint32_t)); 1443 SW_RTN_ON_ERROR(rv); 1444 } 1445 1446 return SW_OK; 1447} 1448 1449static sw_error_t 1450_dess_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) 1451{ 1452 sw_error_t rv; 1453 a_uint32_t empty; 1454 1455 rv = _dess_fdb_resv_commit(dev_id, entry, ARL_PURGE_ENTRY, &empty); 1456 return rv; 1457} 1458 1459static sw_error_t 1460_dess_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) 1461{ 1462 sw_error_t rv; 1463 a_uint32_t empty; 1464 1465 rv = _dess_fdb_resv_commit(dev_id, entry, ARL_FIND_ENTRY, &empty); 1466 return rv; 1467} 1468 1469static sw_error_t 1470_dess_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, 1471 fal_fdb_entry_t * entry) 1472{ 1473 a_uint32_t index, addr, data, tbl[3] = { 0 }; 1474 sw_error_t rv; 1475 1476 if ((NULL == iterator) || (NULL == entry)) 1477 { 1478 return SW_BAD_PTR; 1479 } 1480 1481 if (DESS_RESV_ADDR_NUM < *iterator) 1482 { 1483 return SW_BAD_PARAM; 1484 } 1485 1486 for (index = *iterator; index < DESS_RESV_ADDR_NUM; index++) 1487 { 1488 addr = RESV_ADDR_TBL2_ADDR + (index << 4); 1489 HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), 1490 (a_uint8_t *) (&(tbl[2])), sizeof (a_uint32_t)); 1491 SW_RTN_ON_ERROR(rv); 1492 1493 SW_GET_FIELD_BY_REG(RESV_ADDR_TBL2, RESV_STATUS, data, tbl[2]); 1494 if (data) 1495 { 1496 addr = RESV_ADDR_TBL0_ADDR + (index << 4); 1497 HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), 1498 (a_uint8_t *) (&(tbl[0])), 1499 sizeof (a_uint32_t)); 1500 SW_RTN_ON_ERROR(rv); 1501 1502 addr = RESV_ADDR_TBL1_ADDR + (index << 4); 1503 HSL_REG_ENTRY_GEN_GET(rv, dev_id, addr, sizeof (a_uint32_t), 1504 (a_uint8_t *) (&(tbl[1])), 1505 sizeof (a_uint32_t)); 1506 SW_RTN_ON_ERROR(rv); 1507 1508 _dess_resv_atu_hw_to_sw(tbl, entry); 1509 break; 1510 } 1511 } 1512 1513 if (DESS_RESV_ADDR_NUM == index) 1514 { 1515 return SW_NO_MORE; 1516 } 1517 1518 *iterator = index + 1; 1519 return SW_OK; 1520} 1521 1522static sw_error_t 1523_dess_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, 1524 a_bool_t enable) 1525{ 1526 a_uint32_t data; 1527 sw_error_t rv; 1528 1529 HSL_DEV_ID_CHECK(dev_id); 1530 1531 if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 1532 { 1533 return SW_BAD_PARAM; 1534 } 1535 1536 if (A_TRUE == enable) 1537 { 1538 data = 0xf; 1539 } 1540 else if (A_FALSE == enable) 1541 { 1542 data = 0x7; 1543 } 1544 else 1545 { 1546 return SW_BAD_PARAM; 1547 } 1548 1549 HSL_REG_FIELD_SET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, 1550 SA_LEARN_STATUS, (a_uint8_t *) (&data), 1551 sizeof (a_uint32_t)); 1552 return rv; 1553} 1554 1555static sw_error_t 1556_dess_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, 1557 a_bool_t * enable) 1558{ 1559 a_uint32_t data; 1560 sw_error_t rv; 1561 1562 HSL_DEV_ID_CHECK(dev_id); 1563 1564 if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 1565 { 1566 return SW_BAD_PARAM; 1567 } 1568 1569 HSL_REG_FIELD_GET(rv, dev_id, PORT_LEARN_LIMIT_CTL, port_id, 1570 SA_LEARN_STATUS, (a_uint8_t *) (&data), 1571 sizeof (a_uint32_t)); 1572 SW_RTN_ON_ERROR(rv); 1573 1574 if (0xf == data) 1575 { 1576 *enable = A_TRUE; 1577 } 1578 else 1579 { 1580 *enable = A_FALSE; 1581 } 1582 1583 return SW_OK; 1584} 1585 1586static sw_error_t 1587_dess_fdb_port_update(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id, a_uint32_t op) 1588{ 1589 sw_error_t rv; 1590 fal_fdb_entry_t entry; 1591 fal_fdb_op_t option; 1592 a_uint32_t reg, port; 1593 1594 HSL_DEV_ID_CHECK(dev_id); 1595 1596 if (FAL_SVL_FID < fid) 1597 { 1598 return SW_BAD_PARAM; 1599 } 1600 1601 if (A_TRUE != hsl_port_prop_check(dev_id, port_id, HSL_PP_INCL_CPU)) 1602 { 1603 return SW_BAD_PARAM; 1604 } 1605 1606 aos_mem_zero(&option, sizeof(fal_fdb_op_t)); 1607 aos_mem_copy(&(entry.addr), addr, sizeof(fal_mac_addr_t)); 1608 entry.fid = fid & 0xffff; 1609 rv = _dess_fdb_get(dev_id, &option, &entry, ARL_FIND_ENTRY); 1610 SW_RTN_ON_ERROR(rv); 1611 1612 HSL_REG_ENTRY_GET(rv, dev_id, ADDR_TABLE_FUNC1, 0, 1613 (a_uint8_t *) (®), sizeof (a_uint32_t)); 1614 SW_RTN_ON_ERROR(rv); 1615 1616 SW_GET_FIELD_BY_REG(ADDR_TABLE_FUNC1, DES_PORT, port, reg); 1617 if (op) 1618 { 1619 port |= (0x1 << port_id); 1620 } 1621 else 1622 { 1623 port &= (~(0x1 << port_id)); 1624 } 1625 SW_SET_REG_BY_FIELD(ADDR_TABLE_FUNC1, DES_PORT, port, reg); 1626 HSL_REG_ENTRY_SET(rv, dev_id, ADDR_TABLE_FUNC1, 0, 1627 (a_uint8_t *) (®), sizeof (a_uint32_t)); 1628 1629 rv = _dess_fdb_commit(dev_id, ARL_LOAD_ENTRY); 1630 return rv; 1631} 1632#define FDB_RFS_ADD 1 1633#define FDB_RFS_DEL 2 1634static sw_error_t 1635_dess_fdb_rfs_update(fal_fdb_rfs_t *rfs, fal_fdb_entry_t *entry, char op) 1636{ 1637 _dess_fdb_del_by_mac(0, entry); 1638 if(FDB_RFS_ADD == op) { 1639 entry->static_en = 1; 1640 entry->load_balance_en = 1; 1641 entry->load_balance = rfs->load_balance; 1642 } else { 1643 entry->static_en = 0; 1644 entry->load_balance_en = 0; 1645 } 1646 return _dess_fdb_add(0, entry); 1647} 1648 1649 1650static sw_error_t 1651_dess_fdb_rfs_set(a_uint32_t dev_id, fal_fdb_rfs_t *rfs) 1652{ 1653 1654 fal_fdb_entry_t entry; 1655 sw_error_t ret; 1656 1657 memset(&entry, 0, sizeof(entry)); 1658 1659 entry.addr = rfs->addr; 1660 entry.fid = rfs->fid; 1661 ret = _dess_fdb_find(0, &entry); 1662 if(!ret) { 1663 return _dess_fdb_rfs_update(rfs, &entry, FDB_RFS_ADD); 1664 } else { 1665 entry.addr = rfs->addr; 1666 entry.fid = rfs->fid; 1667 entry.load_balance_en = 1; 1668 entry.load_balance = rfs->load_balance; 1669 entry.static_en = 1; 1670 entry.port.map = 1; 1671 entry.portmap_en = 1; 1672 return _dess_fdb_add(0, &entry); 1673 } 1674} 1675 1676static sw_error_t 1677_dess_fdb_rfs_del(a_uint32_t dev_id, fal_fdb_rfs_t *rfs) 1678{ 1679 1680 fal_fdb_entry_t entry; 1681 sw_error_t ret; 1682 1683 memset(&entry, 0, sizeof(entry)); 1684 entry.addr = rfs->addr; 1685 entry.fid = rfs->fid; 1686 ret = _dess_fdb_find(0, &entry); 1687 if(!ret) { 1688 return _dess_fdb_rfs_update(rfs, &entry, FDB_RFS_DEL); 1689 } else { 1690 return ret; 1691 } 1692} 1693 1694 1695 1696sw_error_t 1697inter_dess_fdb_flush(a_uint32_t dev_id, a_uint32_t flag) 1698{ 1699 if (FAL_FDB_DEL_STATIC & flag) 1700 { 1701 return _dess_fdb_commit(dev_id, ARL_FLUSH_ALL); 1702 } 1703 else 1704 { 1705 return _dess_fdb_commit(dev_id, ARL_FLUSH_ALL_UNLOCK); 1706 } 1707} 1708 1709/** 1710 * @brief Add a Fdb entry 1711 * @param[in] dev_id device id 1712 * @param[in] entry fdb entry 1713 * @return SW_OK or error code 1714 */ 1715HSL_LOCAL sw_error_t 1716dess_fdb_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) 1717{ 1718 sw_error_t rv; 1719 1720 HSL_API_LOCK; 1721 rv = _dess_fdb_add(dev_id, entry); 1722 HSL_API_UNLOCK; 1723 return rv; 1724} 1725 1726/** 1727 * @brief Delete all Fdb entries 1728 * @details Comments: 1729 * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb 1730 * entries otherwise only delete dynamic entries. 1731 * @param[in] dev_id device id 1732 * @param[in] flag delete operation option 1733 * @return SW_OK or error code 1734 */ 1735HSL_LOCAL sw_error_t 1736dess_fdb_del_all(a_uint32_t dev_id, a_uint32_t flag) 1737{ 1738 sw_error_t rv; 1739 1740 HSL_API_LOCK; 1741 rv = _dess_fdb_del_all(dev_id, flag); 1742 HSL_API_UNLOCK; 1743 return rv; 1744} 1745 1746/** 1747 * @brief Delete Fdb entries on a particular port 1748 * @details Comments: 1749 * If set FAL_FDB_DEL_STATIC bit in flag which means delete all fdb 1750 * entries otherwise only delete dynamic entries. 1751 * @param[in] dev_id device id 1752 * @param[in] port_id port id 1753 * @param[in] flag delete operation option 1754 * @return SW_OK or error code 1755 */ 1756HSL_LOCAL sw_error_t 1757dess_fdb_del_by_port(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) 1758{ 1759 sw_error_t rv; 1760 1761 HSL_API_LOCK; 1762 rv = _dess_fdb_del_by_port(dev_id, port_id, flag); 1763 HSL_API_UNLOCK; 1764 return rv; 1765} 1766 1767/** 1768 * @brief Delete a particular Fdb entry through mac address 1769 * @details Comments: 1770 * Only addr field in entry is meaning. For IVL learning vid or fid field 1771 * also is meaning. 1772 * @param[in] dev_id device id 1773 * @param[in] entry fdb entry 1774 * @return SW_OK or error code 1775 */ 1776HSL_LOCAL sw_error_t 1777dess_fdb_del_by_mac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) 1778{ 1779 sw_error_t rv; 1780 1781 HSL_API_LOCK; 1782 rv = _dess_fdb_del_by_mac(dev_id, entry); 1783 HSL_API_UNLOCK; 1784 return rv; 1785} 1786 1787/** 1788 * @brief Find a particular Fdb entry from device through mac address. 1789 * @details Comments: 1790 For input parameter only addr field in entry is meaning. 1791 * @param[in] dev_id device id 1792 * @param[in] entry fdb entry 1793 * @param[out] entry fdb entry 1794 * @return SW_OK or error code 1795 */ 1796HSL_LOCAL sw_error_t 1797dess_fdb_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) 1798{ 1799 sw_error_t rv; 1800 1801 HSL_API_LOCK; 1802 rv = _dess_fdb_find(dev_id, entry); 1803 HSL_API_UNLOCK; 1804 return rv; 1805} 1806 1807/** 1808 * @brief Get next Fdb entry from a particular device 1809 * @param[in] dev_id device id 1810 * @param[in] option next operation options 1811 * @param[out] entry fdb entry 1812 * @return SW_OK or error code 1813 */ 1814HSL_LOCAL sw_error_t 1815dess_fdb_extend_next(a_uint32_t dev_id, fal_fdb_op_t * option, 1816 fal_fdb_entry_t * entry) 1817{ 1818 sw_error_t rv; 1819 1820 HSL_API_LOCK; 1821 rv = _dess_fdb_extend_next(dev_id, option, entry); 1822 HSL_API_UNLOCK; 1823 return rv; 1824} 1825 1826/** 1827 * @brief Get first Fdb entry from a particular device 1828 * @param[in] dev_id device id 1829 * @param[in] option first operation options 1830 * @param[out] entry fdb entry 1831 * @return SW_OK or error code 1832 */ 1833HSL_LOCAL sw_error_t 1834dess_fdb_extend_first(a_uint32_t dev_id, fal_fdb_op_t * option, 1835 fal_fdb_entry_t * entry) 1836{ 1837 sw_error_t rv; 1838 1839 HSL_API_LOCK; 1840 rv = _dess_fdb_extend_first(dev_id, option, entry); 1841 HSL_API_UNLOCK; 1842 return rv; 1843} 1844 1845/** 1846 * @brief Transfer fdb entries port information on a particular device. 1847 * @param[in] dev_id device id 1848 * @param[in] old_port source port id 1849 * @param[in] new_port destination port id 1850 * @param[in] fid filter database id 1851 * @param[in] option transfer operation options 1852 * @return SW_OK or error code 1853 */ 1854HSL_LOCAL sw_error_t 1855dess_fdb_transfer(a_uint32_t dev_id, fal_port_t old_port, fal_port_t new_port, 1856 a_uint32_t fid, fal_fdb_op_t * option) 1857{ 1858 sw_error_t rv; 1859 1860 HSL_API_LOCK; 1861 rv = _dess_fdb_transfer(dev_id, old_port, new_port, fid, option); 1862 HSL_API_UNLOCK; 1863 return rv; 1864} 1865 1866/** 1867 * @brief Set dynamic address learning status on a particular port. 1868 * @details Comments: 1869 * This operation will enable or disable dynamic address learning 1870 * feature on a particular port. 1871 * @param[in] dev_id device id 1872 * @param[in] port_id port id 1873 * @param[in] enable enable or disable 1874 * @return SW_OK or error code 1875 */ 1876HSL_LOCAL sw_error_t 1877dess_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) 1878{ 1879 sw_error_t rv; 1880 1881 HSL_API_LOCK; 1882 rv = _dess_fdb_port_learn_set(dev_id, port_id, enable); 1883 HSL_API_UNLOCK; 1884 return rv; 1885} 1886 1887/** 1888 * @brief Get dynamic address learning status on a particular port. 1889 * @param[in] dev_id device id 1890 * @param[in] port_id port id 1891 * @param[out] enable A_TRUE or A_FALSE 1892 * @return SW_OK or error code 1893 */ 1894HSL_LOCAL sw_error_t 1895dess_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, 1896 a_bool_t * enable) 1897{ 1898 sw_error_t rv; 1899 1900 HSL_API_LOCK; 1901 rv = _dess_fdb_port_learn_get(dev_id, port_id, enable); 1902 HSL_API_UNLOCK; 1903 return rv; 1904} 1905 1906/** 1907 * @brief Set dynamic address aging status on particular device. 1908 * @details Comments: 1909 * This operation will enable or disable dynamic address aging 1910 * feature on particular device. 1911 * @param[in] dev_id device id 1912 * @param[in] enable enable or disable 1913 * @return SW_OK or error code 1914 */ 1915HSL_LOCAL sw_error_t 1916dess_fdb_age_ctrl_set(a_uint32_t dev_id, a_bool_t enable) 1917{ 1918 sw_error_t rv; 1919 1920 HSL_API_LOCK; 1921 rv = _dess_fdb_age_ctrl_set(dev_id, enable); 1922 HSL_API_UNLOCK; 1923 return rv; 1924} 1925 1926/** 1927 * @brief Get dynamic address aging status on particular device. 1928 * @param[in] dev_id device id 1929 * @param[in] enable enable or disable 1930 * @return SW_OK or error code 1931 */ 1932HSL_LOCAL sw_error_t 1933dess_fdb_age_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) 1934{ 1935 sw_error_t rv; 1936 1937 HSL_API_LOCK; 1938 rv = _dess_fdb_age_ctrl_get(dev_id, enable); 1939 HSL_API_UNLOCK; 1940 return rv; 1941} 1942 1943/** 1944 * @brief set arl search mode as ivl or svl when vlan invalid. 1945 * @param[in] dev_id device id 1946 * @param[in] smode INVALID_VLAN_IVL or INVALID_VLAN_SVL 1947 * @return SW_OK or error code 1948 */ 1949HSL_LOCAL sw_error_t 1950dess_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode) 1951{ 1952 sw_error_t rv; 1953 1954 HSL_API_LOCK; 1955 rv = _dess_fdb_vlan_ivl_svl_set(dev_id, smode); 1956 HSL_API_UNLOCK; 1957 return rv; 1958} 1959 1960/** 1961 * @brief get arl search mode when vlan invalid. 1962 * @param[in] dev_id device id 1963 * @param[out] smode INVALID_VLAN_IVL or INVALID_VLAN_SVL 1964 * @return SW_OK or error code 1965 */ 1966HSL_LOCAL sw_error_t 1967dess_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode* smode) 1968{ 1969 sw_error_t rv; 1970 1971 HSL_API_LOCK; 1972 rv = _dess_fdb_vlan_ivl_svl_get(dev_id, smode); 1973 HSL_API_UNLOCK; 1974 return rv; 1975} 1976 1977 1978 1979/** 1980 * @brief Set dynamic address aging time on a particular device. 1981 * @details Comments: 1982 * This operation will set dynamic address aging time on a particular device. 1983 * The unit of time is second. Because different device has differnet 1984 * hardware granularity function will return actual time in hardware. 1985 * @param[in] dev_id device id 1986 * @param time aging time 1987 * @return SW_OK or error code 1988 */ 1989HSL_LOCAL sw_error_t 1990dess_fdb_age_time_set(a_uint32_t dev_id, a_uint32_t * time) 1991{ 1992 sw_error_t rv; 1993 1994 HSL_API_LOCK; 1995 rv = _dess_fdb_age_time_set(dev_id, time); 1996 HSL_API_UNLOCK; 1997 return rv; 1998} 1999 2000/** 2001 * @brief Get dynamic address aging time on a particular device. 2002 * @param[in] dev_id device id 2003 * @param[out] time aging time 2004 * @return SW_OK or error code 2005 */ 2006HSL_LOCAL sw_error_t 2007dess_fdb_age_time_get(a_uint32_t dev_id, a_uint32_t * time) 2008{ 2009 sw_error_t rv; 2010 2011 HSL_API_LOCK; 2012 rv = _dess_fdb_age_time_get(dev_id, time); 2013 HSL_API_UNLOCK; 2014 return rv; 2015} 2016 2017/** 2018 * @brief Set dynamic address learning count limit on a particular port. 2019 * @param[in] dev_id device id 2020 * @param[in] port_id port id 2021 * @param[in] enable A_TRUE or A_FALSE 2022 * @param[in] cnt limit count 2023 * @return SW_OK or error code 2024 */ 2025HSL_LOCAL sw_error_t 2026dess_port_fdb_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, 2027 a_bool_t enable, a_uint32_t cnt) 2028{ 2029 sw_error_t rv; 2030 2031 HSL_API_LOCK; 2032 rv = _dess_port_fdb_learn_limit_set(dev_id, port_id, enable, cnt); 2033 HSL_API_UNLOCK; 2034 return rv; 2035} 2036 2037/** 2038 * @brief Get dynamic address learning count limit on a particular port. 2039 * @param[in] dev_id device id 2040 * @param[in] port_id port id 2041 * @param[out] enable A_TRUE or A_FALSE 2042 * @param[out] cnt limit count 2043 * @return SW_OK or error code 2044 */ 2045HSL_LOCAL sw_error_t 2046dess_port_fdb_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, 2047 a_bool_t * enable, a_uint32_t * cnt) 2048{ 2049 sw_error_t rv; 2050 2051 HSL_API_LOCK; 2052 rv = _dess_port_fdb_learn_limit_get(dev_id, port_id, enable, cnt); 2053 HSL_API_UNLOCK; 2054 return rv; 2055} 2056 2057/** 2058 * @brief Set dynamic address learning count exceed command on a particular port. 2059 * @param[in] dev_id device id 2060 * @param[in] port_id port id 2061 * @param[in] cmd forwarding command 2062 * @return SW_OK or error code 2063 */ 2064HSL_LOCAL sw_error_t 2065dess_port_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_port_t port_id, 2066 fal_fwd_cmd_t cmd) 2067{ 2068 sw_error_t rv; 2069 2070 HSL_API_LOCK; 2071 rv = _dess_port_fdb_learn_exceed_cmd_set(dev_id, port_id, cmd); 2072 HSL_API_UNLOCK; 2073 return rv; 2074} 2075 2076/** 2077 * @brief Get dynamic address learning count exceed command on a particular port. 2078 * @param[in] dev_id device id 2079 * @param[in] port_id port id 2080 * @param[out] cmd forwarding command 2081 * @return SW_OK or error code 2082 */ 2083HSL_LOCAL sw_error_t 2084dess_port_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_port_t port_id, 2085 fal_fwd_cmd_t * cmd) 2086{ 2087 sw_error_t rv; 2088 2089 HSL_API_LOCK; 2090 rv = _dess_port_fdb_learn_exceed_cmd_get(dev_id, port_id, cmd); 2091 HSL_API_UNLOCK; 2092 return rv; 2093} 2094 2095/** 2096 * @brief Set dynamic address learning count limit on a particular device. 2097 * @param[in] dev_id device id 2098 * @param[in] enable A_TRUE or A_FALSE 2099 * @param[in] cnt limit count 2100 * @return SW_OK or error code 2101 */ 2102HSL_LOCAL sw_error_t 2103dess_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt) 2104{ 2105 sw_error_t rv; 2106 2107 HSL_API_LOCK; 2108 rv = _dess_fdb_learn_limit_set(dev_id, enable, cnt); 2109 HSL_API_UNLOCK; 2110 return rv; 2111} 2112 2113/** 2114 * @brief Get dynamic address learning count limit on a particular device. 2115 * @param[in] dev_id device id 2116 * @param[in] enable A_TRUE or A_FALSE 2117 * @param[in] cnt limit count 2118 * @return SW_OK or error code 2119 */ 2120HSL_LOCAL sw_error_t 2121dess_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * cnt) 2122{ 2123 sw_error_t rv; 2124 2125 HSL_API_LOCK; 2126 rv = _dess_fdb_learn_limit_get(dev_id, enable, cnt); 2127 HSL_API_UNLOCK; 2128 return rv; 2129} 2130 2131/** 2132 * @brief Set dynamic address learning count exceed command on a particular device. 2133 * @param[in] dev_id device id 2134 * @param[in] cmd forwarding command 2135 * @return SW_OK or error code 2136 */ 2137HSL_LOCAL sw_error_t 2138dess_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) 2139{ 2140 sw_error_t rv; 2141 2142 HSL_API_LOCK; 2143 rv = _dess_fdb_learn_exceed_cmd_set(dev_id, cmd); 2144 HSL_API_UNLOCK; 2145 return rv; 2146} 2147 2148/** 2149 * @brief Get dynamic address learning count exceed command on a particular device. 2150 * @param[in] dev_id device id 2151 * @param[out] cmd forwarding command 2152 * @return SW_OK or error code 2153 */ 2154HSL_LOCAL sw_error_t 2155dess_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) 2156{ 2157 sw_error_t rv; 2158 2159 HSL_API_LOCK; 2160 rv = _dess_fdb_learn_exceed_cmd_get(dev_id, cmd); 2161 HSL_API_UNLOCK; 2162 return rv; 2163} 2164 2165/** 2166 * @brief Add a particular reserve Fdb entry 2167 * @param[in] dev_id device id 2168 * @param[in] entry reserve fdb entry 2169 * @return SW_OK or error code 2170 */ 2171HSL_LOCAL sw_error_t 2172dess_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) 2173{ 2174 sw_error_t rv; 2175 2176 HSL_API_LOCK; 2177 rv = _dess_fdb_resv_add(dev_id, entry); 2178 HSL_API_UNLOCK; 2179 return rv; 2180} 2181 2182/** 2183 * @brief Delete a particular reserve Fdb entry through mac address 2184 * @param[in] dev_id device id 2185 * @param[in] entry reserve fdb entry 2186 * @return SW_OK or error code 2187 */ 2188HSL_LOCAL sw_error_t 2189dess_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) 2190{ 2191 sw_error_t rv; 2192 2193 HSL_API_LOCK; 2194 rv = _dess_fdb_resv_del(dev_id, entry); 2195 HSL_API_UNLOCK; 2196 return rv; 2197} 2198 2199/** 2200 * @brief Find a particular reserve Fdb entry through mac address 2201 * @param[in] dev_id device id 2202 * @param[in] entry reserve fdb entry 2203 * @param[out] entry reserve fdb entry 2204 * @return SW_OK or error code 2205 */ 2206HSL_LOCAL sw_error_t 2207dess_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) 2208{ 2209 sw_error_t rv; 2210 2211 HSL_API_LOCK; 2212 rv = _dess_fdb_resv_find(dev_id, entry); 2213 HSL_API_UNLOCK; 2214 return rv; 2215} 2216 2217/** 2218 * @brief Iterate all reserve fdb entries on a particular device. 2219 * @param[in] dev_id device id 2220 * @param[in] iterator reserve fdb entry index if it's zero means get the first entry 2221 * @param[out] iterator next valid fdb entry index 2222 * @param[out] entry reserve fdb entry 2223 * @return SW_OK or error code 2224 */ 2225HSL_LOCAL sw_error_t 2226dess_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, 2227 fal_fdb_entry_t * entry) 2228{ 2229 sw_error_t rv; 2230 2231 HSL_API_LOCK; 2232 rv = _dess_fdb_resv_iterate(dev_id, iterator, entry); 2233 HSL_API_UNLOCK; 2234 return rv; 2235} 2236 2237/** 2238 * @brief Set the static status of fdb entries which learned by hardware on a particular port. 2239 * @param[in] dev_id device id 2240 * @param[in] port_id port id 2241 * @param[in] enable A_TRUE or A_FALSE 2242 * @return SW_OK or error code 2243 */ 2244HSL_LOCAL sw_error_t 2245dess_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, 2246 a_bool_t enable) 2247{ 2248 sw_error_t rv; 2249 2250 HSL_API_LOCK; 2251 rv = _dess_fdb_port_learn_static_set(dev_id, port_id, enable); 2252 HSL_API_UNLOCK; 2253 return rv; 2254} 2255 2256/** 2257 * @brief Get the static status of fdb entries which learned by hardware on a particular port. 2258 * @param[in] dev_id device id 2259 * @param[in] port_id port id 2260 * @param[out] enable A_TRUE or A_FALSE 2261 * @return SW_OK or error code 2262 */ 2263HSL_LOCAL sw_error_t 2264dess_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, 2265 a_bool_t * enable) 2266{ 2267 sw_error_t rv; 2268 2269 HSL_API_LOCK; 2270 rv = _dess_fdb_port_learn_static_get(dev_id, port_id, enable); 2271 HSL_API_UNLOCK; 2272 return rv; 2273} 2274 2275/** 2276 * @brief Add a port to an exsiting entry 2277 * @param[in] dev_id device id 2278 * @param[in] fid filtering database id 2279 * @param[in] addr MAC address 2280 * @param[in] port_id port id 2281 * @return SW_OK or error code, If entry not exist will return error. 2282 */ 2283HSL_LOCAL sw_error_t 2284dess_fdb_port_add(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id) 2285{ 2286 sw_error_t rv; 2287 2288 HSL_API_LOCK; 2289 rv = _dess_fdb_port_update(dev_id, fid, addr, port_id, 1); 2290 HSL_API_UNLOCK; 2291 return rv; 2292} 2293 2294/** 2295 * @brief Delete a port from an exsiting entry 2296 * @param[in] dev_id device id 2297 * @param[in] fid filtering database id 2298 * @param[in] addr MAC address 2299 * @param[in] port_id port id 2300 * @return SW_OK or error code, If entry not exist will return error. 2301 */ 2302HSL_LOCAL sw_error_t 2303dess_fdb_port_del(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id) 2304{ 2305 sw_error_t rv; 2306 2307 HSL_API_LOCK; 2308 rv = _dess_fdb_port_update(dev_id, fid, addr, port_id, 0); 2309 HSL_API_UNLOCK; 2310 return rv; 2311} 2312 2313/** 2314 * @brief set a fdb rfs entry 2315 * @param[in] dev_id device id 2316 * @param[in] rfs entry 2317 * @return SW_OK or error code 2318 */ 2319HSL_LOCAL sw_error_t 2320dess_fdb_rfs_set(a_uint32_t dev_id, fal_fdb_rfs_t *rfs) 2321{ 2322 sw_error_t rv; 2323 2324 HSL_API_LOCK; 2325 rv = _dess_fdb_rfs_set(dev_id, rfs); 2326 HSL_API_UNLOCK; 2327 return rv; 2328} 2329 2330/** 2331 * @brief del a fdb rfs entry 2332 * @param[in] dev_id device id 2333 * @param[in] rfs entry 2334 * @return SW_OK or error code 2335 */ 2336HSL_LOCAL sw_error_t 2337dess_fdb_rfs_del(a_uint32_t dev_id, fal_fdb_rfs_t *rfs) 2338{ 2339 sw_error_t rv; 2340 2341 HSL_API_LOCK; 2342 rv = _dess_fdb_rfs_del(dev_id, rfs); 2343 HSL_API_UNLOCK; 2344 return rv; 2345} 2346 2347 2348sw_error_t 2349dess_fdb_init(a_uint32_t dev_id) 2350{ 2351 HSL_DEV_ID_CHECK(dev_id); 2352 2353#ifndef HSL_STANDALONG 2354 { 2355 hsl_api_t *p_api; 2356 2357 SW_RTN_ON_NULL(p_api = hsl_api_ptr_get(dev_id)); 2358 2359 p_api->fdb_add = dess_fdb_add; 2360 p_api->fdb_del_all = dess_fdb_del_all; 2361 p_api->fdb_del_by_port = dess_fdb_del_by_port; 2362 p_api->fdb_del_by_mac = dess_fdb_del_by_mac; 2363 p_api->fdb_find = dess_fdb_find; 2364 p_api->port_learn_set = dess_fdb_port_learn_set; 2365 p_api->port_learn_get = dess_fdb_port_learn_get; 2366 p_api->age_ctrl_set = dess_fdb_age_ctrl_set; 2367 p_api->age_ctrl_get = dess_fdb_age_ctrl_get; 2368 p_api->vlan_ivl_svl_set = dess_fdb_vlan_ivl_svl_set; 2369 p_api->vlan_ivl_svl_get = dess_fdb_vlan_ivl_svl_get; 2370 p_api->age_time_set = dess_fdb_age_time_set; 2371 p_api->age_time_get = dess_fdb_age_time_get; 2372 p_api->fdb_extend_next = dess_fdb_extend_next; 2373 p_api->fdb_extend_first = dess_fdb_extend_first; 2374 p_api->fdb_transfer = dess_fdb_transfer; 2375 p_api->port_fdb_learn_limit_set = dess_port_fdb_learn_limit_set; 2376 p_api->port_fdb_learn_limit_get = dess_port_fdb_learn_limit_get; 2377 p_api->port_fdb_learn_exceed_cmd_set = dess_port_fdb_learn_exceed_cmd_set; 2378 p_api->port_fdb_learn_exceed_cmd_get = dess_port_fdb_learn_exceed_cmd_get; 2379 p_api->fdb_learn_limit_set = dess_fdb_learn_limit_set; 2380 p_api->fdb_learn_limit_get = dess_fdb_learn_limit_get; 2381 p_api->fdb_learn_exceed_cmd_set = dess_fdb_learn_exceed_cmd_set; 2382 p_api->fdb_learn_exceed_cmd_get = dess_fdb_learn_exceed_cmd_get; 2383 p_api->fdb_resv_add = dess_fdb_resv_add; 2384 p_api->fdb_resv_del = dess_fdb_resv_del; 2385 p_api->fdb_resv_find = dess_fdb_resv_find; 2386 p_api->fdb_resv_iterate = dess_fdb_resv_iterate; 2387 p_api->fdb_port_learn_static_set = dess_fdb_port_learn_static_set; 2388 p_api->fdb_port_learn_static_get = dess_fdb_port_learn_static_get; 2389 p_api->fdb_port_add = dess_fdb_port_add; 2390 p_api->fdb_port_del = dess_fdb_port_del; 2391 p_api->fdb_rfs_set = dess_fdb_rfs_set; 2392 p_api->fdb_rfs_del = dess_fdb_rfs_del; 2393 } 2394#endif 2395 2396 return SW_OK; 2397} 2398 2399/** 2400 * @} 2401 */ 2402 2403