// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2018, Intel Corporation. */ #include <linux/vmalloc.h> #include "ice_common.h" /** * ice_aq_read_nvm * @hw: pointer to the HW struct * @module_typeid: module pointer location in words from the NVM beginning * @offset: byte offset from the module beginning * @length: length of the section to be read (in bytes from the offset) * @data: command buffer (size [bytes] = length) * @last_command: tells if this is the last command in a series * @read_shadow_ram: tell if this is a shadow RAM read * @cd: pointer to command details structure or NULL * * Read the NVM using the admin queue commands (0x0701) */ int ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length, void *data, bool last_command, bool read_shadow_ram, struct ice_sq_cd *cd) { … } /** * ice_read_flat_nvm - Read portion of NVM by flat offset * @hw: pointer to the HW struct * @offset: offset from beginning of NVM * @length: (in) number of bytes to read; (out) number of bytes actually read * @data: buffer to return data in (sized to fit the specified length) * @read_shadow_ram: if true, read from shadow RAM instead of NVM * * Reads a portion of the NVM, as a flat memory space. This function correctly * breaks read requests across Shadow RAM sectors and ensures that no single * read request exceeds the maximum 4KB read for a single AdminQ command. * * Returns a status code on failure. Note that the data pointer may be * partially updated if some reads succeed before a failure. */ int ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data, bool read_shadow_ram) { … } /** * ice_aq_update_nvm * @hw: pointer to the HW struct * @module_typeid: module pointer location in words from the NVM beginning * @offset: byte offset from the module beginning * @length: length of the section to be written (in bytes from the offset) * @data: command buffer (size [bytes] = length) * @last_command: tells if this is the last command in a series * @command_flags: command parameters * @cd: pointer to command details structure or NULL * * Update the NVM using the admin queue commands (0x0703) */ int ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length, void *data, bool last_command, u8 command_flags, struct ice_sq_cd *cd) { … } /** * ice_aq_erase_nvm * @hw: pointer to the HW struct * @module_typeid: module pointer location in words from the NVM beginning * @cd: pointer to command details structure or NULL * * Erase the NVM sector using the admin queue commands (0x0702) */ int ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd) { … } /** * ice_read_sr_word_aq - Reads Shadow RAM via AQ * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) * @data: word read from the Shadow RAM * * Reads one 16 bit word from the Shadow RAM using ice_read_flat_nvm. */ static int ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data) { … } /** * ice_acquire_nvm - Generic request for acquiring the NVM ownership * @hw: pointer to the HW structure * @access: NVM access type (read or write) * * This function will request NVM ownership. */ int ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access) { … } /** * ice_release_nvm - Generic request for releasing the NVM ownership * @hw: pointer to the HW structure * * This function will release NVM ownership. */ void ice_release_nvm(struct ice_hw *hw) { … } /** * ice_get_flash_bank_offset - Get offset into requested flash bank * @hw: pointer to the HW structure * @bank: whether to read from the active or inactive flash bank * @module: the module to read from * * Based on the module, lookup the module offset from the beginning of the * flash. * * Returns the flash offset. Note that a value of zero is invalid and must be * treated as an error. */ static u32 ice_get_flash_bank_offset(struct ice_hw *hw, enum ice_bank_select bank, u16 module) { … } /** * ice_read_flash_module - Read a word from one of the main NVM modules * @hw: pointer to the HW structure * @bank: which bank of the module to read * @module: the module to read * @offset: the offset into the module in bytes * @data: storage for the word read from the flash * @length: bytes of data to read * * Read data from the specified flash module. The bank parameter indicates * whether or not to read from the active bank or the inactive bank of that * module. * * The word will be read using flat NVM access, and relies on the * hw->flash.banks data being setup by ice_determine_active_flash_banks() * during initialization. */ static int ice_read_flash_module(struct ice_hw *hw, enum ice_bank_select bank, u16 module, u32 offset, u8 *data, u32 length) { … } /** * ice_read_nvm_module - Read from the active main NVM module * @hw: pointer to the HW structure * @bank: whether to read from active or inactive NVM module * @offset: offset into the NVM module to read, in words * @data: storage for returned word value * * Read the specified word from the active NVM module. This includes the CSS * header at the start of the NVM module. */ static int ice_read_nvm_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data) { … } /** * ice_read_nvm_sr_copy - Read a word from the Shadow RAM copy in the NVM bank * @hw: pointer to the HW structure * @bank: whether to read from the active or inactive NVM module * @offset: offset into the Shadow RAM copy to read, in words * @data: storage for returned word value * * Read the specified word from the copy of the Shadow RAM found in the * specified NVM module. * * Note that the Shadow RAM copy is always located after the CSS header, and * is aligned to 64-byte (32-word) offsets. */ static int ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data) { … } /** * ice_read_netlist_module - Read data from the netlist module area * @hw: pointer to the HW structure * @bank: whether to read from the active or inactive module * @offset: offset into the netlist to read from * @data: storage for returned word value * * Read a word from the specified netlist bank. */ static int ice_read_netlist_module(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data) { … } /** * ice_read_sr_word - Reads Shadow RAM word and acquire NVM if necessary * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) * @data: word read from the Shadow RAM * * Reads one 16 bit word from the Shadow RAM using the ice_read_sr_word_aq. */ int ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data) { … } /** * ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA * @hw: pointer to hardware structure * @module_tlv: pointer to module TLV to return * @module_tlv_len: pointer to module TLV length to return * @module_type: module type requested * * Finds the requested sub module TLV type from the Preserved Field * Area (PFA) and returns the TLV pointer and length. The caller can * use these to read the variable length TLV value. */ int ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len, u16 module_type) { … } /** * ice_read_pba_string - Reads part number string from NVM * @hw: pointer to hardware structure * @pba_num: stores the part number string from the NVM * @pba_num_size: part number string buffer length * * Reads the part number string from the NVM. */ int ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size) { … } /** * ice_get_nvm_ver_info - Read NVM version information * @hw: pointer to the HW struct * @bank: whether to read from the active or inactive flash bank * @nvm: pointer to NVM info structure * * Read the NVM EETRACK ID and map version of the main NVM image bank, filling * in the NVM info structure. */ static int ice_get_nvm_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_nvm_info *nvm) { … } /** * ice_get_inactive_nvm_ver - Read Option ROM version from the inactive bank * @hw: pointer to the HW structure * @nvm: storage for Option ROM version information * * Reads the NVM EETRACK ID, Map version, and security revision of the * inactive NVM bank. Used to access version data for a pending update that * has not yet been activated. */ int ice_get_inactive_nvm_ver(struct ice_hw *hw, struct ice_nvm_info *nvm) { … } /** * ice_get_orom_civd_data - Get the combo version information from Option ROM * @hw: pointer to the HW struct * @bank: whether to read from the active or inactive flash module * @civd: storage for the Option ROM CIVD data. * * Searches through the Option ROM flash contents to locate the CIVD data for * the image. */ static int ice_get_orom_civd_data(struct ice_hw *hw, enum ice_bank_select bank, struct ice_orom_civd_info *civd) { … } /** * ice_get_orom_ver_info - Read Option ROM version information * @hw: pointer to the HW struct * @bank: whether to read from the active or inactive flash module * @orom: pointer to Option ROM info structure * * Read Option ROM version and security revision from the Option ROM flash * section. */ static int ice_get_orom_ver_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_orom_info *orom) { … } /** * ice_get_inactive_orom_ver - Read Option ROM version from the inactive bank * @hw: pointer to the HW structure * @orom: storage for Option ROM version information * * Reads the Option ROM version and security revision data for the inactive * section of flash. Used to access version data for a pending update that has * not yet been activated. */ int ice_get_inactive_orom_ver(struct ice_hw *hw, struct ice_orom_info *orom) { … } /** * ice_get_netlist_info * @hw: pointer to the HW struct * @bank: whether to read from the active or inactive flash bank * @netlist: pointer to netlist version info structure * * Get the netlist version information from the requested bank. Reads the Link * Topology section to find the Netlist ID block and extract the relevant * information into the netlist version structure. */ static int ice_get_netlist_info(struct ice_hw *hw, enum ice_bank_select bank, struct ice_netlist_info *netlist) { … } /** * ice_get_inactive_netlist_ver * @hw: pointer to the HW struct * @netlist: pointer to netlist version info structure * * Read the netlist version data from the inactive netlist bank. Used to * extract version data of a pending flash update in order to display the * version data. */ int ice_get_inactive_netlist_ver(struct ice_hw *hw, struct ice_netlist_info *netlist) { … } /** * ice_discover_flash_size - Discover the available flash size. * @hw: pointer to the HW struct * * The device flash could be up to 16MB in size. However, it is possible that * the actual size is smaller. Use bisection to determine the accessible size * of flash memory. */ static int ice_discover_flash_size(struct ice_hw *hw) { … } /** * ice_read_sr_pointer - Read the value of a Shadow RAM pointer word * @hw: pointer to the HW structure * @offset: the word offset of the Shadow RAM word to read * @pointer: pointer value read from Shadow RAM * * Read the given Shadow RAM word, and convert it to a pointer value specified * in bytes. This function assumes the specified offset is a valid pointer * word. * * Each pointer word specifies whether it is stored in word size or 4KB * sector size by using the highest bit. The reported pointer value will be in * bytes, intended for flat NVM reads. */ static int ice_read_sr_pointer(struct ice_hw *hw, u16 offset, u32 *pointer) { … } /** * ice_read_sr_area_size - Read an area size from a Shadow RAM word * @hw: pointer to the HW structure * @offset: the word offset of the Shadow RAM to read * @size: size value read from the Shadow RAM * * Read the given Shadow RAM word, and convert it to an area size value * specified in bytes. This function assumes the specified offset is a valid * area size word. * * Each area size word is specified in 4KB sector units. This function reports * the size in bytes, intended for flat NVM reads. */ static int ice_read_sr_area_size(struct ice_hw *hw, u16 offset, u32 *size) { … } /** * ice_determine_active_flash_banks - Discover active bank for each module * @hw: pointer to the HW struct * * Read the Shadow RAM control word and determine which banks are active for * the NVM, OROM, and Netlist modules. Also read and calculate the associated * pointer and size. These values are then cached into the ice_flash_info * structure for later use in order to calculate the correct offset to read * from the active module. */ static int ice_determine_active_flash_banks(struct ice_hw *hw) { … } /** * ice_get_nvm_css_hdr_len - Read the CSS header length from the NVM CSS header * @hw: pointer to the HW struct * @bank: whether to read from the active or inactive flash bank * @hdr_len: storage for header length in words * * Read the CSS header length from the NVM CSS header and add the Authentication * header size, and then convert to words. * * Return: zero on success, or a negative error code on failure. */ static int ice_get_nvm_css_hdr_len(struct ice_hw *hw, enum ice_bank_select bank, u32 *hdr_len) { … } /** * ice_determine_css_hdr_len - Discover CSS header length for the device * @hw: pointer to the HW struct * * Determine the size of the CSS header at the start of the NVM module. This * is useful for locating the Shadow RAM copy in the NVM, as the Shadow RAM is * always located just after the CSS header. * * Return: zero on success, or a negative error code on failure. */ static int ice_determine_css_hdr_len(struct ice_hw *hw) { … } /** * ice_init_nvm - initializes NVM setting * @hw: pointer to the HW struct * * This function reads and populates NVM settings such as Shadow RAM size, * max_timeout, and blank_nvm_mode */ int ice_init_nvm(struct ice_hw *hw) { … } /** * ice_nvm_validate_checksum * @hw: pointer to the HW struct * * Verify NVM PFA checksum validity (0x0706) */ int ice_nvm_validate_checksum(struct ice_hw *hw) { … } /** * ice_nvm_write_activate * @hw: pointer to the HW struct * @cmd_flags: flags for write activate command * @response_flags: response indicators from firmware * * Update the control word with the required banks' validity bits * and dumps the Shadow RAM to flash (0x0707) * * cmd_flags controls which banks to activate, the preservation level to use * when activating the NVM bank, and whether an EMP reset is required for * activation. * * Note that the 16bit cmd_flags value is split between two separate 1 byte * flag values in the descriptor. * * On successful return of the firmware command, the response_flags variable * is updated with the flags reported by firmware indicating certain status, * such as whether EMP reset is enabled. */ int ice_nvm_write_activate(struct ice_hw *hw, u16 cmd_flags, u8 *response_flags) { … } /** * ice_aq_nvm_update_empr * @hw: pointer to the HW struct * * Update empr (0x0709). This command allows SW to * request an EMPR to activate new FW. */ int ice_aq_nvm_update_empr(struct ice_hw *hw) { … } /* ice_nvm_set_pkg_data * @hw: pointer to the HW struct * @del_pkg_data_flag: If is set then the current pkg_data store by FW * is deleted. * If bit is set to 1, then buffer should be size 0. * @data: pointer to buffer * @length: length of the buffer * @cd: pointer to command details structure or NULL * * Set package data (0x070A). This command is equivalent to the reception * of a PLDM FW Update GetPackageData cmd. This command should be sent * as part of the NVM update as the first cmd in the flow. */ int ice_nvm_set_pkg_data(struct ice_hw *hw, bool del_pkg_data_flag, u8 *data, u16 length, struct ice_sq_cd *cd) { … } /* ice_nvm_pass_component_tbl * @hw: pointer to the HW struct * @data: pointer to buffer * @length: length of the buffer * @transfer_flag: parameter for determining stage of the update * @comp_response: a pointer to the response from the 0x070B AQC. * @comp_response_code: a pointer to the response code from the 0x070B AQC. * @cd: pointer to command details structure or NULL * * Pass component table (0x070B). This command is equivalent to the reception * of a PLDM FW Update PassComponentTable cmd. This command should be sent once * per component. It can be only sent after Set Package Data cmd and before * actual update. FW will assume these commands are going to be sent until * the TransferFlag is set to End or StartAndEnd. */ int ice_nvm_pass_component_tbl(struct ice_hw *hw, u8 *data, u16 length, u8 transfer_flag, u8 *comp_response, u8 *comp_response_code, struct ice_sq_cd *cd) { … }