| 1 | /*************************************************************** |
|---|
| 2 | ** |
|---|
| 3 | ** Broadcom Corp. Confidential |
|---|
| 4 | ** Copyright 2003-2012 Broadcom Corp. All Rights Reserved. |
|---|
| 5 | ** |
|---|
| 6 | ** THIS SOFTWARE MAY ONLY BE USED JECT 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 | ** JECT TO THE TERMS OF SUCH AN AGREEMENT. |
|---|
| 10 | ** |
|---|
| 11 | ** File: si_nim.c |
|---|
| 12 | ** Description: function that parses the NIM table section. |
|---|
| 13 | ** Modified for A56 standard |
|---|
| 14 | ** |
|---|
| 15 | ** Created: 03/08/2001 |
|---|
| 16 | ** 01/31/2012 modified for A/56 support |
|---|
| 17 | ** |
|---|
| 18 | ** REVISION: |
|---|
| 19 | ** |
|---|
| 20 | ** $Log: $ |
|---|
| 21 | ** |
|---|
| 22 | ** |
|---|
| 23 | ****************************************************************/ |
|---|
| 24 | |
|---|
| 25 | /* common for all SI */ |
|---|
| 26 | #include "si.h" |
|---|
| 27 | #include "si_os.h" |
|---|
| 28 | #include "si_dbg.h" |
|---|
| 29 | #include "si_util.h" |
|---|
| 30 | #include "si_descriptors.h" |
|---|
| 31 | |
|---|
| 32 | /* A56 specific */ |
|---|
| 33 | #include "si_nim.h" |
|---|
| 34 | #include "si_nim_cdt.h" |
|---|
| 35 | #include "si_nim_mmt.h" |
|---|
| 36 | |
|---|
| 37 | unsigned char NIM_Version_Number; |
|---|
| 38 | unsigned char NIM_CDT_Version_Number; |
|---|
| 39 | unsigned char NIM_MMT_Version_Number; |
|---|
| 40 | unsigned char NIM_last_section_number; |
|---|
| 41 | unsigned long NIM_Section_Mask[8]; |
|---|
| 42 | |
|---|
| 43 | unsigned char NIM_CDT_last_section_number; |
|---|
| 44 | unsigned char NIM_MMT_last_section_number; |
|---|
| 45 | unsigned long NIM_CDT_Section_Mask[8]; |
|---|
| 46 | unsigned long NIM_MMT_Section_Mask[8]; |
|---|
| 47 | static SI_NIM_CDT_Callback_t *s_cdt_cb; |
|---|
| 48 | static SI_NIM_MMT_Callback_t *s_mmt_cb; |
|---|
| 49 | |
|---|
| 50 | void SI_NIM_Init (SI_NIM_CDT_Callback_t *p_cdt_cb,SI_NIM_MMT_Callback_t *p_mmt_cb,unsigned char iNIM_CDT_Version_Number, |
|---|
| 51 | unsigned char iNIM_MMT_Version_Number) |
|---|
| 52 | { |
|---|
| 53 | int i; |
|---|
| 54 | |
|---|
| 55 | /* currently just support tables related to cable */ |
|---|
| 56 | s_cdt_cb = p_cdt_cb; |
|---|
| 57 | s_mmt_cb = p_mmt_cb; |
|---|
| 58 | SI_NIM_CDT_Init(s_cdt_cb); |
|---|
| 59 | SI_NIM_MMT_Init(s_mmt_cb); |
|---|
| 60 | |
|---|
| 61 | NIM_CDT_Version_Number = iNIM_CDT_Version_Number; |
|---|
| 62 | NIM_MMT_Version_Number = iNIM_MMT_Version_Number; |
|---|
| 63 | for (i=0; i<8; i++) |
|---|
| 64 | { |
|---|
| 65 | NIM_Section_Mask[i] = NIM_CDT_Section_Mask[i] = NIM_MMT_Section_Mask[i] = 0; |
|---|
| 66 | } |
|---|
| 67 | } |
|---|
| 68 | |
|---|
| 69 | /********************************************************************* |
|---|
| 70 | Function : SI_NIM_CDT_Complete |
|---|
| 71 | Description : Return true if the complete CDT section is received. |
|---|
| 72 | Input : none. |
|---|
| 73 | Output : none. |
|---|
| 74 | **********************************************************************/ |
|---|
| 75 | bool SI_NIM_CDT_Complete() |
|---|
| 76 | { |
|---|
| 77 | return (SI_Chk_Section_complete(NIM_CDT_Section_Mask,NIM_CDT_last_section_number) == SI_SUCCESS); |
|---|
| 78 | } |
|---|
| 79 | |
|---|
| 80 | /********************************************************************* |
|---|
| 81 | Function : SI_NIM_MMT_Complete |
|---|
| 82 | Description : Return true if the complete MMT section is received. |
|---|
| 83 | Input : none. |
|---|
| 84 | Output : none. |
|---|
| 85 | **********************************************************************/ |
|---|
| 86 | bool SI_NIM_MMT_Complete() |
|---|
| 87 | { |
|---|
| 88 | return (SI_Chk_Section_complete(NIM_MMT_Section_Mask,NIM_MMT_last_section_number) == SI_SUCCESS); |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | /********************************************************************* |
|---|
| 92 | Function : SI_NIM_parse |
|---|
| 93 | Description : Function to parse the NIM table. |
|---|
| 94 | Input : nim_table, point to the current NIM table section. |
|---|
| 95 | Output : SI_RET_CODE. |
|---|
| 96 | **********************************************************************/ |
|---|
| 97 | SI_RET_CODE SI_NIM_parse (unsigned char * nim_table) |
|---|
| 98 | { |
|---|
| 99 | unsigned long temp; |
|---|
| 100 | unsigned long section_length, offset, table_len; |
|---|
| 101 | unsigned char first_index, number_of_records, table_type; |
|---|
| 102 | unsigned char desc_count, desc_tag, desc_len; |
|---|
| 103 | unsigned char version_number, section_number, last_section_number; |
|---|
| 104 | int i, j, found_rdd; |
|---|
| 105 | |
|---|
| 106 | found_rdd = 0; |
|---|
| 107 | |
|---|
| 108 | SI_DBG_PRINT(E_SI_DBG_MSG,("NIM Table received.\n")); |
|---|
| 109 | |
|---|
| 110 | temp = *nim_table; |
|---|
| 111 | if (temp != SI_NIM_TABLE_ID) |
|---|
| 112 | { |
|---|
| 113 | SI_DBG_PRINT(E_SI_ERR_MSG,("NIM Table ID error!!! %x\n", temp)); |
|---|
| 114 | return SI_TABLE_ID_ERROR; |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | /* calculate and check section length. */ |
|---|
| 118 | section_length = SI_Construct_Data(nim_table, |
|---|
| 119 | NIM_SECTION_LENGTH_BYTE_INDX, |
|---|
| 120 | NIM_SECTION_LENGTH_BYTE_NUM, |
|---|
| 121 | NIM_SECTION_LENGTH_SHIFT, |
|---|
| 122 | NIM_SECTION_LENGTH_MASK); |
|---|
| 123 | section_length += NIM_SECTION_LENGTH_BYTE_INDX+NIM_SECTION_LENGTH_BYTE_NUM; |
|---|
| 124 | if (section_length > SI_NORMAL_SECTION_LENGTH) |
|---|
| 125 | { |
|---|
| 126 | SI_DBG_PRINT(E_SI_ERR_MSG,("NIM Table section length error!!! %x\n", section_length)); |
|---|
| 127 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 128 | } |
|---|
| 129 | /* We do the CRC check here to verify the contents of this section. */ |
|---|
| 130 | if (SI_CRC32_Check(nim_table, section_length) != SI_SUCCESS) |
|---|
| 131 | { |
|---|
| 132 | SI_DBG_PRINT(E_SI_ERR_MSG,("NIM Table section CRC error!!!\n")); |
|---|
| 133 | return SI_CRC_ERROR; |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | /* check protocol version. It should be zero for now. */ |
|---|
| 137 | temp = SI_Construct_Data(nim_table, |
|---|
| 138 | NIM_PROTOCOL_VERSION_BYTE_INDX, |
|---|
| 139 | NIM_PROTOCOL_VERSION_BYTE_NUM, |
|---|
| 140 | NIM_PROTOCOL_VERSION_SHIFT, |
|---|
| 141 | NIM_PROTOCOL_VERSION_MASK); |
|---|
| 142 | if (temp != SI_CURRENT_PROTOCOL_VERSION) |
|---|
| 143 | { |
|---|
| 144 | SI_DBG_PRINT(E_SI_ERR_MSG,("NIM Table PROTOCOL version error!!! %x\n", temp)); |
|---|
| 145 | return SI_PROTOCOL_VER_ERROR; |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | first_index = SI_Construct_Data(nim_table, |
|---|
| 149 | NIM_FIRST_INDEX_BYTE_INDX, |
|---|
| 150 | NIM_FIRST_INDEX_BYTE_NUM, |
|---|
| 151 | NIM_FIRST_INDEX_SHIFT, |
|---|
| 152 | NIM_FIRST_INDEX_MASK); |
|---|
| 153 | /* make sure the first_index not zero */ |
|---|
| 154 | if (first_index == 0) |
|---|
| 155 | { |
|---|
| 156 | SI_DBG_PRINT(E_SI_ERR_MSG,("NIM Table first index zero!!!")); |
|---|
| 157 | return SI_OTHER_ERROR; |
|---|
| 158 | } |
|---|
| 159 | number_of_records = SI_Construct_Data(nim_table, |
|---|
| 160 | NIM_NUMBER_OF_RECORDS_BYTE_INDX, |
|---|
| 161 | NIM_NUMBER_OF_RECORDS_BYTE_NUM, |
|---|
| 162 | NIM_NUMBER_OF_RECORDS_SHIFT, |
|---|
| 163 | NIM_NUMBER_OF_RECORDS_MASK); |
|---|
| 164 | temp = SI_Construct_Data(nim_table, |
|---|
| 165 | NIM_TRANSMISSION_MEDIUM_BYTE_INDX, |
|---|
| 166 | NIM_TRANSMISSION_MEDIUM_BYTE_NUM, |
|---|
| 167 | NIM_TRANSMISSION_MEDIUM_SHIFT, |
|---|
| 168 | NIM_TRANSMISSION_MEDIUM_MASK); |
|---|
| 169 | if (TRANSMISSION_MEDIUM_CABLE != temp) { |
|---|
| 170 | SI_DBG_PRINT(E_SI_ERR_MSG,("Not supported transmission medium type!!!")); |
|---|
| 171 | return SI_NOT_SUPPORTED_ERROR; |
|---|
| 172 | } |
|---|
| 173 | table_type = SI_Construct_Data(nim_table, |
|---|
| 174 | NIM_TABLE_TYPE_BYTE_INDX, |
|---|
| 175 | NIM_TABLE_TYPE_BYTE_NUM, |
|---|
| 176 | NIM_TABLE_TYPE_SHIFT, |
|---|
| 177 | NIM_TABLE_TYPE_MASK); |
|---|
| 178 | |
|---|
| 179 | /* Now we need to check for the revision descriptors(if there is any) to get the section |
|---|
| 180 | number and revision info. This descriptor should be at the end of the table section just |
|---|
| 181 | before the CRC bytes. NOT at the end of each table type. */ |
|---|
| 182 | offset = NIM_TABLE_TYPE_BYTE_INDX + NIM_TABLE_TYPE_BYTE_NUM; |
|---|
| 183 | switch (table_type) |
|---|
| 184 | { |
|---|
| 185 | case NIM_TT_CDT: |
|---|
| 186 | table_len = NIM_CDT_TABLE_SIZE; |
|---|
| 187 | break; |
|---|
| 188 | case NIM_TT_MMT: |
|---|
| 189 | table_len = NIM_MMT_TABLE_SIZE; |
|---|
| 190 | break; |
|---|
| 191 | default: |
|---|
| 192 | SI_DBG_PRINT(E_SI_ERR_MSG,("NIM Table type not supported!!!\n")); |
|---|
| 193 | return SI_NOT_SUPPORTED_ERROR; |
|---|
| 194 | break; |
|---|
| 195 | } |
|---|
| 196 | /* go through all tables and table descriptors to get to the NIM table descriptor. */ |
|---|
| 197 | for (i=0; i<number_of_records; i++) |
|---|
| 198 | { |
|---|
| 199 | offset += table_len; |
|---|
| 200 | desc_count = *(nim_table + offset++); |
|---|
| 201 | for (j=0; j<desc_count; j++) |
|---|
| 202 | { |
|---|
| 203 | desc_tag = *(nim_table + offset++); |
|---|
| 204 | desc_len = *(nim_table + offset++); |
|---|
| 205 | offset += desc_len; |
|---|
| 206 | } |
|---|
| 207 | } |
|---|
| 208 | if (offset == section_length-SI_CRC_LENGTH) |
|---|
| 209 | { |
|---|
| 210 | SI_DBG_PRINT(E_SI_DBG_MSG,("NIM no table level descriptors found.\n")); |
|---|
| 211 | } |
|---|
| 212 | else if (offset > section_length-SI_CRC_LENGTH) |
|---|
| 213 | { |
|---|
| 214 | SI_DBG_PRINT(E_SI_ERR_MSG,("NIM Table length error!!!\n")); |
|---|
| 215 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 216 | } |
|---|
| 217 | else |
|---|
| 218 | { |
|---|
| 219 | /* we got more descriptors. */ |
|---|
| 220 | while (offset < section_length-SI_CRC_LENGTH) |
|---|
| 221 | { |
|---|
| 222 | desc_tag = *(nim_table + offset++); |
|---|
| 223 | desc_len = *(nim_table + offset++); |
|---|
| 224 | if (desc_tag == SI_DESC_REVISION_DETECTION) |
|---|
| 225 | { |
|---|
| 226 | found_rdd = 1; |
|---|
| 227 | /* we got a revision dectection descriptor. */ |
|---|
| 228 | SI_DBG_PRINT(E_SI_DBG_MSG,("NIM revision detection descriptors found.\n")); |
|---|
| 229 | if (desc_len != DESC_REV_DECTECT_LEN) |
|---|
| 230 | { |
|---|
| 231 | SI_DBG_PRINT(E_SI_ERR_MSG,("NIM Table Rev detect descriptor length error!!!\n")); |
|---|
| 232 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 233 | } |
|---|
| 234 | version_number = SI_Construct_Data( (nim_table + offset), |
|---|
| 235 | DESC_REV_DECTECT_VER_NUM_BYTE_INDEX, |
|---|
| 236 | DESC_REV_DECTECT_VER_NUM_BYTE_NUM, |
|---|
| 237 | DESC_REV_DECTECT_VER_NUM_SHIFT, |
|---|
| 238 | DESC_REV_DECTECT_VER_NUM_MASK); |
|---|
| 239 | section_number = SI_Construct_Data( (nim_table + offset), |
|---|
| 240 | DESC_REV_DECTECT_SEC_NUM_BYTE_INDEX, |
|---|
| 241 | DESC_REV_DECTECT_SEC_NUM_BYTE_NUM, |
|---|
| 242 | DESC_REV_DECTECT_SEC_NUM_SHIFT, |
|---|
| 243 | DESC_REV_DECTECT_SEC_NUM_MASK); |
|---|
| 244 | last_section_number = SI_Construct_Data( (nim_table + offset), |
|---|
| 245 | DESC_REV_DECTECT_LAST_SEC_NUM_BYTE_INDEX, |
|---|
| 246 | DESC_REV_DECTECT_LAST_SEC_NUM_BYTE_NUM, |
|---|
| 247 | DESC_REV_DECTECT_LAST_SEC_NUM_SHIFT, |
|---|
| 248 | DESC_REV_DECTECT_LAST_SEC_NUM_MASK); |
|---|
| 249 | |
|---|
| 250 | NIM_last_section_number = last_section_number; |
|---|
| 251 | if (version_number == NIM_Version_Number) |
|---|
| 252 | { |
|---|
| 253 | /* same version number, check section mask. */ |
|---|
| 254 | if (SI_Chk_Section_mask(NIM_Section_Mask, section_number)) |
|---|
| 255 | ; // return SI_SUCCESS; /* no need to update. */ |
|---|
| 256 | } |
|---|
| 257 | else |
|---|
| 258 | { |
|---|
| 259 | /* different CDT version, inim the CDT table and section mask .*/ |
|---|
| 260 | NIM_Version_Number = version_number; |
|---|
| 261 | SI_Init_Section_Mask(NIM_Section_Mask, last_section_number); |
|---|
| 262 | } |
|---|
| 263 | SI_Set_Section_mask(NIM_Section_Mask, section_number); |
|---|
| 264 | |
|---|
| 265 | if (table_type == NIM_TT_CDT) |
|---|
| 266 | { |
|---|
| 267 | NIM_CDT_last_section_number = last_section_number; |
|---|
| 268 | /* CDT table. */ |
|---|
| 269 | if (version_number == NIM_CDT_Version_Number) |
|---|
| 270 | { |
|---|
| 271 | /* same version number, check section mask. */ |
|---|
| 272 | if (SI_Chk_Section_mask(NIM_CDT_Section_Mask, section_number)) |
|---|
| 273 | return SI_SUCCESS; /* no need to update. */ |
|---|
| 274 | } |
|---|
| 275 | else |
|---|
| 276 | { |
|---|
| 277 | /* different CDT version, inim the CDT table and section mask .*/ |
|---|
| 278 | SI_NIM_CDT_Init(s_cdt_cb); |
|---|
| 279 | NIM_CDT_Version_Number = version_number; |
|---|
| 280 | SI_Init_Section_Mask(NIM_CDT_Section_Mask, last_section_number); |
|---|
| 281 | } |
|---|
| 282 | /* update the mask */ |
|---|
| 283 | SI_Set_Section_mask(NIM_CDT_Section_Mask, section_number); |
|---|
| 284 | } |
|---|
| 285 | else |
|---|
| 286 | { |
|---|
| 287 | NIM_MMT_last_section_number = last_section_number; |
|---|
| 288 | /* MMT table. */ |
|---|
| 289 | if (version_number == NIM_MMT_Version_Number) |
|---|
| 290 | { |
|---|
| 291 | /* same version number, check section mask. */ |
|---|
| 292 | if (SI_Chk_Section_mask(NIM_MMT_Section_Mask, section_number)) |
|---|
| 293 | return SI_SUCCESS; /* no need to update. */ |
|---|
| 294 | } |
|---|
| 295 | else |
|---|
| 296 | { |
|---|
| 297 | /* different MMT version, inim the MMT table and section mask .*/ |
|---|
| 298 | SI_NIM_MMT_Init(s_mmt_cb); |
|---|
| 299 | NIM_MMT_Version_Number = version_number; |
|---|
| 300 | SI_Init_Section_Mask(NIM_MMT_Section_Mask, last_section_number); |
|---|
| 301 | } |
|---|
| 302 | /* update the mask */ |
|---|
| 303 | SI_Set_Section_mask(NIM_MMT_Section_Mask, section_number); |
|---|
| 304 | } |
|---|
| 305 | } |
|---|
| 306 | else if (desc_tag != SI_DESC_STUFFING) |
|---|
| 307 | SI_DBG_PRINT(E_SI_WRN_MSG,("NIM table level descriptor %x we can not handle!\n", desc_tag)); |
|---|
| 308 | /* we just don't handle it. */ |
|---|
| 309 | |
|---|
| 310 | offset += desc_len; |
|---|
| 311 | } |
|---|
| 312 | } |
|---|
| 313 | if (found_rdd == 0) |
|---|
| 314 | { |
|---|
| 315 | #ifdef CONFIG_RDD_REQUIRED |
|---|
| 316 | SI_DBG_PRINT(E_SI_ERR_MSG,("Revistion Detection Descriptor is required!!!\n")); |
|---|
| 317 | return SI_DESCRIPTOR_ERROR; |
|---|
| 318 | #else |
|---|
| 319 | /* update the mask to complete if there is no version descriptor since it is optional */ |
|---|
| 320 | if (NIM_TT_CDT == table_type) { |
|---|
| 321 | NIM_CDT_last_section_number = 0; |
|---|
| 322 | SI_Set_Section_mask(NIM_CDT_Section_Mask, 0); |
|---|
| 323 | } |
|---|
| 324 | if (NIM_TT_MMT == table_type) { |
|---|
| 325 | NIM_MMT_last_section_number = 0; |
|---|
| 326 | SI_Set_Section_mask(NIM_MMT_Section_Mask, 0); |
|---|
| 327 | } |
|---|
| 328 | #endif |
|---|
| 329 | } |
|---|
| 330 | |
|---|
| 331 | if (offset != section_length-SI_CRC_LENGTH) |
|---|
| 332 | { |
|---|
| 333 | SI_DBG_PRINT(E_SI_ERR_MSG,("NIM Table descriptor length error!!!(%d, %d, %d)\n",offset,section_length,section_length-SI_CRC_LENGTH)); |
|---|
| 334 | return SI_SECTION_LENGTH_ERROR; |
|---|
| 335 | } |
|---|
| 336 | |
|---|
| 337 | /* now just update the table. */ |
|---|
| 338 | offset = NIM_TABLE_TYPE_BYTE_INDX + NIM_TABLE_TYPE_BYTE_NUM; |
|---|
| 339 | for (i=0; i<number_of_records; i++) |
|---|
| 340 | { |
|---|
| 341 | if (table_type == NIM_TT_CDT) |
|---|
| 342 | first_index += SI_NIM_CDT_parse( (nim_table + offset), first_index ); |
|---|
| 343 | else |
|---|
| 344 | SI_NIM_MMT_parse ( (nim_table + offset), first_index++ ); |
|---|
| 345 | |
|---|
| 346 | offset += table_len; |
|---|
| 347 | desc_count = *(nim_table + offset++); |
|---|
| 348 | for (j=0; j<desc_count; j++) |
|---|
| 349 | { |
|---|
| 350 | desc_tag = *(nim_table + offset++); |
|---|
| 351 | if (desc_tag != SI_DESC_STUFFING) |
|---|
| 352 | SI_DBG_PRINT(E_SI_WRN_MSG,("NIM Subtable descriptor %x we can not handle!\n", desc_tag)); |
|---|
| 353 | /* we just don't handle it. */ |
|---|
| 354 | desc_len = *(nim_table + offset++); |
|---|
| 355 | offset += desc_len; |
|---|
| 356 | } |
|---|
| 357 | } |
|---|
| 358 | |
|---|
| 359 | return SI_SUCCESS; |
|---|
| 360 | } |
|---|
| 361 | |
|---|
| 362 | |
|---|