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

util.c (50691B)


      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  * General utility routines
      8  */
      9 
     10 #include <assert.h>
     11 
     12 #include <shared/bsl.h>
     13 #include <shared/util.h>
     14 #include <shared/l3.h>
     15 #include <shared/error.h>
     16 #include <soc/error.h>
     17 
     18 #include <sal/types.h>
     19 #include <sal/core/libc.h>
     20 
     21 #define RDPC_MUTEX_TIMEOUT (100000)
     22 
     23 /*
     24  * Swap the bytes in a 32-bit word
     25  */
     26 
     27 STATIC INLINE unsigned int
     28 __shr_swap32(unsigned int i)
     29 {
     30     i = (i << 16) | (i >> 16);
     31 
     32     return (i & 0xff00ffff) >> 8 | (i & 0xffff00ff) << 8;
     33 }
     34 
     35 unsigned int
     36 _shr_swap32(unsigned int i)
     37 {
     38     return __shr_swap32(i);
     39 }
     40 
     41 /*
     42  * Swap the bytes in a 16-bit half-word
     43  */
     44 
     45 STATIC INLINE unsigned short
     46 __shr_swap16(unsigned short i)
     47 {
     48     return i << 8 | i >> 8;
     49 }
     50 
     51 unsigned short
     52 _shr_swap16(unsigned short i)
     53 {
     54     return __shr_swap16(i);
     55 }
     56 
     57 /*
     58  * Return the number of bits set in a unsigned int
     59  */
     60 
     61 int
     62 _shr_popcount(unsigned int n)
     63 {
     64     n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
     65     n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
     66     n = (n + (n >> 4)) & 0x0f0f0f0f;
     67     n = n + (n >> 8);
     68 
     69     return (n + (n >> 16)) & 0xff;
     70 }
     71 
     72 /*
     73  * A few bit twiddling routines, initially for hashing
     74  */
     75 
     76 /* reverse the bits in an 8 bit byte */
     77 uint8
     78 _shr_bit_rev8(uint8 n)
     79 {
     80     n = (((n & 0xaa) >> 1) | ((n & 0x55) << 1));
     81     n = (((n & 0xcc) >> 2) | ((n & 0x33) << 2));
     82     n = (((n & 0xf0) >> 4) | ((n & 0x0f) << 4));
     83     return n;
     84 }
     85 
     86 
     87 /* reverse the bits in an 16 bit short */
     88 uint16
     89 _shr_bit_rev16(uint16 n)
     90 {
     91     n = (((n & 0xaaaa) >> 1) | ((n & 0x5555) << 1));
     92     n = (((n & 0xcccc) >> 2) | ((n & 0x3333) << 2));
     93     n = (((n & 0xf0f0) >> 4) | ((n & 0x0f0f) << 4));
     94     n = (((n & 0xff00) >> 8) | ((n & 0x00ff) << 8));
     95     return n;
     96 }
     97 
     98 /* reverse the bits in an 32 bit long */
     99 uint32
    100 _shr_bit_rev32(uint32 n)
    101 {
    102     n = (((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1));
    103     n = (((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2));
    104     n = (((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4));
    105     n = (((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8));
    106     return (n >> 16) | (n << 16);
    107 }
    108 
    109 /* reverse the bits in each byte of a 32 bit long */
    110 uint32
    111 _shr_bit_rev_by_byte_word32(uint32 n)
    112 {
    113     n = (((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1));
    114     n = (((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2));
    115     n = (((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4));
    116     return n;
    117 }
    118 
    119 /*
    120  * Ethernet CRC Algorithm
    121  *
    122  * To generate CRC, do not include CRC field in data:
    123  *    unsigned int crc = ~_shr_crc32(~0, data, len)
    124  *
    125  * To check CRC, include CRC field in data:
    126  *    unsigned int check = _shr_crc32(~0, data, len)
    127  *    If CRC is correct, result will be _SHR_CRC32_CORRECT.
    128  *
    129  * NOTE: This routine generates the same 32-bit value whether the
    130  * platform is big- or little-endian.  The value must be stored into a
    131  * network packet in big-endian order, i.e. using htonl() or equivalent.
    132  * (Polynomial x ^ 32 + x ^ 28 + x ^ 23 + x ^ 22 + x ^ 16 + x ^ 12 + x ^ 11 +
    133  *             x ^ 10 + x ^ 8 + x ^ 7 + x ^ 5 + x ^ 4 + x ^ 2  + x ^ 1 + 1)
    134  */
    135 
    136 static int		_shr_crc_table_inited;
    137 static unsigned int	_shr_crc_table[256];
    138 
    139 unsigned int
    140 _shr_crc32(unsigned int crc, unsigned char *data, int len)
    141 {
    142     int			i;
    143 
    144     if (!_shr_crc_table_inited) {
    145 	int		j;
    146 	unsigned int		accum;
    147 
    148 	for (i = 0; i < 256; i++) {
    149 	    accum = i;
    150 
    151 	    for (j = 0; j < 8; j++) {
    152 		if (accum & 1) {
    153 		    accum = accum >> 1 ^ 0xedb88320UL;
    154 		} else {
    155 		    accum = accum >> 1;
    156 		}
    157 	    }
    158 
    159 	    _shr_crc_table[i] = __shr_swap32(accum);
    160 	}
    161 
    162 	_shr_crc_table_inited = 1;
    163     }
    164 
    165     for (i = 0; i < len; i++) {
    166 	crc = crc << 8 ^ _shr_crc_table[crc >> 24 ^ data[i]];
    167     }
    168 
    169     return crc;
    170 }
    171 
    172 /* Matches _shr_crc32 above */
    173 unsigned int
    174 _shr_crc32b(unsigned int crc, unsigned char *data, int nbits)
    175 {
    176     int			i;
    177     int		        j;
    178     unsigned int	accum;
    179     unsigned int        poly = 0xedb88320UL;
    180     int                 last_nbits;
    181 
    182     if (!_shr_crc_table_inited) {
    183         for (i = 0; i < 256; i++) {
    184             accum = i;
    185 
    186             for (j = 0; j < 8; j++) {
    187                 accum = (accum & 1) ? (accum >> 1 ^ poly) : (accum >> 1);
    188             }
    189             _shr_crc_table[i] = __shr_swap32(accum);
    190         }
    191 	_shr_crc_table_inited = 1;
    192     }
    193 
    194     for (i = 0; i < (nbits / 8); i++) {
    195 	crc = (crc << 8) ^ _shr_crc_table[data[i] ^ ((crc >> 24) & 0x000FF)];
    196     }
    197 
    198     last_nbits =  nbits % 8;
    199     if (last_nbits) {
    200         accum = ((crc >> (32 - last_nbits)) & ((1 << last_nbits) - 1)) ^
    201                 (data[i]  & ((1 << last_nbits) - 1));
    202         for (j = 0; j < last_nbits; j++) {
    203             accum = (accum & 1) ? (accum >> 1 ^ poly) : (accum >> 1);
    204         }
    205         crc = (crc << last_nbits) ^ __shr_swap32(accum);
    206     }
    207 
    208     return crc;
    209 }
    210 
    211 static int		_shr_crc32bd15_table_inited;
    212 static unsigned int	_shr_crc32bd15_table[256];
    213 
    214 /* Matches Draco 1.5 CRC32 key76 */
    215 
    216 unsigned int
    217 _shr_crc32bd15(unsigned int crc, unsigned char *data, int nbits)
    218 {
    219     int			i;
    220     int		        j;
    221     unsigned int	accum;
    222     unsigned int        poly = 0xedb88320UL;
    223     int                 last_nbits;
    224 
    225     if (!_shr_crc32bd15_table_inited) {
    226         for (i = 0; i < 256; i++) {
    227             accum = i;
    228 
    229             for (j = 0; j < 8; j++) {
    230                 accum = (accum & 1) ? (accum >> 1 ^ poly) : (accum >> 1);
    231             }
    232             _shr_crc32bd15_table[i] = accum;
    233         }
    234 	_shr_crc32bd15_table_inited = 1;
    235     }
    236 
    237     for (i = 0; i < (nbits / 8); i++) {
    238 	crc = (crc >> 8) ^ ((data[i] & 0x000000FF) << 24) ^
    239                _shr_crc32bd15_table[crc & 0x000000FF];
    240     }
    241 
    242     last_nbits =  nbits % 8;
    243     if (last_nbits) {
    244         accum = crc & ((1 << last_nbits) - 1);
    245         for (j = 0; j < last_nbits; j++) {
    246             accum = (accum & 1) ? (accum >> 1 ^ poly) : (accum >> 1);
    247         }
    248         crc = (crc >> last_nbits) ^ accum ^
    249                ((data[i]  & ((1 << last_nbits) - 1)) << (32 - last_nbits));
    250     }
    251 
    252     return crc;
    253 }
    254 
    255 
    256 /*
    257  * CRC16 for Draco (Polynomial x ^ 16 + x ^ 15 + x ^ 2 + 1)
    258  */
    259 
    260 static unsigned short _shr_crc_16_table[16] = {
    261     0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
    262     0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
    263 };
    264 
    265 unsigned short
    266 _shr_crc16(int start, unsigned char *p, int n)
    267 {
    268     unsigned short int crc = start;
    269     int r;
    270 
    271     /* while there is more data to process */
    272     while (n-- > 0) {
    273 
    274         /* compute checksum of lower four bits of *p */
    275         r = _shr_crc_16_table[crc & 0xF];
    276         crc = (crc >> 4) & 0x0FFF;
    277         crc = crc ^ r ^ _shr_crc_16_table[*p & 0xF];
    278 
    279         /* now compute checksum of upper four bits of *p */
    280         r = _shr_crc_16_table[crc & 0xF];
    281         crc = (crc >> 4) & 0x0FFF;
    282         crc = crc ^ r ^ _shr_crc_16_table[(*p >> 4) & 0xF];
    283 
    284         /* next... */
    285         p++;
    286     }
    287 
    288     return(crc);
    289 }
    290 
    291 static int		_shr_crc16b_table_inited;
    292 static unsigned int	_shr_crc_16btable[256];
    293 
    294 /* Matches _shr_crc16 above */
    295 
    296 unsigned short
    297 _shr_crc16b(int crc, unsigned char *data, int nbits)
    298 {
    299     int			i;
    300     int		        j;
    301     unsigned int	accum;
    302     unsigned int        poly = 0xa001;
    303     int                 last_nbits;
    304 
    305     if (!_shr_crc16b_table_inited) {
    306         for (i = 0; i < 256; i++) {
    307             accum = i;
    308 
    309             for (j = 0; j < 8; j++) {
    310                 accum = (accum & 1) ? (accum >> 1 ^ poly) : (accum >> 1);
    311             }
    312             _shr_crc_16btable[i] = accum;
    313         }
    314         _shr_crc16b_table_inited = 1;
    315     }
    316 
    317     for (i = 0; i < (nbits / 8); i++) {
    318 	crc = (crc >> 8) ^ _shr_crc_16btable[((data[i] & 0x000000FF) << 0) ^
    319                                              (crc & 0x000000FF)];
    320     }
    321 
    322     last_nbits =  nbits % 8;
    323     if (last_nbits) {
    324         accum = (crc & ((1 << last_nbits) - 1)) ^
    325                 (data[i]  & ((1 << last_nbits) - 1));
    326         for (j = 0; j < last_nbits; j++) {
    327             accum = (accum & 1) ? (accum >> 1 ^ poly) : (accum >> 1);
    328         }
    329         crc = (crc >> last_nbits) ^ accum;
    330     }
    331 
    332     return crc;
    333 }
    334 
    335 /* Matches Draco 1.5 CRC16 key76 */
    336 
    337 unsigned short
    338 _shr_crc16bd15(int crc, unsigned char *data, int nbits)
    339 {
    340     int			i;
    341     int		        j;
    342     unsigned int	accum;
    343     unsigned int        poly = 0xa001;
    344     int                 last_nbits;
    345 
    346     if (!_shr_crc16b_table_inited) {
    347         for (i = 0; i < 256; i++) {
    348             accum = i;
    349 
    350             for (j = 0; j < 8; j++) {
    351                 accum = (accum & 1) ? (accum >> 1 ^ poly) : (accum >> 1);
    352             }
    353             _shr_crc_16btable[i] = accum;
    354         }
    355         _shr_crc16b_table_inited = 1;
    356     }
    357 
    358     for (i = 0; i < (nbits / 8); i++) {
    359 	crc = (crc >> 8) ^ ((data[i] & 0x000000FF) << 8) ^
    360                _shr_crc_16btable[crc & 0x000000FF];
    361     }
    362 
    363     last_nbits =  nbits % 8;
    364     if (last_nbits) {
    365         accum = crc & ((1 << last_nbits) - 1);
    366         for (j = 0; j < last_nbits; j++) {
    367             accum = (accum & 1) ? (accum >> 1 ^ poly) : (accum >> 1);
    368         }
    369         crc = (crc >> last_nbits) ^ accum ^
    370                ((data[i]  & ((1 << last_nbits) - 1)) << (16 - last_nbits));
    371     }
    372 
    373     return crc;
    374 }
    375 
    376 uint16
    377 _shr_crc16_draco_array(uint32 *hash_words, int n)
    378 {
    379     uint8 data[30];
    380     int i;
    381     uint16 crc;
    382 
    383     sal_memset(data, 0, 30);
    384     
    385     for (i = 0; i < n; i++) {
    386         data[i] = (hash_words[i/4] >> ((i % 4) * 8)) & 0xff;
    387     }
    388 
    389     crc = _shr_crc16(0, data, n);
    390     crc = _shr_bit_rev16(crc);
    391 
    392     return crc;
    393 }
    394 
    395 /* CRC16 CCITT: Polynomial x^16 + x^12 + x^5 + 1 */
    396 
    397 static int	        _shr_crc16_ccitt_table_inited;
    398 static uint16           _shr_crc16_ccitt_table[256];
    399 
    400 uint16
    401 _shr_crc16_ccitt(int crc, unsigned char *data, int len)
    402 {
    403     int			i;
    404     int		        j;
    405     uint32	        accum;
    406     uint32              poly = 0x8408;
    407 
    408     if (!_shr_crc16_ccitt_table_inited) {
    409         for (i = 0; i < 256; i++) {
    410             accum = i;
    411 
    412             for (j = 0; j < 8; j++) {
    413                 accum = (accum & 1) ? (accum >> 1 ^ poly) : (accum >> 1);
    414             }
    415             _shr_crc16_ccitt_table[i] = accum;
    416         }
    417         _shr_crc16_ccitt_table_inited = 1;
    418     }
    419 
    420     for (i = 0; i < len; i++) {
    421 	crc = (crc >> 8) ^
    422             _shr_crc16_ccitt_table[((data[i] & 0x000000FF) << 0) ^
    423                                    (crc & 0x000000FF)];
    424     }
    425 
    426     return crc;
    427 }
    428 
    429 uint16
    430 _shr_crc16_ccitt_array(uint32 *hash_words, int n)
    431 {
    432     uint8 data[30];
    433     int i;
    434     uint16 crc;
    435 
    436     sal_memset(data, 0, 30);
    437     
    438     for (i = 0; i < n; i++) {
    439         data[i] = (hash_words[i/4] >> ((i % 4) * 8)) & 0xff;
    440     }
    441 
    442     crc = _shr_crc16_ccitt(0, data, n);
    443     crc = _shr_bit_rev16(crc);
    444     return crc;
    445 }
    446 
    447 static int    _shr_crc32_cast_table_inited;
    448 static uint32 _shr_crc32_cast_table[256];
    449 
    450 /*
    451  * The following function implements polynomial:
    452  *  x^32 + x^28 + x^27 + x^26 + x^25 + x^23 + x^22 + x^20 + 
    453  *  x^19 + x^18 + x^14 + x^13 + x^11 + x^10 + x^9 + x^8 + x^6 + 1
    454  */
    455 uint32
    456 _shr_crc32_castagnoli(unsigned int crc, unsigned char *data, int len)
    457 {
    458     int			i;
    459 
    460     if (!_shr_crc32_cast_table_inited) {
    461 	int		j;
    462 	unsigned int		accum;
    463 
    464 	for (i = 0; i < 256; i++) {
    465 	    accum = i;
    466 
    467 	    for (j = 0; j < 8; j++) {
    468 		if (accum & 1) {
    469 		    accum = accum >> 1 ^ 0x82F63B78UL;
    470 		} else {
    471 		    accum = accum >> 1;
    472 		}
    473 	    }
    474 
    475 	    _shr_crc32_cast_table[i] = _shr_swap32(accum);
    476 	}
    477 
    478 	_shr_crc32_cast_table_inited = 1;
    479     }
    480 
    481     for (i = 0; i < len; i++) {
    482 	crc = crc << 8 ^ _shr_crc32_cast_table[crc >> 24 ^ data[i]];
    483     }
    484 
    485     return crc;
    486 }
    487 
    488 uint32
    489 _shr_crc32_castagnoli_array(uint32 *hash_words, int n)
    490 {
    491     uint8 data[30];
    492     int i;
    493     uint32 crc;
    494 
    495     sal_memset(data, 0, 30);
    496     
    497     for (i = 0; i < n; i++) {
    498         data[i] = (hash_words[i/4] >> ((i % 4) * 8)) & 0xff;
    499     }
    500 
    501     crc = _shr_crc32_castagnoli(0, data, n);
    502     crc = _shr_bit_rev_by_byte_word32(crc);
    503     return crc;
    504 }
    505 
    506 static int    _shr_crc32_ethernet_table_inited;
    507 static uint32 _shr_crc32_ethernet_table[256];
    508 
    509 /*
    510  * The following function implements polynomial:
    511  *  x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 +
    512  *  x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
    513  */
    514 uint32
    515 _shr_crc32_ethernet(unsigned int crc, unsigned char *data, int len)
    516 {
    517     int i;
    518 
    519     if (!_shr_crc32_ethernet_table_inited) {
    520         int j;
    521         unsigned int accum;
    522 
    523         for (i = 0; i < 256; i++) {
    524             accum = i;
    525 
    526             for (j = 0; j < 8; j++) {
    527                 if (accum & 1) {
    528                     accum = accum >> 1 ^ 0xEDB88320UL;
    529                 } else {
    530                     accum = accum >> 1;
    531                 }
    532             }
    533 
    534             _shr_crc32_ethernet_table[i] = _shr_swap32(accum);
    535         }
    536 
    537         _shr_crc32_ethernet_table_inited = 1;
    538     }
    539 
    540     for (i = 0; i < len; i++) {
    541         crc = crc << 8 ^ _shr_crc32_ethernet_table[crc >> 24 ^ data[i]];
    542     }
    543 
    544     return crc;
    545 }
    546 
    547 uint32
    548 _shr_crc32_ethernet_array(uint32 *hash_words, int n)
    549 {
    550     uint8 data[30];
    551     int i;
    552     uint32 crc;
    553 
    554     sal_memset(data, 0, 30);
    555 
    556     for (i = 0; i < n; i++) {
    557         data[i] = (hash_words[i/4] >> ((i % 4) * 8)) & 0xff;
    558     }
    559 
    560     crc = _shr_crc32_ethernet(0, data, n);
    561     crc = _shr_bit_rev_by_byte_word32(crc);
    562     return crc;
    563 }
    564 
    565 static int    _shr_crc32_koopman_table_inited;
    566 static uint32 _shr_crc32_koopman_table[256];
    567 
    568 /*
    569  * The following function implements polynomial:
    570  *  x^32 + x^30 + x^29 + x^28 + x^26 + x^20 + x^19 + x^17 +
    571  *  x^16 + x^15 + x^11 + x^10 + x^7 + x^6 + x^4 + x^2 + x + 1
    572  */
    573 uint32
    574 _shr_crc32_koopman(unsigned int crc, unsigned char *data, int len)
    575 {
    576     int i;
    577 
    578     if (!_shr_crc32_koopman_table_inited) {
    579         int j;
    580         unsigned int accum;
    581 
    582         for (i = 0; i < 256; i++) {
    583             accum = i;
    584 
    585             for (j = 0; j < 8; j++) {
    586                 if (accum & 1) {
    587                     accum = accum >> 1 ^ 0xEB31D82EUL;
    588                 } else {
    589                     accum = accum >> 1;
    590                 }
    591             }
    592 
    593             _shr_crc32_koopman_table[i] = _shr_swap32(accum);
    594         }
    595 
    596         _shr_crc32_koopman_table_inited = 1;
    597     }
    598 
    599     for (i = 0; i < len; i++) {
    600         crc = crc << 8 ^ _shr_crc32_koopman_table[crc >> 24 ^ data[i]];
    601     }
    602 
    603     return crc;
    604 }
    605 
    606 uint32
    607 _shr_crc32_koopman_array(uint32 *hash_words, int n)
    608 {
    609     uint8 data[30];
    610     int i;
    611     uint32 crc;
    612 
    613     sal_memset(data, 0, 30);
    614 
    615     for (i = 0; i < n; i++) {
    616         data[i] = (hash_words[i/4] >> ((i % 4) * 8)) & 0xff;
    617     }
    618 
    619     crc = _shr_crc32_koopman(0, data, n);
    620     crc = _shr_bit_rev_by_byte_word32(crc);
    621     return crc;
    622 }
    623 
    624 /*
    625  * Function:
    626  *	_shr_sort
    627  * Purpose:
    628  *	Simple general purpose Shell sort with decent performance O(N log N)
    629  */
    630 
    631 #define A(i)	((void *) &((char *)(base))[(i) * (size)])
    632 
    633 void
    634 _shr_sort(void *base, int count, int size, int (*compar)(void *, void *))
    635 {
    636     int		h = 1, i, j;
    637     char	tmp[256];
    638 
    639     assert(size < (int)sizeof(tmp));
    640 
    641     while (h * 3 + 1 < count) {
    642 	h = 3 * h + 1;
    643     }
    644 
    645     while (h > 0) {
    646 	for (i = h - 1; i < count; i++) {
    647 	    sal_memcpy(tmp, A(i), size);
    648 
    649 	    for (j = i; j >= h && (*compar)(A(j - h), tmp) > 0; j -= h) {
    650 		sal_memcpy(A(j), A(j - h), size);
    651 	    }
    652 
    653 	    sal_memcpy(A(j), tmp, size);
    654 	}
    655 
    656 	h /= 3;
    657     }
    658 }
    659 
    660 /*
    661  * Function:
    662  *	_shr_bsearch
    663  * Purpose:
    664  *	Simple general purpose binary search in a (low to high) sorted array.
    665  * Returns: 
    666  *    (negative insertion index) or positive exact match index.
    667  *
    668  *    Note that the negative insertion index is one greater than the
    669  *    actual insertion index to allow for an indication of the
    670  *    insertion index at the beginning of the array (index 0).
    671  */
    672 int
    673 _shr_bsearch(void *base, int count, int size, 
    674              void *target, int (*compar)(void *, void *))
    675 {
    676     int     start = 0;
    677     int     end = count - 1;
    678     int     midpoint;
    679     int     compare_result;
    680 
    681     /* Keep going as long as interval of possible matches not empty. */
    682     while (end >= start) {
    683         midpoint = (end + start) / 2;
    684         compare_result = (*compar)(A(midpoint), target);
    685         if (0 == compare_result) {
    686             return midpoint;
    687         }
    688         if (compare_result < 0) {
    689             start = midpoint + 1;
    690         } else if (compare_result > 0) {
    691             end = midpoint - 1;
    692         }
    693     }
    694 
    695     return (-1) * (start + 1);
    696 }
    697 
    698 #undef A
    699 
    700 /*
    701  * _shr_format_integer
    702  *
    703  *   Format an integer as a string of ASCII digits.
    704  *   Used for debugging printf's in the driver.
    705  */
    706 
    707 void
    708 _shr_format_integer(char *buf, unsigned int n, int min_digits, int base)
    709 {
    710     static char		*digit_char = "0123456789abcdef";
    711     unsigned int	tmp;
    712     int			digit, needed_digits = 0;
    713 
    714     for (tmp = n, needed_digits = 0; tmp; needed_digits++) {
    715 	tmp /= base;
    716     }
    717 
    718     if (needed_digits > min_digits)
    719 	min_digits = needed_digits;
    720 
    721     buf[min_digits] = 0;
    722 
    723     for (digit = min_digits - 1; digit >= 0; digit--) {
    724 	buf[digit] = digit_char[n % base];
    725 	n /= base;
    726     }
    727 }
    728 
    729 /*
    730  * _shr_format_long_integer
    731  *
    732  * Format an arbitrary precision long integer.
    733  *
    734  * If the value is less than 10, prints one decimal digit;
    735  * otherwise output is in hex format with 0x prefix.
    736  *
    737  * val[0] is the least significant word.
    738  * nval is the number of bytes in the value.
    739  */
    740 
    741 void
    742 _shr_format_long_integer(char *buf, unsigned int *val, int nval)
    743 {
    744     int i = BYTES2WORDS(nval) - 1;
    745 
    746     /*
    747     Don't actually skip leading 0's, as this makes packet buffers
    748     and other buffer memories really hard to read and to determine
    749     what the contents are.
    750     */
    751 #if 0
    752     for (i = BYTES2WORDS(nval) - 1; i > 0; i--) {	/* Skip leading zeroes */
    753 	if (val[i]) {
    754 	    break;
    755 	}
    756     }
    757 #endif /* 0 */
    758 
    759     if (i == 0 && val[i] < 10) {	/* Only a single word < 10 */
    760 	buf[0] = '0' + val[i];
    761 	buf[1] = 0;
    762     } else {
    763 	buf[0] = '0';			/* Print first word */
    764 	buf[1] = 'x';
    765 
    766         /*
    767         Don't use the previous value of 1 min digit for multiple
    768         integer values, as that makes a long integer of all zeroes
    769         print as just '0', which makes memory contents hard to read.
    770         Only use mindigit of 1 if only one integer to print
    771         */
    772         if (i == 0) {
    773 	_shr_format_integer(buf + 2, val[i], 1, 16);
    774         }
    775         else
    776         {
    777             if ((nval % 4) == 0) {
    778                 _shr_format_integer(buf + 2, val[i], 8, 16);
    779             }
    780             else
    781             {
    782                 _shr_format_integer(buf + 2, val[i], (2 * (nval % 4)), 16);
    783             }
    784         }
    785 
    786 	while (--i >= 0) {		/* Print rest of words, if any */
    787 	    while (*buf) {
    788 		buf++;
    789 	    }
    790 
    791 	    _shr_format_integer(buf, val[i], 8, 16);
    792 	}
    793     }
    794 }
    795 
    796 /* 
    797  * _shr_format_uint64_hexa_string 
    798  *  
    799  * Converts uint64 to hexa string
    800  */
    801 void 
    802 _shr_format_uint64_hexa_string( uint64 value, char* uint64_hexa_string)
    803 {
    804     if(COMPILER_64_HI(value)) {
    805         sal_sprintf(uint64_hexa_string, "0x%x", COMPILER_64_HI(value));
    806         sal_sprintf(uint64_hexa_string + sal_strlen(uint64_hexa_string), "%08x", COMPILER_64_LO(value));
    807     } else {
    808         sal_sprintf(uint64_hexa_string, "0x%x", COMPILER_64_LO(value));
    809     }
    810 }
    811 
    812 
    813 
    814 
    815 /*
    816  * _shr_ctoi
    817  *
    818  *   Converts a C-style constant integer to unsigned int
    819  */
    820 
    821 unsigned int
    822 _shr_ctoi(const char *s)
    823 {
    824     unsigned int	n, neg, base = 10;
    825 
    826     s += (neg = (*s == '-'));
    827 
    828     if (*s == '0') {
    829 	s++;
    830 
    831 	if (*s == 'x' || *s == 'X') {
    832 	    base = 16;
    833 	    s++;
    834 	} else if (*s == 'b' || *s == 'B') {
    835 	    base = 2;
    836 	    s++;
    837 	} else {
    838 	    base = 8;
    839 	}
    840     }
    841 
    842     for (n = 0; ((*s >= 'a' && *s <= 'z' && base > 10) ||
    843 		 (*s >= 'A' && *s <= 'Z' && base > 10) ||
    844 		 (*s >= '0' && *s <= '9')); s++) {
    845 	n = n * base +
    846 	    (*s >= 'a' ? *s - 'a' + 10 :
    847 	     *s >= 'A' ? *s - 'A' + 10 :
    848 	     *s - '0');
    849     }
    850 
    851     return (neg ? -n : n);
    852 }
    853 
    854 /*
    855  * _shr_ctoa
    856  *
    857  *   Converts a C-style constant string to an address
    858  */
    859 
    860 sal_vaddr_t
    861 _shr_ctoa(const char *s)
    862 {
    863     unsigned int	base = 10;
    864     sal_vaddr_t		n;
    865 
    866     if (*s == '0') {
    867 	s++;
    868 
    869 	if (*s == 'x' || *s == 'X') {
    870 	    base = 16;
    871 	    s++;
    872 	} else if (*s == 'b' || *s == 'B') {
    873 	    base = 2;
    874 	    s++;
    875 	} else {
    876 	    base = 8;
    877 	}
    878     }
    879 
    880     for (n = 0; ((*s >= 'a' && *s <= 'z' && base > 10) ||
    881 		 (*s >= 'A' && *s <= 'Z' && base > 10) ||
    882 		 (*s >= '0' && *s <= '9')); s++) {
    883 	n = n * base +
    884 	    (*s >= 'a' ? *s - 'a' + 10 :
    885 	     *s >= 'A' ? *s - 'A' + 10 :
    886 	     *s - '0');
    887     }
    888 
    889     return (n);
    890 }
    891 
    892 /*
    893  * Functions to get around the lack of floating point support 
    894  * in Linux kernel mode.
    895  */
    896 
    897 /*
    898  * Function:
    899  *	_shr_div_exp10
    900  * Purpose:
    901  *	Do uint32 division while preserving precision and 
    902  *	avoiding overflow.
    903  * Parameters:
    904  *	d1 - dividend
    905  *	d2 - divisor
    906  *	exp10 - factor of 10 by which to multiply the quotient
    907  * Returns:
    908  *	Result of division.
    909  * Notes:
    910  *	Example:
    911  *	5000 * 100000000 / 12345
    912  *	=> d1 = 5000, d2 = 12345, exp10 = 8
    913  */
    914 int
    915 _shr_div_exp10(int d1, int d2, int exp10)
    916 {
    917     int rv;
    918     int e;
    919     int sign = 1;
    920 
    921     if (d2 < 0) {
    922         sign = -1;
    923     }
    924 
    925     while (exp10 && d1 < (0x7FFFFFFF / 10)) {
    926         d1 = d1 * 10;
    927         exp10--;
    928     }
    929     e = 1;
    930     while (exp10) {
    931         e *= 10;
    932         exp10--;
    933     }
    934     rv = (d1 / d2) * e;
    935     if (e > 1) {
    936         rv += ((d1 % d2) * e) / (d2 * sign);
    937     }
    938     return rv;
    939 }
    940 
    941 /*
    942  * Function:
    943  *	_shr_atof_exp10
    944  * Purpose:
    945  *	Parse floating point input string and transform the result 
    946  *	into a 32-bit integer, optionally multiplying with an
    947  *	exponent of 10.
    948  * Parameters:		
    949  *	s - string to parse
    950  * Returns:
    951  *	Binary value of input string.
    952  * Notes:
    953  *	This is a helper function to transform floating point input
    954  *	into an integer value without loosing any information.
    955  *
    956  *	Examples:
    957  *	_shr_atof_exp10("1.33", 6)   =>   1.33 * 10^6 => 1330000
    958  *	_shr_atof_exp10("0.1234", 3) => 0.1234 * 10^3 =>     123
    959  */
    960 
    961 int
    962 _shr_atof_exp10(const char *s, int exp10)
    963 {
    964     int rv = 0;
    965     int dec_pt = 0;
    966     int sign = 10;
    967 
    968     if (exp10 > 9 || exp10 < 0) {
    969         return 0;
    970     }
    971 
    972     exp10++;
    973 
    974     if (*s == '-') {
    975         sign = -10;
    976         s++;
    977     }
    978 
    979     while (*s && exp10) {
    980         if (*s >= '0' && *s <= '9') {
    981             if (exp10) {
    982                 rv *= 10;
    983             }
    984             rv += *s - '0';
    985             if (dec_pt && exp10) {
    986                 exp10--;
    987             }
    988         } else if (*s == '.' && !dec_pt) {
    989             dec_pt = 1;
    990         } else {
    991             break;
    992         }
    993         s++;
    994     }
    995     while (exp10-- > 0) {
    996         rv *= 10;
    997     }
    998 
    999     return (rv + 5) / sign;
   1000 }
   1001 
   1002 /*
   1003  * Function:
   1004  *	_shr_div32r
   1005  * Purpose:
   1006  *	Do 32 bit integer division with rounding.
   1007  * Parameters:		
   1008  *	d1 - dividend
   1009  *	d2 - divisor
   1010  * Returns:
   1011  *	Result of division.
   1012  */
   1013 
   1014 uint32
   1015 _shr_div32r(uint32 d1, uint32 d2)
   1016 {
   1017     uint32 rv;
   1018 
   1019     rv = d1 / d2;
   1020     if ((d1 % d2) >= (d2 / 2)) {
   1021         rv += 1;
   1022     }
   1023     return rv;
   1024 }
   1025 
   1026 /*
   1027  * Function:
   1028  *	_shr_scale_uint64
   1029  * Purpose:
   1030  *	Transform 64 bit integer into a 32 bit integer
   1031  *	and a prefix multiplier (kilo, mega, giga etc.)
   1032  * Parameters:		
   1033  *	d64 - 64 bit integer to scale
   1034  *	base - value of 1k (must be 1000 or 1024)
   1035  *	prec - precision by which result is multiplied
   1036  *	d32 - pointer to 32 bit integer (OUT)
   1037  * Returns:
   1038  *	Prefix multiplier string ("", "K", "M", "G", "T").
   1039  * Notes:
   1040  *	This is helper function for displaying 64 bit
   1041  *	integers without using floating point or 64 bit
   1042  *	mul/div/mod.
   1043  *
   1044  *	Example:
   1045  *	We want to display 20*10^12 (0x000012309ce54000)
   1046  *	as 20.00 T (tera):
   1047  *
   1048  *	d64 is 0x000012309ce54000
   1049  *	base is 1000 (i.e. 1k = 1000)
   1050  *	precision is 100 (2 decimals)
   1051  *
   1052  *	s = _shr_scale_uint64(d64, 1000, 100, &d32);
   1053  *	printf("%d.%02d %s", d32 / 100, d32 % 100, s);
   1054  */
   1055 
   1056 char *
   1057 _shr_scale_uint64(uint64 d64, int base, int prec, uint32 *d32)
   1058 {
   1059     uint32 value;
   1060     uint64 value64;
   1061     int t, e;
   1062 
   1063     *d32 = 0;
   1064 
   1065     switch (base) {
   1066     case 1000:
   1067     case 1024:
   1068         break;
   1069     default:
   1070         return 0;
   1071     }
   1072 
   1073     switch (prec) {
   1074     case 1:
   1075     case 10:
   1076     case 100:
   1077     case 1000:
   1078         break;
   1079     default:
   1080         return 0;
   1081     }
   1082 
   1083     COMPILER_64_SET(value64, COMPILER_64_HI(d64), COMPILER_64_LO(d64));
   1084 
   1085     e = 0;
   1086     while (COMPILER_64_HI(value64)) {
   1087         /* Shift down to 32 bits */
   1088         t = 0;
   1089         while (COMPILER_64_HI(value64)) {
   1090             COMPILER_64_SHR(value64, 1);
   1091             t++;
   1092         }
   1093         /* Perform 32 bit division with rounding */
   1094         value = _shr_div32r(COMPILER_64_LO(value64), base);
   1095         /* Shift back - precision is still adequate */
   1096         COMPILER_64_SET(value64, 0, value);
   1097         COMPILER_64_SHL(value64, t);
   1098         e++;
   1099     }
   1100     value = COMPILER_64_LO(value64);
   1101 
   1102     t = 1;
   1103     while ((value / t) > (uint32)base) {
   1104         t *= base;
   1105         e++;
   1106     }
   1107 
   1108     if (e > 0) {
   1109     /*
   1110      * COVERITY
   1111      * As per switch statement on line 955, The function proceeds
   1112      * only if value of prec  is 1,10,100,1000 only for rest of the
   1113      * values function returns so the stated condition will not occur.
   1114      */
   1115     /* coverity[divide_by_zero : FALSE] */
   1116 	*d32 = _shr_div32r(value, t / prec);
   1117         if (e == 1) {
   1118             return (base == 1000) ? "k" : "K";
   1119         }
   1120         if (e == 2) {
   1121             return "M";
   1122         }
   1123         if (e == 3) {
   1124             return "G";
   1125         }
   1126         return "T";
   1127     }
   1128     *d32 = prec * value;
   1129     return "";
   1130 }
   1131 
   1132 /*
   1133  * Function:
   1134  *      _shr_ip6_mask_create
   1135  * Purpose:
   1136  *      Create IPv6 network address from prefix length
   1137  * Parameters:
   1138  *      ip6 - (OUT) IPv6 address holder
   1139  *      len - the prefix/mask length
   1140  * Returns:
   1141  *      none
   1142  */
   1143 
   1144 int
   1145 _shr_ip6_mask_create(uint8 *ip6, int len)
   1146 {
   1147     int num_bytes, bits_left;
   1148     int i;
   1149 
   1150     sal_memset(ip6, 0, _SHR_L3_IP6_ADDRLEN);
   1151     if (len == 0) {
   1152         return _SHR_E_PARAM;
   1153     }
   1154 
   1155     if (len > _SHR_L3_IP6_MAX_NETLEN) {
   1156         len = _SHR_L3_IP6_MAX_NETLEN;
   1157     }
   1158 
   1159     num_bytes = len / 8;
   1160     bits_left = len % 8;
   1161 
   1162     for (i = 0; i < num_bytes; i++) {
   1163         ip6[i] = 0xff;
   1164     }
   1165 
   1166     if (bits_left) {
   1167         ip6[i] = (0xff << (8 - bits_left));
   1168     }
   1169 
   1170     return _SHR_E_NONE;
   1171 }
   1172 
   1173 
   1174 /*
   1175  * Function:
   1176  *      _shr_ip6_mask_length
   1177  * Purpose:
   1178  *      Return the mask length from IPv6 network address
   1179  * Parameters: 
   1180  *      mask - IPv6 address
   1181  * Returns:
   1182  *      The prefix/mask length
   1183  */
   1184 
   1185 int
   1186 _shr_ip6_mask_length(uint8 *mask)
   1187 {
   1188     int masklen, i, j;
   1189     uint8 temp;
   1190             
   1191     /* Convert netmask to number of bits */
   1192     masklen = 0;
   1193     
   1194     for (i = 0; i < _SHR_L3_IP6_ADDRLEN; i++) {
   1195         temp = mask[i];
   1196         for (j = 0; j < 8; j++) {
   1197             if (temp & 0x80) {
   1198                 masklen++;
   1199                 temp = temp << 1;
   1200             } else {
   1201                 break;
   1202             }
   1203         }
   1204     }
   1205     return masklen;
   1206 }
   1207 
   1208 /*
   1209  * Function
   1210  *      _shr_ip6_addr_compare
   1211  * Purpose
   1212  *      Compare IPv6 address from LSB to MSB
   1213  * Parameters
   1214  *      addr1 - (IN) IPv6 address
   1215  *      addr2 - (IN) IPv6 address
   1216  * Returns
   1217  *      Compare result
   1218  */
   1219 int
   1220 _shr_ip6_addr_compare(uint8 *addr1, uint8 *addr2)
   1221 {
   1222     int i = 0;
   1223     for (i = _SHR_L3_IP6_ADDRLEN - 1; i >= 0; i--) {
   1224         if (addr1[i] != addr2[i]) {
   1225             return -1;
   1226         }
   1227     }
   1228 
   1229     return 0;
   1230 
   1231 }
   1232 
   1233 /*
   1234  * Function:
   1235  *      _shr_ip_mask_create
   1236  * Purpose:
   1237  *      Create IPv4 network address from prefix length
   1238  * Parameters:
   1239  *      len - the prefix/mask length
   1240  * Returns:
   1241  *      The IPv4 mask
   1242  */
   1243 uint32
   1244 _shr_ip_mask_create(int len)
   1245 {
   1246     return ((len) ? (~((0x1 << (32 - (len))) - 1)) : 0);
   1247 }
   1248 
   1249 /*
   1250  * Function:
   1251  *      _shr_ip_mask_length
   1252  * Purpose:
   1253  *      Return the mask length from IPv4 network address
   1254  * Parameters:
   1255  *      mask - The IPv4 mask as IP address
   1256  * Returns:
   1257  *      The IPv4 mask length
   1258  */
   1259 int
   1260 _shr_ip_mask_length(uint32 mask)
   1261 {
   1262     int masklen, i;
   1263 
   1264     /* Convert netmask to number of bits */
   1265     masklen = 0;
   1266 
   1267     for (i = 0; i < _SHR_L3_IP_ADDRLEN * 8; i++) {
   1268         if (mask & 0x80000000) {
   1269             masklen++;
   1270             mask = mask << 1;
   1271         } else {
   1272             break;
   1273         }
   1274     }
   1275 
   1276     return (masklen);
   1277 }
   1278 
   1279 /*
   1280  * Function:
   1281  *      _shr_ip_chksum
   1282  * Purpose:
   1283  *      Calculate IP style checksum
   1284  * Parameters:
   1285  *      - length - length of data in bytes
   1286  *      - data - pointer to data
   1287  * Returns:
   1288  *      -checksum
   1289  */
   1290 unsigned short
   1291 _shr_ip_chksum(unsigned int length, unsigned char *data)
   1292 {
   1293     unsigned int chksum = 0;
   1294     unsigned short w16;
   1295     int i=0;
   1296 
   1297     while (length > 1) {
   1298         w16 = (((unsigned int)data[i]) << 8) + data[i+1];
   1299         chksum += w16;
   1300         i+=2;
   1301         length -= 2;
   1302     }
   1303     if (length) {
   1304         w16 = (((unsigned int)data[i]) << 8) + 0;
   1305         chksum += w16;
   1306     }
   1307 
   1308     while (chksum >> 16) {
   1309         chksum = (chksum & 0xFFFF) + (chksum >> 16);
   1310     }
   1311 
   1312     return (~chksum);
   1313 }
   1314 
   1315 
   1316 /*
   1317  * Function:
   1318  *      _shr_tolower
   1319  * Purpose:
   1320  *      Converts uppercase char to lowercase char
   1321  * Parameters:
   1322  *      - c - Char to convert
   1323  * Returns:
   1324  *      Lowercase char
   1325  */
   1326 #define _shr_tolower(c) ((c >= 'A' && c <= 'Z') ? (c + 37):c)
   1327 
   1328 /*
   1329  * Function:
   1330  *      _shr_isxdigit
   1331  * Purpose:
   1332  *      Returns true if char is a valid hex digit
   1333  * Parameters:
   1334  *      - c - Char to evaluate
   1335  * Returns:
   1336  *      True if valid hex digit, else false
   1337  */
   1338 int  _shr_isxdigit(char c) {
   1339     if ((c >= '0' && c <= '9') || 
   1340 	(c >= 'a' && c <= 'f') ||
   1341 	(c >= 'A' && c <= 'F'))
   1342 	return 1; 
   1343     return 0;
   1344 }
   1345 
   1346 /*
   1347  * Function:
   1348  *      _shr_xdigit2i
   1349  * Purpose:
   1350  *      Converts ASCII char to integer
   1351  * Parameters:
   1352  *      - c - Char to evaluate
   1353  * Returns:
   1354  *      Integer value of hex digit
   1355  */
   1356 int _shr_xdigit2i(char c) {
   1357     if (c >= '0' && c <= '9')
   1358 	return (int)(c - '0');
   1359     else if (c >= 'a' && c <= 'f')
   1360 	return (int)(c - 'a') + 10;
   1361     else if (c >= 'A' && c <= 'F')
   1362 	return (int)(c - 'A') + 10;
   1363     return 0;
   1364 }
   1365 
   1366 /*
   1367  * Function:
   1368  *      _shr_strchr
   1369  * Purpose:
   1370  *      Finds first occurance of char in string
   1371  * Parameters:
   1372  *      - str - String to evaluate
   1373  *      - c - Char to find in string
   1374  * Returns:
   1375  *      Pointer to first occurance of c in string, else NULL
   1376  */
   1377 char *_shr_strchr(const char *str, int c) {
   1378     const char *ptr = str;
   1379 
   1380     while(*ptr != '\0') {
   1381 	if (*ptr == (char)c)
   1382 	    return (char*)ptr;
   1383 	ptr++;
   1384     }
   1385 
   1386     return NULL;
   1387 }
   1388 
   1389 
   1390 /*
   1391  * Function:
   1392  *      _shr_isint
   1393  * Purpose:
   1394  *      Identify well-formed int
   1395  * Parameters:
   1396  *      - s - String to evaluate
   1397  * Returns:
   1398  *      Return true if a constant is a well-formed integer of the type
   1399  *      supported by parse_integer.
   1400  */
   1401 
   1402 int
   1403 _shr_isint(char *s)
   1404 {
   1405     int base;
   1406 
   1407     if (s == NULL) {
   1408         return 0;
   1409     }
   1410 
   1411     if (*s == '-') {
   1412         s++;
   1413     }
   1414 
   1415     if (*s == '0') {
   1416         if (s[1] == 'b' || s[1] == 'B') {
   1417             base = 2;
   1418             s += 2;
   1419         } else if (s[1] == 'x' || s[1] == 'X') {
   1420             base = 16;
   1421             s += 2;
   1422         } else
   1423             base = 8;
   1424     } else {
   1425         base = 10;
   1426     }
   1427 
   1428     do {
   1429         if (!_shr_isxdigit((unsigned) *s) || _shr_xdigit2i(*s) >= base) {
   1430             return(0);
   1431         }
   1432     } while (*++s);
   1433 
   1434     return(1);
   1435 }
   1436 
   1437 /*
   1438  * Function:
   1439  *      _shr_parse_macaddr
   1440  * Purpose:
   1441  *      Convert mac address string to six bytes of data
   1442  * Parameters:
   1443  *      - str - MAC string to evaluate
   1444  *      - macaddr - Place to store the result
   1445  * Returns:
   1446  */
   1447 int _shr_parse_macaddr(char *str, uint8 *macaddr)
   1448 {
   1449     char *s;
   1450     int	colon = FALSE;
   1451     int	i, c1, c2;
   1452 
   1453     if (_shr_strchr(str, ':')) {		/* Colon format */
   1454 	colon = TRUE;
   1455     } else if (*str++ != '0' || _shr_tolower(*str++) != 'x') {
   1456 	return -1;
   1457     } else {
   1458 	sal_memset(macaddr, 0, 6);
   1459     }
   1460     /* Start at end and work back */
   1461     s = str + sal_strlen(str);
   1462     for (i = 5; (i >= 0) && (s >= str); i--) {
   1463 	c2 = (s > str && _shr_isxdigit((unsigned) s[-1])) ? _shr_xdigit2i((unsigned) *--s) : 0;
   1464 	c1 = (s > str && _shr_isxdigit((unsigned) s[-1])) ? _shr_xdigit2i((unsigned) *--s) : 0;
   1465 	macaddr[i] = c1 * 16 + c2;
   1466 	if (colon && (s >= str) && (':' != *--s))
   1467 	    break;
   1468     }
   1469     return(((s <= str) && (!colon || (i == 0))) ? 0 : -1);
   1470 }
   1471 
   1472 /*
   1473  * Function:
   1474  *      _shr_parse_ipaddr
   1475  * Purpose:
   1476  *      Convert ip address string to four bytes of data
   1477  * Parameters:
   1478  *      - str - IP address string to evaluate
   1479  *      - ipaddr - Place to store the result
   1480  * Returns:
   1481  */
   1482 int
   1483 _shr_parse_ipaddr(char *s, sal_ip_addr_t *ipaddr)
   1484 {
   1485     char *ts;
   1486     int i, x;
   1487     sal_ip_addr_t ip = 0;
   1488 
   1489     if (strchr(s, '.')) {               /* dotted notation */
   1490         for (i = 0; i < 4; i++) {
   1491             x = sal_ctoi(s, &ts);
   1492             if ((x > 0xff) || (x < 0)) {
   1493                 return(-1);
   1494             } 
   1495             ip = (ip << 8) | x;
   1496             if (*ts != '.') {   /* End of string */
   1497                 break;
   1498             }
   1499             s = ts + 1;
   1500         }
   1501         if (((i != 3) || (*ts != '\0'))) {
   1502             return(-1);
   1503         } else {
   1504             *ipaddr = ip;
   1505             return(0);
   1506         }
   1507     } else if (_shr_isint(s)){
   1508         *ipaddr = _shr_ctoi(s);
   1509         return(0);
   1510     } else {
   1511         return(-1);
   1512     }
   1513 }
   1514 
   1515 /* routines for moving uint[16|32|64] and int64 to/from network order buffers */
   1516 
   1517 /*                                                                                                            
   1518  * Function:                                                                                                  
   1519  *      _shr_uint16_read                                                                                  
   1520  * Purpose:                                                                                                   
   1521  *      Read a 16-bit unsigned integer from a buffer in network byte order.                                   
   1522  * Parameters:                                                                                                
   1523  *      buffer - (IN) Data buffer.                                                                            
   1524  * Returns:                                                                                                   
   1525  *      Result.                                                                                               
   1526  * Notes:                                                                                                     
   1527  */
   1528 uint16
   1529 _shr_uint16_read(
   1530     uint8* buffer)
   1531 {
   1532     return ((((uint16)(buffer[0])) << 8) + (((uint16)(buffer[1]))));
   1533 }
   1534 
   1535 
   1536 /*                                                                                                            
   1537  * Function:                                                                                                  
   1538  *      _shr_uint16_write                                                                                 
   1539  * Purpose:                                                                                                   
   1540  *      Write a 16-bit unsigned integer to a buffer in network byte order.                                    
   1541  * Parameters:                                                                                                
   1542  *      value  - (IN)  Data.                                                                                  
   1543  *      buffer - (OUT) Data buffer.                                                                           
   1544  * Returns:                                                                                                   
   1545  *      None.                                                                                                 
   1546  * Notes:                                                                                                     
   1547  */
   1548 void
   1549 _shr_uint16_write(
   1550     uint8* buffer,
   1551     const uint16 value)
   1552 {
   1553     buffer[0] = ((value >> 8) & 0xff);
   1554     buffer[1] = ((value) & 0xff);
   1555 }
   1556 
   1557 
   1558 /*                                                                                                            
   1559  * Function:                                                                                                  
   1560  *      _shr_uint32_read                                                                                  
   1561  * Purpose:                                                                                                   
   1562  *      Read a 32-bit unsigned integer from a buffer in network byte order.                                   
   1563  * Parameters:                                                                                                
   1564  *      buffer - (IN) Data buffer.                                                                            
   1565  * Returns:                                                                                                   
   1566  *      Result.                                                                                               
   1567  * Notes:                                                                                                     
   1568  */
   1569 uint32
   1570 _shr_uint32_read(
   1571     uint8* buffer)
   1572 {
   1573     return ((((uint32)(buffer[0])) << 24) +
   1574             (((uint32)(buffer[1])) << 16) +
   1575             (((uint32)(buffer[2])) << 8)  +
   1576             (((uint32)(buffer[3]))));
   1577 }
   1578 
   1579 
   1580 /*                                                                                                            
   1581  * Function:                                                                                                  
   1582  *      _shr_uint32_write                                                                                 
   1583  * Purpose:                                                                                                   
   1584  *      Write a 32-bit unsigned integer to a buffer in network byte order.                                    
   1585  * Parameters:                                                                                                
   1586  *      value  - (IN)  Data.                                                                                  
   1587  *      buffer - (OUT) Data buffer.                                                                           
   1588  * Returns:                                                                                                   
   1589  *      None.                                                                                                 
   1590  * Notes:                                                                                                     
   1591  */
   1592 void
   1593 _shr_uint32_write(
   1594     uint8* buffer,
   1595     const uint32 value)
   1596 {
   1597     buffer[0] = ((value >> 24) & 0xff);
   1598     buffer[1] = ((value >> 16) & 0xff);
   1599     buffer[2] = ((value >> 8) & 0xff);
   1600     buffer[3] = ((value) & 0xff);
   1601 }
   1602 
   1603 
   1604 /*                                                                                                            
   1605  * Function:                                                                                                  
   1606  *      _shr_uint64_read                                                                                  
   1607  * Purpose:                                                                                                   
   1608  *      Read a 64-bit unsigned integer from a buffer in network byte order.                                   
   1609  * Parameters:                                                                                                
   1610  *      buffer - (IN) Data buffer.                                                                            
   1611  * Returns:                                                                                                   
   1612  *      Result.                                                                                               
   1613  * Notes:                                                                                                     
   1614  */
   1615 uint64
   1616 _shr_uint64_read(uint8* buffer)
   1617 {
   1618     uint64 val64;
   1619 
   1620     COMPILER_64_SET(val64,
   1621                     (buffer[0] << 24) + (buffer[1] << 16) +
   1622                     (buffer[2] << 8)  + buffer[3],
   1623                     (buffer[4] << 24) + (buffer[5] << 16) +
   1624                     (buffer[6] << 8)  + buffer[7]);
   1625     return val64;
   1626 }
   1627 
   1628 
   1629 /*                                                                                                            
   1630  * Function:                                                                                                  
   1631  *      _shr_uint64_write                                                                                 
   1632  * Purpose:                                                                                                   
   1633  *      Write a 64-bit unsigned integer to a buffer in network byte order.                                    
   1634  * Parameters:                                                                                                
   1635  *      value  - (IN)  Data.                                                                                  
   1636  *      buffer - (OUT) Data buffer.                                                                           
   1637  * Returns:                                                                                                   
   1638  *      None.                                                                                                 
   1639  * Notes:                                                                                                     
   1640  */
   1641 void
   1642 _shr_uint64_write(
   1643     uint8* buffer,
   1644     const uint64 value)
   1645 {
   1646     uint32 low;
   1647     uint32 high;
   1648 
   1649     COMPILER_64_TO_32_LO(low,value);
   1650     COMPILER_64_TO_32_HI(high,value);
   1651 
   1652     buffer[0] = ((high >> 24) & 0xff);
   1653     buffer[1] = ((high >> 16) & 0xff);
   1654     buffer[2] = ((high >> 8) & 0xff);
   1655     buffer[3] = ((high) & 0xff);
   1656     buffer[4] = ((low >> 24) & 0xff);
   1657     buffer[5] = ((low >> 16) & 0xff);
   1658     buffer[6] = ((low >> 8) & 0xff);
   1659     buffer[7] = ((low) & 0xff);
   1660 }
   1661 
   1662 
   1663 /*                                                                                                            
   1664  * Function:                                                                                                  
   1665  *      _shr_int64_read                                                                                   
   1666  * Purpose:                                                                                                   
   1667  *      Read a 64-bit signed integer from a buffer in network byte order.                                     
   1668  * Parameters:                                                                                                
   1669  *      buffer - (IN) Data buffer.                                                                            
   1670  * Returns:                                                                                                   
   1671  *      Result.                                                                                               
   1672  * Notes:                                                                                                     
   1673  *      Casting to and from int64_t is not available on some platforms                                        
   1674  */
   1675 int64
   1676 _shr_int64_read(uint8* buffer)
   1677 {
   1678     int64 val;
   1679     int64 temp;
   1680 
   1681     COMPILER_64_SET(temp, buffer[0] << 24, 0);
   1682     val = temp;
   1683     COMPILER_64_SET(temp, buffer[1] << 16, 0);
   1684     COMPILER_64_ADD_64(val, temp);
   1685     COMPILER_64_SET(temp, buffer[2] << 8, 0);
   1686     COMPILER_64_ADD_64(val, temp);
   1687     COMPILER_64_SET(temp, buffer[3], 0);
   1688     COMPILER_64_ADD_64(val, temp);
   1689     COMPILER_64_SET(temp, 0, buffer[4] << 24);
   1690     COMPILER_64_ADD_64(val, temp);
   1691     COMPILER_64_SET(temp, 0, buffer[5] << 16);
   1692     COMPILER_64_ADD_64(val, temp);
   1693     COMPILER_64_SET(temp, 0, buffer[6] << 8);
   1694     COMPILER_64_ADD_64(val, temp);
   1695     COMPILER_64_SET(temp, 0, buffer[7]);
   1696     COMPILER_64_ADD_64(val, temp);
   1697 
   1698     return val;
   1699 }
   1700 
   1701 
   1702 /*                                                                                                            
   1703  * Function:                                                                                                  
   1704  *      _shr_int64_write                                                                                  
   1705  * Purpose:                                                                                                   
   1706  *      Write a 64-bit signed integer to a buffer in network byte order.                                      
   1707  * Parameters:                                                                                                
   1708  *      value  - (IN)  Data.                                                                                  
   1709  *      buffer - (OUT) Data buffer.                                                                           
   1710  * Returns:                                                                                                   
   1711  *      None.                                                                                                 
   1712  * Notes:                                                                                                     
   1713  *      Casting to and from int64_t is not available on some platforms                                        
   1714  */
   1715 void
   1716 _shr_int64_write(
   1717     uint8* buffer,
   1718     const int64 value)
   1719 {
   1720     buffer[0] = (COMPILER_64_HI(value) >> 24) & 0xff;
   1721     buffer[1] = (COMPILER_64_HI(value) >> 16) & 0xff;
   1722     buffer[2] = (COMPILER_64_HI(value) >> 8) & 0xff;
   1723     buffer[3] = (COMPILER_64_HI(value) & 0xff);
   1724     buffer[4] = (COMPILER_64_LO(value) >> 24) & 0xff;
   1725     buffer[5] = (COMPILER_64_LO(value) >> 16) & 0xff;
   1726     buffer[6] = (COMPILER_64_LO(value) >> 8) & 0xff;
   1727     buffer[7] = (COMPILER_64_LO(value) & 0xff);
   1728 }
   1729 
   1730 static void shr_rdpc_dispatcher(void *owner, void* p0, void* p1, void* p2, void* p3)
   1731 {
   1732     shr_rdpc_t *rdpc = (shr_rdpc_t *)owner;
   1733     sal_usecs_t next_call = 0;
   1734 
   1735     if (rdpc->running) {
   1736         next_call = rdpc->func(&p0, &p1, &p2, &p3);
   1737     }
   1738 
   1739     if (sal_mutex_take(rdpc->call_count_lock, RDPC_MUTEX_TIMEOUT) != 0) {
   1740         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META("RDPC dispatch failed to get mutex\n")));
   1741     } else {
   1742         if (next_call && rdpc->running && rdpc->run_count == 1) {
   1743             int rv = sal_dpc_time(next_call, &shr_rdpc_dispatcher, (void*)rdpc, p0, p1, p2, p3);
   1744             if (rv) {
   1745                 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META("RDPC scheduling of DPC failed\n")));
   1746                 rdpc->run_count--;
   1747             }
   1748         } else {
   1749             if (rdpc->run_count <= 0) {
   1750                 /* run count was incremented every time this rdpc was started, and decremented
   1751                    when it did not reschedule itself.  If we're here, it should be positive */
   1752                 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META("RDPC run count invalid\n")));
   1753             } else {
   1754                 /* Either the RDPC was stopped, or it was started multiple times (possibly racing a stop) */
   1755                 /* in the latter case, let it drain so only one DPC is scheduled for it */
   1756                 rdpc->run_count--;
   1757             }
   1758         }
   1759         sal_mutex_give(rdpc->call_count_lock);
   1760     }
   1761 }
   1762 
   1763 /*
   1764  * Function:
   1765  *      shr_rdpc_callback_create
   1766  * Purpose:
   1767  *      Creates a new RDPC callback in the provided structure.  RDPC will not be called until started.
   1768  * Parameters:
   1769  *      rdpc    - (IN/OUT) Pointer to RDPC structure to be initialized/created
   1770  *      func    - (IN) The callback function
   1771  * Returns:
   1772  *      Error code or SOC_E_NONE
   1773  * Notes:
   1774  */
   1775 int shr_rdpc_callback_create(shr_rdpc_t *rdpc, shr_rdpc_fn_t func)
   1776 {
   1777     rdpc->func = func;
   1778     rdpc->call_count_lock = sal_mutex_create("rdpc");
   1779     rdpc->run_count = 0;
   1780     rdpc->running = 0;
   1781 
   1782     return rdpc->call_count_lock ? SOC_E_NONE : SOC_E_MEMORY;
   1783 }
   1784 
   1785 /*
   1786  * Function:
   1787  *      shr_rdpc_callback_created
   1788  * Purpose:
   1789  *      Indicates whether a shr_rdpc_t structures with static/global allocation has been created
   1790  * Parameters:
   1791  *      rdpc    - (IN/OUT) Pointer to RDPC structure to be initialized/created
   1792  * Returns:
   1793  *      SOC_E_INIT (callback is null) or SOC_E_NONE (callback has been created)
   1794  * Notes:
   1795  */
   1796 int shr_rdpc_callback_created(shr_rdpc_t *rdpc)
   1797 {
   1798     return (rdpc->call_count_lock) ? SOC_E_NONE : SOC_E_INIT;
   1799 }
   1800 
   1801 /*
   1802  * Function:
   1803  *      shr_rdpc_callback_start
   1804  * Purpose:
   1805  *      Runs the callback after the specified interval.  The value returned from
   1806  *      the callback will be used as the interval before the subsequent call.
   1807  *      If callback is already scheduled to run, it will execute at the earlier time.
   1808  * Parameters:
   1809  *      rdpc           - (IN) Pointer to RDPC structure
   1810  *      first_interval - time in usecs before the callback should be called
   1811  *      p0...p3        - callback will get pointers to these void* parameters
   1812  * Returns:
   1813  *      Error code or SOC_E_NONE
   1814  * Notes:
   1815  */
   1816 int shr_rdpc_callback_start(shr_rdpc_t *rdpc, sal_usecs_t first_interval,
   1817                                       void* p0, void* p1, void* p2, void* p3)
   1818 {
   1819     int rv = SOC_E_NONE;
   1820 
   1821     if (sal_mutex_take(rdpc->call_count_lock, RDPC_MUTEX_TIMEOUT) != 0) {
   1822         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META("RDPC dispatch failed to get mutex\n")));
   1823         return SOC_E_INTERNAL;
   1824     }
   1825 
   1826     rdpc->running = 1;
   1827     rdpc->run_count++;
   1828     rv = sal_dpc_time(first_interval, &shr_rdpc_dispatcher, (void*)rdpc, (void*)p0, (void*)p1, (void*)p2, (void*)p3);
   1829 
   1830     sal_mutex_give(rdpc->call_count_lock);
   1831 
   1832     return rv;
   1833 }
   1834 
   1835 /*
   1836  * Function:
   1837  *      shr_rdpc_callback_stop
   1838  * Purpose:
   1839  *      Stops further calls of the callback.
   1840  * Parameters:
   1841  *      rdpc           - (IN) Pointer to RDPC structure
   1842  * Returns:
   1843  *      Error code or SOC_E_NONE
   1844  * Notes:
   1845  */
   1846 int shr_rdpc_callback_stop(shr_rdpc_t *rdpc)
   1847 {
   1848     int rv = SOC_E_NONE;
   1849 
   1850     if (sal_mutex_take(rdpc->call_count_lock, RDPC_MUTEX_TIMEOUT) != 0) {
   1851         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META("RDPC dispatch failed to get mutex\n")));
   1852         return SOC_E_INTERNAL;
   1853     }
   1854     rdpc->running = 0;
   1855     sal_mutex_give(rdpc->call_count_lock);
   1856     return rv;
   1857 }
   1858 
   1859 /*
   1860  * Function:
   1861  *      shr_rdpc_callback_finished
   1862  * Purpose:
   1863  *      Indicates whether the callback structure is still in use after having been stopped.
   1864  * Parameters:
   1865  *      rdpc           - (IN) Pointer to RDPC structure
   1866  * Returns:
   1867  *      SOC_E_BUSY : still in use.  The callback should not be destroyed yet.
   1868  *      SOC_E_NONE : all activity has been completed, callback may be destroyed.
   1869  * Notes:
   1870  */
   1871 int shr_rdpc_callback_finished(shr_rdpc_t *rdpc)
   1872 {
   1873     int rv = SOC_E_NONE;
   1874 
   1875     if (sal_mutex_take(rdpc->call_count_lock, RDPC_MUTEX_TIMEOUT) != 0) {
   1876         LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META("RDPC dispatch failed to get mutex\n")));
   1877         return SOC_E_INTERNAL;
   1878     }
   1879     if (rdpc->run_count > 0) {
   1880         rv = SOC_E_BUSY;
   1881     }
   1882     sal_mutex_give(rdpc->call_count_lock);
   1883     return rv;
   1884 }
   1885 /*
   1886  * Function:
   1887  *      shr_rdpc_callback_destroy
   1888  * Purpose:
   1889  *      Releases resources associated with the RDPC structure
   1890  * Parameters:
   1891  *      rdpc           - (IN) Pointer to RDPC structure
   1892  * Returns:
   1893  *      SOC_E_BUSY : callback is still in use and was not destroyed
   1894  *      SOC_E_NONE
   1895  * Notes:
   1896  */
   1897 int shr_rdpc_callback_destroy(shr_rdpc_t *rdpc)
   1898 {
   1899     int rv = shr_rdpc_callback_finished(rdpc);
   1900     if (rv == 0) {
   1901         sal_mutex_destroy(rdpc->call_count_lock);
   1902     }
   1903 
   1904     return rv;
   1905 }