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

tbhmod_spd_ctrl.c (35841B)


      1 /*------------------------------------------------------------------------------
      2  * 
      3  *
      4  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      5  * 
      6  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      7  *  Broadcom Corporation
      8  *  Proprietary and Confidential information
      9  *  All rights reserved
     10  *  This source file is the property of Broadcom Corporation, and
     11  *  may not be copied or distributed in any isomorphic form without the
     12  *  prior written consent of Broadcom Corporation.
     13  *------------------------------------------------------------------------------
     14  *  Description: Functons for Speed Table, AM Table, and UM Table access.
     15  *----------------------------------------------------------------------------*/
     16 #ifndef _TBHMOD_SPD_CTRL_C_
     17 #define _TBHMOD_SPD_CTRL_C_ 
     18 
     19 #include "tbhmod_spd_ctrl_defines.h"
     20 #include "tbhmod_spd_ctrl.h"
     21 
     22 /*
     23  * spd_ctrl_unpack_spd_id_tbl_entry() : Unpacks a char array into a spd_id_tbl_entry_t
     24  */
     25 void spd_ctrl_unpack_spd_id_tbl_entry(uint32_t *packed_entry, spd_id_tbl_entry_t *entry)
     26 {
     27     int word_size = 32;
     28     int word_idx;
     29     int bit_idx;
     30     int high_bits;
     31     int low_bits;
     32     int high_mask;
     33     int low_mask;
     34    
     35     /* AM_TABLE_INDEX */
     36     word_idx = SPD_ID_TBL_AM_TABLE_INDEX_OFFSET / word_size;
     37     bit_idx  = SPD_ID_TBL_AM_TABLE_INDEX_OFFSET % word_size;
     38     entry->am_table_index = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_AM_TABLE_INDEX_MASK;
     39 
     40     /* FEC_ARCH */
     41     word_idx = SPD_ID_TBL_FEC_ARCH_OFFSET / word_size;
     42     bit_idx  = SPD_ID_TBL_FEC_ARCH_OFFSET % word_size;
     43     entry->fec_arch = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_FEC_ARCH_MASK;
     44 
     45     /* SYMBOL_INTERLEAVE */
     46     word_idx = SPD_ID_TBL_SYMBOL_INTERLEAVE_OFFSET / word_size;
     47     bit_idx  = SPD_ID_TBL_SYMBOL_INTERLEAVE_OFFSET % word_size;
     48     entry->symbol_interleave = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_SYMBOL_INTERLEAVE_MASK;
     49 
     50     /* TC_XOR_CONTROL */
     51     word_idx = SPD_ID_TBL_TC_XOR_CONTROL_OFFSET / word_size;
     52     bit_idx  = SPD_ID_TBL_TC_XOR_CONTROL_OFFSET % word_size;
     53     entry->tc_xor_control = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_TC_XOR_CONTROL_MASK;
     54 
     55     /* RS_FEC_SYNC_HEADER_MODE */
     56     word_idx = SPD_ID_TBL_RS_FEC_SYNC_HEADER_MODE_OFFSET / word_size;
     57     bit_idx  = SPD_ID_TBL_RS_FEC_SYNC_HEADER_MODE_OFFSET % word_size;
     58     entry->rs_fec_sync_header_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_RS_FEC_SYNC_HEADER_MODE_MASK;
     59 
     60     /* RS_FEC_CWM_NIBBLE_MATCH_COUNT */
     61     word_idx = SPD_ID_TBL_RS_FEC_CWM_NIBBLE_MATCH_COUNT_OFFSET / word_size;
     62     bit_idx  = SPD_ID_TBL_RS_FEC_CWM_NIBBLE_MATCH_COUNT_OFFSET % word_size;
     63     entry->rs_fec_cwm_nibble_match_count = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_RS_FEC_CWM_NIBBLE_MATCH_COUNT_MASK;
     64 
     65     /* BASE_R_FEC_SYNC_HEADER_MODE */
     66     word_idx = SPD_ID_TBL_BASE_R_FEC_SYNC_HEADER_MODE_OFFSET / word_size;
     67     bit_idx  = SPD_ID_TBL_BASE_R_FEC_SYNC_HEADER_MODE_OFFSET % word_size;
     68     entry->base_r_fec_sync_header_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_BASE_R_FEC_SYNC_HEADER_MODE_MASK;
     69 
     70     /* RS_FEC_SYMBOL_ERROR_WINDOW_MODE */
     71     word_idx = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_WINDOW_MODE_OFFSET / word_size;
     72     bit_idx  = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_WINDOW_MODE_OFFSET % word_size;
     73     entry->rs_fec_symbol_error_window_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_WINDOW_MODE_MASK;
     74 
     75     /* RS_FEC_SYMBOL_ERROR_COUNT_THRESHOLD */
     76     word_idx = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_COUNT_THRESHOLD_OFFSET / word_size;
     77     bit_idx  = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_COUNT_THRESHOLD_OFFSET % word_size;
     78     low_bits = word_size - bit_idx;
     79     low_mask = (1 << low_bits)  -1;
     80     high_bits = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_COUNT_THRESHOLD_WIDTH - low_bits;
     81     high_mask = (1 << high_bits) - 1;
     82     entry->rs_fec_symbol_error_count_threshold = (packed_entry[word_idx] >> bit_idx) & low_mask;
     83     entry->rs_fec_symbol_error_count_threshold |= (packed_entry[word_idx + 1] & high_mask) << low_bits;
     84 
     85     /* DESKEW_FORWARDING_THRESHOLD_2XN */
     86     word_idx = SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_2XN_OFFSET / word_size;
     87     bit_idx  = SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_2XN_OFFSET % word_size;
     88     entry->deskew_forwarding_threshold_2xn = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_2XN_MASK;
     89 
     90     /* DESKEW_FORWARDING_THRESHOLD_1XN */
     91     word_idx = SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_1XN_OFFSET / word_size;
     92     bit_idx  = SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_1XN_OFFSET % word_size;
     93     entry->deskew_forwarding_threshold_1xn = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_1XN_MASK;
     94 
     95     /* BIT_MUX_MODE */
     96     word_idx = SPD_ID_TBL_BIT_MUX_MODE_OFFSET / word_size;
     97     bit_idx  = SPD_ID_TBL_BIT_MUX_MODE_OFFSET % word_size;
     98     entry->bit_mux_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_BIT_MUX_MODE_MASK;
     99 
    100     /* NUM_LANES */
    101     word_idx = SPD_ID_TBL_NUM_LANES_OFFSET / word_size;
    102     bit_idx  = SPD_ID_TBL_NUM_LANES_OFFSET % word_size;
    103     entry->num_lanes = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_NUM_LANES_MASK;
    104 
    105     /* DESKEW_WINDOW_WITHOUT_RS_FEC */
    106     word_idx = SPD_ID_TBL_DESKEW_WINDOW_WITHOUT_RS_FEC_OFFSET / word_size;
    107     bit_idx  = SPD_ID_TBL_DESKEW_WINDOW_WITHOUT_RS_FEC_OFFSET % word_size;
    108     entry->deskew_window_without_rs_fec = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_DESKEW_WINDOW_WITHOUT_RS_FEC_MASK;
    109 
    110     /* DESKEW_WINDOW_WITH_RS_FEC */
    111     word_idx = SPD_ID_TBL_DESKEW_WINDOW_WITH_RS_FEC_OFFSET / word_size;
    112     bit_idx  = SPD_ID_TBL_DESKEW_WINDOW_WITH_RS_FEC_OFFSET % word_size;
    113     entry->deskew_window_with_rs_fec = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_DESKEW_WINDOW_WITH_RS_FEC_MASK;
    114 
    115     /* BER_FSM_DISABLE_WITH_RS_FEC */
    116     word_idx = SPD_ID_TBL_BER_FSM_DISABLE_WITH_RS_FEC_OFFSET / word_size;
    117     bit_idx  = SPD_ID_TBL_BER_FSM_DISABLE_WITH_RS_FEC_OFFSET % word_size;
    118     entry->ber_fsm_disable_with_rs_fec = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_BER_FSM_DISABLE_WITH_RS_FEC_MASK;
    119 
    120     /* BER_FSM_DISABLE_WITHOUT_RS_FEC */
    121     word_idx = SPD_ID_TBL_BER_FSM_DISABLE_WITHOUT_RS_FEC_OFFSET / word_size;
    122     bit_idx  = SPD_ID_TBL_BER_FSM_DISABLE_WITHOUT_RS_FEC_OFFSET % word_size;
    123     entry->ber_fsm_disable_without_rs_fec = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_BER_FSM_DISABLE_WITHOUT_RS_FEC_MASK;
    124 
    125     /* BER_WINDOW_MODE */
    126     word_idx = SPD_ID_TBL_BER_WINDOW_MODE_OFFSET / word_size;
    127     bit_idx  = SPD_ID_TBL_BER_WINDOW_MODE_OFFSET % word_size;
    128     entry->ber_window_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_BER_WINDOW_MODE_MASK;
    129 
    130     /* BER_TRIGGER_COUNT */
    131     word_idx = SPD_ID_TBL_BER_TRIGGER_COUNT_OFFSET / word_size;
    132     bit_idx  = SPD_ID_TBL_BER_TRIGGER_COUNT_OFFSET % word_size;
    133     entry->ber_trigger_count = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_BER_TRIGGER_COUNT_MASK;
    134 
    135     /* CREDIT_QUOTIENT */
    136     word_idx = SPD_ID_TBL_CREDIT_QUOTIENT_OFFSET / word_size;
    137     bit_idx  = SPD_ID_TBL_CREDIT_QUOTIENT_OFFSET % word_size;
    138     entry->credit_quotient = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_CREDIT_QUOTIENT_MASK;
    139 
    140     /* CREDIT_REMAINDER */
    141     word_idx = SPD_ID_TBL_CREDIT_REMAINDER_OFFSET / word_size;
    142     bit_idx  = SPD_ID_TBL_CREDIT_REMAINDER_OFFSET % word_size;
    143     entry->credit_remainder = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_CREDIT_REMAINDER_MASK;
    144 
    145     /* CREDIT_DIVISOR */
    146     word_idx = SPD_ID_TBL_CREDIT_DIVISOR_OFFSET / word_size;
    147     bit_idx  = SPD_ID_TBL_CREDIT_DIVISOR_OFFSET % word_size;
    148     low_bits = word_size - bit_idx;
    149     low_mask = (1 << low_bits)  -1;
    150     high_bits = SPD_ID_TBL_CREDIT_DIVISOR_WIDTH - low_bits;
    151     high_mask = (1 << high_bits) - 1;
    152     entry->credit_divisor = (packed_entry[word_idx] >> bit_idx) & low_mask;
    153     entry->credit_divisor |= (packed_entry[word_idx + 1] & high_mask) << low_bits;
    154 
    155     /* USE_CL49_BLOCK_SYNC */
    156     word_idx = SPD_ID_TBL_USE_CL49_BLOCK_SYNC_OFFSET / word_size;
    157     bit_idx  = SPD_ID_TBL_USE_CL49_BLOCK_SYNC_OFFSET % word_size;
    158     entry->use_cl49_block_sync = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_USE_CL49_BLOCK_SYNC_MASK;
    159 
    160     /* SCR_MODE */
    161     word_idx = SPD_ID_TBL_SCR_MODE_OFFSET / word_size;
    162     bit_idx  = SPD_ID_TBL_SCR_MODE_OFFSET % word_size;
    163     entry->scr_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_SCR_MODE_MASK;
    164 
    165     /* CODEC_MODE */
    166     word_idx = SPD_ID_TBL_CODEC_MODE_OFFSET / word_size;
    167     bit_idx  = SPD_ID_TBL_CODEC_MODE_OFFSET % word_size;
    168     entry->codec_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_CODEC_MODE_MASK;
    169 
    170     /* TRAINING_EN */
    171     word_idx = SPD_ID_TBL_TRAINING_EN_OFFSET / word_size;
    172     bit_idx  = SPD_ID_TBL_TRAINING_EN_OFFSET % word_size;
    173     entry->training_en = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_TRAINING_EN_MASK;
    174 
    175     /* AN_TIMER_SELECT */
    176     word_idx = SPD_ID_TBL_AN_TIMER_SELECT_OFFSET / word_size;
    177     bit_idx  = SPD_ID_TBL_AN_TIMER_SELECT_OFFSET % word_size;
    178     entry->an_timer_select = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_AN_TIMER_SELECT_MASK;
    179 
    180     /* PMD_PAM4_MODE */
    181     word_idx = SPD_ID_TBL_PMD_PAM4_MODE_OFFSET / word_size;
    182     bit_idx  = SPD_ID_TBL_PMD_PAM4_MODE_OFFSET % word_size;
    183     entry->pmd_pam4_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_PMD_PAM4_MODE_MASK;
    184 
    185     /* PMD_OSR_MODE */
    186     word_idx = SPD_ID_TBL_PMD_OSR_MODE_OFFSET / word_size;
    187     bit_idx  = SPD_ID_TBL_PMD_OSR_MODE_OFFSET % word_size;
    188     entry->pmd_osr_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_PMD_OSR_MODE_MASK;
    189 
    190     /* T_PMA_WATERMARK */
    191     word_idx = SPD_ID_TBL_T_PMA_WATERMARK_OFFSET / word_size;
    192     bit_idx  = SPD_ID_TBL_T_PMA_WATERMARK_OFFSET % word_size;
    193     entry->t_pma_watermark = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_T_PMA_WATERMARK_MASK;
    194 
    195     /* L_TPMA_WATERMARK */
    196     word_idx = SPD_ID_TBL_L_TPMA_WATERMARK_OFFSET / word_size;
    197     bit_idx  = SPD_ID_TBL_L_TPMA_WATERMARK_OFFSET % word_size;
    198     entry->l_tpma_watermark = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_L_TPMA_WATERMARK_MASK;
    199 
    200     /* LOOP_BLOCK_COUNT_FOR_TS */
    201     word_idx = SPD_ID_TBL_LOOP_BLOCK_COUNT_FOR_TS_OFFSET / word_size;
    202     bit_idx  = SPD_ID_TBL_LOOP_BLOCK_COUNT_FOR_TS_OFFSET % word_size;
    203     low_bits = word_size - bit_idx;
    204     low_mask = (1 << low_bits)  -1;
    205     high_bits = SPD_ID_TBL_LOOP_BLOCK_COUNT_FOR_TS_WIDTH - low_bits;
    206     high_mask = (1 << high_bits) - 1;
    207     entry->loop_block_count_for_ts = (packed_entry[word_idx] >> bit_idx) & low_mask;
    208     entry->loop_block_count_for_ts |= (packed_entry[word_idx + 1] & high_mask) << low_bits;
    209 
    210     /* LOOP_BIT_COUNT_FOR_TS */
    211     word_idx = SPD_ID_TBL_LOOP_BIT_COUNT_FOR_TS_OFFSET / word_size;
    212     bit_idx  = SPD_ID_TBL_LOOP_BIT_COUNT_FOR_TS_OFFSET % word_size;
    213     entry->loop_bit_count_for_ts = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_LOOP_BIT_COUNT_FOR_TS_MASK;
    214 
    215     /* AM_LOCK_FSM_MODE */
    216     word_idx = SPD_ID_TBL_AM_LOCK_FSM_MODE_OFFSET / word_size;
    217     bit_idx  = SPD_ID_TBL_AM_LOCK_FSM_MODE_OFFSET % word_size;
    218     entry->am_lock_fsm_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_AM_LOCK_FSM_MODE_MASK;
    219 
    220     /* T_PMA_START_MODE */
    221     word_idx = SPD_ID_TBL_T_PMA_START_MODE_OFFSET / word_size;
    222     bit_idx  = SPD_ID_TBL_T_PMA_START_MODE_OFFSET % word_size;
    223     entry->t_pma_start_mode = (packed_entry[word_idx] >> bit_idx) & SPD_ID_TBL_T_PMA_START_MODE_MASK;
    224 
    225     return;
    226 }
    227 
    228 /*
    229  * spd_ctrl_pack_spd_id_tbl_entry() : Pack a spd_id_tbl_entry_t into an array of 32-bit blocks
    230  */
    231 void spd_ctrl_pack_spd_id_tbl_entry(spd_id_tbl_entry_t *entry, uint32_t *packed_entry)
    232 {
    233     int num_words = 5;
    234     int word_size = 32;
    235     int word_idx = 0;
    236     int bit_idx = 0;
    237     int high_bits;
    238     int low_bits;
    239     int high_mask;
    240     int low_mask;
    241     int i;
    242 
    243     /* Initialize the packed_entry array to 0's */
    244     for (i = 0; i < num_words; i++) {
    245         packed_entry[i] = 0;
    246     }
    247 
    248     /* AM_TABLE_INDEX */
    249     word_idx = SPD_ID_TBL_AM_TABLE_INDEX_OFFSET / word_size;
    250     bit_idx  = SPD_ID_TBL_AM_TABLE_INDEX_OFFSET % word_size;
    251     packed_entry[word_idx] |= (entry->am_table_index & SPD_ID_TBL_AM_TABLE_INDEX_MASK) << bit_idx;
    252 
    253     /* FEC_ARCH */
    254     word_idx = SPD_ID_TBL_FEC_ARCH_OFFSET / word_size;
    255     bit_idx  = SPD_ID_TBL_FEC_ARCH_OFFSET % word_size;
    256     packed_entry[word_idx] |= (entry->fec_arch & SPD_ID_TBL_FEC_ARCH_MASK) << bit_idx;
    257 
    258     /* SYMBOL_INTERLEAVE */
    259     word_idx = SPD_ID_TBL_SYMBOL_INTERLEAVE_OFFSET / word_size;
    260     bit_idx  = SPD_ID_TBL_SYMBOL_INTERLEAVE_OFFSET % word_size;
    261     packed_entry[word_idx] |= (entry->symbol_interleave & SPD_ID_TBL_SYMBOL_INTERLEAVE_MASK) << bit_idx;
    262 
    263     /* TC_XOR_CONTROL */
    264     word_idx = SPD_ID_TBL_TC_XOR_CONTROL_OFFSET / word_size;
    265     bit_idx  = SPD_ID_TBL_TC_XOR_CONTROL_OFFSET % word_size;
    266     packed_entry[word_idx] |= (entry->tc_xor_control & SPD_ID_TBL_TC_XOR_CONTROL_MASK) << bit_idx;
    267 
    268     /* RS_FEC_SYNC_HEADER_MODE */
    269     word_idx = SPD_ID_TBL_RS_FEC_SYNC_HEADER_MODE_OFFSET / word_size;
    270     bit_idx  = SPD_ID_TBL_RS_FEC_SYNC_HEADER_MODE_OFFSET % word_size;
    271     packed_entry[word_idx] |= (entry->rs_fec_sync_header_mode & SPD_ID_TBL_RS_FEC_SYNC_HEADER_MODE_MASK) << bit_idx;
    272 
    273     /* RS_FEC_CWM_NIBBLE_MATCH_COUNT */
    274     word_idx = SPD_ID_TBL_RS_FEC_CWM_NIBBLE_MATCH_COUNT_OFFSET / word_size;
    275     bit_idx  = SPD_ID_TBL_RS_FEC_CWM_NIBBLE_MATCH_COUNT_OFFSET % word_size;
    276     packed_entry[word_idx] |= (entry->rs_fec_cwm_nibble_match_count & SPD_ID_TBL_RS_FEC_CWM_NIBBLE_MATCH_COUNT_MASK) << bit_idx;
    277 
    278     /* BASE_R_FEC_SYNC_HEADER_MODE */
    279     word_idx = SPD_ID_TBL_BASE_R_FEC_SYNC_HEADER_MODE_OFFSET / word_size;
    280     bit_idx  = SPD_ID_TBL_BASE_R_FEC_SYNC_HEADER_MODE_OFFSET % word_size;
    281     packed_entry[word_idx] |= (entry->base_r_fec_sync_header_mode & SPD_ID_TBL_BASE_R_FEC_SYNC_HEADER_MODE_MASK) << bit_idx;
    282 
    283     /* RS_FEC_SYMBOL_ERROR_WINDOW_MODE */
    284     word_idx = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_WINDOW_MODE_OFFSET / word_size;
    285     bit_idx  = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_WINDOW_MODE_OFFSET % word_size;
    286     packed_entry[word_idx] |= (entry->rs_fec_symbol_error_window_mode & SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_WINDOW_MODE_MASK) << bit_idx;
    287 
    288     /* RS_FEC_SYMBOL_ERROR_COUNT_THRESHOLD */
    289     word_idx = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_COUNT_THRESHOLD_OFFSET / word_size;
    290     bit_idx  = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_COUNT_THRESHOLD_OFFSET % word_size;
    291     low_bits = word_size - bit_idx;
    292     low_mask = (1 << low_bits)  -1;
    293     high_bits = SPD_ID_TBL_RS_FEC_SYMBOL_ERROR_COUNT_THRESHOLD_WIDTH - low_bits;
    294     high_mask = (1 << high_bits) - 1;
    295     packed_entry[word_idx] |= (entry->rs_fec_symbol_error_count_threshold & low_mask) << bit_idx;
    296     packed_entry[word_idx + 1] |= (entry->rs_fec_symbol_error_count_threshold >> low_bits) & high_mask;
    297 
    298     /* DESKEW_FORWARDING_THRESHOLD_2XN */
    299     word_idx = SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_2XN_OFFSET / word_size;
    300     bit_idx  = SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_2XN_OFFSET % word_size;
    301     packed_entry[word_idx] |= (entry->deskew_forwarding_threshold_2xn & SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_2XN_MASK) << bit_idx;
    302 
    303     /* DESKEW_FORWARDING_THRESHOLD_1XN */
    304     word_idx = SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_1XN_OFFSET / word_size;
    305     bit_idx  = SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_1XN_OFFSET % word_size;
    306     packed_entry[word_idx] |= (entry->deskew_forwarding_threshold_1xn & SPD_ID_TBL_DESKEW_FORWARDING_THRESHOLD_1XN_MASK) << bit_idx;
    307 
    308     /* BIT_MUX_MODE */
    309     word_idx = SPD_ID_TBL_BIT_MUX_MODE_OFFSET / word_size;
    310     bit_idx  = SPD_ID_TBL_BIT_MUX_MODE_OFFSET % word_size;
    311     packed_entry[word_idx] |= (entry->bit_mux_mode & SPD_ID_TBL_BIT_MUX_MODE_MASK) << bit_idx;
    312 
    313     /* NUM_LANES */
    314     word_idx = SPD_ID_TBL_NUM_LANES_OFFSET / word_size;
    315     bit_idx  = SPD_ID_TBL_NUM_LANES_OFFSET % word_size;
    316     packed_entry[word_idx] |= (entry->num_lanes & SPD_ID_TBL_NUM_LANES_MASK) << bit_idx;
    317 
    318     /* DESKEW_WINDOW_WITHOUT_RS_FEC */
    319     word_idx = SPD_ID_TBL_DESKEW_WINDOW_WITHOUT_RS_FEC_OFFSET / word_size;
    320     bit_idx  = SPD_ID_TBL_DESKEW_WINDOW_WITHOUT_RS_FEC_OFFSET % word_size;
    321     packed_entry[word_idx] |= (entry->deskew_window_without_rs_fec & SPD_ID_TBL_DESKEW_WINDOW_WITHOUT_RS_FEC_MASK) << bit_idx;
    322 
    323     /* DESKEW_WINDOW_WITH_RS_FEC */
    324     word_idx = SPD_ID_TBL_DESKEW_WINDOW_WITH_RS_FEC_OFFSET / word_size;
    325     bit_idx  = SPD_ID_TBL_DESKEW_WINDOW_WITH_RS_FEC_OFFSET % word_size;
    326     packed_entry[word_idx] |= (entry->deskew_window_with_rs_fec & SPD_ID_TBL_DESKEW_WINDOW_WITH_RS_FEC_MASK) << bit_idx;
    327 
    328     /* BER_FSM_DISABLE_WITH_RS_FEC */
    329     word_idx = SPD_ID_TBL_BER_FSM_DISABLE_WITH_RS_FEC_OFFSET / word_size;
    330     bit_idx  = SPD_ID_TBL_BER_FSM_DISABLE_WITH_RS_FEC_OFFSET % word_size;
    331     packed_entry[word_idx] |= (entry->ber_fsm_disable_with_rs_fec & SPD_ID_TBL_BER_FSM_DISABLE_WITH_RS_FEC_MASK) << bit_idx;
    332 
    333     /* BER_FSM_DISABLE_WITHOUT_RS_FEC */
    334     word_idx = SPD_ID_TBL_BER_FSM_DISABLE_WITHOUT_RS_FEC_OFFSET / word_size;
    335     bit_idx  = SPD_ID_TBL_BER_FSM_DISABLE_WITHOUT_RS_FEC_OFFSET % word_size;
    336     packed_entry[word_idx] |= (entry->ber_fsm_disable_without_rs_fec & SPD_ID_TBL_BER_FSM_DISABLE_WITHOUT_RS_FEC_MASK) << bit_idx;
    337 
    338     /* BER_WINDOW_MODE */
    339     word_idx = SPD_ID_TBL_BER_WINDOW_MODE_OFFSET / word_size;
    340     bit_idx  = SPD_ID_TBL_BER_WINDOW_MODE_OFFSET % word_size;
    341     packed_entry[word_idx] |= (entry->ber_window_mode & SPD_ID_TBL_BER_WINDOW_MODE_MASK) << bit_idx;
    342 
    343     /* BER_TRIGGER_COUNT */
    344     word_idx = SPD_ID_TBL_BER_TRIGGER_COUNT_OFFSET / word_size;
    345     bit_idx  = SPD_ID_TBL_BER_TRIGGER_COUNT_OFFSET % word_size;
    346         packed_entry[word_idx] |= (entry->ber_trigger_count & SPD_ID_TBL_BER_TRIGGER_COUNT_MASK) << bit_idx;
    347 
    348     /* CREDIT_QUOTIENT */
    349     word_idx = SPD_ID_TBL_CREDIT_QUOTIENT_OFFSET / word_size;
    350     bit_idx  = SPD_ID_TBL_CREDIT_QUOTIENT_OFFSET % word_size;
    351     packed_entry[word_idx] |= (entry->credit_quotient & SPD_ID_TBL_CREDIT_QUOTIENT_MASK) << bit_idx;
    352 
    353     /* CREDIT_REMAINDER */
    354     word_idx = SPD_ID_TBL_CREDIT_REMAINDER_OFFSET / word_size;
    355     bit_idx  = SPD_ID_TBL_CREDIT_REMAINDER_OFFSET % word_size;
    356     packed_entry[word_idx] |= (entry->credit_remainder & SPD_ID_TBL_CREDIT_REMAINDER_MASK) << bit_idx;
    357 
    358     /* CREDIT_DIVISOR */
    359     word_idx = SPD_ID_TBL_CREDIT_DIVISOR_OFFSET / word_size;
    360     bit_idx  = SPD_ID_TBL_CREDIT_DIVISOR_OFFSET % word_size;
    361     low_bits = word_size - bit_idx;
    362     low_mask = (1 << low_bits)  -1;
    363     high_bits = SPD_ID_TBL_CREDIT_DIVISOR_WIDTH - low_bits;
    364     high_mask = (1 << high_bits) - 1;
    365     packed_entry[word_idx] |= (entry->credit_divisor & low_mask) << bit_idx;
    366     packed_entry[word_idx + 1] |= (entry->credit_divisor >> low_bits) & high_mask;
    367 
    368     /* USE_CL49_BLOCK_SYNC */
    369     word_idx = SPD_ID_TBL_USE_CL49_BLOCK_SYNC_OFFSET / word_size;
    370     bit_idx  = SPD_ID_TBL_USE_CL49_BLOCK_SYNC_OFFSET % word_size;
    371     packed_entry[word_idx] |= (entry->use_cl49_block_sync & SPD_ID_TBL_USE_CL49_BLOCK_SYNC_MASK) << bit_idx;
    372 
    373     /* SCR_MODE */
    374     word_idx = SPD_ID_TBL_SCR_MODE_OFFSET / word_size;
    375     bit_idx  = SPD_ID_TBL_SCR_MODE_OFFSET % word_size;
    376     packed_entry[word_idx] |= (entry->scr_mode & SPD_ID_TBL_SCR_MODE_MASK) << bit_idx;
    377 
    378     /* CODEC_MODE */
    379     word_idx = SPD_ID_TBL_CODEC_MODE_OFFSET / word_size;
    380     bit_idx  = SPD_ID_TBL_CODEC_MODE_OFFSET % word_size;
    381     packed_entry[word_idx] |= (entry->codec_mode & SPD_ID_TBL_CODEC_MODE_MASK) << bit_idx;
    382 
    383     /* TRAINING_EN */
    384     word_idx = SPD_ID_TBL_TRAINING_EN_OFFSET / word_size;
    385     bit_idx  = SPD_ID_TBL_TRAINING_EN_OFFSET % word_size;
    386     packed_entry[word_idx] |= (entry->training_en & SPD_ID_TBL_TRAINING_EN_MASK) << bit_idx;
    387 
    388     /* AN_TIMER_SELECT */
    389     word_idx = SPD_ID_TBL_AN_TIMER_SELECT_OFFSET / word_size;
    390     bit_idx  = SPD_ID_TBL_AN_TIMER_SELECT_OFFSET % word_size;
    391     packed_entry[word_idx] |= (entry->an_timer_select & SPD_ID_TBL_AN_TIMER_SELECT_MASK) << bit_idx;
    392 
    393     /* PMD_PAM4_MODE */
    394     word_idx = SPD_ID_TBL_PMD_PAM4_MODE_OFFSET / word_size;
    395     bit_idx  = SPD_ID_TBL_PMD_PAM4_MODE_OFFSET % word_size;
    396     packed_entry[word_idx] |= (entry->pmd_pam4_mode & SPD_ID_TBL_PMD_PAM4_MODE_MASK) << bit_idx;
    397 
    398     /* PMD_OSR_MODE */
    399     word_idx = SPD_ID_TBL_PMD_OSR_MODE_OFFSET / word_size;
    400     bit_idx  = SPD_ID_TBL_PMD_OSR_MODE_OFFSET % word_size;
    401     packed_entry[word_idx] |= (entry->pmd_osr_mode & SPD_ID_TBL_PMD_OSR_MODE_MASK) << bit_idx;
    402 
    403     /* T_PMA_WATERMARK */
    404     word_idx = SPD_ID_TBL_T_PMA_WATERMARK_OFFSET / word_size;
    405     bit_idx  = SPD_ID_TBL_T_PMA_WATERMARK_OFFSET % word_size;
    406     packed_entry[word_idx] |= (entry->t_pma_watermark & SPD_ID_TBL_T_PMA_WATERMARK_MASK) << bit_idx;
    407 
    408     /* L_TPMA_WATERMARK */
    409     word_idx = SPD_ID_TBL_L_TPMA_WATERMARK_OFFSET / word_size;
    410     bit_idx  = SPD_ID_TBL_L_TPMA_WATERMARK_OFFSET % word_size;
    411     packed_entry[word_idx] |= (entry->l_tpma_watermark & SPD_ID_TBL_L_TPMA_WATERMARK_MASK) << bit_idx;
    412 
    413     /* LOOP_BLOCK_COUNT_FOR_TS */
    414     word_idx = SPD_ID_TBL_LOOP_BLOCK_COUNT_FOR_TS_OFFSET / word_size;
    415     bit_idx  = SPD_ID_TBL_LOOP_BLOCK_COUNT_FOR_TS_OFFSET % word_size;
    416     low_bits = word_size - bit_idx;
    417     low_mask = (1 << low_bits)  -1;
    418     high_bits = SPD_ID_TBL_LOOP_BLOCK_COUNT_FOR_TS_WIDTH - low_bits;
    419     high_mask = (1 << high_bits) - 1;
    420     packed_entry[word_idx] |= (entry->loop_block_count_for_ts & low_mask) << bit_idx;
    421     packed_entry[word_idx + 1] |= (entry->loop_block_count_for_ts >> low_bits) & high_mask;
    422 
    423     /* LOOP_BIT_COUNT_FOR_TS */
    424     word_idx = SPD_ID_TBL_LOOP_BIT_COUNT_FOR_TS_OFFSET / word_size;
    425     bit_idx  = SPD_ID_TBL_LOOP_BIT_COUNT_FOR_TS_OFFSET % word_size;
    426     packed_entry[word_idx] |= (entry->loop_bit_count_for_ts & SPD_ID_TBL_LOOP_BIT_COUNT_FOR_TS_MASK) << bit_idx;
    427 
    428     /* AM_LOCK_FSM_MODE */
    429     word_idx = SPD_ID_TBL_AM_LOCK_FSM_MODE_OFFSET / word_size;
    430     bit_idx  = SPD_ID_TBL_AM_LOCK_FSM_MODE_OFFSET % word_size;
    431     packed_entry[word_idx] |= (entry->am_lock_fsm_mode & SPD_ID_TBL_AM_LOCK_FSM_MODE_MASK) << bit_idx;
    432 
    433     /* T_PMA_START_MODE */
    434     word_idx = SPD_ID_TBL_T_PMA_START_MODE_OFFSET / word_size;
    435     bit_idx  = SPD_ID_TBL_T_PMA_START_MODE_OFFSET % word_size;
    436     packed_entry[word_idx] |= (entry->t_pma_start_mode & SPD_ID_TBL_T_PMA_START_MODE_MASK) << bit_idx;
    437 
    438     return;
    439 }
    440 
    441 
    442 #ifdef _DV_TB_
    443 /*
    444  * spd_ctrl_print_spd_id_tbl_entry() : Print the contents of a UM Table Entry
    445  */
    446 void spd_ctrl_print_spd_id_tbl_entry(spd_id_tbl_entry_t *entry) 
    447 {
    448     printf("AM_TABLE_INDEX                      : 0x%0x\n", entry->am_table_index);
    449     printf("FEC_ARCH                            : 0x%0x\n", entry->fec_arch);
    450     printf("SYMBOL_INTERLEAVE                   : 0x%0x\n", entry->symbol_interleave);
    451     printf("TC_XOR_CONTROL                      : 0x%0x\n", entry->tc_xor_control);
    452     printf("RS_FEC_SYNC_HEADER_MODE             : 0x%0x\n", entry->rs_fec_sync_header_mode);
    453     printf("RS_FEC_CWM_NIBBLE_MATCH_COUNT       : 0x%0x\n", entry->rs_fec_cwm_nibble_match_count);
    454     printf("BASE_R_FEC_SYNC_HEADER_MODE         : 0x%0x\n", entry->base_r_fec_sync_header_mode);
    455     printf("RS_FEC_SYMBOL_ERROR_WINDOW_MODE     : 0x%0x\n", entry->rs_fec_symbol_error_window_mode);
    456     printf("RS_FEC_SYMBOL_ERROR_COUNT_THRESHOLD : 0x%0x\n", entry->rs_fec_symbol_error_count_threshold);
    457     printf("DESKEW_FORWARDING_THRESHOLD_2XN     : 0x%0x\n", entry->deskew_forwarding_threshold_2xn);
    458     printf("DESKEW_FORWARDING_THRESHOLD_1XN     : 0x%0x\n", entry->deskew_forwarding_threshold_1xn);
    459     printf("BIT_MUX_MODE                        : 0x%0x\n", entry->bit_mux_mode);
    460     printf("NUM_LANES                           : 0x%0x\n", entry->num_lanes);
    461     printf("DESKEW_WINDOW_WITHOUT_RS_FEC        : 0x%0x\n", entry->deskew_window_without_rs_fec);
    462     printf("DESKEW_WINDOW_WITH_RS_FEC           : 0x%0x\n", entry->deskew_window_with_rs_fec);
    463     printf("BER_FSM_DISABLE_WITH_RS_FEC         : 0x%0x\n", entry->ber_fsm_disable_with_rs_fec);
    464     printf("BER_FSM_DISABLE_WITHOUT_RS_FEC      : 0x%0x\n", entry->ber_fsm_disable_without_rs_fec);
    465     printf("BER_WINDOW_MODE                     : 0x%0x\n", entry->ber_window_mode);
    466     printf("BER_TRIGGER_COUNT                   : 0x%0x\n", entry->ber_trigger_count);
    467     printf("CREDIT_QUOTIENT                     : 0x%0x\n", entry->credit_quotient);
    468     printf("CREDIT_REMAINDER                    : 0x%0x\n", entry->credit_remainder);
    469     printf("CREDIT_DIVISOR                      : 0x%0x\n", entry->credit_divisor);
    470     printf("USE_CL49_BLOCK_SYNC                 : 0x%0x\n", entry->use_cl49_block_sync);
    471     printf("SCR_MODE                            : 0x%0x\n", entry->scr_mode);
    472     printf("CODEC_MODE                          : 0x%0x\n", entry->codec_mode);
    473     printf("TRAINING_EN                         : 0x%0x\n", entry->training_en);
    474     printf("AN_TIMER_SELECT                     : 0x%0x\n", entry->an_timer_select);
    475     printf("PMD_PAM4_MODE                       : 0x%0x\n", entry->pmd_pam4_mode);
    476     printf("PMD_OSR_MODE                        : 0x%0x\n", entry->pmd_osr_mode);
    477     printf("T_PMA_WATERMARK                     : 0x%0x\n", entry->t_pma_watermark);
    478     printf("L_TPMA_WATERMARK                    : 0x%0x\n", entry->l_tpma_watermark);
    479     printf("LOOP_BLOCK_COUNT_FOR_TS             : 0x%0x\n", entry->loop_block_count_for_ts);
    480     printf("LOOP_BIT_COUNT_FOR_TS               : 0x%0x\n", entry->loop_bit_count_for_ts);
    481     printf("AM_LOCK_FSM_MODE                    : 0x%0x\n", entry->am_lock_fsm_mode);
    482     printf("T_PMA_START_MODE                    : 0x%0x\n", entry->t_pma_start_mode);                   
    483 
    484     return;
    485 }
    486 #endif
    487 
    488 /*
    489  * spd_ctrl_unpack_am_tbl_entry() : Unpacks a char array into an am_tbl_entry_t
    490  */
    491 void spd_ctrl_unpack_am_tbl_entry(uint32_t *packed_entry, am_tbl_entry_t *entry)
    492 {
    493     int word_size = 32;
    494     int word_idx;
    495     int bit_idx;
    496     int high_bits;
    497     int low_bits;
    498     int high_mask;
    499     int low_mask;
    500 
    501     /* AM_COMPRESSION_MODE */
    502     word_idx = AM_TBL_AM_COMPRESSION_MODE_OFFSET / word_size;
    503     bit_idx  = AM_TBL_AM_COMPRESSION_MODE_OFFSET % word_size;
    504     entry->am_compression_mode = (packed_entry[word_idx] >> bit_idx) & AM_TBL_AM_COMPRESSION_MODE_MASK;
    505 
    506     /* AM_SIZE */
    507     word_idx = AM_TBL_AM_SIZE_OFFSET / word_size;
    508     bit_idx  = AM_TBL_AM_SIZE_OFFSET % word_size;
    509     entry->am_size = (packed_entry[word_idx] >> bit_idx) & AM_TBL_AM_SIZE_MASK;
    510 
    511     /* PAD_MODE */
    512     word_idx = AM_TBL_PAD_MODE_OFFSET / word_size;
    513     bit_idx  = AM_TBL_PAD_MODE_OFFSET % word_size;
    514     entry->pad_mode = (packed_entry[word_idx] >> bit_idx) & AM_TBL_PAD_MODE_MASK;
    515 
    516     /* UM_TABLE_COUNT */
    517     word_idx = AM_TBL_UM_TABLE_COUNT_OFFSET / word_size;
    518     bit_idx  = AM_TBL_UM_TABLE_COUNT_OFFSET % word_size;
    519     entry->um_table_count = (packed_entry[word_idx] >> bit_idx) & AM_TBL_UM_TABLE_COUNT_MASK;
    520 
    521     /* UM_TABLE_INDEX */
    522     word_idx = AM_TBL_UM_TABLE_INDEX_OFFSET / word_size;
    523     bit_idx  = AM_TBL_UM_TABLE_INDEX_OFFSET % word_size;
    524     entry->um_table_index = (packed_entry[word_idx] >> bit_idx) & AM_TBL_UM_TABLE_INDEX_MASK;
    525 
    526     /* CM */
    527     word_idx = AM_TBL_CM_OFFSET / word_size;
    528     bit_idx  = AM_TBL_CM_OFFSET % word_size;
    529     low_bits = word_size - bit_idx;
    530     low_mask = (1 << low_bits)  -1;
    531     high_bits = AM_TBL_CM_WIDTH - low_bits;
    532     high_mask = (1 << high_bits) - 1;
    533     entry->cm = (packed_entry[word_idx] >> bit_idx) & low_mask;
    534     entry->cm |= (packed_entry[word_idx + 1] & high_mask) << low_bits;
    535 
    536     /* USE_FIXED */
    537     word_idx = AM_TBL_USE_FIXED_OFFSET / word_size;
    538     bit_idx  = AM_TBL_USE_FIXED_OFFSET % word_size;
    539     entry->use_fixed = (packed_entry[word_idx] >> bit_idx) & AM_TBL_USE_FIXED_MASK;
    540 
    541     /* AM_SPACING_RS */
    542     word_idx = AM_TBL_AM_SPACING_RS_OFFSET / word_size;
    543     bit_idx  = AM_TBL_AM_SPACING_RS_OFFSET % word_size;
    544     entry->am_spacing_rs = (packed_entry[word_idx] >> bit_idx) & AM_TBL_AM_SPACING_RS_MASK;
    545 
    546     /* AM_SPACING_NO_RS */
    547     word_idx = AM_TBL_AM_SPACING_NO_RS_OFFSET / word_size;
    548     bit_idx  = AM_TBL_AM_SPACING_NO_RS_OFFSET % word_size;
    549     low_bits = word_size - bit_idx;
    550     low_mask = (1 << low_bits)  -1;
    551     high_bits = AM_TBL_AM_SPACING_NO_RS_WIDTH - low_bits;
    552     high_mask = (1 << high_bits) - 1;
    553     entry->am_spacing_no_rs = (packed_entry[word_idx] >> bit_idx) & low_mask;
    554     entry->am_spacing_no_rs |= (packed_entry[word_idx + 1] & high_mask) << low_bits;
    555 
    556     /* AM_SPACING_CREDITS */
    557     word_idx = AM_TBL_AM_SPACING_CREDITS_OFFSET / word_size;
    558     bit_idx  = AM_TBL_AM_SPACING_CREDITS_OFFSET % word_size;
    559     entry->am_spacing_credits = (packed_entry[word_idx] >> bit_idx) & AM_TBL_AM_SPACING_CREDITS_MASK;
    560 
    561     return;
    562 }
    563 
    564 
    565 /*
    566  * spd_ctrl_pack_am_tbl_entry() : Packet an am_tbl_entry_t into an array of 32-bit blocks
    567  */
    568 void spd_ctrl_pack_am_tbl_entry(am_tbl_entry_t *entry, uint32_t *packed_entry)
    569 {
    570     int num_words = 3;
    571     int word_size = 32;
    572     int word_idx = 0;
    573     int bit_idx = 0;
    574     int high_bits;
    575     int low_bits;
    576     int high_mask;
    577     int low_mask;
    578     int i;
    579 
    580     /* Initialize the packed_entry array to 0's */
    581     for (i = 0; i < num_words; i++) {
    582         packed_entry[i] = 0;
    583     }
    584 
    585     /* AM_COMPRESSION_MODE */
    586     word_idx = AM_TBL_AM_COMPRESSION_MODE_OFFSET / word_size;    
    587     bit_idx  = AM_TBL_AM_COMPRESSION_MODE_OFFSET % word_size;
    588     packed_entry[word_idx] |= (entry->am_compression_mode & AM_TBL_AM_COMPRESSION_MODE_MASK) << bit_idx;
    589 
    590     /* AM_SIZE */
    591     word_idx = AM_TBL_AM_SIZE_OFFSET / word_size;    
    592     bit_idx  = AM_TBL_AM_SIZE_OFFSET % word_size;
    593     packed_entry[word_idx] |= (entry->am_size & AM_TBL_AM_SIZE_MASK) << bit_idx;
    594 
    595     /* PAD_MODE */
    596     word_idx = AM_TBL_PAD_MODE_OFFSET / word_size;    
    597     bit_idx  = AM_TBL_PAD_MODE_OFFSET % word_size;
    598     packed_entry[word_idx] |= (entry->pad_mode & AM_TBL_PAD_MODE_MASK) << bit_idx;
    599 
    600     /* UM_TABLE_COUNT */
    601     word_idx = AM_TBL_UM_TABLE_COUNT_OFFSET / word_size;    
    602     bit_idx  = AM_TBL_UM_TABLE_COUNT_OFFSET % word_size;
    603     packed_entry[word_idx] |= (entry->um_table_count & AM_TBL_UM_TABLE_COUNT_MASK) << bit_idx;
    604 
    605     /* UM_TABLE_INDEX */
    606     word_idx = AM_TBL_UM_TABLE_INDEX_OFFSET / word_size;    
    607     bit_idx  = AM_TBL_UM_TABLE_INDEX_OFFSET % word_size;
    608     packed_entry[word_idx] |= (entry->um_table_index & AM_TBL_UM_TABLE_INDEX_MASK) << bit_idx;
    609 
    610     /* CM */
    611     word_idx = AM_TBL_CM_OFFSET / word_size;    
    612     bit_idx  = AM_TBL_CM_OFFSET % word_size;
    613     low_bits  = 32 - bit_idx;
    614     low_mask  = (1 << low_bits) - 1;
    615     high_bits = AM_TBL_CM_WIDTH - low_bits;
    616     high_mask  = (1 << high_bits) - 1;
    617     packed_entry[word_idx] |= (entry->cm & low_mask) << bit_idx;
    618     packed_entry[word_idx + 1] |= (entry->cm & high_mask) >> low_bits;
    619 
    620     /* USE_FIXED */
    621     word_idx = AM_TBL_USE_FIXED_OFFSET / word_size;    
    622     bit_idx  = AM_TBL_USE_FIXED_OFFSET % word_size;
    623     packed_entry[word_idx] |= (entry->use_fixed & AM_TBL_USE_FIXED_MASK) << bit_idx;
    624 
    625     /* AM_SPACING_RS */
    626     word_idx = AM_TBL_AM_SPACING_RS_OFFSET / word_size;    
    627     bit_idx  = AM_TBL_AM_SPACING_RS_OFFSET % word_size;
    628     packed_entry[word_idx] |= (entry->am_spacing_rs & AM_TBL_AM_SPACING_RS_MASK) << bit_idx;
    629 
    630     /* AM_SPACING_NO_RS */
    631     word_idx = AM_TBL_AM_SPACING_NO_RS_OFFSET / word_size;    
    632     bit_idx  = AM_TBL_AM_SPACING_NO_RS_OFFSET % word_size;
    633     low_bits  = 32 - bit_idx;
    634     low_mask  = (1 << low_bits) - 1;
    635     high_bits = AM_TBL_AM_SPACING_NO_RS_WIDTH - low_bits;
    636     high_mask  = (1 << high_bits) - 1;
    637     packed_entry[word_idx] |= (entry->am_spacing_no_rs & low_mask) << bit_idx;
    638     packed_entry[word_idx + 1] |= (entry->am_spacing_no_rs & high_mask) >> low_bits;
    639 
    640     /* AM_SPACING_CREDITS */
    641     word_idx = AM_TBL_AM_SPACING_CREDITS_OFFSET / word_size;    
    642     bit_idx  = AM_TBL_AM_SPACING_CREDITS_OFFSET % word_size;
    643     packed_entry[word_idx] |= (entry->am_spacing_credits & AM_TBL_AM_SPACING_CREDITS_MASK) << bit_idx;
    644 
    645 
    646     return;
    647 }
    648 
    649 #ifdef _DV_TB_
    650 /*
    651  * spd_ctrl_print_am_tbl_entry() : Print the contents of a UM Table Entry
    652  */
    653 void spd_ctrl_print_am_tbl_entry(am_tbl_entry_t *entry) 
    654 {
    655    printf("AM_SPACING_CREDITS  : 0x%0x\n", entry->am_spacing_credits);
    656    printf("AM_SPACING_NO_RS    : 0x%0x\n", entry->am_spacing_no_rs);
    657    printf("AM_SPACING_RS       : 0x%0x\n", entry->am_spacing_rs);
    658    printf("USE_FIXED           : 0x%0x\n", entry->use_fixed);
    659    printf("CM                  : 0x%0x\n", entry->cm);
    660    printf("UM_TABLE_INDEX      : 0x%0x\n", entry->um_table_index);
    661    printf("UM_TABLE_COUNT      : 0x%0x\n", entry->um_table_count);
    662    printf("PAD_MODE            : 0x%0x\n", entry->pad_mode);
    663    printf("AM_SIZE             : 0x%0x\n", entry->am_size);
    664    printf("AM_COMPRESSION_MODE : 0x%0x\n", entry->am_compression_mode);
    665    return;
    666 }
    667 #endif
    668 
    669 /*
    670  * spd_ctrl_unpack_um_tbl_entry() : Unpacks a uint8_t array into an um_tbl_entry_t
    671  */
    672 void spd_ctrl_unpack_um_tbl_entry(uint32_t *packed_entry, um_tbl_entry_t *entry)
    673 {
    674     int word_size = 32;
    675     int word_idx;
    676     int bit_idx;
    677     int high_bits;
    678     int low_bits;
    679     int high_mask;
    680     int low_mask;
    681 
    682     /* CM_CONTROL */
    683     word_idx = UM_TBL_CM_CONTROL_OFFSET / word_size;
    684     bit_idx  = UM_TBL_CM_CONTROL_OFFSET % word_size;
    685     entry->cm_control = (packed_entry[word_idx] >> bit_idx) & UM_TBL_CM_CONTROL_MASK;
    686     
    687     /* UM_PAD */
    688     word_idx = UM_TBL_UM_PAD_OFFSET / word_size;
    689     bit_idx  = UM_TBL_UM_PAD_OFFSET % word_size;
    690     entry->um_pad = (packed_entry[word_idx] >> bit_idx) & UM_TBL_UM_PAD_MASK;
    691 
    692     /* CM_PAD */
    693     word_idx = UM_TBL_CM_PAD_OFFSET / word_size;
    694     bit_idx  = UM_TBL_CM_PAD_OFFSET % word_size;
    695     entry->cm_pad = (packed_entry[word_idx] >> bit_idx) & UM_TBL_CM_PAD_MASK;
    696 
    697     /* UM */
    698     word_idx = UM_TBL_UM_OFFSET / word_size;
    699     bit_idx  = UM_TBL_UM_OFFSET % word_size;
    700     low_bits = word_size - bit_idx;
    701     low_mask = (1 << low_bits)  -1;
    702     high_bits = UM_TBL_UM_WIDTH - low_bits;
    703     high_mask =  (1 << high_bits) - 1;
    704     entry->um = (packed_entry[word_idx] >> bit_idx) & low_mask;
    705     entry->um |= (packed_entry[word_idx + 1] & high_mask) << low_bits;
    706 
    707     return;
    708 }
    709 
    710 /*
    711  * spd_ctrl_pack_um_tbl_entry() : Packet an am_tbl_entry_t into an array of 32-bit blocks
    712  */
    713 void spd_ctrl_pack_um_tbl_entry(um_tbl_entry_t *entry, uint32_t *packed_entry)
    714 {
    715     int num_words = 2;
    716     int word_size = 32;
    717     int word_idx = 0;
    718     int bit_idx = 0;
    719     int high_bits;
    720     int low_bits;
    721     int high_mask;
    722     int low_mask;
    723     int i;
    724 
    725     /* Initialize the packed_entry array to 0's */
    726     for (i = 0; i < num_words; i++) {
    727         packed_entry[i] = 0;
    728     }
    729 
    730     /* CM_CONTROL */
    731     word_idx = UM_TBL_CM_CONTROL_OFFSET / word_size;    
    732     bit_idx  = UM_TBL_CM_CONTROL_OFFSET % word_size;
    733     packed_entry[word_idx] |= (entry->cm_control & UM_TBL_CM_CONTROL_MASK) << bit_idx;
    734 
    735     /* UM_PAD */
    736     word_idx = UM_TBL_UM_PAD_OFFSET / word_size;    
    737     bit_idx  = UM_TBL_UM_PAD_OFFSET % word_size;
    738     packed_entry[word_idx] |= (entry->um_pad & UM_TBL_UM_PAD_MASK) << bit_idx;
    739 
    740     /* CM_PAD */
    741     word_idx = UM_TBL_CM_PAD_OFFSET / word_size;    
    742     bit_idx  = UM_TBL_CM_PAD_OFFSET % word_size;
    743     packed_entry[word_idx] |= (entry->cm_pad & UM_TBL_CM_PAD_MASK) << bit_idx;
    744 
    745     /* UM */
    746     word_idx = UM_TBL_UM_OFFSET / word_size;    
    747     bit_idx  = UM_TBL_UM_OFFSET % word_size;
    748     low_bits  = word_size - bit_idx;
    749     low_mask  = (1 << low_bits) - 1;
    750     high_bits = UM_TBL_UM_WIDTH - low_bits;
    751     high_mask  = (1 << high_bits) - 1;
    752     packed_entry[word_idx] |= (entry->um & low_mask) << bit_idx;
    753     packed_entry[word_idx + 1] |= (entry->um >> low_bits) & high_mask;
    754 
    755     return;
    756 }
    757 
    758 #ifdef _DV_TB_
    759 /*
    760  * spd_ctrl_print_um_tbl_entry() : Print the contents of a UM Table Entry
    761  */
    762 void spd_ctrl_print_um_tbl_entry(um_tbl_entry_t *entry) 
    763 {
    764    printf("UM         : 0x%0x\n", entry->um);
    765    printf("CM_PAD     : 0x%0x\n", entry->cm_pad);
    766    printf("UM_PAD     : 0x%0x\n", entry->um_pad);
    767    printf("CM_CONTROL : 0x%0x\n", entry->cm_control);
    768    return;
    769 }
    770 #endif
    771 #endif  /* _TBHMOD_SPD_CTRL_C_ */