openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

lplist.c (17017B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        lplist.c
      8  * Purpose:     Logical port list functions
      9  * Requires:
     10  *
     11  * Notes:       The following is intended:
     12  *
     13  *     bcmx_lplist_t alist;
     14  *
     15  *     ... list is built up with some elements ....
     16  *
     17  *     if (!bcmx_lplist_init(alist, 0, 0))  {
     18  *
     19  *         ... list is built up with some elements, then ....
     20  *
     21  *         BCMX_LPLIST_ITER(alist, lport, count) {
     22  *             .... do stuff with lport ....
     23  *         }
     24  *     }
     25  */    
     26 
     27 #include <sdk_config.h>
     28 #include <sal/core/libc.h>
     29 #include <shared/alloc.h>
     30 
     31 #include <bcm/error.h>
     32 
     33 #include <bcmx/bcmx.h>
     34 #include <bcmx/lplist.h>
     35 
     36 /* This is min size of a list when allocated. */
     37 #ifndef BCMX_LPLIST_MIN_COUNT
     38 #define BCMX_LPLIST_MIN_COUNT 16
     39 #endif
     40 
     41 /* This is the increment when reallocating */
     42 #ifndef BCMX_LPLIST_MIN_INCREMENT
     43 #define BCMX_LPLIST_MIN_INCREMENT 16
     44 #endif
     45 
     46 /* Is list empty? */
     47 #define LP_EMPTY(list)  ((list)->lp_last < 0)
     48 
     49 /* Number of elements currently in list */
     50 #define LP_COUNT(list)  ((list)->lp_last + 1)
     51 
     52 /* Size of an 'n' list elements */
     53 #define LP_ELSIZE(n) ((n) * sizeof(bcmx_lport_t))
     54 
     55 /* Next free cell on the list.  No updates to list. */
     56 #define LP_FIRST_FREE(list)    ((list)->lp_ports[(list)->lp_last + 1])
     57 
     58 /*
     59  * Function:
     60  *      _bcmx_lplist_realloc
     61  * Purpose:
     62  *      Re-allocate a port list
     63  * Parameters:
     64  *      list       -  The port list to change
     65  *      new_count  -  The new count of ports
     66  * Returns:
     67  *      BCM_E_XXX
     68  */
     69 
     70 STATIC int
     71 _bcmx_lplist_realloc(bcmx_lplist_t *list, int new_count)
     72 {
     73     bcmx_lport_t *old_ports;
     74 
     75     if (list == NULL || list->lp_ports == NULL) {
     76         return BCM_E_INTERNAL;
     77     }
     78 
     79     old_ports = list->lp_ports;
     80 
     81     list->lp_ports = (bcmx_lport_t *)
     82         sal_alloc(LP_ELSIZE(new_count), "lplist");
     83 
     84     if (!list->lp_ports) {
     85         list->lp_ports = old_ports;
     86         return BCM_E_MEMORY;
     87     }
     88 
     89     sal_memcpy(list->lp_ports, old_ports, LP_ELSIZE(LP_COUNT(list)));
     90 
     91     list->lp_alloc = new_count;
     92 
     93     sal_free(old_ports);
     94 
     95     return BCM_E_NONE;
     96 }
     97 
     98 /*
     99  * Function:
    100  *      bcmx_lplist_init
    101  * Purpose:
    102  *      Allocate and initialize a port list
    103  * Parameters:
    104  *      list        - The port list to initialize
    105  *      init_count  - The initial count to use
    106  *      flags       - List flags - deprecated and ignored
    107  * Returns:
    108  *      BCM_E_XXX
    109  * Notes:
    110  *      If successful, then list->lp_max != 0.
    111  *      At least BCMX_LPLIST_MIN_COUNT ports will be allocated.
    112  *      The port list structure itself must be allocated already
    113  *      (that is, list != NULL).
    114  */
    115 
    116 int
    117 bcmx_lplist_init(bcmx_lplist_t *list, int init_count, uint32 flags)
    118 {
    119     int ports = BCMX_LPLIST_MIN_COUNT;
    120 
    121     if (!list) {
    122         return BCM_E_PARAM;
    123     }
    124 
    125     if (init_count > ports) {
    126         ports = init_count;
    127     }
    128 
    129     list->lp_ports = sal_alloc(LP_ELSIZE(ports), "lpports");
    130     if (!list->lp_ports) {
    131         return BCM_E_MEMORY;
    132     }
    133 
    134     list->lp_alloc = ports;
    135     list->lp_last = -1;
    136 
    137     return BCM_E_NONE;
    138 }
    139 
    140 /*
    141  * Function:
    142  *      bcmx_lplist_t_init
    143  * Purpose:
    144  *      Initialize the bcmx_lplist_t structure.
    145  *      Allocate and initialize a port list.
    146  * Parameters:
    147  *      list       -  Pointer to port list structure to initialize
    148  * Returns:
    149  *      None
    150  * Note:
    151  *      Although the functionality of this routine is also provided by
    152  *      bcmx_lplist_init, this has an API interface consistent
    153  *      with other structure initialization/free routines.
    154  */
    155 void
    156 bcmx_lplist_t_init(bcmx_lplist_t *list)
    157 {
    158     bcmx_lplist_init(list, 0, 0);
    159 }
    160 
    161 /*
    162  * Function:
    163  *      bcmx_lplist_free
    164  * Purpose:
    165  *      De-allocate a port list
    166  * Parameters:
    167  *      list        - The port list to de-allocate
    168  * Returns:
    169  *      BCM_E_XXX
    170  */
    171 
    172 int
    173 bcmx_lplist_free(bcmx_lplist_t *list)
    174 {
    175     int rv = BCM_E_PARAM;
    176 
    177     if (!bcmx_lplist_is_null(list)) {
    178         if (list->lp_ports) {
    179             sal_free(list->lp_ports);
    180         }
    181         list->lp_ports = 0;
    182         rv = BCM_E_NONE;
    183     }
    184 
    185     return rv;
    186 }
    187 
    188 /*
    189  * Function:
    190  *      bcmx_lplist_t_free
    191  * Purpose:
    192  *      De-allocate a port list
    193  * Parameters:
    194  *      list        - The port list to de-allocate
    195  * Returns:
    196  *      None
    197  * Note:
    198  *      Although the functionality of this routine is also provided by
    199  *      bcmx_lplist_free, this has an API interface consistent
    200  *      with other structure initialization/free routines.
    201  */
    202 void
    203 bcmx_lplist_t_free(bcmx_lplist_t *list)
    204 {
    205     bcmx_lplist_free(list);
    206 }
    207 
    208 /*
    209  * Function:
    210  *      bcmx_lplist_clear
    211  * Purpose:
    212  *      Make a port list empty
    213  * Parameters:
    214  *      list       -  The port list to clear
    215  * Returns:
    216  *      BCM_E_XXX
    217  * Notes:
    218  */
    219 
    220 int
    221 bcmx_lplist_clear(bcmx_lplist_t *list)
    222 {
    223     if (!bcmx_lplist_is_null(list)) {
    224         list->lp_last = -1;
    225     }
    226 
    227     return BCM_E_NONE;
    228 }
    229 
    230 
    231 /****************************************************************
    232  *
    233  * The base Logical Port List functions.
    234  *
    235  * See also the macros BCMX_LPLIST_REMOVE, etc.
    236  */
    237 
    238 
    239 /*
    240  * Function:
    241  *      bcmx_lplist_index_get
    242  * Purpose:
    243  *      Get the index of the first occurrance of a port on the list
    244  * Parameters:
    245  *      list       -- The list to search
    246  * Returns:
    247  *      Index >= 0 if found; otherwise BCM_E_NOT_FOUND
    248  */
    249 
    250 int
    251 bcmx_lplist_index_get(bcmx_lplist_t *list, bcmx_lport_t port)
    252 {
    253     return bcmx_lplist_index_get_from(list, 0, port);
    254 }
    255 
    256 
    257 /*
    258  * Function:
    259  *      bcmx_lplist_index_get_from
    260  * Purpose:
    261  *      Get the index of the first occurrance of a port on the list
    262  *      starting at position
    263  * Parameters:
    264  *      list       -- The list to search
    265  *      position   -- The position to start the search
    266  * Returns:
    267  *      BCM_E_PARAM if position is out of range
    268  *      Index >= 0 if found; otherwise BCM_E_NOT_FOUND
    269  */
    270 
    271 int
    272 bcmx_lplist_index_get_from(bcmx_lplist_t *list, int position, bcmx_lport_t port)
    273 {
    274     int i;
    275 
    276     if (bcmx_lplist_is_empty(list)) {
    277         return BCM_E_NOT_FOUND;
    278     }
    279 
    280     if (position < 0 || position > list->lp_last) {
    281         return BCM_E_PARAM;
    282     }
    283 
    284     for (i = position; i <= list->lp_last; i++) {
    285         if (list->lp_ports[i] == port) {
    286             return i;
    287         }
    288     }
    289 
    290     return BCM_E_NOT_FOUND;
    291 }
    292 
    293 /*
    294  * Function:
    295  *      bcmx_lplist_index
    296  * Purpose:
    297  *      Get the lport at position
    298  * Parameters:
    299  *      list       -- The list to index
    300  *      position   -- The position to retrieve lport
    301  * Returns:
    302  *      BCMX_NO_SUCH_LPORT if position is out of range
    303  *      otherwise lport
    304  */
    305 
    306 bcmx_lport_t
    307 bcmx_lplist_index(bcmx_lplist_t *list, int position)
    308 {
    309     bcmx_lport_t lport = BCMX_NO_SUCH_LPORT;
    310 
    311     if (!bcmx_lplist_is_null(list) &&
    312         position >= 0 && position <= list->lp_last) {
    313         lport = list->lp_ports[position];
    314     }
    315 
    316     return lport;
    317 }
    318 
    319 /*
    320  * Function:
    321  *      bcmx_lplist_add
    322  * Purpose:
    323  *      Add a port to the end of a lplist
    324  * Parameters:
    325  *      list       -- The list to update
    326  *      lport      -- The port to add
    327  * Returns:
    328  *      BCM_E_XXX
    329  * Notes:
    330  *      Will initialize the list if it is NULL.
    331  *      Reallocates if not enough space for list.
    332  */
    333 
    334 int
    335 bcmx_lplist_add(bcmx_lplist_t *list, bcmx_lport_t lport)
    336 {
    337     if (bcmx_lplist_is_null(list)) {
    338         BCM_IF_ERROR_RETURN(bcmx_lplist_init(list, -1, 0));
    339     }
    340 
    341     if (BCMX_LPLIST_COUNT(list) + 1 >= list->lp_alloc) {
    342         if (_bcmx_lplist_realloc(list, list->lp_alloc +
    343                                  BCMX_LPLIST_MIN_INCREMENT)
    344             != BCM_E_NONE) {
    345             return BCM_E_MEMORY;
    346         }
    347     }
    348 
    349     (list->lp_last)++;
    350     list->lp_ports[list->lp_last] = lport;
    351 
    352     return BCM_E_NONE;
    353 }
    354 
    355 
    356 /*
    357  * Function:
    358  *      _bcmx_lplist_pbmp_add
    359  * Purpose:
    360  *      
    361  * Parameters:
    362  *      list       -  The port list to access
    363  *      unit
    364  *      pbm
    365  * Returns:
    366  * Notes:
    367  */
    368 
    369 
    370 int
    371 _bcmx_lplist_pbmp_add(bcmx_lplist_t *list, int unit, bcm_pbmp_t pbm)
    372 {
    373     bcmx_lport_t lport;
    374     bcm_port_t port;
    375     int rv = BCM_E_NONE;
    376 
    377     BCM_PBMP_ITER(pbm, port) {
    378 	lport = bcmx_unit_port_to_lport(unit, port);
    379 	rv = bcmx_lplist_add(list, lport);
    380 	if (rv < 0) {
    381 	    break;
    382 	}
    383     }
    384 
    385     return rv;
    386 }
    387 
    388 /*
    389  * Function:
    390  *      bcmx_lplist_port_remove
    391  * Purpose:
    392  *      Remove a port from the list.  
    393  * Parameters:
    394  *      list     - The list to act on
    395  *      lport    - The logical port to look for and remove
    396  *      all      - If true, remove all occurances; otherwise just first.
    397  * Returns:
    398  *      BCM_E_PARAM - parameter error
    399  *      BCM_E_NONE  - port removed
    400  * Notes:
    401  */
    402 
    403 int
    404 bcmx_lplist_port_remove(bcmx_lplist_t *list, bcmx_lport_t lport, int all)
    405 {
    406     int rv = BCM_E_NONE;
    407     int count = 0;
    408     int idx = 0;
    409 
    410     while ((idx=bcmx_lplist_index_get_from(list, idx, lport)) >= 0) {
    411         count++;
    412         bcmx_lplist_idx_remove(list, idx);
    413         if (!all || (idx > list->lp_last)) {
    414             break;
    415         }
    416     }
    417 
    418     if ((idx < 0 && idx != BCM_E_NOT_FOUND) || count == 0) {
    419         rv = idx;
    420     }
    421    
    422 
    423     return rv;
    424 }
    425 
    426 /*
    427  * Function:
    428  *      bcmx_lplist_eq
    429  * Purpose:
    430  *      Compare two port lists
    431  * Parameters:
    432  *      list1   - List to examine
    433  *      list2   - List to examine
    434  * Returns:
    435  *      1 if equal, 0 if not
    436  * Notes:
    437  *     Just a simple check that every port in one list is in the other.
    438  *     Thus it doesn't detect differences in order or multiplicity.
    439  */
    440 
    441 int
    442 bcmx_lplist_eq(bcmx_lplist_t *list1, bcmx_lplist_t *list2)
    443 {
    444     bcmx_lport_t lport;
    445     int count;
    446     int list1_empty, list2_empty;
    447 
    448     list1_empty = bcmx_lplist_is_empty(list1);
    449     list2_empty = bcmx_lplist_is_empty(list2);
    450 
    451     if (list1_empty && list2_empty) {
    452         /* Both lists are empty */
    453         return 1;
    454     } else if (list1_empty != list2_empty) {
    455         /* One list is empty, the other not empty */
    456         return 0;
    457     } else {
    458         /* Both lists not empty */
    459         BCMX_LPLIST_IDX_ITER(list1, lport, count) {
    460             if (bcmx_lplist_index_get(list2, lport) < 0) {
    461                 return 0;
    462             }
    463         }
    464 
    465         BCMX_LPLIST_IDX_ITER(list2, lport, count) {
    466             if (bcmx_lplist_index_get(list1, lport) < 0) {
    467                 return 0;
    468             }
    469         }
    470     }
    471     return 1;
    472 }
    473 
    474 /*
    475  * Function:
    476  *      bcmx_lplist_append
    477  * Purpose:
    478  *      Copy list2 to end of list1
    479  * Parameters:
    480  *      list1     - List to change
    481  *      list2     - List copied onto the end of list1
    482  *
    483  * Returns:
    484  *      BCM_E_XXX
    485  * Notes:
    486  *      Does not support sorted lists.
    487  *      Does not support extra flags for port types
    488  */
    489 
    490 int
    491 bcmx_lplist_append(bcmx_lplist_t *list1, bcmx_lplist_t *list2)
    492 {
    493     int total;
    494 
    495     if (bcmx_lplist_is_null(list1)) {
    496         BCM_IF_ERROR_RETURN(bcmx_lplist_init(list1, -1, 0));
    497     }
    498 
    499     if (bcmx_lplist_is_empty(list2)) {
    500         return BCM_E_NONE;
    501     }
    502 
    503     total = LP_COUNT(list1) + LP_COUNT(list2);
    504     if (list1->lp_alloc <= total) {
    505         BCM_IF_ERROR_RETURN(_bcmx_lplist_realloc(list1,
    506                 total + BCMX_LPLIST_MIN_INCREMENT));
    507     }
    508 
    509     sal_memcpy(&(LP_FIRST_FREE(list1)), list2->lp_ports,
    510                LP_ELSIZE(LP_COUNT(list2)));
    511 
    512     list1->lp_last += LP_COUNT(list2);
    513 
    514     return BCM_E_NONE;
    515 }
    516 
    517 /*
    518  * Function:
    519  *      bcmx_lplist_copy
    520  * Purpose:
    521  *      Copy src to dest, overwriting dest
    522  * Parameters:
    523  *      dest    - Destination list
    524  *      src     - Source list
    525  * Returns:
    526  *      BCM_E_XXX
    527  * Notes:
    528  */
    529 
    530 int
    531 bcmx_lplist_copy(bcmx_lplist_t *dest, bcmx_lplist_t *src)
    532 {
    533     if (bcmx_lplist_is_null(dest)) {
    534         BCM_IF_ERROR_RETURN(bcmx_lplist_init(dest, -1, 0));
    535     }
    536 
    537     if (bcmx_lplist_is_empty(src)) {
    538         return bcmx_lplist_clear(dest);
    539     }
    540 
    541     dest->lp_last = 0;
    542     if (dest->lp_alloc < src->lp_alloc) {
    543         BCM_IF_ERROR_RETURN(_bcmx_lplist_realloc(dest, src->lp_alloc));
    544     }
    545 
    546     sal_memcpy(dest->lp_ports, src->lp_ports, LP_ELSIZE(LP_COUNT(src)));
    547     dest->lp_last = src->lp_last;
    548 
    549     return BCM_E_NONE;
    550 }
    551 
    552 
    553 
    554 /* Current absolute max for number of logical ports in a list */
    555 #ifndef BCMX_LPLIST_ABSOLUTE_MAX_LEN
    556 #define BCMX_LPLIST_ABSOLUTE_MAX_LEN 3000  
    557 #endif
    558 
    559 /*
    560  * Function:
    561  *      bcmx_lplist_check
    562  * Purpose:
    563  *      Debug function.  Check the consistency of a list
    564  * Parameters:
    565  *      list   - List to examine
    566  * Returns:
    567  *      0 if okay, < 0 if not consistent
    568  */
    569 
    570 int
    571 bcmx_lplist_check(bcmx_lplist_t *list)
    572 {
    573     if (!list) {
    574         return -1;
    575     }
    576 
    577     if (!list->lp_ports) {
    578         return -2;
    579     }
    580 
    581     if (list->lp_alloc < 0) {
    582         return -3;
    583     }
    584 
    585     if (list->lp_alloc > BCMX_LPLIST_ABSOLUTE_MAX_LEN) {
    586         return -4;
    587     }
    588 
    589     if (list->lp_last >= list->lp_alloc) {
    590         return -5;
    591     }
    592 
    593     return 0;
    594 }
    595 
    596 /*
    597  * Function:
    598  *      bcmx_lplist_range
    599  * Purpose:
    600  *      Add a range of ports to a port list
    601  * Parameters:
    602  *      list     - list to add ports to
    603  *      start    - Low port to add
    604  *      end      - Last port to add
    605  * Returns:
    606  *      BCM_E_XXX
    607  */
    608 
    609 int
    610 bcmx_lplist_range(bcmx_lplist_t *list, bcmx_lport_t start, bcmx_lport_t end)
    611 {
    612     bcmx_lport_t curport = start;
    613     int rv;
    614 
    615     while ((curport != end) && (curport != BCMX_NO_SUCH_LPORT)) {
    616         if ((rv = bcmx_lplist_add(list, curport)) < 0) {
    617             return rv;
    618         }
    619         curport = BCMX_LPORT_NEXT(curport);
    620     }
    621     if (curport == end) {
    622         if ((rv = bcmx_lplist_add(list, curport)) < 0) {
    623             return rv;
    624         }
    625     }
    626 
    627     return BCM_E_NONE;
    628 }
    629 
    630 /* Functional version of lplist macros */
    631 
    632 
    633 /*
    634  * Function:
    635  *      bcmx_lplist_is_null
    636  * Purpose:
    637  *      
    638  * Parameters:
    639  *      list
    640  *
    641  * Returns:
    642  */
    643 
    644 int
    645 bcmx_lplist_is_null(bcmx_lplist_t *list)
    646 {
    647     return BCMX_LPLIST_IS_NULL(list);
    648 }
    649 
    650 
    651 /*
    652  * Function:
    653  *      bcmx_lplist_is_empty
    654  * Purpose:
    655  *      
    656  * Parameters:
    657  *      list
    658  *
    659  * Returns:
    660  */
    661 
    662 int
    663 bcmx_lplist_is_empty(bcmx_lplist_t *list)
    664 {
    665     return BCMX_LPLIST_IS_EMPTY(list);
    666 }
    667 
    668 
    669 /*
    670  * Function:
    671  *      bcmx_lplist_count
    672  * Purpose:
    673  *      
    674  * Parameters:
    675  *      list
    676  *
    677  * Returns:
    678  */
    679 
    680 int
    681 bcmx_lplist_count(bcmx_lplist_t *list)
    682 {
    683     return BCMX_LPLIST_COUNT(list);
    684 }
    685 
    686 
    687 /*
    688  * Function:
    689  *      bcmx_lplist_remove
    690  * Purpose:
    691  *      
    692  * Parameters:
    693  *      list
    694  *      lport
    695  *
    696  * Returns:
    697  */
    698 
    699 void
    700 bcmx_lplist_remove(bcmx_lplist_t *list, int lport)
    701 {
    702     if (!bcmx_lplist_is_empty(list)) {
    703         BCMX_LPLIST_REMOVE(list, lport);
    704     }
    705 }
    706 
    707 
    708 /*
    709  * Function:
    710  *      bcmx_lplist_idx_remove
    711  * Purpose:
    712  *      
    713  * Parameters:
    714  *      list
    715  *      idx
    716  *
    717  * Returns:
    718  */
    719 
    720 void
    721 bcmx_lplist_idx_remove(bcmx_lplist_t *list, int idx)
    722 {
    723     if (!bcmx_lplist_is_empty(list)) {
    724         BCMX_LPLIST_IDX_REMOVE(list, idx);
    725     }
    726 }
    727 
    728 
    729 /*
    730  * Function:
    731  *      bcmx_lplist_pbmp_add
    732  * Purpose:
    733  *      
    734  * Parameters:
    735  *      list
    736  *      unit
    737  *      pbm
    738  *
    739  * Returns:
    740  */
    741 
    742 int
    743 bcmx_lplist_pbmp_add(bcmx_lplist_t *list, int unit, bcm_pbmp_t *pbm)
    744 {
    745     int rv = BCM_E_PARAM;
    746 
    747     if (list) {
    748         rv = _bcmx_lplist_pbmp_add(list, unit, *pbm);
    749     }
    750 
    751     return rv;
    752 }
    753 
    754 
    755 /*
    756  * Function:
    757  *      bcmx_lplist_to_pbmp
    758  * Purpose:
    759  *      
    760  * Parameters:
    761  *      list
    762  *      unit
    763  *      pbm
    764  *
    765  * Returns:
    766  *      void
    767  */
    768 
    769 void
    770 bcmx_lplist_to_pbmp(bcmx_lplist_t *list, int unit, bcm_pbmp_t *pbm)
    771 {
    772     bcm_pbmp_t p;
    773 
    774     BCM_PBMP_CLEAR(p);
    775     if (!bcmx_lplist_is_empty(list)) {
    776         BCMX_LPLISTPTR_TO_PBMP(list, unit, p);
    777     }
    778     *pbm = p;
    779 }
    780 
    781 
    782 /*
    783  * Function:
    784  *      _bcmx_lplist_lport_compare
    785  * Purpose:
    786  *      lport sort compare function
    787  * Parameters:
    788  *      a - pointer to 1st element
    789  *      b - pointer to 2nd element
    790  * Returns:
    791  *      -1 if *a < *b
    792  *       0 if *a = *b
    793  *      +1 if *a > *b
    794  */
    795 
    796 
    797 STATIC int
    798 _bcmx_lplist_lport_compare(void *a, void *b)
    799 {
    800     bcmx_lport_t        ap, bp;
    801     int rv;
    802 
    803     ap = *(bcmx_lport_t *)a;
    804     bp = *(bcmx_lport_t *)b;
    805 
    806     if (ap < bp) {
    807 	rv = -1;
    808     } else if (ap > bp) {
    809 	rv = 1;
    810     } else {
    811         rv = 0;
    812     }
    813 
    814     return rv;
    815 }
    816 
    817 
    818 /*
    819  * Function:
    820  *      bcmx_lplist_sort
    821  * Purpose:
    822  *      Sort lplist in ascending order
    823  * Parameters:
    824  *      list   - List to sort
    825  * Returns:
    826  *      BCM_E_NONE  - list sorted
    827  */
    828 
    829 int
    830 bcmx_lplist_sort(bcmx_lplist_t *list)
    831 {
    832     if (!bcmx_lplist_is_empty(list)) {
    833         _shr_sort(list->lp_ports, LP_COUNT(list),
    834                   sizeof(bcmx_lport_t), _bcmx_lplist_lport_compare);
    835     }
    836 
    837     return BCM_E_NONE;
    838 }
    839 
    840 
    841 /*
    842  * Function:
    843  *      bcmx_lplist_uniq
    844  * Purpose:
    845  *      Delete duplicate elements in list
    846  * Parameters:
    847  *      list   - List to uniqueify
    848  * Returns:
    849  *      BCM_E_NONE
    850  */
    851 
    852 int
    853 bcmx_lplist_uniq(bcmx_lplist_t *list)
    854 {
    855     int idx, dup;
    856     bcmx_lport_t lport;
    857 
    858     if (!bcmx_lplist_is_empty(list)) {
    859         for ( idx = 0; idx < list->lp_last; idx++ ) {
    860             lport = list->lp_ports[idx];
    861             while ((dup = bcmx_lplist_index_get_from(list,
    862                                                      idx+1, lport)) >= 0) {
    863                 bcmx_lplist_idx_remove(list, dup);
    864             }
    865         }
    866     }
    867 
    868     return BCM_E_NONE;
    869 }