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