/* * Copyright (c) 2011-2015, Emulex * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include typedef enum dir_e { DIR_WRITE, DIR_READ, } dir_t; static int image_load_common(elxu_device_t *device, dir_t direction, uint32_t op_type, uint8_t *buffer, uint32_t bufferLength); /** * @brief Download UFI flash image component. * * @par Description * The flash image given by 'buffer' for 'bufferLength' is * passed to the flash. 'op_type' defines which flash image * component is to be written. * * * @param device Pointer to device descriptor. * @param op_type flash component to update. * @param buffer Pointer to memory buffer with flash data. * @param bufferlength Length of flash data. * * @return Returns 0 on success; or a negative error code value * on failure. */ int ufi_image_download(elxu_device_t *device, uint32_t op_type, uint8_t *buffer, uint32_t bufferLength) { return image_load_common(device, DIR_WRITE, op_type, buffer, bufferLength); } /** * @brief Upload UFI flash image component. * * @par Description * The flash image 'op_type' is read into 'buffer' * * @param device Pointer to device descriptor. * @param op_type flash component to update. * @param buffer Pointer to memory buffer with flash data. * @param bufferLength Length of flash data. * @return Returns 0 on success; or a negative error code value * on failure. * */ int ufi_image_upload(elxu_device_t *device, uint32_t op_type, uint8_t *buffer, uint32_t bufferLength) { return image_load_common(device, DIR_READ, op_type, buffer, bufferLength); } /** * @brief Read or Write UFI flash image component * * @par Description * Read or write UFI flash image. The request is broken * up into a series of requests. * * @param device Pointer to device descriptor. * @param direction Of transfer. * @param op_type UFI flash component to update. * @param buffer Pointer to memory buffer with flash data. * @param bufferLength Length of flash data. * * @return Returns 0 on success; or a negative error code value * on failure. * */ static int image_load_common(elxu_device_t *device, dir_t direction, uint32_t op_type, uint8_t *buffer, uint32_t bufferLength) { uint32_t n; uint32_t offset = 0; uint32_t op_code; int rval = ELXU_SUCCESS; while (offset < bufferLength) { n = (bufferLength - offset); if (n > MBOX_MAX_BUFFER) { n = MBOX_MAX_BUFFER; } switch (direction) { case DIR_WRITE: op_code = ((offset + n) >= bufferLength) ? MGMT_FLASHROM_OPCODE_FLASH : MGMT_FLASHROM_OPCODE_SAVE; rval = mbox_write_flashrom(device, op_code, op_type, offset, buffer, n); break; case DIR_READ: rval = mbox_read_flashrom(device, MGMT_FLASHROM_OPCODE_REPORT, op_type, offset, buffer, n); break; } if (rval < 0) { break; } offset += n; buffer += n; } return rval; } /** * @brief Return length of FAT. * * @par Description * Issues MANAGE_FAT mailbox command and returns the length of * the FAT. * * @param device Device descriptor. * * @return Returns the length of the FAT on success; negative * error code on failure. */ int fat_info(elxu_device_t *device) { return mbox_manage_fat(device, FAT_OPERATION_QUERY, 0, NULL, 0); } /** * @brief Read FAT. * * @par Description * Reads FAT into buffer. * * * @param device Device descriptor. * @param buffer Read buffer. * @param bufferLength Read buffer length. * * @return Returns the number of bytes read on success; negative * error code on failure. */ int fat_read(elxu_device_t *device, uint8_t *buffer, uint32_t bufferLength) { int rval = 0; int fatLength; uint32_t n; uint32_t offset; // Fetch the log length rval = fat_info(device); if (rval < 0) { return rval; } fatLength = rval; if (fatLength < bufferLength) { bufferLength = fatLength; } offset = 0; while (bufferLength > 0) { n = bufferLength; if (n > MBOX_MAX_BUFFER) { n = MBOX_MAX_BUFFER; } rval = mbox_manage_fat(device, FAT_OPERATION_RETRIEVE, offset, buffer, n); if (rval < 0) { break; } offset += n; buffer += n; bufferLength -= n; } if (rval >= 0) { rval = offset; } return rval; } /** * @brief Issue EFD get capabilities mailbox command. * * @par Description * The COMMON_GET_EXT_FAT_CAPABILIEIS mailbox command is issued. * WARNING: this command will return a variable amount of data * based on the configuration. There are BSG limitations that * may keep all data from being correctly returned. * * * @param device Device descriptor. * @param Parameter_type parameter type (0 for default, 1 for * current set). * @param params Pointer to ext_fat_config_params_t structure. * @param paramsLength Length of parameters structure. * * @return Returns 0 on success; or a negative error code value * on failure. */ int get_ext_fat_capabilities(elxu_device_t *device, uint32_t parameter_type, ext_fat_config_params_t *params, uint32_t paramsLength) { mbox_common_get_ext_fat_capabilities_t *mbox = zmalloc(paramsLength); int rval; mbox->params.request.parameter_type = parameter_type; rval = mbox_ext_fat(device, OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES, mbox, paramsLength); if (rval == 0) { memcpy(params, &mbox->params.response, paramsLength); } zfree(mbox); return rval; } /** * @brief Issue configure EFD snapshot mailbox command. * * @par Description * The OPCODE_COMMON_EXT_FAT_CONFIGURATION_SNAPSHOT mailbox * command is issued. The command returns total log entries in * the snapshot buffer. * * * @param device Device descriptor. * * @return Returns the length of snapshot EFD log entries on * success; negative error code on failure. */ int ext_fat_config_snapshot (elxu_device_t *device) { int rtval; mbox_common_ext_fat_configure_snapshot_t *mbox = (mbox_common_ext_fat_configure_snapshot_t *) zmalloc (sizeof (mbox_common_ext_fat_configure_snapshot_t)); rtval = mbox_ext_fat(device, OPCODE_COMMON_EXT_FAT_CONFIGURE_SNAPSHOT, mbox, sizeof (mbox_common_ext_fat_configure_snapshot_t)); if (rtval == 0) { rtval = mbox->params.response.total_log_entries; } zfree (mbox); return rtval; } /** * @brief Issue retrieve EFD snapshot mailbox command. * * @par Description * The OPCODE_COMMON_EXT_FAT_RETRIEVE_SHAPSHOT mailbox command * is issued. Because of BSG limitations only 32 logs are * requested per read. Upper layer executing * OPCODE_COMMON_EXT_FAT_CONFIGURATION_SNAPSHOT mailbox command * already knows the total number of log entries. * * * @param device Device descriptor. * @param buf The EFD snapshot data buffer. * @param len The buffer length. * @param numlogs The number of logs to retrieve. * * @return Returns 0 on success; or a negative error code value * on failure. */ int ext_fat_retrieve_snapshot (elxu_device_t *device, uint8_t *buf, uint32_t len, uint32_t numlogs) { int rtval; int logs_per_read = 32; int trace_chunk; uint32_t returned_bytes = 0; uint32_t returned_logs = 0; mbox_ioctl_common_ext_fat_retrieve_snapshot_t *mbox; int mbox_len; uint32_t retlogs; uint8_t *rsp; uint32_t struct_len = sizeof(mbox_ioctl_common_ext_fat_retrieve_snapshot_t); mbox_len = struct_len + (logs_per_read * sizeof (arm_trace_record_t)); mbox = zmalloc (mbox_len); if (mbox == NULL) { return MALLOC_FAILED; } while (numlogs > 0) { if (numlogs > logs_per_read) { trace_chunk = logs_per_read; } else { trace_chunk = numlogs; } memset (mbox,0,mbox_len); mbox->params.request.snapshot_mode = EXT_FAT_RETRIEVE_MODE_VRAM; mbox->params.request.start_index = returned_logs; mbox->params.request.num_log_entries = trace_chunk; rtval = mbox_ext_fat(device, OPCODE_COMMON_EXT_FAT_RETRIEVE_SHAPSHOT, mbox, mbox_len); if (rtval < 0) { printf ("Retrieving EFD data failure\n"); break; } retlogs = mbox->params.response.num_log_entries; rsp = (uint8_t *) &mbox->params.response; if (((returned_logs + retlogs) * sizeof (arm_trace_record_t)) <= len) { memcpy ((buf + returned_bytes),rsp + 4, (retlogs * sizeof (arm_trace_record_t))); } returned_logs += retlogs; returned_bytes = ( returned_logs * sizeof (arm_trace_record_t)); numlogs -= retlogs; } zfree (mbox); return rtval; } /** * @brief Issue EXT_FAT_READ_STRING_TABLE mailbox command. * * @par Description * The OPCODE_COMMON_EXT_FAT_READ_STRING_TABLE mailbox command * is issued. The upper layer has to provide a number of bytes * to be retrieved and the number of bytes already retrieved. * The function returns the response param part of * ioctl_common_ext_fat_read_string_table_t structure. * * * @param device Device descriptor. * @param tblinfo Pointer to the param response structure. * @param tbl_info_len Param response structure length. * @param bytes_to_read Bytes to read. * @param bytes_read Bytes already read. * * @return Returns 0 on success; or a negative error code value * on failure. */ int ext_fat_read_string_table (elxu_device_t *device, mbox_ext_fat_read_string_params_t *tblinfo, uint32_t tbl_info_len, uint32_t bytes_to_read, uint32_t bytes_read) { ioctl_common_ext_fat_read_string_table_t *mbox = NULL; uint32_t ioctl_mbx_len = bytes_to_read + sizeof (*mbox); int rval; mbox = zmalloc(ioctl_mbx_len); if (mbox == NULL) { return MALLOC_FAILED; } mbox->params.request.num_bytes = bytes_to_read; mbox->params.request.byte_offset = bytes_read; rval = mbox_ext_fat(device, OPCODE_COMMON_EXT_FAT_READ_STRING_TABLE,mbox, ioctl_mbx_len); if (rval == 0) { memcpy(tblinfo, &mbox->params.response, tbl_info_len); } zfree(mbox); return rval; } /** * @page elxsdkutil_oce11102.html OCe11102 Adapters * * @section oce11102_fw_download Firmware Download API * * The OCe11102 firmware download API consists of the functions shown in the * following table. * * * * * *
Function NameDescription
ufi_image_download()Download OCe11100 flash image component.
ufi_image_upload()Upload OCe11100 flash image component.
* * * @section oce11102_fat FAT File API * * The OCe11102 FAT file API consists of the functions shown in the * following table. * * * * * *
Function NameDescription
fat_info()Return length of the FAT.
fat_read()Read the FAT.
* * * @section oce11102_efd EFD File API * * The OCe11102 EFD file API consists of the functions shown in the * following table. * * * * * * * *
Function NameDescription
ext_fat_read_string_table()Issues the OPCODE_COMMON_EXT_FAT_READ_STRING_TABLE mailbox command.
ext_fat_read_string_table_upld()FAT data upload functionality.
ext_fat_retrieve_snapshot()Issues the COMMON_EXT_FAT_RETRIEVE_SNAPSHOT command.
ext_fat_snapshot_upload()EXT FAT data upload functionality.
* * * @section oce11102_flash Flash Access APIs * * The OCe11102 flash access APIs all result in an associated mailbox command. The * functions shown in the following table provide a generic interface to the required * mailbox commands. * * * * * * * *
Function NameDescription
get_ext_fat_capabilities()Issue EFD get capabilities command.
ext_fat_config_snapshot()Get the total number of log entries in the snapshot buffer. *
ext_fat_retrieve_snapshot()Retrieve log entries from the snapshot buffer using starting * offset and number of log entries.
ext_fat_read_string_table()Read the string table to be placed at the start of the EFD * data file.
* *

* */