| /* |
| <:copyright-BRCM:2014:DUAL/GPL:standard |
| |
| Copyright (c) 2014 Broadcom Corporation |
| All Rights Reserved |
| |
| Unless you and Broadcom execute a separate written software license |
| agreement governing use of this software, this software is licensed |
| to you under the terms of the GNU General Public License version 2 |
| (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| with the following added to such license: |
| |
| As a special exception, the copyright holders of this software give |
| you permission to link this software with independent modules, and |
| to copy and distribute the resulting executable under terms of your |
| choice, provided that you also meet, for each linked independent |
| module, the terms and conditions of the license of that module. |
| An independent module is a module which is not derived from this |
| software. The special exception does not apply to any modifications |
| of the software. |
| |
| Not withstanding the above, under no circumstances may you combine |
| this software in any way with any other Broadcom software provided |
| under a license other than the GPL, without Broadcom's express prior |
| written consent. |
| |
| :> |
| */ |
| |
| /* |
| * This file is contains the customer-provided code. |
| * This file is provided as an example. |
| * The customer may change the file path/names. |
| * The customer may change the file access functions. |
| * The customer may adjust the data block size. |
| * Adding a new image type requires the object model change and sync up with |
| * the embedded size, which should be done by the Broadcom engineering. |
| */ |
| |
| #include <bcmolt_conv.h> |
| #include "bcmolt_image_transfer.h" |
| #include "bcmolt_image_transfer_user.h" |
| #include "bcmolt_utils.h" |
| |
| /* example names for debugging purpose only */ |
| #define BOOT_FILE "/opt/bcm68620/bcm68620_boot.bin" |
| #define APPL_FILE "/opt/bcm68620/bcm68620_appl.bin" |
| #define ITU_PON_ONU_FW_FILE "/opt/bcm68620/gpon_onu_fw.w" |
| #define EPON_ONU_FW_FILE "/opt/bcm68620/epon_onu_fw.tkf" |
| |
| static int2str_t image_type2str[] = |
| { |
| {BCMOLT_DEVICE_IMAGE_TYPE_BOOTLOADER, BOOT_FILE}, |
| {BCMOLT_DEVICE_IMAGE_TYPE_APPLICATION, APPL_FILE}, |
| {BCMOLT_DEVICE_IMAGE_TYPE_ITU_PON_ONU_FIRMWARE, ITU_PON_ONU_FW_FILE}, |
| {BCMOLT_DEVICE_IMAGE_TYPE_EPON_ONU_FIRMWARE, EPON_ONU_FW_FILE}, |
| {-1} |
| }; |
| |
| /** Get the device file name. |
| * |
| * \param[in] image_type Image type. defined in the object model. |
| * |
| * \return string Pointer to device image name, including the path. |
| */ |
| const char *bcmuser_device_image_name_get(bcmolt_device_image_type image_type) |
| { |
| if (image_type < BCMOLT_DEVICE_IMAGE_TYPE__NUM_OF) |
| { |
| return int2str(image_type2str, image_type); |
| } |
| return NULL; |
| } |
| |
| /** Open a file with given image type. |
| * |
| * \param[in] image_type Image type. defined in the object model. |
| * \param[out] fpp File pointer |
| * |
| * \return bcmos_errno Error code |
| */ |
| static bcmos_errno bcmuser_image_transfer_file_open(bcmolt_device_image_type image_type, FILE **fpp) |
| { |
| bcmos_errno rc = BCM_ERR_PARM; |
| |
| if (image_type < BCMOLT_DEVICE_IMAGE_TYPE__NUM_OF) |
| { |
| FILE *fp; |
| const char *fname = bcmuser_device_image_name_get(image_type); |
| fp = fopen(fname, "rb"); |
| if (fp != NULL) |
| { |
| *fpp = fp; |
| rc = BCM_ERR_OK; |
| } |
| } |
| return rc; |
| } |
| |
| /** Get the size of the file. |
| * |
| * \param[in] device Device ID |
| * \param[in] image_type Image type. defined in the object model. |
| * \param[out] fsize File size |
| * |
| * \return bcmos_errno |
| */ |
| bcmos_errno bcmuser_image_transfer_file_size_get(bcmolt_devid device, |
| bcmolt_device_image_type image_type, uint32_t *fsize) |
| { |
| FILE *fp; |
| long fp_prev; |
| bcmos_errno rc = BCM_ERR_OK; |
| (void)device; |
| |
| rc = bcmuser_image_transfer_file_open(image_type, &fp); |
| if (rc == BCM_ERR_OK) |
| { |
| fp_prev = ftell(fp); |
| BUG_ON(fp_prev < 0); |
| BUG_ON(fseek(fp, 0, SEEK_END) != 0); |
| *fsize = ftell(fp); |
| BUG_ON(fseek(fp, fp_prev, SEEK_SET) != 0); /* go back to where we were. */ |
| BUG_ON(fclose(fp) != 0); |
| } |
| return rc; |
| } |
| |
| /** Read data from given offset. |
| * |
| * \param[in] device Device ID |
| * \param[in] image_type Image type. defined in the object model. |
| * \param[in] offset File position indicator |
| * \param[out] buf Buffer to store the data |
| * \param[in] buf_size Buffer size |
| * |
| * \return Bytes read |
| */ |
| int bcmuser_image_transfer_read_data(bcmolt_devid device, bcmolt_device_image_type image_type, |
| uint32_t offset, uint8_t *buf, uint32_t buf_size) |
| { |
| FILE *fp; |
| uint32_t bytes_read = 0; |
| (void)device; |
| |
| if (bcmuser_image_transfer_file_open(image_type, &fp) == BCM_ERR_OK) |
| { |
| BUG_ON(fseek(fp, 0, SEEK_END) != 0); |
| if (offset < ftell(fp)) |
| { |
| BUG_ON(fseek(fp, offset, SEEK_SET) != 0); |
| bytes_read = fread(buf, 1, buf_size, fp); |
| } |
| BUG_ON(fclose(fp) != 0); |
| } |
| return bytes_read; |
| } |
| |
| /** Get the unit size of the transfer data block. |
| * |
| * \return Size of the block in bytes. |
| */ |
| uint32_t bcmuser_image_transfer_block_size_get(void) |
| { |
| return MFTP_DATA_BLOCK_SIZE; |
| } |
| |
| /** Returns the CRC32 checksum of entire image. |
| * |
| * \param[in] device Device ID |
| * \param[in] image_type Image type. defined in the object model. |
| * |
| * \return CRC32 checksum |
| */ |
| uint32_t bcmuser_image_transfer_crc_get(bcmolt_devid device, bcmolt_device_image_type image_type) |
| { |
| FILE *fp; |
| uint32_t crc = 0; |
| (void)device; |
| |
| if (bcmuser_image_transfer_file_open(image_type, &fp) == BCM_ERR_OK) |
| { |
| while (1) |
| { |
| char buf[512]; /* any size is OK. */ |
| uint32_t bytes_read; |
| |
| bytes_read = fread(buf, 1, sizeof(buf), fp); |
| if (bytes_read == 0) |
| break; |
| crc = eth_calc_crc32(crc, buf, bytes_read); |
| } |
| BUG_ON(fclose(fp) != 0); |
| } |
| return crc; |
| } |
| |
| /** Process the notification from the image transfer module. |
| * |
| * \param[in] device Device ID |
| * \param[in] image_type Image type. defined in the object model. |
| * \param[in] block_num last block number |
| * \param[in] status Image transfer status |
| */ |
| void bcmuser_image_transfer_notification_rx(bcmolt_devid device, |
| bcmolt_device_image_type image_type, uint32_t block_num, |
| bcmolt_image_transfer_status status) |
| { |
| const char *str = bcmolt_user_mftp_status_to_str(status); |
| bcmos_printf("Image transfer: %s: type=%u block=%u\n", str, image_type, block_num); |
| } |
| |