Shad Ansari | 2f7f9be | 2017-06-07 13:34:53 -0700 | [diff] [blame^] | 1 | /* |
| 2 | <:copyright-BRCM:2014:DUAL/GPL:standard |
| 3 | |
| 4 | Copyright (c) 2014 Broadcom Corporation |
| 5 | All Rights Reserved |
| 6 | |
| 7 | Unless you and Broadcom execute a separate written software license |
| 8 | agreement governing use of this software, this software is licensed |
| 9 | to you under the terms of the GNU General Public License version 2 |
| 10 | (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| 11 | with the following added to such license: |
| 12 | |
| 13 | As a special exception, the copyright holders of this software give |
| 14 | you permission to link this software with independent modules, and |
| 15 | to copy and distribute the resulting executable under terms of your |
| 16 | choice, provided that you also meet, for each linked independent |
| 17 | module, the terms and conditions of the license of that module. |
| 18 | An independent module is a module which is not derived from this |
| 19 | software. The special exception does not apply to any modifications |
| 20 | of the software. |
| 21 | |
| 22 | Not withstanding the above, under no circumstances may you combine |
| 23 | this software in any way with any other Broadcom software provided |
| 24 | under a license other than the GPL, without Broadcom's express prior |
| 25 | written consent. |
| 26 | |
| 27 | :> |
| 28 | */ |
| 29 | |
| 30 | /* |
| 31 | * This file is contains the customer-provided code. |
| 32 | * This file is provided as an example. |
| 33 | * The customer may change the file path/names. |
| 34 | * The customer may change the file access functions. |
| 35 | * The customer may adjust the data block size. |
| 36 | * Adding a new image type requires the object model change and sync up with |
| 37 | * the embedded size, which should be done by the Broadcom engineering. |
| 38 | */ |
| 39 | |
| 40 | #include <bcmolt_conv.h> |
| 41 | #include "bcmolt_image_transfer.h" |
| 42 | #include "bcmolt_image_transfer_user.h" |
| 43 | #include "bcmolt_utils.h" |
| 44 | |
| 45 | /* example names for debugging purpose only */ |
| 46 | #define BOOT_FILE "/opt/bcm68620/bcm68620_boot.bin" |
| 47 | #define APPL_FILE "/opt/bcm68620/bcm68620_appl.bin" |
| 48 | #define ITU_PON_ONU_FW_FILE "/opt/bcm68620/gpon_onu_fw.w" |
| 49 | #define EPON_ONU_FW_FILE "/opt/bcm68620/epon_onu_fw.tkf" |
| 50 | |
| 51 | static int2str_t image_type2str[] = |
| 52 | { |
| 53 | {BCMOLT_DEVICE_IMAGE_TYPE_BOOTLOADER, BOOT_FILE}, |
| 54 | {BCMOLT_DEVICE_IMAGE_TYPE_APPLICATION, APPL_FILE}, |
| 55 | {BCMOLT_DEVICE_IMAGE_TYPE_ITU_PON_ONU_FIRMWARE, ITU_PON_ONU_FW_FILE}, |
| 56 | {BCMOLT_DEVICE_IMAGE_TYPE_EPON_ONU_FIRMWARE, EPON_ONU_FW_FILE}, |
| 57 | {-1} |
| 58 | }; |
| 59 | |
| 60 | /** Get the device file name. |
| 61 | * |
| 62 | * \param[in] image_type Image type. defined in the object model. |
| 63 | * |
| 64 | * \return string Pointer to device image name, including the path. |
| 65 | */ |
| 66 | const char *bcmuser_device_image_name_get(bcmolt_device_image_type image_type) |
| 67 | { |
| 68 | if (image_type < BCMOLT_DEVICE_IMAGE_TYPE__NUM_OF) |
| 69 | { |
| 70 | return int2str(image_type2str, image_type); |
| 71 | } |
| 72 | return NULL; |
| 73 | } |
| 74 | |
| 75 | /** Open a file with given image type. |
| 76 | * |
| 77 | * \param[in] image_type Image type. defined in the object model. |
| 78 | * \param[out] fpp File pointer |
| 79 | * |
| 80 | * \return bcmos_errno Error code |
| 81 | */ |
| 82 | static bcmos_errno bcmuser_image_transfer_file_open(bcmolt_device_image_type image_type, FILE **fpp) |
| 83 | { |
| 84 | bcmos_errno rc = BCM_ERR_PARM; |
| 85 | |
| 86 | if (image_type < BCMOLT_DEVICE_IMAGE_TYPE__NUM_OF) |
| 87 | { |
| 88 | FILE *fp; |
| 89 | const char *fname = bcmuser_device_image_name_get(image_type); |
| 90 | fp = fopen(fname, "rb"); |
| 91 | if (fp != NULL) |
| 92 | { |
| 93 | *fpp = fp; |
| 94 | rc = BCM_ERR_OK; |
| 95 | } |
| 96 | } |
| 97 | return rc; |
| 98 | } |
| 99 | |
| 100 | /** Get the size of the file. |
| 101 | * |
| 102 | * \param[in] device Device ID |
| 103 | * \param[in] image_type Image type. defined in the object model. |
| 104 | * \param[out] fsize File size |
| 105 | * |
| 106 | * \return bcmos_errno |
| 107 | */ |
| 108 | bcmos_errno bcmuser_image_transfer_file_size_get(bcmolt_devid device, |
| 109 | bcmolt_device_image_type image_type, uint32_t *fsize) |
| 110 | { |
| 111 | FILE *fp; |
| 112 | long fp_prev; |
| 113 | bcmos_errno rc = BCM_ERR_OK; |
| 114 | (void)device; |
| 115 | |
| 116 | rc = bcmuser_image_transfer_file_open(image_type, &fp); |
| 117 | if (rc == BCM_ERR_OK) |
| 118 | { |
| 119 | fp_prev = ftell(fp); |
| 120 | BUG_ON(fp_prev < 0); |
| 121 | BUG_ON(fseek(fp, 0, SEEK_END) != 0); |
| 122 | *fsize = ftell(fp); |
| 123 | BUG_ON(fseek(fp, fp_prev, SEEK_SET) != 0); /* go back to where we were. */ |
| 124 | BUG_ON(fclose(fp) != 0); |
| 125 | } |
| 126 | return rc; |
| 127 | } |
| 128 | |
| 129 | /** Read data from given offset. |
| 130 | * |
| 131 | * \param[in] device Device ID |
| 132 | * \param[in] image_type Image type. defined in the object model. |
| 133 | * \param[in] offset File position indicator |
| 134 | * \param[out] buf Buffer to store the data |
| 135 | * \param[in] buf_size Buffer size |
| 136 | * |
| 137 | * \return Bytes read |
| 138 | */ |
| 139 | int bcmuser_image_transfer_read_data(bcmolt_devid device, bcmolt_device_image_type image_type, |
| 140 | uint32_t offset, uint8_t *buf, uint32_t buf_size) |
| 141 | { |
| 142 | FILE *fp; |
| 143 | uint32_t bytes_read = 0; |
| 144 | (void)device; |
| 145 | |
| 146 | if (bcmuser_image_transfer_file_open(image_type, &fp) == BCM_ERR_OK) |
| 147 | { |
| 148 | BUG_ON(fseek(fp, 0, SEEK_END) != 0); |
| 149 | if (offset < ftell(fp)) |
| 150 | { |
| 151 | BUG_ON(fseek(fp, offset, SEEK_SET) != 0); |
| 152 | bytes_read = fread(buf, 1, buf_size, fp); |
| 153 | } |
| 154 | BUG_ON(fclose(fp) != 0); |
| 155 | } |
| 156 | return bytes_read; |
| 157 | } |
| 158 | |
| 159 | /** Get the unit size of the transfer data block. |
| 160 | * |
| 161 | * \return Size of the block in bytes. |
| 162 | */ |
| 163 | uint32_t bcmuser_image_transfer_block_size_get(void) |
| 164 | { |
| 165 | return MFTP_DATA_BLOCK_SIZE; |
| 166 | } |
| 167 | |
| 168 | /** Returns the CRC32 checksum of entire image. |
| 169 | * |
| 170 | * \param[in] device Device ID |
| 171 | * \param[in] image_type Image type. defined in the object model. |
| 172 | * |
| 173 | * \return CRC32 checksum |
| 174 | */ |
| 175 | uint32_t bcmuser_image_transfer_crc_get(bcmolt_devid device, bcmolt_device_image_type image_type) |
| 176 | { |
| 177 | FILE *fp; |
| 178 | uint32_t crc = 0; |
| 179 | (void)device; |
| 180 | |
| 181 | if (bcmuser_image_transfer_file_open(image_type, &fp) == BCM_ERR_OK) |
| 182 | { |
| 183 | while (1) |
| 184 | { |
| 185 | char buf[512]; /* any size is OK. */ |
| 186 | uint32_t bytes_read; |
| 187 | |
| 188 | bytes_read = fread(buf, 1, sizeof(buf), fp); |
| 189 | if (bytes_read == 0) |
| 190 | break; |
| 191 | crc = eth_calc_crc32(crc, buf, bytes_read); |
| 192 | } |
| 193 | BUG_ON(fclose(fp) != 0); |
| 194 | } |
| 195 | return crc; |
| 196 | } |
| 197 | |
| 198 | /** Process the notification from the image transfer module. |
| 199 | * |
| 200 | * \param[in] device Device ID |
| 201 | * \param[in] image_type Image type. defined in the object model. |
| 202 | * \param[in] block_num last block number |
| 203 | * \param[in] status Image transfer status |
| 204 | */ |
| 205 | void bcmuser_image_transfer_notification_rx(bcmolt_devid device, |
| 206 | bcmolt_device_image_type image_type, uint32_t block_num, |
| 207 | bcmolt_image_transfer_status status) |
| 208 | { |
| 209 | const char *str = bcmolt_user_mftp_status_to_str(status); |
| 210 | bcmos_printf("Image transfer: %s: type=%u block=%u\n", str, image_type, block_num); |
| 211 | } |
| 212 | |