1/* 2 * Copyright (C) 2013 Realtek Semiconductor Corp. 3 * All Rights Reserved. 4 * 5 * This program is the proprietary software of Realtek Semiconductor 6 * Corporation and/or its licensors, and only be used, duplicated, 7 * modified or distributed under the authorized license from Realtek. 8 * 9 * ANY USE OF THE SOFTWARE OTHER THAN AS AUTHORIZED UNDER 10 * THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. 11 * 12 * $Revision: 50498 $ 13 * $Date: 2014-08-21 14:59:13 +0800 (������, 21 ������ 2014) $ 14 * 15 * Purpose : RTK switch high-level API for RTL8367/RTL8367C 16 * Feature : Here is a list of all functions and variables in L2 module. 17 * 18 */ 19 20#include <rtk_switch.h> 21#include <rtk_error.h> 22#include <l2.h> 23#ifndef __KERNEL__ 24#include <string.h> 25#else 26#include <linux/string.h> 27#endif 28 29#include <rtl8367c_asicdrv.h> 30#include <rtl8367c_asicdrv_lut.h> 31#include <rtl8367c_asicdrv_port.h> 32 33/* Function Name: 34 * rtk_l2_init 35 * Description: 36 * Initialize l2 module of the specified device. 37 * Input: 38 * None 39 * Output: 40 * None 41 * Return: 42 * RT_ERR_OK - OK 43 * RT_ERR_FAILED - Failed 44 * RT_ERR_SMI - SMI access error 45 * Note: 46 * Initialize l2 module before calling any l2 APIs. 47 */ 48rtk_api_ret_t rtk_l2_init(void) 49{ 50 rtk_api_ret_t retVal; 51 rtk_uint32 port; 52 53 /* Check initialization state */ 54 RTK_CHK_INIT_STATE(); 55 56 if ((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) 57 return retVal; 58 59 /*Enable CAM Usage*/ 60 if ((retVal = rtl8367c_setAsicLutCamTbUsage(ENABLED)) != RT_ERR_OK) 61 return retVal; 62 63 if ((retVal = rtl8367c_setAsicLutAgeTimerSpeed(6,2)) != RT_ERR_OK) 64 return retVal; 65 66 RTK_SCAN_ALL_LOG_PORT(port) 67 { 68 if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), rtk_switch_maxLutAddrNumber_get())) != RT_ERR_OK) 69 return retVal; 70 } 71 72 return RT_ERR_OK; 73} 74 75 76/* Function Name: 77 * rtk_l2_addr_add 78 * Description: 79 * Add LUT unicast entry. 80 * Input: 81 * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. 82 * pL2_data - Unicast entry parameter 83 * Output: 84 * None 85 * Return: 86 * RT_ERR_OK - OK 87 * RT_ERR_FAILED - Failed 88 * RT_ERR_SMI - SMI access error 89 * RT_ERR_PORT_ID - Invalid port number. 90 * RT_ERR_MAC - Invalid MAC address. 91 * RT_ERR_L2_FID - Invalid FID . 92 * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. 93 * RT_ERR_INPUT - Invalid input parameters. 94 * Note: 95 * If the unicast mac address already existed in LUT, it will udpate the status of the entry. 96 * Otherwise, it will find an empty or asic auto learned entry to write. If all the entries 97 * with the same hash value can't be replaced, ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. 98 */ 99rtk_api_ret_t rtk_l2_addr_add(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) 100{ 101 rtk_api_ret_t retVal; 102 rtk_uint32 method; 103 rtl8367c_luttb l2Table; 104 105 /* Check initialization state */ 106 RTK_CHK_INIT_STATE(); 107 108 /* must be unicast address */ 109 if ((pMac == NULL) || (pMac->octet[0] & 0x1)) 110 return RT_ERR_MAC; 111 112 if(pL2_data == NULL) 113 return RT_ERR_MAC; 114 115 RTK_CHK_PORT_VALID(pL2_data->port); 116 117 if (pL2_data->ivl >= RTK_ENABLE_END) 118 return RT_ERR_INPUT; 119 120 if (pL2_data->cvid > RTL8367C_VIDMAX) 121 return RT_ERR_L2_VID; 122 123 if (pL2_data->fid > RTL8367C_FIDMAX) 124 return RT_ERR_L2_FID; 125 126 if (pL2_data->is_static>= RTK_ENABLE_END) 127 return RT_ERR_INPUT; 128 129 if (pL2_data->sa_block>= RTK_ENABLE_END) 130 return RT_ERR_INPUT; 131 132 if (pL2_data->da_block>= RTK_ENABLE_END) 133 return RT_ERR_INPUT; 134 135 if (pL2_data->auth>= RTK_ENABLE_END) 136 return RT_ERR_INPUT; 137 138 if (pL2_data->efid> RTL8367C_EFIDMAX) 139 return RT_ERR_INPUT; 140 141 if (pL2_data->priority > RTL8367C_PRIMAX) 142 return RT_ERR_INPUT; 143 144 if (pL2_data->sa_pri_en >= RTK_ENABLE_END) 145 return RT_ERR_INPUT; 146 147 if (pL2_data->fwd_pri_en >= RTK_ENABLE_END) 148 return RT_ERR_INPUT; 149 150 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 151 152 /* fill key (MAC,FID) to get L2 entry */ 153 memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); 154 l2Table.ivl_svl = pL2_data->ivl; 155 l2Table.fid = pL2_data->fid; 156 l2Table.cvid_fid = pL2_data->cvid; 157 l2Table.efid = pL2_data->efid; 158 method = LUTREADMETHOD_MAC; 159 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 160 if (RT_ERR_OK == retVal ) 161 { 162 memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); 163 l2Table.ivl_svl = pL2_data->ivl; 164 l2Table.cvid_fid = pL2_data->cvid; 165 l2Table.fid = pL2_data->fid; 166 l2Table.efid = pL2_data->efid; 167 l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); 168 l2Table.nosalearn = pL2_data->is_static; 169 l2Table.sa_block = pL2_data->sa_block; 170 l2Table.da_block = pL2_data->da_block; 171 l2Table.l3lookup = 0; 172 l2Table.auth = pL2_data->auth; 173 l2Table.age = 6; 174 l2Table.lut_pri = pL2_data->priority; 175 l2Table.sa_en = pL2_data->sa_pri_en; 176 l2Table.fwd_en = pL2_data->fwd_pri_en; 177 if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 178 return retVal; 179 180 pL2_data->address = l2Table.address; 181 return RT_ERR_OK; 182 } 183 else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) 184 { 185 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 186 memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); 187 l2Table.ivl_svl = pL2_data->ivl; 188 l2Table.cvid_fid = pL2_data->cvid; 189 l2Table.fid = pL2_data->fid; 190 l2Table.efid = pL2_data->efid; 191 l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); 192 l2Table.nosalearn = pL2_data->is_static; 193 l2Table.sa_block = pL2_data->sa_block; 194 l2Table.da_block = pL2_data->da_block; 195 l2Table.l3lookup = 0; 196 l2Table.auth = pL2_data->auth; 197 l2Table.age = 6; 198 l2Table.lut_pri = pL2_data->priority; 199 l2Table.sa_en = pL2_data->sa_pri_en; 200 l2Table.fwd_en = pL2_data->fwd_pri_en; 201 202 if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 203 return retVal; 204 205 pL2_data->address = l2Table.address; 206 207 method = LUTREADMETHOD_MAC; 208 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 209 if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) 210 return RT_ERR_L2_INDEXTBL_FULL; 211 else 212 return retVal; 213 } 214 else 215 return retVal; 216 217} 218 219/* Function Name: 220 * rtk_l2_addr_get 221 * Description: 222 * Get LUT unicast entry. 223 * Input: 224 * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. 225 * Output: 226 * pL2_data - Unicast entry parameter 227 * Return: 228 * RT_ERR_OK - OK 229 * RT_ERR_FAILED - Failed 230 * RT_ERR_SMI - SMI access error 231 * RT_ERR_PORT_ID - Invalid port number. 232 * RT_ERR_MAC - Invalid MAC address. 233 * RT_ERR_L2_FID - Invalid FID . 234 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 235 * RT_ERR_INPUT - Invalid input parameters. 236 * Note: 237 * If the unicast mac address existed in LUT, it will return the port and fid where 238 * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. 239 */ 240rtk_api_ret_t rtk_l2_addr_get(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) 241{ 242 rtk_api_ret_t retVal; 243 rtk_uint32 method; 244 rtl8367c_luttb l2Table; 245 246 /* Check initialization state */ 247 RTK_CHK_INIT_STATE(); 248 249 /* must be unicast address */ 250 if ((pMac == NULL) || (pMac->octet[0] & 0x1)) 251 return RT_ERR_MAC; 252 253 if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) 254 return RT_ERR_L2_FID; 255 256 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 257 258 memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); 259 l2Table.ivl_svl = pL2_data->ivl; 260 l2Table.cvid_fid = pL2_data->cvid; 261 l2Table.fid = pL2_data->fid; 262 l2Table.efid = pL2_data->efid; 263 method = LUTREADMETHOD_MAC; 264 265 if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) 266 return retVal; 267 268 memcpy(pL2_data->mac.octet, pMac->octet,ETHER_ADDR_LEN); 269 pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); 270 pL2_data->fid = l2Table.fid; 271 pL2_data->efid = l2Table.efid; 272 pL2_data->ivl = l2Table.ivl_svl; 273 pL2_data->cvid = l2Table.cvid_fid; 274 pL2_data->is_static = l2Table.nosalearn; 275 pL2_data->auth = l2Table.auth; 276 pL2_data->sa_block = l2Table.sa_block; 277 pL2_data->da_block = l2Table.da_block; 278 pL2_data->priority = l2Table.lut_pri; 279 pL2_data->sa_pri_en = l2Table.sa_en; 280 pL2_data->fwd_pri_en= l2Table.fwd_en; 281 pL2_data->address = l2Table.address; 282 283 return RT_ERR_OK; 284} 285 286/* Function Name: 287 * rtk_l2_addr_next_get 288 * Description: 289 * Get Next LUT unicast entry. 290 * Input: 291 * read_method - The reading method. 292 * port - The port number if the read_metohd is READMETHOD_NEXT_L2UCSPA 293 * pAddress - The Address ID 294 * Output: 295 * pL2_data - Unicast entry parameter 296 * Return: 297 * RT_ERR_OK - OK 298 * RT_ERR_FAILED - Failed 299 * RT_ERR_SMI - SMI access error 300 * RT_ERR_PORT_ID - Invalid port number. 301 * RT_ERR_MAC - Invalid MAC address. 302 * RT_ERR_L2_FID - Invalid FID . 303 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 304 * RT_ERR_INPUT - Invalid input parameters. 305 * Note: 306 * Get the next unicast entry after the current entry pointed by pAddress. 307 * The address of next entry is returned by pAddress. User can use (address + 1) 308 * as pAddress to call this API again for dumping all entries is LUT. 309 */ 310rtk_api_ret_t rtk_l2_addr_next_get(rtk_l2_read_method_t read_method, rtk_port_t port, rtk_uint32 *pAddress, rtk_l2_ucastAddr_t *pL2_data) 311{ 312 rtk_api_ret_t retVal; 313 rtk_uint32 method; 314 rtl8367c_luttb l2Table; 315 316 /* Check initialization state */ 317 RTK_CHK_INIT_STATE(); 318 319 /* Error Checking */ 320 if ((pL2_data == NULL) || (pAddress == NULL)) 321 return RT_ERR_MAC; 322 323 if(read_method == READMETHOD_NEXT_L2UC) 324 method = LUTREADMETHOD_NEXT_L2UC; 325 else if(read_method == READMETHOD_NEXT_L2UCSPA) 326 method = LUTREADMETHOD_NEXT_L2UCSPA; 327 else 328 return RT_ERR_INPUT; 329 330 /* Check Port Valid */ 331 RTK_CHK_PORT_VALID(port); 332 333 if(*pAddress > RTK_MAX_LUT_ADDR_ID ) 334 return RT_ERR_L2_L2UNI_PARAM; 335 336 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 337 l2Table.address = *pAddress; 338 339 if(read_method == READMETHOD_NEXT_L2UCSPA) 340 l2Table.spa = port; 341 342 if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) 343 return retVal; 344 345 if(l2Table.address < *pAddress) 346 return RT_ERR_L2_ENTRY_NOTFOUND; 347 348 memcpy(pL2_data->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); 349 pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); 350 pL2_data->fid = l2Table.fid; 351 pL2_data->efid = l2Table.efid; 352 pL2_data->ivl = l2Table.ivl_svl; 353 pL2_data->cvid = l2Table.cvid_fid; 354 pL2_data->is_static = l2Table.nosalearn; 355 pL2_data->auth = l2Table.auth; 356 pL2_data->sa_block = l2Table.sa_block; 357 pL2_data->da_block = l2Table.da_block; 358 pL2_data->priority = l2Table.lut_pri; 359 pL2_data->sa_pri_en = l2Table.sa_en; 360 pL2_data->fwd_pri_en= l2Table.fwd_en; 361 pL2_data->address = l2Table.address; 362 363 *pAddress = l2Table.address; 364 365 return RT_ERR_OK; 366 367} 368 369/* Function Name: 370 * rtk_l2_addr_del 371 * Description: 372 * Delete LUT unicast entry. 373 * Input: 374 * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. 375 * fid - Filtering database 376 * Output: 377 * None 378 * Return: 379 * RT_ERR_OK - OK 380 * RT_ERR_FAILED - Failed 381 * RT_ERR_SMI - SMI access error 382 * RT_ERR_PORT_ID - Invalid port number. 383 * RT_ERR_MAC - Invalid MAC address. 384 * RT_ERR_L2_FID - Invalid FID . 385 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 386 * RT_ERR_INPUT - Invalid input parameters. 387 * Note: 388 * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. 389 */ 390rtk_api_ret_t rtk_l2_addr_del(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) 391{ 392 rtk_api_ret_t retVal; 393 rtk_uint32 method; 394 rtl8367c_luttb l2Table; 395 396 /* Check initialization state */ 397 RTK_CHK_INIT_STATE(); 398 399 /* must be unicast address */ 400 if ((pMac == NULL) || (pMac->octet[0] & 0x1)) 401 return RT_ERR_MAC; 402 403 if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) 404 return RT_ERR_L2_FID; 405 406 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 407 408 /* fill key (MAC,FID) to get L2 entry */ 409 memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); 410 l2Table.ivl_svl = pL2_data->ivl; 411 l2Table.cvid_fid = pL2_data->cvid; 412 l2Table.fid = pL2_data->fid; 413 l2Table.efid = pL2_data->efid; 414 method = LUTREADMETHOD_MAC; 415 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 416 if (RT_ERR_OK == retVal) 417 { 418 memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); 419 l2Table.ivl_svl = pL2_data->ivl; 420 l2Table.cvid_fid = pL2_data->cvid; 421 l2Table.fid = pL2_data->fid; 422 l2Table.efid = pL2_data->efid; 423 l2Table.spa = 0; 424 l2Table.nosalearn = 0; 425 l2Table.sa_block = 0; 426 l2Table.da_block = 0; 427 l2Table.auth = 0; 428 l2Table.age = 0; 429 l2Table.lut_pri = 0; 430 l2Table.sa_en = 0; 431 l2Table.fwd_en = 0; 432 if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 433 return retVal; 434 435 pL2_data->address = l2Table.address; 436 return RT_ERR_OK; 437 } 438 else 439 return retVal; 440} 441 442/* Function Name: 443 * rtk_l2_mcastAddr_add 444 * Description: 445 * Add LUT multicast entry. 446 * Input: 447 * pMcastAddr - L2 multicast entry structure 448 * Output: 449 * None 450 * Return: 451 * RT_ERR_OK - OK 452 * RT_ERR_FAILED - Failed 453 * RT_ERR_SMI - SMI access error 454 * RT_ERR_PORT_ID - Invalid port number. 455 * RT_ERR_MAC - Invalid MAC address. 456 * RT_ERR_L2_FID - Invalid FID . 457 * RT_ERR_L2_VID - Invalid VID . 458 * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. 459 * RT_ERR_PORT_MASK - Invalid portmask. 460 * RT_ERR_INPUT - Invalid input parameters. 461 * Note: 462 * If the multicast mac address already existed in the LUT, it will udpate the 463 * port mask of the entry. Otherwise, it will find an empty or asic auto learned 464 * entry to write. If all the entries with the same hash value can't be replaced, 465 * ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. 466 */ 467rtk_api_ret_t rtk_l2_mcastAddr_add(rtk_l2_mcastAddr_t *pMcastAddr) 468{ 469 rtk_api_ret_t retVal; 470 rtk_uint32 method; 471 rtl8367c_luttb l2Table; 472 rtk_uint32 pmask; 473 474 /* Check initialization state */ 475 RTK_CHK_INIT_STATE(); 476 477 if(NULL == pMcastAddr) 478 return RT_ERR_NULL_POINTER; 479 480 /* must be L2 multicast address */ 481 if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) 482 return RT_ERR_MAC; 483 484 RTK_CHK_PORTMASK_VALID(&pMcastAddr->portmask); 485 486 if(pMcastAddr->ivl == 1) 487 { 488 if (pMcastAddr->vid > RTL8367C_VIDMAX) 489 return RT_ERR_L2_VID; 490 } 491 else if(pMcastAddr->ivl == 0) 492 { 493 if (pMcastAddr->fid > RTL8367C_FIDMAX) 494 return RT_ERR_L2_FID; 495 } 496 else 497 return RT_ERR_INPUT; 498 499 if(pMcastAddr->fwd_pri_en >= RTK_ENABLE_END) 500 return RT_ERR_INPUT; 501 502 if(pMcastAddr->priority > RTL8367C_PRIMAX) 503 return RT_ERR_INPUT; 504 505 /* Get physical port mask */ 506 if ((retVal = rtk_switch_portmask_L2P_get(&pMcastAddr->portmask, &pmask)) != RT_ERR_OK) 507 return retVal; 508 509 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 510 511 /* fill key (MAC,FID) to get L2 entry */ 512 memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); 513 l2Table.ivl_svl = pMcastAddr->ivl; 514 515 if(pMcastAddr->ivl) 516 l2Table.cvid_fid = pMcastAddr->vid; 517 else 518 l2Table.cvid_fid = pMcastAddr->fid; 519 520 method = LUTREADMETHOD_MAC; 521 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 522 if (RT_ERR_OK == retVal) 523 { 524 memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); 525 l2Table.ivl_svl = pMcastAddr->ivl; 526 527 if(pMcastAddr->ivl) 528 l2Table.cvid_fid = pMcastAddr->vid; 529 else 530 l2Table.cvid_fid = pMcastAddr->fid; 531 532 l2Table.mbr = pmask; 533 l2Table.nosalearn = 1; 534 l2Table.l3lookup = 0; 535 l2Table.lut_pri = pMcastAddr->priority; 536 l2Table.fwd_en = pMcastAddr->fwd_pri_en; 537 if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 538 return retVal; 539 540 pMcastAddr->address = l2Table.address; 541 return RT_ERR_OK; 542 } 543 else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) 544 { 545 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 546 memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); 547 l2Table.ivl_svl = pMcastAddr->ivl; 548 if(pMcastAddr->ivl) 549 l2Table.cvid_fid = pMcastAddr->vid; 550 else 551 l2Table.cvid_fid = pMcastAddr->fid; 552 553 l2Table.mbr = pmask; 554 l2Table.nosalearn = 1; 555 l2Table.l3lookup = 0; 556 l2Table.lut_pri = pMcastAddr->priority; 557 l2Table.fwd_en = pMcastAddr->fwd_pri_en; 558 if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 559 return retVal; 560 561 pMcastAddr->address = l2Table.address; 562 563 method = LUTREADMETHOD_MAC; 564 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 565 if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) 566 return RT_ERR_L2_INDEXTBL_FULL; 567 else 568 return retVal; 569 } 570 else 571 return retVal; 572 573} 574 575/* Function Name: 576 * rtk_l2_mcastAddr_get 577 * Description: 578 * Get LUT multicast entry. 579 * Input: 580 * pMcastAddr - L2 multicast entry structure 581 * Output: 582 * pMcastAddr - L2 multicast entry structure 583 * Return: 584 * RT_ERR_OK - OK 585 * RT_ERR_FAILED - Failed 586 * RT_ERR_SMI - SMI access error 587 * RT_ERR_MAC - Invalid MAC address. 588 * RT_ERR_L2_FID - Invalid FID . 589 * RT_ERR_L2_VID - Invalid VID . 590 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 591 * RT_ERR_INPUT - Invalid input parameters. 592 * Note: 593 * If the multicast mac address existed in the LUT, it will return the port where 594 * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. 595 */ 596rtk_api_ret_t rtk_l2_mcastAddr_get(rtk_l2_mcastAddr_t *pMcastAddr) 597{ 598 rtk_api_ret_t retVal; 599 rtk_uint32 method; 600 rtl8367c_luttb l2Table; 601 602 /* Check initialization state */ 603 RTK_CHK_INIT_STATE(); 604 605 if(NULL == pMcastAddr) 606 return RT_ERR_NULL_POINTER; 607 608 /* must be L2 multicast address */ 609 if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) 610 return RT_ERR_MAC; 611 612 if(pMcastAddr->ivl == 1) 613 { 614 if (pMcastAddr->vid > RTL8367C_VIDMAX) 615 return RT_ERR_L2_VID; 616 } 617 else if(pMcastAddr->ivl == 0) 618 { 619 if (pMcastAddr->fid > RTL8367C_FIDMAX) 620 return RT_ERR_L2_FID; 621 } 622 else 623 return RT_ERR_INPUT; 624 625 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 626 memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); 627 l2Table.ivl_svl = pMcastAddr->ivl; 628 629 if(pMcastAddr->ivl) 630 l2Table.cvid_fid = pMcastAddr->vid; 631 else 632 l2Table.cvid_fid = pMcastAddr->fid; 633 634 method = LUTREADMETHOD_MAC; 635 636 if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) 637 return retVal; 638 639 pMcastAddr->priority = l2Table.lut_pri; 640 pMcastAddr->fwd_pri_en = l2Table.fwd_en; 641 pMcastAddr->igmp_asic = l2Table.igmp_asic; 642 pMcastAddr->igmp_index = l2Table.igmpidx; 643 pMcastAddr->address = l2Table.address; 644 645 /* Get Logical port mask */ 646 if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) 647 return retVal; 648 649 return RT_ERR_OK; 650} 651 652/* Function Name: 653 * rtk_l2_mcastAddr_next_get 654 * Description: 655 * Get Next L2 Multicast entry. 656 * Input: 657 * pAddress - The Address ID 658 * Output: 659 * pMcastAddr - L2 multicast entry structure 660 * Return: 661 * RT_ERR_OK - OK 662 * RT_ERR_FAILED - Failed 663 * RT_ERR_SMI - SMI access error 664 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 665 * RT_ERR_INPUT - Invalid input parameters. 666 * Note: 667 * Get the next L2 multicast entry after the current entry pointed by pAddress. 668 * The address of next entry is returned by pAddress. User can use (address + 1) 669 * as pAddress to call this API again for dumping all multicast entries is LUT. 670 */ 671rtk_api_ret_t rtk_l2_mcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_mcastAddr_t *pMcastAddr) 672{ 673 rtk_api_ret_t retVal; 674 rtl8367c_luttb l2Table; 675 676 /* Check initialization state */ 677 RTK_CHK_INIT_STATE(); 678 679 /* Error Checking */ 680 if ((pAddress == NULL) || (pMcastAddr == NULL)) 681 return RT_ERR_INPUT; 682 683 if(*pAddress > RTK_MAX_LUT_ADDR_ID ) 684 return RT_ERR_L2_L2UNI_PARAM; 685 686 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 687 l2Table.address = *pAddress; 688 689 if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L2MC, &l2Table)) != RT_ERR_OK) 690 return retVal; 691 692 if(l2Table.address < *pAddress) 693 return RT_ERR_L2_ENTRY_NOTFOUND; 694 695 memcpy(pMcastAddr->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); 696 pMcastAddr->ivl = l2Table.ivl_svl; 697 698 if(pMcastAddr->ivl) 699 pMcastAddr->vid = l2Table.cvid_fid; 700 else 701 pMcastAddr->fid = l2Table.cvid_fid; 702 703 pMcastAddr->priority = l2Table.lut_pri; 704 pMcastAddr->fwd_pri_en = l2Table.fwd_en; 705 pMcastAddr->igmp_asic = l2Table.igmp_asic; 706 pMcastAddr->igmp_index = l2Table.igmpidx; 707 pMcastAddr->address = l2Table.address; 708 709 /* Get Logical port mask */ 710 if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) 711 return retVal; 712 713 *pAddress = l2Table.address; 714 715 return RT_ERR_OK; 716} 717 718/* Function Name: 719 * rtk_l2_mcastAddr_del 720 * Description: 721 * Delete LUT multicast entry. 722 * Input: 723 * pMcastAddr - L2 multicast entry structure 724 * Output: 725 * None 726 * Return: 727 * RT_ERR_OK - OK 728 * RT_ERR_FAILED - Failed 729 * RT_ERR_SMI - SMI access error 730 * RT_ERR_MAC - Invalid MAC address. 731 * RT_ERR_L2_FID - Invalid FID . 732 * RT_ERR_L2_VID - Invalid VID . 733 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 734 * RT_ERR_INPUT - Invalid input parameters. 735 * Note: 736 * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. 737 */ 738rtk_api_ret_t rtk_l2_mcastAddr_del(rtk_l2_mcastAddr_t *pMcastAddr) 739{ 740 rtk_api_ret_t retVal; 741 rtk_uint32 method; 742 rtl8367c_luttb l2Table; 743 744 /* Check initialization state */ 745 RTK_CHK_INIT_STATE(); 746 747 if(NULL == pMcastAddr) 748 return RT_ERR_NULL_POINTER; 749 750 /* must be L2 multicast address */ 751 if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) 752 return RT_ERR_MAC; 753 754 if(pMcastAddr->ivl == 1) 755 { 756 if (pMcastAddr->vid > RTL8367C_VIDMAX) 757 return RT_ERR_L2_VID; 758 } 759 else if(pMcastAddr->ivl == 0) 760 { 761 if (pMcastAddr->fid > RTL8367C_FIDMAX) 762 return RT_ERR_L2_FID; 763 } 764 else 765 return RT_ERR_INPUT; 766 767 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 768 769 /* fill key (MAC,FID) to get L2 entry */ 770 memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); 771 l2Table.ivl_svl = pMcastAddr->ivl; 772 773 if(pMcastAddr->ivl) 774 l2Table.cvid_fid = pMcastAddr->vid; 775 else 776 l2Table.cvid_fid = pMcastAddr->fid; 777 778 method = LUTREADMETHOD_MAC; 779 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 780 if (RT_ERR_OK == retVal) 781 { 782 memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); 783 l2Table.ivl_svl = pMcastAddr->ivl; 784 785 if(pMcastAddr->ivl) 786 l2Table.cvid_fid = pMcastAddr->vid; 787 else 788 l2Table.cvid_fid = pMcastAddr->fid; 789 790 l2Table.mbr = 0; 791 l2Table.nosalearn = 0; 792 l2Table.sa_block = 0; 793 l2Table.l3lookup = 0; 794 l2Table.lut_pri = 0; 795 l2Table.fwd_en = 0; 796 if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 797 return retVal; 798 799 pMcastAddr->address = l2Table.address; 800 return RT_ERR_OK; 801 } 802 else 803 return retVal; 804} 805 806/* Function Name: 807 * rtk_l2_ipMcastAddr_add 808 * Description: 809 * Add Lut IP multicast entry 810 * Input: 811 * pIpMcastAddr - IP Multicast entry 812 * Output: 813 * None 814 * Return: 815 * RT_ERR_OK - OK 816 * RT_ERR_FAILED - Failed 817 * RT_ERR_SMI - SMI access error 818 * RT_ERR_PORT_ID - Invalid port number. 819 * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. 820 * RT_ERR_PORT_MASK - Invalid portmask. 821 * RT_ERR_INPUT - Invalid input parameters. 822 * Note: 823 * System supports L2 entry with IP multicast DIP/SIP to forward IP multicasting frame as user 824 * desired. If this function is enabled, then system will be looked up L2 IP multicast entry to 825 * forward IP multicast frame directly without flooding. 826 */ 827rtk_api_ret_t rtk_l2_ipMcastAddr_add(rtk_l2_ipMcastAddr_t *pIpMcastAddr) 828{ 829 rtk_api_ret_t retVal; 830 rtk_uint32 method; 831 rtl8367c_luttb l2Table; 832 rtk_uint32 pmask; 833 834 /* Check initialization state */ 835 RTK_CHK_INIT_STATE(); 836 837 if(NULL == pIpMcastAddr) 838 return RT_ERR_NULL_POINTER; 839 840 /* check port mask */ 841 RTK_CHK_PORTMASK_VALID(&pIpMcastAddr->portmask); 842 843 if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) 844 return RT_ERR_INPUT; 845 846 if(pIpMcastAddr->fwd_pri_en >= RTK_ENABLE_END) 847 return RT_ERR_ENABLE; 848 849 if(pIpMcastAddr->priority > RTL8367C_PRIMAX) 850 return RT_ERR_INPUT; 851 852 /* Get Physical port mask */ 853 if ((retVal = rtk_switch_portmask_L2P_get(&pIpMcastAddr->portmask, &pmask)) != RT_ERR_OK) 854 return retVal; 855 856 memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); 857 l2Table.sip = pIpMcastAddr->sip; 858 l2Table.dip = pIpMcastAddr->dip; 859 l2Table.l3lookup = 1; 860 l2Table.l3vidlookup = 0; 861 method = LUTREADMETHOD_MAC; 862 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 863 if (RT_ERR_OK == retVal) 864 { 865 l2Table.sip = pIpMcastAddr->sip; 866 l2Table.dip = pIpMcastAddr->dip; 867 l2Table.mbr = pmask; 868 l2Table.nosalearn = 1; 869 l2Table.l3lookup = 1; 870 l2Table.l3vidlookup = 0; 871 l2Table.lut_pri = pIpMcastAddr->priority; 872 l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; 873 if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 874 return retVal; 875 876 pIpMcastAddr->address = l2Table.address; 877 return RT_ERR_OK; 878 } 879 else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) 880 { 881 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 882 l2Table.sip = pIpMcastAddr->sip; 883 l2Table.dip = pIpMcastAddr->dip; 884 l2Table.mbr = pmask; 885 l2Table.nosalearn = 1; 886 l2Table.l3lookup = 1; 887 l2Table.l3vidlookup = 0; 888 l2Table.lut_pri = pIpMcastAddr->priority; 889 l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; 890 if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 891 return retVal; 892 893 pIpMcastAddr->address = l2Table.address; 894 895 method = LUTREADMETHOD_MAC; 896 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 897 if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) 898 return RT_ERR_L2_INDEXTBL_FULL; 899 else 900 return retVal; 901 902 } 903 else 904 return retVal; 905 906} 907 908/* Function Name: 909 * rtk_l2_ipMcastAddr_get 910 * Description: 911 * Get LUT IP multicast entry. 912 * Input: 913 * pIpMcastAddr - IP Multicast entry 914 * Output: 915 * pIpMcastAddr - IP Multicast entry 916 * Return: 917 * RT_ERR_OK - OK 918 * RT_ERR_FAILED - Failed 919 * RT_ERR_SMI - SMI access error 920 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 921 * RT_ERR_INPUT - Invalid input parameters. 922 * Note: 923 * The API can get Lut table of IP multicast entry. 924 */ 925rtk_api_ret_t rtk_l2_ipMcastAddr_get(rtk_l2_ipMcastAddr_t *pIpMcastAddr) 926{ 927 rtk_api_ret_t retVal; 928 rtk_uint32 method; 929 rtl8367c_luttb l2Table; 930 931 /* Check initialization state */ 932 RTK_CHK_INIT_STATE(); 933 934 if(NULL == pIpMcastAddr) 935 return RT_ERR_NULL_POINTER; 936 937 if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) 938 return RT_ERR_INPUT; 939 940 memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); 941 l2Table.sip = pIpMcastAddr->sip; 942 l2Table.dip = pIpMcastAddr->dip; 943 l2Table.l3lookup = 1; 944 l2Table.l3vidlookup = 0; 945 method = LUTREADMETHOD_MAC; 946 if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) 947 return retVal; 948 949 /* Get Logical port mask */ 950 if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) 951 return retVal; 952 953 pIpMcastAddr->priority = l2Table.lut_pri; 954 pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; 955 pIpMcastAddr->igmp_asic = l2Table.igmp_asic; 956 pIpMcastAddr->igmp_index = l2Table.igmpidx; 957 pIpMcastAddr->address = l2Table.address; 958 959 return RT_ERR_OK; 960} 961 962/* Function Name: 963 * rtk_l2_ipMcastAddr_next_get 964 * Description: 965 * Get Next IP Multicast entry. 966 * Input: 967 * pAddress - The Address ID 968 * Output: 969 * pIpMcastAddr - IP Multicast entry 970 * Return: 971 * RT_ERR_OK - OK 972 * RT_ERR_FAILED - Failed 973 * RT_ERR_SMI - SMI access error 974 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 975 * RT_ERR_INPUT - Invalid input parameters. 976 * Note: 977 * Get the next IP multicast entry after the current entry pointed by pAddress. 978 * The address of next entry is returned by pAddress. User can use (address + 1) 979 * as pAddress to call this API again for dumping all IP multicast entries is LUT. 980 */ 981rtk_api_ret_t rtk_l2_ipMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipMcastAddr_t *pIpMcastAddr) 982{ 983 rtk_api_ret_t retVal; 984 rtl8367c_luttb l2Table; 985 986 /* Check initialization state */ 987 RTK_CHK_INIT_STATE(); 988 989 /* Error Checking */ 990 if ((pAddress == NULL) || (pIpMcastAddr == NULL) ) 991 return RT_ERR_INPUT; 992 993 if(*pAddress > RTK_MAX_LUT_ADDR_ID ) 994 return RT_ERR_L2_L2UNI_PARAM; 995 996 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 997 l2Table.address = *pAddress; 998 999 do 1000 { 1001 if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) 1002 return retVal; 1003 1004 if(l2Table.address < *pAddress) 1005 return RT_ERR_L2_ENTRY_NOTFOUND; 1006 1007 }while(l2Table.l3vidlookup == 1); 1008 1009 pIpMcastAddr->sip = l2Table.sip; 1010 pIpMcastAddr->dip = l2Table.dip; 1011 1012 /* Get Logical port mask */ 1013 if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) 1014 return retVal; 1015 1016 pIpMcastAddr->priority = l2Table.lut_pri; 1017 pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; 1018 pIpMcastAddr->igmp_asic = l2Table.igmp_asic; 1019 pIpMcastAddr->igmp_index = l2Table.igmpidx; 1020 pIpMcastAddr->address = l2Table.address; 1021 *pAddress = l2Table.address; 1022 1023 return RT_ERR_OK; 1024} 1025 1026/* Function Name: 1027 * rtk_l2_ipMcastAddr_del 1028 * Description: 1029 * Delete a ip multicast address entry from the specified device. 1030 * Input: 1031 * pIpMcastAddr - IP Multicast entry 1032 * Output: 1033 * None 1034 * Return: 1035 * RT_ERR_OK - OK 1036 * RT_ERR_FAILED - Failed 1037 * RT_ERR_SMI - SMI access error 1038 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 1039 * RT_ERR_INPUT - Invalid input parameters. 1040 * Note: 1041 * The API can delete a IP multicast address entry from the specified device. 1042 */ 1043rtk_api_ret_t rtk_l2_ipMcastAddr_del(rtk_l2_ipMcastAddr_t *pIpMcastAddr) 1044{ 1045 rtk_api_ret_t retVal; 1046 rtk_uint32 method; 1047 rtl8367c_luttb l2Table; 1048 1049 /* Check initialization state */ 1050 RTK_CHK_INIT_STATE(); 1051 1052 /* Error Checking */ 1053 if (pIpMcastAddr == NULL) 1054 return RT_ERR_INPUT; 1055 1056 if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) 1057 return RT_ERR_INPUT; 1058 1059 memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); 1060 l2Table.sip = pIpMcastAddr->sip; 1061 l2Table.dip = pIpMcastAddr->dip; 1062 l2Table.l3lookup = 1; 1063 l2Table.l3vidlookup = 0; 1064 method = LUTREADMETHOD_MAC; 1065 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 1066 if (RT_ERR_OK == retVal) 1067 { 1068 l2Table.sip = pIpMcastAddr->sip; 1069 l2Table.dip = pIpMcastAddr->dip; 1070 l2Table.mbr = 0; 1071 l2Table.nosalearn = 0; 1072 l2Table.l3lookup = 1; 1073 l2Table.l3vidlookup = 0; 1074 l2Table.lut_pri = 0; 1075 l2Table.fwd_en = 0; 1076 if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 1077 return retVal; 1078 1079 pIpMcastAddr->address = l2Table.address; 1080 return RT_ERR_OK; 1081 } 1082 else 1083 return retVal; 1084} 1085 1086/* Function Name: 1087 * rtk_l2_ipVidMcastAddr_add 1088 * Description: 1089 * Add Lut IP multicast+VID entry 1090 * Input: 1091 * pIpVidMcastAddr - IP & VID multicast Entry 1092 * Output: 1093 * None 1094 * Return: 1095 * RT_ERR_OK - OK 1096 * RT_ERR_FAILED - Failed 1097 * RT_ERR_SMI - SMI access error 1098 * RT_ERR_PORT_ID - Invalid port number. 1099 * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. 1100 * RT_ERR_PORT_MASK - Invalid portmask. 1101 * RT_ERR_INPUT - Invalid input parameters. 1102 * Note: 1103 * 1104 */ 1105rtk_api_ret_t rtk_l2_ipVidMcastAddr_add(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) 1106{ 1107 rtk_api_ret_t retVal; 1108 rtk_uint32 method; 1109 rtl8367c_luttb l2Table; 1110 rtk_uint32 pmask; 1111 1112 /* Check initialization state */ 1113 RTK_CHK_INIT_STATE(); 1114 1115 if(NULL == pIpVidMcastAddr) 1116 return RT_ERR_NULL_POINTER; 1117 1118 /* check port mask */ 1119 RTK_CHK_PORTMASK_VALID(&pIpVidMcastAddr->portmask); 1120 1121 if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) 1122 return RT_ERR_L2_VID; 1123 1124 if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) 1125 return RT_ERR_INPUT; 1126 1127 /* Get Physical port mask */ 1128 if ((retVal = rtk_switch_portmask_L2P_get(&pIpVidMcastAddr->portmask, &pmask)) != RT_ERR_OK) 1129 return retVal; 1130 1131 memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); 1132 l2Table.sip = pIpVidMcastAddr->sip; 1133 l2Table.dip = pIpVidMcastAddr->dip; 1134 l2Table.l3lookup = 1; 1135 l2Table.l3vidlookup = 1; 1136 l2Table.l3_vid = pIpVidMcastAddr->vid; 1137 method = LUTREADMETHOD_MAC; 1138 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 1139 if (RT_ERR_OK == retVal) 1140 { 1141 l2Table.sip = pIpVidMcastAddr->sip; 1142 l2Table.dip = pIpVidMcastAddr->dip; 1143 l2Table.mbr = pmask; 1144 l2Table.nosalearn = 1; 1145 l2Table.l3lookup = 1; 1146 l2Table.l3vidlookup = 1; 1147 l2Table.l3_vid = pIpVidMcastAddr->vid; 1148 if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 1149 return retVal; 1150 1151 pIpVidMcastAddr->address = l2Table.address; 1152 return RT_ERR_OK; 1153 } 1154 else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) 1155 { 1156 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 1157 l2Table.sip = pIpVidMcastAddr->sip; 1158 l2Table.dip = pIpVidMcastAddr->dip; 1159 l2Table.mbr = pmask; 1160 l2Table.nosalearn = 1; 1161 l2Table.l3lookup = 1; 1162 l2Table.l3vidlookup = 1; 1163 l2Table.l3_vid = pIpVidMcastAddr->vid; 1164 if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 1165 return retVal; 1166 1167 pIpVidMcastAddr->address = l2Table.address; 1168 1169 method = LUTREADMETHOD_MAC; 1170 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 1171 if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) 1172 return RT_ERR_L2_INDEXTBL_FULL; 1173 else 1174 return retVal; 1175 1176 } 1177 else 1178 return retVal; 1179} 1180 1181/* Function Name: 1182 * rtk_l2_ipVidMcastAddr_get 1183 * Description: 1184 * Get LUT IP multicast+VID entry. 1185 * Input: 1186 * pIpVidMcastAddr - IP & VID multicast Entry 1187 * Output: 1188 * pIpVidMcastAddr - IP & VID multicast Entry 1189 * Return: 1190 * RT_ERR_OK - OK 1191 * RT_ERR_FAILED - Failed 1192 * RT_ERR_SMI - SMI access error 1193 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 1194 * RT_ERR_INPUT - Invalid input parameters. 1195 * Note: 1196 * 1197 */ 1198rtk_api_ret_t rtk_l2_ipVidMcastAddr_get(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) 1199{ 1200 rtk_api_ret_t retVal; 1201 rtk_uint32 method; 1202 rtl8367c_luttb l2Table; 1203 1204 /* Check initialization state */ 1205 RTK_CHK_INIT_STATE(); 1206 1207 if(NULL == pIpVidMcastAddr) 1208 return RT_ERR_NULL_POINTER; 1209 1210 if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) 1211 return RT_ERR_L2_VID; 1212 1213 if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) 1214 return RT_ERR_INPUT; 1215 1216 memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); 1217 l2Table.sip = pIpVidMcastAddr->sip; 1218 l2Table.dip = pIpVidMcastAddr->dip; 1219 l2Table.l3lookup = 1; 1220 l2Table.l3vidlookup = 1; 1221 l2Table.l3_vid = pIpVidMcastAddr->vid; 1222 method = LUTREADMETHOD_MAC; 1223 if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) 1224 return retVal; 1225 1226 pIpVidMcastAddr->address = l2Table.address; 1227 1228 /* Get Logical port mask */ 1229 if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) 1230 return retVal; 1231 1232 return RT_ERR_OK; 1233} 1234 1235/* Function Name: 1236 * rtk_l2_ipVidMcastAddr_next_get 1237 * Description: 1238 * Get Next IP Multicast+VID entry. 1239 * Input: 1240 * pAddress - The Address ID 1241 * Output: 1242 * pIpVidMcastAddr - IP & VID multicast Entry 1243 * Return: 1244 * RT_ERR_OK - OK 1245 * RT_ERR_FAILED - Failed 1246 * RT_ERR_SMI - SMI access error 1247 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 1248 * RT_ERR_INPUT - Invalid input parameters. 1249 * Note: 1250 * Get the next IP multicast entry after the current entry pointed by pAddress. 1251 * The address of next entry is returned by pAddress. User can use (address + 1) 1252 * as pAddress to call this API again for dumping all IP multicast entries is LUT. 1253 */ 1254rtk_api_ret_t rtk_l2_ipVidMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) 1255{ 1256 rtk_api_ret_t retVal; 1257 rtl8367c_luttb l2Table; 1258 1259 /* Check initialization state */ 1260 RTK_CHK_INIT_STATE(); 1261 1262 /* Error Checking */ 1263 if ((pAddress == NULL) || (pIpVidMcastAddr == NULL)) 1264 return RT_ERR_INPUT; 1265 1266 if(*pAddress > RTK_MAX_LUT_ADDR_ID ) 1267 return RT_ERR_L2_L2UNI_PARAM; 1268 1269 memset(&l2Table, 0, sizeof(rtl8367c_luttb)); 1270 l2Table.address = *pAddress; 1271 1272 do 1273 { 1274 if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) 1275 return retVal; 1276 1277 if(l2Table.address < *pAddress) 1278 return RT_ERR_L2_ENTRY_NOTFOUND; 1279 1280 }while(l2Table.l3vidlookup == 0); 1281 1282 pIpVidMcastAddr->sip = l2Table.sip; 1283 pIpVidMcastAddr->dip = l2Table.dip; 1284 pIpVidMcastAddr->vid = l2Table.l3_vid; 1285 pIpVidMcastAddr->address = l2Table.address; 1286 1287 /* Get Logical port mask */ 1288 if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) 1289 return retVal; 1290 1291 *pAddress = l2Table.address; 1292 1293 return RT_ERR_OK; 1294} 1295 1296/* Function Name: 1297 * rtk_l2_ipVidMcastAddr_del 1298 * Description: 1299 * Delete a ip multicast+VID address entry from the specified device. 1300 * Input: 1301 * pIpVidMcastAddr - IP & VID multicast Entry 1302 * Output: 1303 * None 1304 * Return: 1305 * RT_ERR_OK - OK 1306 * RT_ERR_FAILED - Failed 1307 * RT_ERR_SMI - SMI access error 1308 * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. 1309 * RT_ERR_INPUT - Invalid input parameters. 1310 * Note: 1311 * 1312 */ 1313rtk_api_ret_t rtk_l2_ipVidMcastAddr_del(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) 1314{ 1315 rtk_api_ret_t retVal; 1316 rtk_uint32 method; 1317 rtl8367c_luttb l2Table; 1318 1319 /* Check initialization state */ 1320 RTK_CHK_INIT_STATE(); 1321 1322 if(NULL == pIpVidMcastAddr) 1323 return RT_ERR_NULL_POINTER; 1324 1325 if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) 1326 return RT_ERR_L2_VID; 1327 1328 if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) 1329 return RT_ERR_INPUT; 1330 1331 memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); 1332 l2Table.sip = pIpVidMcastAddr->sip; 1333 l2Table.dip = pIpVidMcastAddr->dip; 1334 l2Table.l3lookup = 1; 1335 l2Table.l3vidlookup = 1; 1336 l2Table.l3_vid = pIpVidMcastAddr->vid; 1337 method = LUTREADMETHOD_MAC; 1338 retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); 1339 if (RT_ERR_OK == retVal) 1340 { 1341 l2Table.sip = pIpVidMcastAddr->sip; 1342 l2Table.dip = pIpVidMcastAddr->dip; 1343 l2Table.mbr= 0; 1344 l2Table.nosalearn = 0; 1345 l2Table.l3lookup = 1; 1346 l2Table.l3vidlookup = 1; 1347 l2Table.l3_vid = pIpVidMcastAddr->vid; 1348 if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) 1349 return retVal; 1350 1351 pIpVidMcastAddr->address = l2Table.address; 1352 return RT_ERR_OK; 1353 } 1354 else 1355 return retVal; 1356} 1357 1358/* Function Name: 1359 * rtk_l2_ucastAddr_flush 1360 * Description: 1361 * Flush L2 mac address by type in the specified device (both dynamic and static). 1362 * Input: 1363 * pConfig - flush configuration 1364 * Output: 1365 * None 1366 * Return: 1367 * RT_ERR_OK - OK 1368 * RT_ERR_FAILED - Failed 1369 * RT_ERR_SMI - SMI access error 1370 * RT_ERR_PORT_ID - Invalid port number. 1371 * RT_ERR_VLAN_VID - Invalid VID parameter. 1372 * RT_ERR_INPUT - Invalid input parameters. 1373 * Note: 1374 * flushByVid - 1: Flush by VID, 0: Don't flush by VID 1375 * vid - VID (0 ~ 4095) 1376 * flushByFid - 1: Flush by FID, 0: Don't flush by FID 1377 * fid - FID (0 ~ 15) 1378 * flushByPort - 1: Flush by Port, 0: Don't flush by Port 1379 * port - Port ID 1380 * flushByMac - Not Supported 1381 * ucastAddr - Not Supported 1382 * flushStaticAddr - 1: Flush both Static and Dynamic entries, 0: Flush only Dynamic entries 1383 * flushAddrOnAllPorts - 1: Flush VID-matched entries at all ports, 0: Flush VID-matched entries per port. 1384 */ 1385rtk_api_ret_t rtk_l2_ucastAddr_flush(rtk_l2_flushCfg_t *pConfig) 1386{ 1387 rtk_api_ret_t retVal; 1388 1389 /* Check initialization state */ 1390 RTK_CHK_INIT_STATE(); 1391 1392 if(pConfig == NULL) 1393 return RT_ERR_NULL_POINTER; 1394 1395 if(pConfig->flushByVid >= RTK_ENABLE_END) 1396 return RT_ERR_ENABLE; 1397 1398 if(pConfig->flushByFid >= RTK_ENABLE_END) 1399 return RT_ERR_ENABLE; 1400 1401 if(pConfig->flushByPort >= RTK_ENABLE_END) 1402 return RT_ERR_ENABLE; 1403 1404 if(pConfig->flushByMac >= RTK_ENABLE_END) 1405 return RT_ERR_ENABLE; 1406 1407 if(pConfig->flushStaticAddr >= RTK_ENABLE_END) 1408 return RT_ERR_ENABLE; 1409 1410 if(pConfig->flushAddrOnAllPorts >= RTK_ENABLE_END) 1411 return RT_ERR_ENABLE; 1412 1413 if(pConfig->vid > RTL8367C_VIDMAX) 1414 return RT_ERR_VLAN_VID; 1415 1416 if(pConfig->fid > RTL8367C_FIDMAX) 1417 return RT_ERR_INPUT; 1418 1419 /* check port valid */ 1420 RTK_CHK_PORT_VALID(pConfig->port); 1421 1422 if(pConfig->flushByVid == ENABLED) 1423 { 1424 if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_VID)) != RT_ERR_OK) 1425 return retVal; 1426 1427 if ((retVal = rtl8367c_setAsicLutFlushVid(pConfig->vid)) != RT_ERR_OK) 1428 return retVal; 1429 1430 if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) 1431 return retVal; 1432 1433 if(pConfig->flushAddrOnAllPorts == ENABLED) 1434 { 1435 if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) 1436 return retVal; 1437 } 1438 else if(pConfig->flushByPort == ENABLED) 1439 { 1440 if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) 1441 return retVal; 1442 } 1443 else 1444 return RT_ERR_INPUT; 1445 } 1446 else if(pConfig->flushByFid == ENABLED) 1447 { 1448 if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_FID)) != RT_ERR_OK) 1449 return retVal; 1450 1451 if ((retVal = rtl8367c_setAsicLutFlushFid(pConfig->fid)) != RT_ERR_OK) 1452 return retVal; 1453 1454 if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) 1455 return retVal; 1456 1457 if(pConfig->flushAddrOnAllPorts == ENABLED) 1458 { 1459 if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) 1460 return retVal; 1461 } 1462 else if(pConfig->flushByPort == ENABLED) 1463 { 1464 if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) 1465 return retVal; 1466 } 1467 else 1468 return RT_ERR_INPUT; 1469 } 1470 else if(pConfig->flushByPort == ENABLED) 1471 { 1472 if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) 1473 return retVal; 1474 1475 if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_PORT)) != RT_ERR_OK) 1476 return retVal; 1477 1478 if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) 1479 return retVal; 1480 } 1481 else if(pConfig->flushByMac == ENABLED) 1482 { 1483 /* Should use API "rtk_l2_addr_del" to remove a specified entry*/ 1484 return RT_ERR_CHIP_NOT_SUPPORTED; 1485 } 1486 else 1487 return RT_ERR_INPUT; 1488 1489 return RT_ERR_OK; 1490} 1491 1492/* Function Name: 1493 * rtk_l2_table_clear 1494 * Description: 1495 * Flush all static & dynamic entries in LUT. 1496 * Input: 1497 * None 1498 * Output: 1499 * None 1500 * Return: 1501 * RT_ERR_OK - OK 1502 * RT_ERR_FAILED - Failed 1503 * RT_ERR_SMI - SMI access error 1504 * Note: 1505 * 1506 */ 1507rtk_api_ret_t rtk_l2_table_clear(void) 1508{ 1509 rtk_api_ret_t retVal; 1510 1511 /* Check initialization state */ 1512 RTK_CHK_INIT_STATE(); 1513 1514 if ((retVal = rtl8367c_setAsicLutFlushAll()) != RT_ERR_OK) 1515 return retVal; 1516 1517 return RT_ERR_OK; 1518} 1519 1520/* Function Name: 1521 * rtk_l2_table_clearStatus_get 1522 * Description: 1523 * Get table clear status 1524 * Input: 1525 * None 1526 * Output: 1527 * pStatus - Clear status, 1:Busy, 0:finish 1528 * Return: 1529 * RT_ERR_OK - OK 1530 * RT_ERR_FAILED - Failed 1531 * RT_ERR_SMI - SMI access error 1532 * Note: 1533 * 1534 */ 1535rtk_api_ret_t rtk_l2_table_clearStatus_get(rtk_l2_clearStatus_t *pStatus) 1536{ 1537 rtk_api_ret_t retVal; 1538 1539 /* Check initialization state */ 1540 RTK_CHK_INIT_STATE(); 1541 1542 if(NULL == pStatus) 1543 return RT_ERR_NULL_POINTER; 1544 1545 if ((retVal = rtl8367c_getAsicLutFlushAllStatus((rtk_uint32 *)pStatus)) != RT_ERR_OK) 1546 return retVal; 1547 1548 return RT_ERR_OK; 1549} 1550 1551/* Function Name: 1552 * rtk_l2_flushLinkDownPortAddrEnable_set 1553 * Description: 1554 * Set HW flush linkdown port mac configuration of the specified device. 1555 * Input: 1556 * port - Port id. 1557 * enable - link down flush status 1558 * Output: 1559 * None 1560 * Return: 1561 * RT_ERR_OK - OK 1562 * RT_ERR_FAILED - Failed 1563 * RT_ERR_SMI - SMI access error 1564 * RT_ERR_PORT_ID - Invalid port number. 1565 * RT_ERR_ENABLE - Invalid enable input. 1566 * Note: 1567 * The status of flush linkdown port address is as following: 1568 * - DISABLED 1569 * - ENABLED 1570 */ 1571rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_set(rtk_port_t port, rtk_enable_t enable) 1572{ 1573 rtk_api_ret_t retVal; 1574 1575 /* Check initialization state */ 1576 RTK_CHK_INIT_STATE(); 1577 1578 if (port != RTK_WHOLE_SYSTEM) 1579 return RT_ERR_PORT_ID; 1580 1581 if (enable >= RTK_ENABLE_END) 1582 return RT_ERR_ENABLE; 1583 1584 if ((retVal = rtl8367c_setAsicLutLinkDownForceAging(enable)) != RT_ERR_OK) 1585 return retVal; 1586 1587 1588 return RT_ERR_OK; 1589} 1590 1591/* Function Name: 1592 * rtk_l2_flushLinkDownPortAddrEnable_get 1593 * Description: 1594 * Get HW flush linkdown port mac configuration of the specified device. 1595 * Input: 1596 * port - Port id. 1597 * Output: 1598 * pEnable - link down flush status 1599 * Return: 1600 * RT_ERR_OK - OK 1601 * RT_ERR_FAILED - Failed 1602 * RT_ERR_SMI - SMI access error 1603 * RT_ERR_PORT_ID - Invalid port number. 1604 * Note: 1605 * The status of flush linkdown port address is as following: 1606 * - DISABLED 1607 * - ENABLED 1608 */ 1609rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_get(rtk_port_t port, rtk_enable_t *pEnable) 1610{ 1611 rtk_api_ret_t retVal; 1612 1613 /* Check initialization state */ 1614 RTK_CHK_INIT_STATE(); 1615 1616 if (port != RTK_WHOLE_SYSTEM) 1617 return RT_ERR_PORT_ID; 1618 1619 if(NULL == pEnable) 1620 return RT_ERR_NULL_POINTER; 1621 1622 if ((retVal = rtl8367c_getAsicLutLinkDownForceAging(pEnable)) != RT_ERR_OK) 1623 return retVal; 1624 1625 return RT_ERR_OK; 1626} 1627 1628/* Function Name: 1629 * rtk_l2_agingEnable_set 1630 * Description: 1631 * Set L2 LUT aging status per port setting. 1632 * Input: 1633 * port - Port id. 1634 * enable - Aging status 1635 * Output: 1636 * None 1637 * Return: 1638 * RT_ERR_OK - OK 1639 * RT_ERR_FAILED - Failed 1640 * RT_ERR_SMI - SMI access error 1641 * RT_ERR_PORT_ID - Invalid port number. 1642 * RT_ERR_ENABLE - Invalid enable input. 1643 * Note: 1644 * This API can be used to set L2 LUT aging status per port. 1645 */ 1646rtk_api_ret_t rtk_l2_agingEnable_set(rtk_port_t port, rtk_enable_t enable) 1647{ 1648 rtk_api_ret_t retVal; 1649 1650 /* Check initialization state */ 1651 RTK_CHK_INIT_STATE(); 1652 1653 /* check port valid */ 1654 RTK_CHK_PORT_VALID(port); 1655 1656 if (enable >= RTK_ENABLE_END) 1657 return RT_ERR_ENABLE; 1658 1659 if(enable == 1) 1660 enable = 0; 1661 else 1662 enable = 1; 1663 1664 if ((retVal = rtl8367c_setAsicLutDisableAging(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) 1665 return retVal; 1666 1667 return RT_ERR_OK; 1668} 1669 1670/* Function Name: 1671 * rtk_l2_agingEnable_get 1672 * Description: 1673 * Get L2 LUT aging status per port setting. 1674 * Input: 1675 * port - Port id. 1676 * Output: 1677 * pEnable - Aging status 1678 * Return: 1679 * RT_ERR_OK - OK 1680 * RT_ERR_FAILED - Failed 1681 * RT_ERR_SMI - SMI access error 1682 * RT_ERR_PORT_ID - Invalid port number. 1683 * Note: 1684 * This API can be used to get L2 LUT aging function per port. 1685 */ 1686rtk_api_ret_t rtk_l2_agingEnable_get(rtk_port_t port, rtk_enable_t *pEnable) 1687{ 1688 rtk_api_ret_t retVal; 1689 1690 /* Check initialization state */ 1691 RTK_CHK_INIT_STATE(); 1692 1693 /* check port valid */ 1694 RTK_CHK_PORT_VALID(port); 1695 1696 if(NULL == pEnable) 1697 return RT_ERR_NULL_POINTER; 1698 1699 if ((retVal = rtl8367c_getAsicLutDisableAging(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) 1700 return retVal; 1701 1702 if(*pEnable == 1) 1703 *pEnable = 0; 1704 else 1705 *pEnable = 1; 1706 1707 return RT_ERR_OK; 1708} 1709 1710/* Function Name: 1711 * rtk_l2_limitLearningCnt_set 1712 * Description: 1713 * Set per-Port auto learning limit number 1714 * Input: 1715 * port - Port id. 1716 * mac_cnt - Auto learning entries limit number 1717 * Output: 1718 * None 1719 * Return: 1720 * RT_ERR_OK - OK 1721 * RT_ERR_FAILED - Failed 1722 * RT_ERR_SMI - SMI access error 1723 * RT_ERR_PORT_ID - Invalid port number. 1724 * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number 1725 * Note: 1726 * The API can set per-port ASIC auto learning limit number from 0(disable learning) 1727 * to 2112. 1728 */ 1729rtk_api_ret_t rtk_l2_limitLearningCnt_set(rtk_port_t port, rtk_mac_cnt_t mac_cnt) 1730{ 1731 rtk_api_ret_t retVal; 1732 1733 /* Check initialization state */ 1734 RTK_CHK_INIT_STATE(); 1735 1736 /* check port valid */ 1737 RTK_CHK_PORT_VALID(port); 1738 1739 if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) 1740 return RT_ERR_LIMITED_L2ENTRY_NUM; 1741 1742 if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), mac_cnt)) != RT_ERR_OK) 1743 return retVal; 1744 1745 return RT_ERR_OK; 1746} 1747 1748/* Function Name: 1749 * rtk_l2_limitLearningCnt_get 1750 * Description: 1751 * Get per-Port auto learning limit number 1752 * Input: 1753 * port - Port id. 1754 * Output: 1755 * pMac_cnt - Auto learning entries limit number 1756 * Return: 1757 * RT_ERR_OK - OK 1758 * RT_ERR_FAILED - Failed 1759 * RT_ERR_SMI - SMI access error 1760 * RT_ERR_PORT_ID - Invalid port number. 1761 * Note: 1762 * The API can get per-port ASIC auto learning limit number. 1763 */ 1764rtk_api_ret_t rtk_l2_limitLearningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) 1765{ 1766 rtk_api_ret_t retVal; 1767 1768 /* Check initialization state */ 1769 RTK_CHK_INIT_STATE(); 1770 1771 /* check port valid */ 1772 RTK_CHK_PORT_VALID(port); 1773 1774 if(NULL == pMac_cnt) 1775 return RT_ERR_NULL_POINTER; 1776 1777 if ((retVal = rtl8367c_getAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) 1778 return retVal; 1779 1780 return RT_ERR_OK; 1781} 1782 1783/* Function Name: 1784 * rtk_l2_limitSystemLearningCnt_set 1785 * Description: 1786 * Set System auto learning limit number 1787 * Input: 1788 * mac_cnt - Auto learning entries limit number 1789 * Output: 1790 * None 1791 * Return: 1792 * RT_ERR_OK - OK 1793 * RT_ERR_FAILED - Failed 1794 * RT_ERR_SMI - SMI access error 1795 * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number 1796 * Note: 1797 * The API can set system ASIC auto learning limit number from 0(disable learning) 1798 * to 2112. 1799 */ 1800rtk_api_ret_t rtk_l2_limitSystemLearningCnt_set(rtk_mac_cnt_t mac_cnt) 1801{ 1802 rtk_api_ret_t retVal; 1803 1804 /* Check initialization state */ 1805 RTK_CHK_INIT_STATE(); 1806 1807 if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) 1808 return RT_ERR_LIMITED_L2ENTRY_NUM; 1809 1810 if ((retVal = rtl8367c_setAsicSystemLutLearnLimitNo(mac_cnt)) != RT_ERR_OK) 1811 return retVal; 1812 1813 return RT_ERR_OK; 1814} 1815 1816/* Function Name: 1817 * rtk_l2_limitSystemLearningCnt_get 1818 * Description: 1819 * Get System auto learning limit number 1820 * Input: 1821 * None 1822 * Output: 1823 * pMac_cnt - Auto learning entries limit number 1824 * Return: 1825 * RT_ERR_OK - OK 1826 * RT_ERR_FAILED - Failed 1827 * RT_ERR_SMI - SMI access error 1828 * RT_ERR_PORT_ID - Invalid port number. 1829 * Note: 1830 * The API can get system ASIC auto learning limit number. 1831 */ 1832rtk_api_ret_t rtk_l2_limitSystemLearningCnt_get(rtk_mac_cnt_t *pMac_cnt) 1833{ 1834 rtk_api_ret_t retVal; 1835 1836 /* Check initialization state */ 1837 RTK_CHK_INIT_STATE(); 1838 1839 if(NULL == pMac_cnt) 1840 return RT_ERR_NULL_POINTER; 1841 1842 if ((retVal = rtl8367c_getAsicSystemLutLearnLimitNo(pMac_cnt)) != RT_ERR_OK) 1843 return retVal; 1844 1845 return RT_ERR_OK; 1846} 1847 1848/* Function Name: 1849 * rtk_l2_limitLearningCntAction_set 1850 * Description: 1851 * Configure auto learn over limit number action. 1852 * Input: 1853 * port - Port id. 1854 * action - Auto learning entries limit number 1855 * Output: 1856 * None 1857 * Return: 1858 * RT_ERR_OK - OK 1859 * RT_ERR_FAILED - Failed 1860 * RT_ERR_SMI - SMI access error 1861 * RT_ERR_PORT_ID - Invalid port number. 1862 * RT_ERR_NOT_ALLOWED - Invalid learn over action 1863 * Note: 1864 * The API can set SA unknown packet action while auto learn limit number is over 1865 * The action symbol as following: 1866 * - LIMIT_LEARN_CNT_ACTION_DROP, 1867 * - LIMIT_LEARN_CNT_ACTION_FORWARD, 1868 * - LIMIT_LEARN_CNT_ACTION_TO_CPU, 1869 */ 1870rtk_api_ret_t rtk_l2_limitLearningCntAction_set(rtk_port_t port, rtk_l2_limitLearnCntAction_t action) 1871{ 1872 rtk_api_ret_t retVal; 1873 rtk_uint32 data; 1874 1875 /* Check initialization state */ 1876 RTK_CHK_INIT_STATE(); 1877 1878 if (port != RTK_WHOLE_SYSTEM) 1879 return RT_ERR_PORT_ID; 1880 1881 if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) 1882 data = 1; 1883 else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) 1884 data = 0; 1885 else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) 1886 data = 2; 1887 else 1888 return RT_ERR_NOT_ALLOWED; 1889 1890 if ((retVal = rtl8367c_setAsicLutLearnOverAct(data)) != RT_ERR_OK) 1891 return retVal; 1892 1893 return RT_ERR_OK; 1894} 1895 1896/* Function Name: 1897 * rtk_l2_limitLearningCntAction_get 1898 * Description: 1899 * Get auto learn over limit number action. 1900 * Input: 1901 * port - Port id. 1902 * Output: 1903 * pAction - Learn over action 1904 * Return: 1905 * RT_ERR_OK - OK 1906 * RT_ERR_FAILED - Failed 1907 * RT_ERR_SMI - SMI access error 1908 * RT_ERR_PORT_ID - Invalid port number. 1909 * Note: 1910 * The API can get SA unknown packet action while auto learn limit number is over 1911 * The action symbol as following: 1912 * - LIMIT_LEARN_CNT_ACTION_DROP, 1913 * - LIMIT_LEARN_CNT_ACTION_FORWARD, 1914 * - LIMIT_LEARN_CNT_ACTION_TO_CPU, 1915 */ 1916rtk_api_ret_t rtk_l2_limitLearningCntAction_get(rtk_port_t port, rtk_l2_limitLearnCntAction_t *pAction) 1917{ 1918 rtk_api_ret_t retVal; 1919 rtk_uint32 action; 1920 1921 /* Check initialization state */ 1922 RTK_CHK_INIT_STATE(); 1923 1924 if (port != RTK_WHOLE_SYSTEM) 1925 return RT_ERR_PORT_ID; 1926 1927 if(NULL == pAction) 1928 return RT_ERR_NULL_POINTER; 1929 1930 if ((retVal = rtl8367c_getAsicLutLearnOverAct(&action)) != RT_ERR_OK) 1931 return retVal; 1932 1933 if ( 1 == action ) 1934 *pAction = LIMIT_LEARN_CNT_ACTION_DROP; 1935 else if ( 0 == action ) 1936 *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; 1937 else if ( 2 == action ) 1938 *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; 1939 else 1940 *pAction = action; 1941 1942 return RT_ERR_OK; 1943} 1944 1945/* Function Name: 1946 * rtk_l2_limitSystemLearningCntAction_set 1947 * Description: 1948 * Configure system auto learn over limit number action. 1949 * Input: 1950 * port - Port id. 1951 * action - Auto learning entries limit number 1952 * Output: 1953 * None 1954 * Return: 1955 * RT_ERR_OK - OK 1956 * RT_ERR_FAILED - Failed 1957 * RT_ERR_SMI - SMI access error 1958 * RT_ERR_PORT_ID - Invalid port number. 1959 * RT_ERR_NOT_ALLOWED - Invalid learn over action 1960 * Note: 1961 * The API can set SA unknown packet action while auto learn limit number is over 1962 * The action symbol as following: 1963 * - LIMIT_LEARN_CNT_ACTION_DROP, 1964 * - LIMIT_LEARN_CNT_ACTION_FORWARD, 1965 * - LIMIT_LEARN_CNT_ACTION_TO_CPU, 1966 */ 1967rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_set(rtk_l2_limitLearnCntAction_t action) 1968{ 1969 rtk_api_ret_t retVal; 1970 rtk_uint32 data; 1971 1972 /* Check initialization state */ 1973 RTK_CHK_INIT_STATE(); 1974 1975 if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) 1976 data = 1; 1977 else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) 1978 data = 0; 1979 else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) 1980 data = 2; 1981 else 1982 return RT_ERR_NOT_ALLOWED; 1983 1984 if ((retVal = rtl8367c_setAsicSystemLutLearnOverAct(data)) != RT_ERR_OK) 1985 return retVal; 1986 1987 return RT_ERR_OK; 1988} 1989 1990/* Function Name: 1991 * rtk_l2_limitSystemLearningCntAction_get 1992 * Description: 1993 * Get system auto learn over limit number action. 1994 * Input: 1995 * None. 1996 * Output: 1997 * pAction - Learn over action 1998 * Return: 1999 * RT_ERR_OK - OK 2000 * RT_ERR_FAILED - Failed 2001 * RT_ERR_SMI - SMI access error 2002 * RT_ERR_PORT_ID - Invalid port number. 2003 * Note: 2004 * The API can get SA unknown packet action while auto learn limit number is over 2005 * The action symbol as following: 2006 * - LIMIT_LEARN_CNT_ACTION_DROP, 2007 * - LIMIT_LEARN_CNT_ACTION_FORWARD, 2008 * - LIMIT_LEARN_CNT_ACTION_TO_CPU, 2009 */ 2010rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_get(rtk_l2_limitLearnCntAction_t *pAction) 2011{ 2012 rtk_api_ret_t retVal; 2013 rtk_uint32 action; 2014 2015 /* Check initialization state */ 2016 RTK_CHK_INIT_STATE(); 2017 2018 if(NULL == pAction) 2019 return RT_ERR_NULL_POINTER; 2020 2021 if ((retVal = rtl8367c_getAsicSystemLutLearnOverAct(&action)) != RT_ERR_OK) 2022 return retVal; 2023 2024 if ( 1 == action ) 2025 *pAction = LIMIT_LEARN_CNT_ACTION_DROP; 2026 else if ( 0 == action ) 2027 *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; 2028 else if ( 2 == action ) 2029 *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; 2030 else 2031 *pAction = action; 2032 2033 return RT_ERR_OK; 2034} 2035 2036/* Function Name: 2037 * rtk_l2_limitSystemLearningCntPortMask_set 2038 * Description: 2039 * Configure system auto learn portmask 2040 * Input: 2041 * pPortmask - Port Mask 2042 * Output: 2043 * None 2044 * Return: 2045 * RT_ERR_OK - OK 2046 * RT_ERR_FAILED - Failed 2047 * RT_ERR_SMI - SMI access error 2048 * RT_ERR_PORT_MASK - Invalid port mask. 2049 * Note: 2050 * 2051 */ 2052rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_set(rtk_portmask_t *pPortmask) 2053{ 2054 rtk_api_ret_t retVal; 2055 rtk_uint32 pmask; 2056 2057 /* Check initialization state */ 2058 RTK_CHK_INIT_STATE(); 2059 2060 if(NULL == pPortmask) 2061 return RT_ERR_NULL_POINTER; 2062 2063 /* Check port mask */ 2064 RTK_CHK_PORTMASK_VALID(pPortmask); 2065 2066 if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) 2067 return retVal; 2068 2069 if ((retVal = rtl8367c_setAsicSystemLutLearnPortMask(pmask)) != RT_ERR_OK) 2070 return retVal; 2071 2072 return RT_ERR_OK; 2073} 2074 2075/* Function Name: 2076 * rtk_l2_limitSystemLearningCntPortMask_get 2077 * Description: 2078 * get system auto learn portmask 2079 * Input: 2080 * None 2081 * Output: 2082 * pPortmask - Port Mask 2083 * Return: 2084 * RT_ERR_OK - OK 2085 * RT_ERR_FAILED - Failed 2086 * RT_ERR_SMI - SMI access error 2087 * RT_ERR_NULL_POINTER - Null pointer. 2088 * Note: 2089 * 2090 */ 2091rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_get(rtk_portmask_t *pPortmask) 2092{ 2093 rtk_api_ret_t retVal; 2094 rtk_uint32 pmask; 2095 2096 /* Check initialization state */ 2097 RTK_CHK_INIT_STATE(); 2098 2099 if(NULL == pPortmask) 2100 return RT_ERR_NULL_POINTER; 2101 2102 if ((retVal = rtl8367c_getAsicSystemLutLearnPortMask(&pmask)) != RT_ERR_OK) 2103 return retVal; 2104 2105 if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) 2106 return retVal; 2107 2108 return RT_ERR_OK; 2109} 2110 2111/* Function Name: 2112 * rtk_l2_learningCnt_get 2113 * Description: 2114 * Get per-Port current auto learning number 2115 * Input: 2116 * port - Port id. 2117 * Output: 2118 * pMac_cnt - ASIC auto learning entries number 2119 * Return: 2120 * RT_ERR_OK - OK 2121 * RT_ERR_FAILED - Failed 2122 * RT_ERR_SMI - SMI access error 2123 * RT_ERR_PORT_ID - Invalid port number. 2124 * Note: 2125 * The API can get per-port ASIC auto learning number 2126 */ 2127rtk_api_ret_t rtk_l2_learningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) 2128{ 2129 rtk_api_ret_t retVal; 2130 2131 /* Check initialization state */ 2132 RTK_CHK_INIT_STATE(); 2133 2134 /* check port valid */ 2135 RTK_CHK_PORT_VALID(port); 2136 2137 if(NULL == pMac_cnt) 2138 return RT_ERR_NULL_POINTER; 2139 2140 if ((retVal = rtl8367c_getAsicLutLearnNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) 2141 return retVal; 2142 2143 return RT_ERR_OK; 2144} 2145 2146/* Function Name: 2147 * rtk_l2_floodPortMask_set 2148 * Description: 2149 * Set flooding portmask 2150 * Input: 2151 * type - flooding type. 2152 * pFlood_portmask - flooding porkmask 2153 * Output: 2154 * None 2155 * Return: 2156 * RT_ERR_OK - OK 2157 * RT_ERR_FAILED - Failed 2158 * RT_ERR_SMI - SMI access error 2159 * RT_ERR_PORT_MASK - Invalid portmask. 2160 * RT_ERR_INPUT - Invalid input parameters. 2161 * Note: 2162 * This API can set the flooding mask. 2163 * The flooding type is as following: 2164 * - FLOOD_UNKNOWNDA 2165 * - FLOOD_UNKNOWNMC 2166 * - FLOOD_BC 2167 */ 2168rtk_api_ret_t rtk_l2_floodPortMask_set(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) 2169{ 2170 rtk_api_ret_t retVal; 2171 rtk_uint32 pmask; 2172 2173 /* Check initialization state */ 2174 RTK_CHK_INIT_STATE(); 2175 2176 if (floood_type >= FLOOD_END) 2177 return RT_ERR_INPUT; 2178 2179 /* check port valid */ 2180 RTK_CHK_PORTMASK_VALID(pFlood_portmask); 2181 2182 /* Get Physical port mask */ 2183 if ((retVal = rtk_switch_portmask_L2P_get(pFlood_portmask, &pmask))!=RT_ERR_OK) 2184 return retVal; 2185 2186 switch (floood_type) 2187 { 2188 case FLOOD_UNKNOWNDA: 2189 if ((retVal = rtl8367c_setAsicPortUnknownDaFloodingPortmask(pmask)) != RT_ERR_OK) 2190 return retVal; 2191 break; 2192 case FLOOD_UNKNOWNMC: 2193 if ((retVal = rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(pmask)) != RT_ERR_OK) 2194 return retVal; 2195 break; 2196 case FLOOD_BC: 2197 if ((retVal = rtl8367c_setAsicPortBcastFloodingPortmask(pmask)) != RT_ERR_OK) 2198 return retVal; 2199 break; 2200 default: 2201 break; 2202 } 2203 2204 return RT_ERR_OK; 2205} 2206/* Function Name: 2207 * rtk_l2_floodPortMask_get 2208 * Description: 2209 * Get flooding portmask 2210 * Input: 2211 * type - flooding type. 2212 * Output: 2213 * pFlood_portmask - flooding porkmask 2214 * Return: 2215 * RT_ERR_OK - OK 2216 * RT_ERR_FAILED - Failed 2217 * RT_ERR_SMI - SMI access error 2218 * RT_ERR_PORT_ID - Invalid port number. 2219 * Note: 2220 * This API can get the flooding mask. 2221 * The flooding type is as following: 2222 * - FLOOD_UNKNOWNDA 2223 * - FLOOD_UNKNOWNMC 2224 * - FLOOD_BC 2225 */ 2226rtk_api_ret_t rtk_l2_floodPortMask_get(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) 2227{ 2228 rtk_api_ret_t retVal; 2229 rtk_uint32 pmask; 2230 2231 /* Check initialization state */ 2232 RTK_CHK_INIT_STATE(); 2233 2234 if (floood_type >= FLOOD_END) 2235 return RT_ERR_INPUT; 2236 2237 if(NULL == pFlood_portmask) 2238 return RT_ERR_NULL_POINTER; 2239 2240 switch (floood_type) 2241 { 2242 case FLOOD_UNKNOWNDA: 2243 if ((retVal = rtl8367c_getAsicPortUnknownDaFloodingPortmask(&pmask)) != RT_ERR_OK) 2244 return retVal; 2245 break; 2246 case FLOOD_UNKNOWNMC: 2247 if ((retVal = rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(&pmask)) != RT_ERR_OK) 2248 return retVal; 2249 break; 2250 case FLOOD_BC: 2251 if ((retVal = rtl8367c_getAsicPortBcastFloodingPortmask(&pmask)) != RT_ERR_OK) 2252 return retVal; 2253 break; 2254 default: 2255 break; 2256 } 2257 2258 /* Get Logical port mask */ 2259 if ((retVal = rtk_switch_portmask_P2L_get(pmask, pFlood_portmask))!=RT_ERR_OK) 2260 return retVal; 2261 2262 return RT_ERR_OK; 2263} 2264 2265/* Function Name: 2266 * rtk_l2_localPktPermit_set 2267 * Description: 2268 * Set permittion of frames if source port and destination port are the same. 2269 * Input: 2270 * port - Port id. 2271 * permit - permittion status 2272 * Output: 2273 * None 2274 * Return: 2275 * RT_ERR_OK - OK 2276 * RT_ERR_FAILED - Failed 2277 * RT_ERR_SMI - SMI access error 2278 * RT_ERR_PORT_ID - Invalid port number. 2279 * RT_ERR_ENABLE - Invalid permit value. 2280 * Note: 2281 * This API is setted to permit frame if its source port is equal to destination port. 2282 */ 2283rtk_api_ret_t rtk_l2_localPktPermit_set(rtk_port_t port, rtk_enable_t permit) 2284{ 2285 rtk_api_ret_t retVal; 2286 2287 /* Check initialization state */ 2288 RTK_CHK_INIT_STATE(); 2289 2290 /* check port valid */ 2291 RTK_CHK_PORT_VALID(port); 2292 2293 if (permit >= RTK_ENABLE_END) 2294 return RT_ERR_ENABLE; 2295 2296 if ((retVal = rtl8367c_setAsicPortBlockSpa(rtk_switch_port_L2P_get(port), permit)) != RT_ERR_OK) 2297 return retVal; 2298 2299 return RT_ERR_OK; 2300} 2301 2302/* Function Name: 2303 * rtk_l2_localPktPermit_get 2304 * Description: 2305 * Get permittion of frames if source port and destination port are the same. 2306 * Input: 2307 * port - Port id. 2308 * Output: 2309 * pPermit - permittion status 2310 * Return: 2311 * RT_ERR_OK - OK 2312 * RT_ERR_FAILED - Failed 2313 * RT_ERR_SMI - SMI access error 2314 * RT_ERR_PORT_ID - Invalid port number. 2315 * Note: 2316 * This API is to get permittion status for frames if its source port is equal to destination port. 2317 */ 2318rtk_api_ret_t rtk_l2_localPktPermit_get(rtk_port_t port, rtk_enable_t *pPermit) 2319{ 2320 rtk_api_ret_t retVal; 2321 2322 /* Check initialization state */ 2323 RTK_CHK_INIT_STATE(); 2324 2325 /* check port valid */ 2326 RTK_CHK_PORT_VALID(port); 2327 2328 if(NULL == pPermit) 2329 return RT_ERR_NULL_POINTER; 2330 2331 if ((retVal = rtl8367c_getAsicPortBlockSpa(rtk_switch_port_L2P_get(port), pPermit)) != RT_ERR_OK) 2332 return retVal; 2333 2334 return RT_ERR_OK; 2335} 2336 2337/* Function Name: 2338 * rtk_l2_aging_set 2339 * Description: 2340 * Set LUT agging out speed 2341 * Input: 2342 * aging_time - Agging out time. 2343 * Output: 2344 * None 2345 * Return: 2346 * RT_ERR_OK - OK 2347 * RT_ERR_FAILED - Failed 2348 * RT_ERR_SMI - SMI access error 2349 * RT_ERR_OUT_OF_RANGE - input out of range. 2350 * Note: 2351 * The API can set LUT agging out period for each entry and the range is from 45s to 458s. 2352 */ 2353rtk_api_ret_t rtk_l2_aging_set(rtk_l2_age_time_t aging_time) 2354{ 2355 rtk_uint32 i; 2356 CONST_T rtk_uint32 agePara[10][3] = { 2357 {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, 2358 {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; 2359 2360 /* Check initialization state */ 2361 RTK_CHK_INIT_STATE(); 2362 2363 if (aging_time>agePara[9][0]) 2364 return RT_ERR_OUT_OF_RANGE; 2365 2366 for (i = 0; i<10; i++) 2367 { 2368 if (aging_time<=agePara[i][0]) 2369 { 2370 return rtl8367c_setAsicLutAgeTimerSpeed(agePara[i][2], agePara[i][1]); 2371 } 2372 } 2373 2374 return RT_ERR_FAILED; 2375} 2376 2377/* Function Name: 2378 * rtk_l2_aging_get 2379 * Description: 2380 * Get LUT agging out time 2381 * Input: 2382 * None 2383 * Output: 2384 * pEnable - Aging status 2385 * Return: 2386 * RT_ERR_OK - OK 2387 * RT_ERR_FAILED - Failed 2388 * RT_ERR_SMI - SMI access error 2389 * RT_ERR_PORT_ID - Invalid port number. 2390 * Note: 2391 * The API can get LUT agging out period for each entry. 2392 */ 2393rtk_api_ret_t rtk_l2_aging_get(rtk_l2_age_time_t *pAging_time) 2394{ 2395 rtk_api_ret_t retVal; 2396 rtk_uint32 i,time, speed; 2397 CONST_T rtk_uint32 agePara[10][3] = { 2398 {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, 2399 {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; 2400 2401 /* Check initialization state */ 2402 RTK_CHK_INIT_STATE(); 2403 2404 if(NULL == pAging_time) 2405 return RT_ERR_NULL_POINTER; 2406 2407 if ((retVal = rtl8367c_getAsicLutAgeTimerSpeed(&time, &speed)) != RT_ERR_OK) 2408 return retVal; 2409 2410 for (i = 0; i<10; i++) 2411 { 2412 if (time==agePara[i][2]&&speed==agePara[i][1]) 2413 { 2414 *pAging_time = agePara[i][0]; 2415 return RT_ERR_OK; 2416 } 2417 } 2418 2419 return RT_ERR_FAILED; 2420} 2421 2422/* Function Name: 2423 * rtk_l2_ipMcastAddrLookup_set 2424 * Description: 2425 * Set Lut IP multicast lookup function 2426 * Input: 2427 * type - Lookup type for IPMC packet. 2428 * Output: 2429 * None. 2430 * Return: 2431 * RT_ERR_OK - OK 2432 * RT_ERR_FAILED - Failed 2433 * RT_ERR_SMI - SMI access error 2434 * Note: 2435 * LOOKUP_MAC - Lookup by MAC address 2436 * LOOKUP_IP - Lookup by IP address 2437 * LOOKUP_IP_VID - Lookup by IP address & VLAN ID 2438 */ 2439rtk_api_ret_t rtk_l2_ipMcastAddrLookup_set(rtk_l2_ipmc_lookup_type_t type) 2440{ 2441 rtk_api_ret_t retVal; 2442 2443 /* Check initialization state */ 2444 RTK_CHK_INIT_STATE(); 2445 2446 if(type == LOOKUP_MAC) 2447 { 2448 if((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) 2449 return retVal; 2450 } 2451 else if(type == LOOKUP_IP) 2452 { 2453 if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) 2454 return retVal; 2455 2456 if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(DISABLED))!=RT_ERR_OK) 2457 return retVal; 2458 2459 if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) 2460 return retVal; 2461 } 2462 else if(type == LOOKUP_IP_VID) 2463 { 2464 if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) 2465 return retVal; 2466 2467 if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(ENABLED))!=RT_ERR_OK) 2468 return retVal; 2469 2470 if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) 2471 return retVal; 2472 } 2473 else 2474 return RT_ERR_INPUT; 2475 2476 return RT_ERR_OK; 2477} 2478 2479/* Function Name: 2480 * rtk_l2_ipMcastAddrLookup_get 2481 * Description: 2482 * Get Lut IP multicast lookup function 2483 * Input: 2484 * None. 2485 * Output: 2486 * pType - Lookup type for IPMC packet. 2487 * Return: 2488 * RT_ERR_OK - OK 2489 * RT_ERR_FAILED - Failed 2490 * RT_ERR_SMI - SMI access error 2491 * Note: 2492 * None. 2493 */ 2494rtk_api_ret_t rtk_l2_ipMcastAddrLookup_get(rtk_l2_ipmc_lookup_type_t *pType) 2495{ 2496 rtk_api_ret_t retVal; 2497 rtk_uint32 enabled, vid_lookup; 2498 2499 /* Check initialization state */ 2500 RTK_CHK_INIT_STATE(); 2501 2502 if(NULL == pType) 2503 return RT_ERR_NULL_POINTER; 2504 2505 if((retVal = rtl8367c_getAsicLutIpMulticastLookup(&enabled)) != RT_ERR_OK) 2506 return retVal; 2507 2508 if ((retVal = rtl8367c_getAsicLutIpMulticastVidLookup(&vid_lookup))!=RT_ERR_OK) 2509 return retVal; 2510 2511 if(enabled == ENABLED) 2512 { 2513 if(vid_lookup == ENABLED) 2514 *pType = LOOKUP_IP_VID; 2515 else 2516 *pType = LOOKUP_IP; 2517 } 2518 else 2519 *pType = LOOKUP_MAC; 2520 2521 return RT_ERR_OK; 2522} 2523 2524/* Function Name: 2525 * rtk_l2_ipMcastForwardRouterPort_set 2526 * Description: 2527 * Set IPMC packet forward to rounter port also or not 2528 * Input: 2529 * enabled - 1: Inlcude router port, 0, exclude router port 2530 * Output: 2531 * None. 2532 * Return: 2533 * RT_ERR_OK - OK 2534 * RT_ERR_FAILED - Failed 2535 * RT_ERR_SMI - SMI access error 2536 * Note: 2537 * 2538 */ 2539rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_set(rtk_enable_t enabled) 2540{ 2541 rtk_api_ret_t retVal; 2542 2543 /* Check initialization state */ 2544 RTK_CHK_INIT_STATE(); 2545 2546 if (enabled >= RTK_ENABLE_END) 2547 return RT_ERR_ENABLE; 2548 2549 if((retVal = rtl8367c_setAsicLutIpmcFwdRouterPort(enabled)) != RT_ERR_OK) 2550 return retVal; 2551 2552 return RT_ERR_OK; 2553} 2554 2555/* Function Name: 2556 * rtk_l2_ipMcastForwardRouterPort_get 2557 * Description: 2558 * Get IPMC packet forward to rounter port also or not 2559 * Input: 2560 * None. 2561 * Output: 2562 * pEnabled - 1: Inlcude router port, 0, exclude router port 2563 * Return: 2564 * RT_ERR_OK - OK 2565 * RT_ERR_FAILED - Failed 2566 * RT_ERR_NULL_POINTER - Null pointer 2567 * Note: 2568 * 2569 */ 2570rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_get(rtk_enable_t *pEnabled) 2571{ 2572 rtk_api_ret_t retVal; 2573 2574 /* Check initialization state */ 2575 RTK_CHK_INIT_STATE(); 2576 2577 if (NULL == pEnabled) 2578 return RT_ERR_NULL_POINTER; 2579 2580 if((retVal = rtl8367c_getAsicLutIpmcFwdRouterPort(pEnabled)) != RT_ERR_OK) 2581 return retVal; 2582 2583 return RT_ERR_OK; 2584} 2585 2586/* Function Name: 2587 * rtk_l2_ipMcastGroupEntry_add 2588 * Description: 2589 * Add an IP Multicast entry to group table 2590 * Input: 2591 * ip_addr - IP address 2592 * vid - VLAN ID 2593 * pPortmask - portmask 2594 * Output: 2595 * None. 2596 * Return: 2597 * RT_ERR_OK - OK 2598 * RT_ERR_FAILED - Failed 2599 * RT_ERR_SMI - SMI access error 2600 * RT_ERR_TBL_FULL - Table Full 2601 * Note: 2602 * Add an entry to IP Multicast Group table. 2603 */ 2604rtk_api_ret_t rtk_l2_ipMcastGroupEntry_add(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) 2605{ 2606 rtk_uint32 empty_idx = 0xFFFF; 2607 rtk_int32 index; 2608 ipaddr_t group_addr; 2609 rtk_uint32 group_vid; 2610 rtk_uint32 pmask; 2611 rtk_uint32 valid; 2612 rtk_uint32 physicalPortmask; 2613 rtk_api_ret_t retVal; 2614 2615 /* Check initialization state */ 2616 RTK_CHK_INIT_STATE(); 2617 2618 if (vid > RTL8367C_VIDMAX) 2619 return RT_ERR_L2_VID; 2620 2621 if(NULL == pPortmask) 2622 return RT_ERR_NULL_POINTER; 2623 2624 if((ip_addr & 0xF0000000) != 0xE0000000) 2625 return RT_ERR_INPUT; 2626 2627 /* Get Physical port mask */ 2628 if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &physicalPortmask))!=RT_ERR_OK) 2629 return retVal; 2630 2631 for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) 2632 { 2633 if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) 2634 return retVal; 2635 2636 if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) 2637 { 2638 if(pmask != physicalPortmask) 2639 { 2640 pmask = physicalPortmask; 2641 if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, ip_addr, vid, pmask, valid))!=RT_ERR_OK) 2642 return retVal; 2643 } 2644 2645 return RT_ERR_OK; 2646 } 2647 2648 if( (valid == DISABLED) && (empty_idx == 0xFFFF) ) /* Unused */ 2649 empty_idx = (rtk_uint32)index; 2650 } 2651 2652 if(empty_idx == 0xFFFF) 2653 return RT_ERR_TBL_FULL; 2654 2655 pmask = physicalPortmask; 2656 if ((retVal = rtl8367c_setAsicLutIPMCGroup(empty_idx, ip_addr, vid, pmask, ENABLED))!=RT_ERR_OK) 2657 return retVal; 2658 2659 return RT_ERR_OK; 2660} 2661 2662/* Function Name: 2663 * rtk_l2_ipMcastGroupEntry_del 2664 * Description: 2665 * Delete an entry from IP Multicast group table 2666 * Input: 2667 * ip_addr - IP address 2668 * vid - VLAN ID 2669 * Output: 2670 * None. 2671 * Return: 2672 * RT_ERR_OK - OK 2673 * RT_ERR_FAILED - Failed 2674 * RT_ERR_SMI - SMI access error 2675 * RT_ERR_TBL_FULL - Table Full 2676 * Note: 2677 * Delete an entry from IP Multicast group table. 2678 */ 2679rtk_api_ret_t rtk_l2_ipMcastGroupEntry_del(ipaddr_t ip_addr, rtk_uint32 vid) 2680{ 2681 rtk_int32 index; 2682 ipaddr_t group_addr; 2683 rtk_uint32 group_vid; 2684 rtk_uint32 pmask; 2685 rtk_uint32 valid; 2686 rtk_api_ret_t retVal; 2687 2688 /* Check initialization state */ 2689 RTK_CHK_INIT_STATE(); 2690 2691 if (vid > RTL8367C_VIDMAX) 2692 return RT_ERR_L2_VID; 2693 2694 if((ip_addr & 0xF0000000) != 0xE0000000) 2695 return RT_ERR_INPUT; 2696 2697 for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) 2698 { 2699 if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) 2700 return retVal; 2701 2702 if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) 2703 { 2704 group_addr = 0xE0000000; 2705 group_vid = 0; 2706 pmask = 0; 2707 if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, group_addr, group_vid, pmask, DISABLED))!=RT_ERR_OK) 2708 return retVal; 2709 2710 return RT_ERR_OK; 2711 } 2712 } 2713 2714 return RT_ERR_FAILED; 2715} 2716 2717/* Function Name: 2718 * rtk_l2_ipMcastGroupEntry_get 2719 * Description: 2720 * get an entry from IP Multicast group table 2721 * Input: 2722 * ip_addr - IP address 2723 * vid - VLAN ID 2724 * Output: 2725 * pPortmask - member port mask 2726 * Return: 2727 * RT_ERR_OK - OK 2728 * RT_ERR_FAILED - Failed 2729 * RT_ERR_SMI - SMI access error 2730 * RT_ERR_TBL_FULL - Table Full 2731 * Note: 2732 * Delete an entry from IP Multicast group table. 2733 */ 2734rtk_api_ret_t rtk_l2_ipMcastGroupEntry_get(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) 2735{ 2736 rtk_int32 index; 2737 ipaddr_t group_addr; 2738 rtk_uint32 group_vid; 2739 rtk_uint32 valid; 2740 rtk_uint32 pmask; 2741 rtk_api_ret_t retVal; 2742 2743 /* Check initialization state */ 2744 RTK_CHK_INIT_STATE(); 2745 2746 if((ip_addr & 0xF0000000) != 0xE0000000) 2747 return RT_ERR_INPUT; 2748 2749 if (vid > RTL8367C_VIDMAX) 2750 return RT_ERR_L2_VID; 2751 2752 if(NULL == pPortmask) 2753 return RT_ERR_NULL_POINTER; 2754 2755 for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) 2756 { 2757 if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) 2758 return retVal; 2759 2760 if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) 2761 { 2762 if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) 2763 return retVal; 2764 2765 return RT_ERR_OK; 2766 } 2767 } 2768 2769 return RT_ERR_FAILED; 2770} 2771 2772/* Function Name: 2773 * rtk_l2_entry_get 2774 * Description: 2775 * Get LUT unicast entry. 2776 * Input: 2777 * pL2_entry - Index field in the structure. 2778 * Output: 2779 * pL2_entry - other fields such as MAC, port, age... 2780 * Return: 2781 * RT_ERR_OK - OK 2782 * RT_ERR_FAILED - Failed 2783 * RT_ERR_SMI - SMI access error 2784 * RT_ERR_L2_EMPTY_ENTRY - Empty LUT entry. 2785 * RT_ERR_INPUT - Invalid input parameters. 2786 * Note: 2787 * This API is used to get address by index from 0~2111. 2788 */ 2789rtk_api_ret_t rtk_l2_entry_get(rtk_l2_addr_table_t *pL2_entry) 2790{ 2791 rtk_api_ret_t retVal; 2792 rtk_uint32 method; 2793 rtl8367c_luttb l2Table; 2794 2795 /* Check initialization state */ 2796 RTK_CHK_INIT_STATE(); 2797 2798 if (pL2_entry->index >= rtk_switch_maxLutAddrNumber_get()) 2799 return RT_ERR_INPUT; 2800 2801 l2Table.address= pL2_entry->index; 2802 method = LUTREADMETHOD_ADDRESS; 2803 if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) 2804 return retVal; 2805 2806 if ((pL2_entry->index>0x800)&&(l2Table.lookup_hit==0)) 2807 return RT_ERR_L2_EMPTY_ENTRY; 2808 2809 if(l2Table.l3lookup) 2810 { 2811 if(l2Table.l3vidlookup) 2812 { 2813 memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); 2814 pL2_entry->is_ipmul = l2Table.l3lookup; 2815 pL2_entry->sip = l2Table.sip; 2816 pL2_entry->dip = l2Table.dip; 2817 pL2_entry->is_static = l2Table.nosalearn; 2818 2819 /* Get Logical port mask */ 2820 if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) 2821 return retVal; 2822 2823 pL2_entry->fid = 0; 2824 pL2_entry->age = 0; 2825 pL2_entry->auth = 0; 2826 pL2_entry->sa_block = 0; 2827 pL2_entry->is_ipvidmul = 1; 2828 pL2_entry->l3_vid = l2Table.l3_vid; 2829 } 2830 else 2831 { 2832 memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); 2833 pL2_entry->is_ipmul = l2Table.l3lookup; 2834 pL2_entry->sip = l2Table.sip; 2835 pL2_entry->dip = l2Table.dip; 2836 pL2_entry->is_static = l2Table.nosalearn; 2837 2838 /* Get Logical port mask */ 2839 if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) 2840 return retVal; 2841 2842 pL2_entry->fid = 0; 2843 pL2_entry->age = 0; 2844 pL2_entry->auth = 0; 2845 pL2_entry->sa_block = 0; 2846 pL2_entry->is_ipvidmul = 0; 2847 pL2_entry->l3_vid = 0; 2848 } 2849 } 2850 else if(l2Table.mac.octet[0]&0x01) 2851 { 2852 memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); 2853 memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); 2854 pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; 2855 pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; 2856 pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; 2857 pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; 2858 pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; 2859 pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; 2860 pL2_entry->is_ipmul = l2Table.l3lookup; 2861 pL2_entry->is_static = l2Table.nosalearn; 2862 2863 /* Get Logical port mask */ 2864 if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) 2865 return retVal; 2866 2867 pL2_entry->ivl = l2Table.ivl_svl; 2868 if(l2Table.ivl_svl == 1) /* IVL */ 2869 { 2870 pL2_entry->cvid = l2Table.cvid_fid; 2871 pL2_entry->fid = 0; 2872 } 2873 else /* SVL*/ 2874 { 2875 pL2_entry->cvid = 0; 2876 pL2_entry->fid = l2Table.cvid_fid; 2877 } 2878 pL2_entry->auth = l2Table.auth; 2879 pL2_entry->sa_block = l2Table.sa_block; 2880 pL2_entry->age = 0; 2881 pL2_entry->is_ipvidmul = 0; 2882 pL2_entry->l3_vid = 0; 2883 } 2884 else if((l2Table.age != 0)||(l2Table.nosalearn == 1)) 2885 { 2886 memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); 2887 memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); 2888 pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; 2889 pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; 2890 pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; 2891 pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; 2892 pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; 2893 pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; 2894 pL2_entry->is_ipmul = l2Table.l3lookup; 2895 pL2_entry->is_static = l2Table.nosalearn; 2896 2897 /* Get Logical port mask */ 2898 if ((retVal = rtk_switch_portmask_P2L_get(1<<(l2Table.spa), &(pL2_entry->portmask)))!=RT_ERR_OK) 2899 return retVal; 2900 2901 pL2_entry->ivl = l2Table.ivl_svl; 2902 pL2_entry->cvid = l2Table.cvid_fid; 2903 pL2_entry->fid = l2Table.fid; 2904 pL2_entry->auth = l2Table.auth; 2905 pL2_entry->sa_block = l2Table.sa_block; 2906 pL2_entry->age = l2Table.age; 2907 pL2_entry->is_ipvidmul = 0; 2908 pL2_entry->l3_vid = 0; 2909 } 2910 else 2911 return RT_ERR_L2_EMPTY_ENTRY; 2912 2913 return RT_ERR_OK; 2914} 2915 2916 2917