furia_micro_seq.c (18601B)
1 /* 2 * 3 * 4 * 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 6 * 7 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 8 */ 9 /* 10 * Includes 11 */ 12 #include <phymod/phymod_system.h> 13 #include "furia_micro_seq.h" 14 #include "furia_cfg_seq.h" 15 #include "furia_regs_structs.h" 16 #include "furia_reg_access.h" 17 #include "furia_address_defines.h" 18 #include "furia_types.h" 19 20 /* 21 * Defines 22 */ 23 #define FURIA_FW_DLOAD_RETRY_CNT 50000 24 #define FURIA_M0_EEPROM_PAGE_SIZE 64 25 /* 26 * Types 27 */ 28 29 /* 30 * Macros 31 */ 32 33 /* 34 * Global Variables 35 */ 36 37 /* 38 * Functions 39 */ 40 41 /** Wait master message out 42 * This function is to ensure whether master has sent the previous message 43 * out successfully 44 * 45 * @param pa Pointer to phymod access structure 46 * @param exp_message Expected message specified by user 47 * @param poll_time Poll interval 48 * 49 * @return PHYMOD_E_NONE successful function execution 50 */ 51 int _furia_wait_mst_msgout(const phymod_access_t *pa, 52 FURIA_MSGOUT_E exp_message, 53 int poll_time) 54 { 55 int retry_count = FURIA_FW_DLOAD_RETRY_CNT; 56 FURIA_MSGOUT_E msgout = 0; 57 FUR_GEN_CNTRLS_MSGOUT_t msgout_t; 58 59 do { 60 /* Read general control msg out Register */ 61 PHYMOD_IF_ERR_RETURN 62 (READ_FURIA_PMA_PMD_REG(pa,\ 63 FUR_GEN_CNTRLS_msgout_Adr,\ 64 &msgout_t.data)); 65 msgout = (FURIA_MSGOUT_E) msgout_t.fields.msgout_val; 66 /* wait before reading again */ 67 if (poll_time != 0) { 68 /* sleep for specified seconds*/ 69 PHYMOD_USLEEP(poll_time/FURIA_FW_DLOAD_RETRY_CNT); 70 } 71 retry_count--; 72 } while ((msgout != exp_message) && retry_count); 73 74 if(!retry_count) { 75 if(exp_message == MSGOUT_PRGRM_DONE) { 76 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, (_PHYMOD_MSG("Fusing Firmware failed"))); 77 } else { 78 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INIT, (_PHYMOD_MSG("Firmware download failed"))); 79 } 80 } 81 82 return PHYMOD_E_NONE; 83 } 84 /** Download and Fuse firmware 85 * This function is used to download the firmware through I2C/MDIO 86 * and fuse it to SPI EEPROM if prg_eeprom flag is set 87 * 88 * @param pa Pointer to phymod access structure 89 * @param new_fw Pointer to firmware array 90 * @param fw_length Length of the firmware array 91 * @param prg_eeprom Flag used to program EEPROM 92 * 93 * @return num_bytes number of bytes successfully downloaded 94 */ 95 int furia_download_prog_eeprom(const phymod_access_t *pa, 96 uint8_t *new_fw, 97 uint32_t fw_length, 98 uint8_t prg_eeprom) 99 { 100 uint16_t data16 = 0; 101 uint16_t num_bytes = 0; 102 uint16_t num_words = 0; 103 uint16_t j = 0; 104 uint16_t ser_boot_busy = 0; 105 FUR_GEN_CNTRLS_MSGIN_t msgin; 106 FUR_GEN_CNTRLS_GEN_CONTROL2_t gen_ctrl2; 107 FUR_GEN_CNTRLS_GEN_CONTROL3_t gen_ctrl3; 108 FUR_GEN_CNTRLS_BOOT_t gen_ctrl_boot; 109 FUR_GEN_CNTRLS_SPI_CODE_LOAD_EN_t spi_code_ld_en; 110 FUR_MICRO_BOOT_BOOT_POR_t micro_boot_por; 111 FUR_GEN_CNTRLS_MST_RUNNING_CHKSUM_t mst_running_chksum; 112 FUR_GEN_CNTRLS_SLV_RUNNING_CHKSUM_t slv_running_chksum; 113 FUR_GEN_CNTRLS_MST_RUNNING_BYTE_CNT_t mst_running_byte_cnt; 114 FUR_GEN_CNTRLS_SLV_RUNNING_BYTE_CNT_t slv_running_byte_cnt; 115 FUR_GEN_CNTRLS_GEN_CONTROL1_t gen_ctrl1; 116 FUR_GEN_CNTRLS_gpreg14_t gpreg14; 117 FUR_GEN_CNTRLS_gpreg15_t gpreg15; 118 uint16_t m_chksum = 0; 119 uint16_t s_chksum = 0; 120 uint16_t m_byte_cnt = 0; 121 uint16_t s_byte_cnt = 0; 122 uint16_t check_sum = 0; 123 int retry_count = FURIA_FW_DLOAD_RETRY_CNT; 124 int eeprom_num_of_pages = 0; 125 phymod_tx_t tx_params; 126 127 PHYMOD_MEMSET(&msgin, 0, sizeof(FUR_GEN_CNTRLS_MSGIN_t)); 128 PHYMOD_MEMSET(&gen_ctrl2, 0, sizeof(FUR_GEN_CNTRLS_GEN_CONTROL2_t)); 129 PHYMOD_MEMSET(&gen_ctrl3, 0, sizeof(FUR_GEN_CNTRLS_GEN_CONTROL3_t)); 130 PHYMOD_MEMSET(&gen_ctrl_boot, 0, sizeof(FUR_GEN_CNTRLS_BOOT_t)); 131 PHYMOD_MEMSET(&spi_code_ld_en, 0, sizeof(FUR_GEN_CNTRLS_SPI_CODE_LOAD_EN_t)); 132 PHYMOD_MEMSET(µ_boot_por, 0, sizeof(FUR_MICRO_BOOT_BOOT_POR_t)); 133 PHYMOD_MEMSET(&mst_running_chksum, 0, sizeof(FUR_GEN_CNTRLS_MST_RUNNING_CHKSUM_t)); 134 PHYMOD_MEMSET(&slv_running_chksum, 0, sizeof(FUR_GEN_CNTRLS_SLV_RUNNING_CHKSUM_t)); 135 PHYMOD_MEMSET(&mst_running_byte_cnt, 0, sizeof(FUR_GEN_CNTRLS_MST_RUNNING_BYTE_CNT_t)); 136 PHYMOD_MEMSET(&slv_running_byte_cnt, 0, sizeof(FUR_GEN_CNTRLS_SLV_RUNNING_BYTE_CNT_t)); 137 PHYMOD_MEMSET(&gen_ctrl1, 0 , sizeof(FUR_GEN_CNTRLS_GEN_CONTROL1_t)); 138 PHYMOD_MEMSET(&gpreg14, 0 , sizeof(FUR_GEN_CNTRLS_gpreg14_t)); 139 PHYMOD_MEMSET(&gpreg15, 0 , sizeof(FUR_GEN_CNTRLS_gpreg15_t)); 140 PHYMOD_MEMSET(&tx_params, 0 , sizeof(phymod_tx_t)); 141 142 /* Skip the firmware download 143 * i) if serboot bin is low and mst_download, slv_dwld_done bits are set 144 */ 145 PHYMOD_IF_ERR_RETURN 146 (READ_FURIA_PMA_PMD_REG(pa,\ 147 FUR_MICRO_BOOT_boot_por_Adr,\ 148 µ_boot_por.data)); 149 150 if (!prg_eeprom) { 151 PHYMOD_IF_ERR_RETURN 152 (READ_FURIA_PMA_PMD_REG(pa,\ 153 FUR_GEN_CNTRLS_mst_running_byte_cnt_Adr,\ 154 &mst_running_byte_cnt.data)); 155 m_byte_cnt = mst_running_byte_cnt.fields.mst_running_byte_cnt_val; 156 157 PHYMOD_IF_ERR_RETURN 158 (READ_FURIA_PMA_PMD_REG(pa,\ 159 FUR_GEN_CNTRLS_slv_running_byte_cnt_Adr,\ 160 &slv_running_byte_cnt.data)); 161 s_byte_cnt = slv_running_byte_cnt.fields.slv_running_byte_cnt_val; 162 163 if (((m_byte_cnt == fw_length) || 164 (s_byte_cnt == fw_length))&& 165 (micro_boot_por.fields.mst_dwld_done) && 166 (micro_boot_por.fields.slv_dwld_done)) { 167 return FURIA_FW_ALREADY_DOWNLOADED; 168 } 169 } 170 171 /* Set Tx driver current, FIR main/pre/post default values 172 * Default values are 173 * driver current = 0xf 174 * TX FIR main = 0x3c 175 * TX FIR pre = 0x0 176 * TX FIR post = 0x0 177 */ 178 179 PHYMOD_IF_ERR_RETURN 180 (furia_tx_get(pa, &tx_params)); 181 tx_params.amp = 0xf; 182 tx_params.pre = 0x0; 183 tx_params.post = 0x0; 184 tx_params.main = 0x3c; 185 PHYMOD_IF_ERR_RETURN 186 (furia_tx_set(pa, &tx_params)); 187 /* Do chip reset */ 188 PHYMOD_IF_ERR_RETURN 189 (READ_FURIA_PMA_PMD_REG(pa,\ 190 FUR_GEN_CNTRLS_gen_control1_Adr,\ 191 &gen_ctrl1.data)); 192 gen_ctrl1.fields.resetb = 0; 193 194 PHYMOD_IF_ERR_RETURN 195 (WRITE_FURIA_PMA_PMD_REG(pa,\ 196 FUR_GEN_CNTRLS_gen_control1_Adr,\ 197 gen_ctrl1.data)); 198 199 /* Perform master reset */ 200 PHYMOD_IF_ERR_RETURN 201 (READ_FURIA_PMA_PMD_REG(pa,\ 202 FUR_GEN_CNTRLS_gen_control2_Adr,\ 203 &gen_ctrl2.data)); 204 gen_ctrl2.fields.m0_mstr_rstb = 0; 205 gen_ctrl2.fields.m0_mstr_ucp_rstb = 0; 206 207 PHYMOD_IF_ERR_RETURN 208 (WRITE_FURIA_PMA_PMD_REG(pa,\ 209 FUR_GEN_CNTRLS_gen_control2_Adr,\ 210 gen_ctrl2.data)); 211 212 /* Wait for the serboot busy bit to become zero */ 213 PHYMOD_IF_ERR_RETURN 214 (READ_FURIA_PMA_PMD_REG(pa,\ 215 FUR_GEN_CNTRLS_boot_Adr,\ 216 &gen_ctrl_boot.data)); 217 218 /* Wait for any pending SPI download 219 * SPI download is not interrupted by Master Reset 220 * (this is a safety feature) so we need to wait its 221 * completion before starting the MDIO Download */ 222 do { 223 PHYMOD_IF_ERR_RETURN 224 (READ_FURIA_PMA_PMD_REG(pa,\ 225 FUR_GEN_CNTRLS_boot_Adr,\ 226 &gen_ctrl_boot.data)); 227 ser_boot_busy = gen_ctrl_boot.fields.serboot_busy; 228 PHYMOD_USLEEP(500); 229 retry_count--; 230 } while((ser_boot_busy != 0) && (retry_count)); 231 232 if (retry_count == 0) { 233 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, 234 (_PHYMOD_MSG("ERR:SERBOOT BUSY BIT SET"))); 235 } 236 237 /* Program master enable, slave enable, broadcast enable bits */ 238 PHYMOD_IF_ERR_RETURN 239 (READ_FURIA_PMA_PMD_REG(pa,\ 240 FUR_GEN_CNTRLS_spi_code_load_en_Adr,\ 241 &spi_code_ld_en.data)); 242 243 spi_code_ld_en.fields.code_broadcast_en = 1; 244 spi_code_ld_en.fields.slave_code_download_en = 1; 245 spi_code_ld_en.fields.master_code_download_en = 1; 246 247 PHYMOD_IF_ERR_RETURN 248 (WRITE_FURIA_PMA_PMD_REG(pa,\ 249 FUR_GEN_CNTRLS_spi_code_load_en_Adr,\ 250 spi_code_ld_en.data)); 251 252 PHYMOD_IF_ERR_RETURN 253 (READ_FURIA_PMA_PMD_REG(pa,\ 254 FUR_GEN_CNTRLS_spi_code_load_en_Adr,\ 255 &spi_code_ld_en.data)); 256 if ((spi_code_ld_en.fields.code_broadcast_en != 1) && 257 (spi_code_ld_en.fields.master_code_download_en != 1) && 258 (spi_code_ld_en.fields.slave_code_download_en != 1)) { 259 return PHYMOD_E_INTERNAL; 260 } 261 /* Select SPI speed */ 262 PHYMOD_IF_ERR_RETURN 263 (READ_FURIA_PMA_PMD_REG(pa,\ 264 FUR_GEN_CNTRLS_gen_control3_Adr,\ 265 &gen_ctrl3.data)); 266 gen_ctrl3.fields.ucspi_slow = 1; 267 PHYMOD_IF_ERR_RETURN 268 (WRITE_FURIA_PMA_PMD_REG(pa,\ 269 FUR_GEN_CNTRLS_gen_control3_Adr,\ 270 gen_ctrl3.data)); 271 if(prg_eeprom) { 272 /* Configuration for programming SPI EEPROM */ 273 eeprom_num_of_pages = fw_length/FURIA_M0_EEPROM_PAGE_SIZE; 274 /*program GPReg 14 with eeprom start page */ 275 gpreg14.data = 0; 276 PHYMOD_IF_ERR_RETURN 277 (WRITE_FURIA_PMA_PMD_REG(pa, FUR_GEN_CNTRLS_gpreg14_Adr, gpreg14.data)); 278 /*program GPReg 15 with eeprom number of pages */ 279 gpreg15.data = eeprom_num_of_pages; 280 PHYMOD_IF_ERR_RETURN 281 (WRITE_FURIA_PMA_PMD_REG(pa, 282 FUR_GEN_CNTRLS_gpreg15_Adr, 283 gpreg15.data)); 284 285 /* Assert Reset by writing zero to spi_rstb, spi2x_rstb */ 286 PHYMOD_IF_ERR_RETURN 287 (READ_FURIA_PMA_PMD_REG(pa,\ 288 FUR_GEN_CNTRLS_gen_control2_Adr,\ 289 &gen_ctrl2.data)); 290 gen_ctrl2.fields.spi_rstb = 0; 291 gen_ctrl2.fields.spi2x_rstb = 0; 292 293 PHYMOD_IF_ERR_RETURN 294 (WRITE_FURIA_PMA_PMD_REG(pa,\ 295 FUR_GEN_CNTRLS_gen_control2_Adr,\ 296 gen_ctrl2.data)); 297 298 /* Deassert Reset by setting spi_rstb, spi2x_rstb bits */ 299 PHYMOD_IF_ERR_RETURN 300 (READ_FURIA_PMA_PMD_REG(pa,\ 301 FUR_GEN_CNTRLS_gen_control2_Adr,\ 302 &gen_ctrl2.data)); 303 gen_ctrl2.fields.spi_rstb = 1; 304 gen_ctrl2.fields.spi2x_rstb = 1; 305 306 PHYMOD_IF_ERR_RETURN 307 (WRITE_FURIA_PMA_PMD_REG(pa,\ 308 FUR_GEN_CNTRLS_gen_control2_Adr,\ 309 gen_ctrl2.data)); 310 } 311 /* Force master download done, slave download done bit to 0 312 * set external boot (serboot) to 1 */ 313 PHYMOD_IF_ERR_RETURN 314 (READ_FURIA_PMA_PMD_REG(pa,\ 315 FUR_MICRO_BOOT_boot_por_Adr,\ 316 µ_boot_por.data)); 317 318 micro_boot_por.fields.mst_dwld_done = 0; 319 micro_boot_por.fields.slv_dwld_done = 0; 320 micro_boot_por.fields.serboot = 1; 321 micro_boot_por.fields.spi_port_used = 0; 322 PHYMOD_IF_ERR_RETURN 323 (WRITE_FURIA_PMA_PMD_REG(pa,\ 324 FUR_MICRO_BOOT_boot_por_Adr,\ 325 micro_boot_por.data)); 326 327 328 /* Bring back m0 master to normal state*/ 329 PHYMOD_IF_ERR_RETURN 330 (READ_FURIA_PMA_PMD_REG(pa,\ 331 FUR_GEN_CNTRLS_gen_control2_Adr,\ 332 &gen_ctrl2.data)); 333 334 gen_ctrl2.fields.m0_mstr_rstb = 1; 335 gen_ctrl2.fields.m0_mstr_ucp_rstb = 1; 336 337 PHYMOD_IF_ERR_RETURN 338 (WRITE_FURIA_PMA_PMD_REG(pa,\ 339 FUR_GEN_CNTRLS_gen_control2_Adr,\ 340 gen_ctrl2.data)); 341 342 /* MDI/I2C Download */ 343 /* Waiting for serboot_busy */ 344 retry_count = FURIA_FW_DLOAD_RETRY_CNT; 345 do { 346 PHYMOD_IF_ERR_RETURN 347 (READ_FURIA_PMA_PMD_REG(pa,\ 348 FUR_GEN_CNTRLS_boot_Adr,\ 349 &gen_ctrl_boot.data)); 350 351 ser_boot_busy = gen_ctrl_boot.fields.serboot_busy; 352 PHYMOD_USLEEP(500); 353 retry_count--; 354 } while ((ser_boot_busy == 0) && (retry_count)); 355 if (retry_count == 0) { 356 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, 357 (_PHYMOD_MSG("ERR:SERBOOT BUSY BIT SET"))); 358 } 359 /* Program master and slave boot address */ 360 PHYMOD_IF_ERR_RETURN 361 (_furia_wait_mst_msgout(pa, MSGOUT_NEXT, 0)); 362 363 msgin.fields.msgin_val = 0x0000; 364 PHYMOD_IF_ERR_RETURN 365 (WRITE_FURIA_PMA_PMD_REG(pa,\ 366 FUR_GEN_CNTRLS_msgin_Adr,\ 367 msgin.data)); 368 369 PHYMOD_IF_ERR_RETURN 370 (_furia_wait_mst_msgout(pa, MSGOUT_NEXT, 0)); 371 msgin.fields.msgin_val = 0x0000; 372 PHYMOD_IF_ERR_RETURN 373 (WRITE_FURIA_PMA_PMD_REG(pa,\ 374 FUR_GEN_CNTRLS_msgin_Adr,\ 375 msgin.data)); 376 377 PHYMOD_IF_ERR_RETURN 378 (_furia_wait_mst_msgout(pa, MSGOUT_NEXT, 0)); 379 380 /* Calculate the number of words */ 381 num_words = (fw_length) / 2; 382 383 /* Update message in value field with word length */ 384 msgin.fields.msgin_val = num_words; 385 PHYMOD_IF_ERR_RETURN 386 (WRITE_FURIA_PMA_PMD_REG(pa,\ 387 FUR_GEN_CNTRLS_msgin_Adr,\ 388 msgin.data)); 389 390 num_bytes = fw_length; 391 392 for (j = 0; j < num_bytes; j += 2) { 393 /* Wait MSGOUT_NEXT from M0 */ 394 PHYMOD_IF_ERR_RETURN 395 (_furia_wait_mst_msgout(pa, MSGOUT_NEXT, 0)); 396 397 data16 = (new_fw[j + 1] << 8) | new_fw[j]; 398 check_sum ^= new_fw[j] ^ new_fw[j + 1]; 399 /* Send next word */ 400 msgin.fields.msgin_val = data16; 401 402 PHYMOD_IF_ERR_RETURN 403 (WRITE_FURIA_PMA_PMD_REG(pa,\ 404 FUR_GEN_CNTRLS_msgin_Adr,\ 405 msgin.data)); 406 } 407 408 check_sum = check_sum ? check_sum : 0x600D; 409 /*Check whether firmware is downloaded for both master and slave micro*/ 410 PHYMOD_IF_ERR_RETURN 411 (READ_FURIA_PMA_PMD_REG(pa,\ 412 FUR_MICRO_BOOT_boot_por_Adr,\ 413 µ_boot_por.data)); 414 415 if((!micro_boot_por.fields.mst_dwld_done) || (!micro_boot_por.fields.slv_dwld_done)) { 416 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INIT, (_PHYMOD_MSG("Firmware download failed"))); 417 } 418 419 PHYMOD_IF_ERR_RETURN 420 (READ_FURIA_PMA_PMD_REG(pa,\ 421 FUR_GEN_CNTRLS_mst_running_byte_cnt_Adr,\ 422 &mst_running_byte_cnt.data)); 423 m_byte_cnt = mst_running_byte_cnt.fields.mst_running_byte_cnt_val; 424 425 PHYMOD_IF_ERR_RETURN 426 (READ_FURIA_PMA_PMD_REG(pa,\ 427 FUR_GEN_CNTRLS_slv_running_byte_cnt_Adr,\ 428 &slv_running_byte_cnt.data)); 429 s_byte_cnt = slv_running_byte_cnt.fields.slv_running_byte_cnt_val; 430 431 if ((m_byte_cnt != num_bytes) || (s_byte_cnt != num_bytes)) { 432 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INIT, (_PHYMOD_MSG("Firmware download incomplete with byte count mismatch"))); 433 } 434 435 /* Compare the checksum for data integrity */ 436 PHYMOD_IF_ERR_RETURN 437 (READ_FURIA_PMA_PMD_REG(pa,\ 438 FUR_GEN_CNTRLS_mst_running_chksum_Adr,\ 439 &mst_running_chksum.data)); 440 m_chksum = mst_running_chksum.fields.mst_running_chksum_val; 441 PHYMOD_IF_ERR_RETURN 442 (READ_FURIA_PMA_PMD_REG(pa,\ 443 FUR_GEN_CNTRLS_slv_running_chksum_Adr,\ 444 &slv_running_chksum.data)); 445 s_chksum = slv_running_chksum.fields.slv_running_chksum_val; 446 447 if((m_chksum != check_sum) || (s_chksum != check_sum)) { 448 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INIT, (_PHYMOD_MSG("Firmware download failed with checksum mismatch"))); 449 } 450 451 /* To Check whether the firmware download through MDIO is done */ 452 PHYMOD_IF_ERR_RETURN 453 (_furia_wait_mst_msgout(pa, MSGOUT_DWNLD_DONE, 0)); 454 /* Wait for programming EEPROM */ 455 if(prg_eeprom) { 456 PHYMOD_IF_ERR_RETURN 457 (_furia_wait_mst_msgout(pa, MSGOUT_PRGRM_DONE, 10000000)); 458 /* Assert Reset by writing zero to spi_rstb, spi2x_rstb */ 459 PHYMOD_IF_ERR_RETURN 460 (READ_FURIA_PMA_PMD_REG(pa,\ 461 FUR_GEN_CNTRLS_gen_control2_Adr,\ 462 &gen_ctrl2.data)); 463 gen_ctrl2.fields.spi_rstb = 0; 464 gen_ctrl2.fields.spi2x_rstb = 0; 465 466 PHYMOD_IF_ERR_RETURN 467 (WRITE_FURIA_PMA_PMD_REG(pa,\ 468 FUR_GEN_CNTRLS_gen_control2_Adr,\ 469 gen_ctrl2.data)); 470 } 471 472 return m_byte_cnt; 473 } 474 475 int furia_firmware_info_get(const phymod_access_t *pa, phymod_core_firmware_info_t *fw_info) 476 { 477 FUR_GEN_CNTRLS_FIRMWARE_VERSION_t firmware_version; 478 FUR_GEN_CNTRLS_MST_RUNNING_CHKSUM_t mst_running_chksum; 479 /* Read the firmware version */ 480 PHYMOD_IF_ERR_RETURN 481 (READ_FURIA_PMA_PMD_REG(pa,\ 482 FUR_GEN_CNTRLS_firmware_version_Adr,\ 483 &firmware_version.data)); 484 fw_info->fw_version = firmware_version.data; 485 PHYMOD_IF_ERR_RETURN 486 (READ_FURIA_PMA_PMD_REG(pa,\ 487 FUR_GEN_CNTRLS_mst_running_chksum_Adr,\ 488 &mst_running_chksum.data)); 489 fw_info->fw_crc = mst_running_chksum.data; 490 return PHYMOD_E_NONE; 491 }