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