| 1 | /*************************************************************** |
|---|
| 2 | ** |
|---|
| 3 | ** Broadcom Corp. Confidential |
|---|
| 4 | ** Copyright 2003-2008 Broadcom Corp. All Rights Reserved. |
|---|
| 5 | ** |
|---|
| 6 | ** THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED |
|---|
| 7 | ** SOFTWARE LICENSE AGREEMENT BETWEEN THE USER AND BROADCOM. |
|---|
| 8 | ** YOU HAVE NO RIGHT TO USE OR EXPLOIT THIS MATERIAL EXCEPT |
|---|
| 9 | ** SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. |
|---|
| 10 | ** |
|---|
| 11 | ** File: si_svct.c |
|---|
| 12 | ** Description: function that parses the S-VCT table sections. |
|---|
| 13 | ** |
|---|
| 14 | ** Created: 03/08/2001 |
|---|
| 15 | ** |
|---|
| 16 | ** REVISION: |
|---|
| 17 | ** |
|---|
| 18 | ** $Log: $ |
|---|
| 19 | ** |
|---|
| 20 | ** |
|---|
| 21 | ****************************************************************/ |
|---|
| 22 | #include "si.h" |
|---|
| 23 | #include "si_os.h" |
|---|
| 24 | #include "si_dbg.h" |
|---|
| 25 | #include "si_util.h" |
|---|
| 26 | #include "si_list.h" |
|---|
| 27 | #include "si_vct.h" |
|---|
| 28 | #include "si_svct_vcm.h" |
|---|
| 29 | #include "si_svct.h" |
|---|
| 30 | #include "si_descriptors.h" |
|---|
| 31 | |
|---|
| 32 | unsigned char SVCT_VCM_version_number; |
|---|
| 33 | unsigned char SVCT_VCM_last_section_number; |
|---|
| 34 | unsigned long SVCT_VCM_section_mask[8]; |
|---|
| 35 | unsigned short g_vct_id = 0; |
|---|
| 36 | |
|---|
| 37 | static SI_SVCT_VCM_Callback_t *s_svct_vcm_cb = NULL; |
|---|
| 38 | |
|---|
| 39 | void SI_SVCT_Init(SI_SVCT_VCM_Callback_t *cb, |
|---|
| 40 | unsigned char iSVCT_VCM_version_number) |
|---|
| 41 | { |
|---|
| 42 | unsigned long i; |
|---|
| 43 | |
|---|
| 44 | s_svct_vcm_cb = cb; |
|---|
| 45 | SI_SVCT_VCM_Init(s_svct_vcm_cb); |
|---|
| 46 | SVCT_VCM_version_number = iSVCT_VCM_version_number; |
|---|
| 47 | for (i=0; i<8; i++) |
|---|
| 48 | SVCT_VCM_section_mask[i] = 0; |
|---|
| 49 | } |
|---|
| 50 | |
|---|
| 51 | |
|---|
| 52 | /********************************************************************* |
|---|
| 53 | Function : SI_SVCT_Get |
|---|
| 54 | Description : Return the version numbers and masks. |
|---|
| 55 | Input : none. |
|---|
| 56 | Output : version number and pointers to section masks. |
|---|
| 57 | **********************************************************************/ |
|---|
| 58 | bool SI_SVCT_Complete(void) |
|---|
| 59 | { |
|---|
| 60 | return (SI_Chk_Section_complete(SVCT_VCM_section_mask,SVCT_VCM_last_section_number) == SI_SUCCESS); |
|---|
| 61 | } |
|---|
| 62 | |
|---|
| 63 | /********************************************************************* |
|---|
| 64 | Function : SI_SVCT_parse |
|---|
| 65 | Description : Function to parse the S-VCT table. |
|---|
| 66 | Input : unsigned char * table: point to the current S-VCT table section. |
|---|
| 67 | Output : SI_RET_CODE. |
|---|
| 68 | **********************************************************************/ |
|---|
| 69 | SI_RET_CODE SI_SVCT_parse (unsigned char * table) |
|---|
| 70 | { |
|---|
| 71 | unsigned long temp; |
|---|
| 72 | unsigned long section_length; |
|---|
| 73 | unsigned char table_subtype; |
|---|
| 74 | unsigned long desc_tag, len; |
|---|
| 75 | unsigned char version_number, section_number, last_section_number; |
|---|
| 76 | unsigned char *current, *crc_start; |
|---|
| 77 | int found_rdd; |
|---|
| 78 | /*unsigned long desc_len; |
|---|
| 79 | int i, j;*/ |
|---|
| 80 | |
|---|
| 81 | found_rdd = 0; |
|---|
| 82 | |
|---|
| 83 | SI_DBG_PRINT(E_SI_DBG_MSG,("SVCT Table received.\n")); |
|---|
| 84 | |
|---|
| 85 | temp = *table; |
|---|
| 86 | if (temp != SI_SVCT_TABLE_ID) |
|---|
| 87 | { |
|---|
| 88 | SI_DBG_PRINT(E_SI_ERR_MSG,("S-VCT Table ID error!!! %x\n", temp)); |
|---|
| 89 | return SI_TABLE_ID_ERROR; |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | /* calculate and check section length. */ |
|---|
| 93 | section_length = SI_Construct_Data(table, |
|---|
| 94 | SVCT_SECTION_LENGTH_BYTE_INDX, |
|---|
| 95 | SVCT_SECTION_LENGTH_BYTE_NUM, |
|---|
| 96 | SVCT_SECTION_LENGTH_SHIFT, |
|---|
| 97 | SVCT_SECTION_LENGTH_MASK); |
|---|
| 98 | section_length += SVCT_SECTION_LENGTH_BYTE_INDX+SVCT_SECTION_LENGTH_BYTE_NUM; |
|---|
| 99 | if (section_length > SI_NORMAL_SECTION_LENGTH) |
|---|
| 100 | { |
|---|
| 101 | SI_DBG_PRINT(E_SI_ERR_MSG,("S-VCT Table section length error!!! %x\n", section_length)); |
|---|
| 102 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 103 | } |
|---|
| 104 | |
|---|
| 105 | /* We do the CRC check here to verify the contents of this section. */ |
|---|
| 106 | if (SI_CRC32_Check(table, section_length) != SI_SUCCESS) |
|---|
| 107 | { |
|---|
| 108 | SI_DBG_PRINT(E_SI_ERR_MSG,("S-VCT Table section CRC error!!!\n")); |
|---|
| 109 | return SI_CRC_ERROR; |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | /* check protocol version. It should be zero for now. */ |
|---|
| 113 | temp = SI_Construct_Data(table, |
|---|
| 114 | SVCT_PROTOCOL_VERSION_BYTE_INDX, |
|---|
| 115 | SVCT_PROTOCOL_VERSION_BYTE_NUM, |
|---|
| 116 | SVCT_PROTOCOL_VERSION_SHIFT, |
|---|
| 117 | SVCT_PROTOCOL_VERSION_MASK); |
|---|
| 118 | if (temp != SI_CURRENT_PROTOCOL_VERSION) |
|---|
| 119 | { |
|---|
| 120 | SI_DBG_PRINT(E_SI_ERR_MSG,("S-VCT Table PROTOCOL version error!!! %x\n", temp)); |
|---|
| 121 | return SI_PROTOCOL_VER_ERROR; |
|---|
| 122 | } |
|---|
| 123 | |
|---|
| 124 | /* we just need to handle VCM. Ignore the ICM or DCM for now. */ |
|---|
| 125 | table_subtype = SI_Construct_Data(table, |
|---|
| 126 | SVCT_TABLE_SUBTYPE_BYTE_INDX, |
|---|
| 127 | SVCT_TABLE_SUBTYPE_BYTE_NUM, |
|---|
| 128 | SVCT_TABLE_SUBTYPE_SHIFT, |
|---|
| 129 | SVCT_TABLE_SUBTYPE_MASK); |
|---|
| 130 | |
|---|
| 131 | if (table_subtype != VCM) |
|---|
| 132 | { |
|---|
| 133 | SI_DBG_PRINT(E_SI_DBG_MSG,("We are only interested in VCM of SVCT right now.\n")); |
|---|
| 134 | return SI_SUCCESS; |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | g_vct_id = SI_Construct_Data(table, |
|---|
| 138 | SVCT_VCT_ID_BYTE_INDX, |
|---|
| 139 | SVCT_VCT_ID_BYTE_NUM, |
|---|
| 140 | SVCT_VCT_ID_SHIFT, |
|---|
| 141 | SVCT_VCT_ID_MASK); |
|---|
| 142 | |
|---|
| 143 | /* we get a VCM record. see if we have any table level |
|---|
| 144 | descriptors for revision dectection. */ |
|---|
| 145 | current = table + SVCT_VCT_ID_BYTE_INDX + SVCT_VCT_ID_BYTE_NUM; |
|---|
| 146 | |
|---|
| 147 | /* point to the start of table level descriptor. */ |
|---|
| 148 | current = SI_SVCT_VCM_Pointer(current); |
|---|
| 149 | crc_start = table + section_length - SI_CRC_LENGTH; |
|---|
| 150 | |
|---|
| 151 | /* go through all descriptors. */ |
|---|
| 152 | while ((unsigned long)current < (unsigned long)crc_start) |
|---|
| 153 | { |
|---|
| 154 | desc_tag = *(current++); |
|---|
| 155 | len = *(current++); |
|---|
| 156 | switch(desc_tag) |
|---|
| 157 | { |
|---|
| 158 | case SI_DESC_REVISION_DETECTION: |
|---|
| 159 | found_rdd = 1; |
|---|
| 160 | /* we got a revision dectection descriptor. */ |
|---|
| 161 | SI_DBG_PRINT(E_SI_DBG_MSG,("SVCT VCM revision detection descriptors found.\n")); |
|---|
| 162 | version_number = SI_Construct_Data( current, |
|---|
| 163 | DESC_REV_DECTECT_VER_NUM_BYTE_INDEX, |
|---|
| 164 | DESC_REV_DECTECT_VER_NUM_BYTE_NUM, |
|---|
| 165 | DESC_REV_DECTECT_VER_NUM_SHIFT, |
|---|
| 166 | DESC_REV_DECTECT_VER_NUM_MASK); |
|---|
| 167 | section_number = SI_Construct_Data( current, |
|---|
| 168 | DESC_REV_DECTECT_SEC_NUM_BYTE_INDEX, |
|---|
| 169 | DESC_REV_DECTECT_SEC_NUM_BYTE_NUM, |
|---|
| 170 | DESC_REV_DECTECT_SEC_NUM_SHIFT, |
|---|
| 171 | DESC_REV_DECTECT_SEC_NUM_MASK); |
|---|
| 172 | last_section_number = SI_Construct_Data( current, |
|---|
| 173 | DESC_REV_DECTECT_LAST_SEC_NUM_BYTE_INDEX, |
|---|
| 174 | DESC_REV_DECTECT_LAST_SEC_NUM_BYTE_NUM, |
|---|
| 175 | DESC_REV_DECTECT_LAST_SEC_NUM_SHIFT, |
|---|
| 176 | DESC_REV_DECTECT_LAST_SEC_NUM_MASK); |
|---|
| 177 | SVCT_VCM_last_section_number = last_section_number; |
|---|
| 178 | if (version_number == SVCT_VCM_version_number) |
|---|
| 179 | { |
|---|
| 180 | /* same version number, check section mask. */ |
|---|
| 181 | if (SI_Chk_Section_mask(SVCT_VCM_section_mask, section_number)) |
|---|
| 182 | return SI_SUCCESS; /* no need to update. */ |
|---|
| 183 | } |
|---|
| 184 | else |
|---|
| 185 | { |
|---|
| 186 | /* different CDS version, init the CDS table and section mask .*/ |
|---|
| 187 | SI_SVCT_VCM_Free_List(); |
|---|
| 188 | SVCT_VCM_version_number = version_number; |
|---|
| 189 | SI_Init_Section_Mask(SVCT_VCM_section_mask, last_section_number); |
|---|
| 190 | } |
|---|
| 191 | /* update the mask */ |
|---|
| 192 | SI_Set_Section_mask(SVCT_VCM_section_mask, section_number); |
|---|
| 193 | break; |
|---|
| 194 | |
|---|
| 195 | default: |
|---|
| 196 | SI_DBG_PRINT(E_SI_WRN_MSG,("SVCT VCM table descriptor %x received! Ignoring!\n", desc_tag)); |
|---|
| 197 | break; |
|---|
| 198 | } |
|---|
| 199 | |
|---|
| 200 | /* update pointer. */ |
|---|
| 201 | current += len; |
|---|
| 202 | } |
|---|
| 203 | |
|---|
| 204 | /* check for desc length. */ |
|---|
| 205 | if ((unsigned long)current != (unsigned long)crc_start) |
|---|
| 206 | { |
|---|
| 207 | SI_DBG_PRINT(E_SI_ERR_MSG,("S-VCT Table length error!!!\n")); |
|---|
| 208 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 209 | } |
|---|
| 210 | |
|---|
| 211 | #ifdef CONFIG_RDD_REQUIRED |
|---|
| 212 | if (found_rdd == 0) |
|---|
| 213 | { |
|---|
| 214 | SI_DBG_PRINT(E_SI_ERR_MSG,("Revistion Detection Descriptor is required!!!\n")); |
|---|
| 215 | return SI_DESCRIPTOR_ERROR; |
|---|
| 216 | } |
|---|
| 217 | #endif |
|---|
| 218 | |
|---|
| 219 | /* we either need to update the channel table or we don't have a revision detection. */ |
|---|
| 220 | current = table + SVCT_VCT_ID_BYTE_INDX + SVCT_VCT_ID_BYTE_NUM; |
|---|
| 221 | return SI_SVCT_VCM_Parse(current); |
|---|
| 222 | } |
|---|