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

phymod_symbol_fields.c (4101B)


      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 
      8 /*******************************************************************************
      9  *
     10  * PHYMOD Symbol Field Routines
     11  */
     12 
     13 #include <phymod/phymod_symbols.h>
     14 
     15 /*
     16  * Function:
     17  *	phymod_field_get
     18  * Purpose:
     19  *	Extract multi-word field value from multi-word register/memory.
     20  * Parameters:
     21  *	entbuf - current contents of register/memory (word array)
     22  *      sbit - bit number of first bit of the field to extract
     23  *      ebit - bit number of last bit of the field to extract
     24  *      fbuf - buffer where to store extracted field value
     25  * Returns:
     26  *      Pointer to extracted field value.
     27  */
     28 uint32_t *
     29 phymod_field_get(const uint32_t *entbuf, int sbit, int ebit, uint32_t *fbuf)
     30 {
     31     int i, wp, bp, len;
     32 
     33     bp = sbit;
     34     len = ebit - sbit + 1;
     35 
     36     wp = bp / 32;
     37     bp = bp & (32 - 1);
     38     i = 0;
     39 
     40     for (; len > 0; len -= 32, i++) {
     41         if (bp) {
     42             fbuf[i] = (entbuf[wp++] >> bp) & ((1 << (32 - bp)) - 1);
     43             if (len > (32 - bp)) {
     44                 fbuf[i] |= entbuf[wp] << (32 - bp);
     45             }
     46         } else {
     47             fbuf[i] = entbuf[wp++];
     48         }
     49         if (len < 32) {
     50             fbuf[i] &= ((1 << len) - 1);
     51         }
     52     }
     53 
     54     return fbuf;
     55 }
     56 
     57 /*
     58  * Function:
     59  *	phymod_field_set
     60  * Purpose:
     61  *	Assign multi-word field value in multi-word register/memory.
     62  * Parameters:
     63  *	entbuf - current contents of register/memory (word array)
     64  *      sbit - bit number of first bit of the field to extract
     65  *      ebit - bit number of last bit of the field to extract
     66  *      fbuf - buffer with new field value
     67  * Returns:
     68  *      Nothing.
     69  */
     70 int
     71 phymod_field_set(uint32_t *entbuf, int sbit, int ebit, uint32_t *fbuf)
     72 {
     73     uint32_t mask;
     74     int i, wp, bp, len;
     75 
     76     if (fbuf == NULL) {
     77         return -1;
     78     }
     79 
     80     bp = sbit;
     81     len = ebit - sbit + 1;
     82     if (len <= 0) {
     83         return -1;
     84     }
     85 
     86     wp = bp / 32;
     87     bp = bp & (32 - 1);
     88     i = 0;
     89 
     90     for (; len > 0; len -= 32, i++) {
     91         if (bp) {
     92             if (len < 32) {
     93                 mask = (1 << len) - 1;
     94             } else {
     95                 mask = ~0;
     96             }
     97             entbuf[wp] &= ~(mask << bp);
     98             entbuf[wp++] |= fbuf[i] << bp;
     99             if (len > (32 - bp)) {
    100                 entbuf[wp] &= ~(mask >> (32 - bp));
    101                 entbuf[wp] |= fbuf[i] >> (32 - bp) & ((1 << bp) - 1);
    102             }
    103         } else {
    104             if (len < 32) {
    105                 mask = (1 << len) - 1;
    106                 entbuf[wp] &= ~mask;
    107                 entbuf[wp++] |= (fbuf[i] & mask) << bp;
    108             } else {
    109                 entbuf[wp++] = fbuf[i];
    110             }
    111         }
    112     }
    113     return 0;
    114 }
    115 
    116 uint32_t *
    117 phymod_field_info_decode(uint32_t* fp, phymod_field_info_t* finfo, const char** fnames)
    118 {
    119     if(!fp) {
    120         return NULL; 
    121     }
    122 
    123     if(finfo) {
    124         /*
    125          * Single or Double Word Descriptor?
    126          */
    127         if(PHYMOD_SYMBOL_FIELD_EXT(*fp)) {
    128             /* Double Word */
    129             finfo->fid = PHYMOD_SYMBOL_FIELD_EXT_ID_GET(*fp); 
    130             finfo->maxbit = PHYMOD_SYMBOL_FIELD_EXT_MAX_GET(*(fp+1)); 
    131             finfo->minbit = PHYMOD_SYMBOL_FIELD_EXT_MIN_GET(*(fp+1)); 
    132         }       
    133         else {
    134             /* Single Word */
    135             finfo->fid = PHYMOD_SYMBOL_FIELD_ID_GET(*fp); 
    136             finfo->maxbit = PHYMOD_SYMBOL_FIELD_MAX_GET(*fp); 
    137             finfo->minbit = PHYMOD_SYMBOL_FIELD_MIN_GET(*fp); 
    138         }       
    139 
    140         if(fnames) {
    141             finfo->name = fnames[finfo->fid]; 
    142         }
    143         else {
    144             finfo->name = NULL; 
    145         }       
    146     }
    147 
    148     if(PHYMOD_SYMBOL_FIELD_LAST(*fp)) {
    149         return NULL; 
    150     }
    151 
    152     if(PHYMOD_SYMBOL_FIELD_EXT(*fp)) {
    153         return fp+2; 
    154     }
    155 
    156     return fp+1; 
    157 }
    158 
    159 uint32_t
    160 phymod_field_info_count(uint32_t* fp)
    161 {    
    162     int count = 0; 
    163     while(fp) {
    164         fp = phymod_field_info_decode(fp, NULL, NULL); 
    165         count++; 
    166     }   
    167     return count; 
    168 }