// SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 2013 - 2018 Intel Corporation. */ #include <linux/bitfield.h> #include <linux/delay.h> #include "i40e_alloc.h" #include "i40e_prototype.h" /** * i40e_init_nvm - Initialize NVM function pointers * @hw: pointer to the HW structure * * Setup the function pointers and the NVM info structure. Should be called * once per NVM initialization, e.g. inside the i40e_init_shared_code(). * Please notice that the NVM term is used here (& in all methods covered * in this file) as an equivalent of the FLASH part mapped into the SR. * We are accessing FLASH always thru the Shadow RAM. **/ int i40e_init_nvm(struct i40e_hw *hw) { … } /** * i40e_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 for reading * via the proper Admin Command. **/ int i40e_acquire_nvm(struct i40e_hw *hw, enum i40e_aq_resource_access_type access) { … } /** * i40e_release_nvm - Generic request for releasing the NVM ownership * @hw: pointer to the HW structure * * This function will release NVM resource via the proper Admin Command. **/ void i40e_release_nvm(struct i40e_hw *hw) { … } /** * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit * @hw: pointer to the HW structure * * Polls the SRCTL Shadow RAM register done bit. **/ static int i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw) { … } /** * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register * @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 GLNVM_SRCTL register. **/ static int i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset, u16 *data) { … } /** * i40e_read_nvm_aq - Read Shadow RAM. * @hw: pointer to the HW structure. * @module_pointer: module pointer location in words from the NVM beginning * @offset: offset in words from module start * @words: number of words to read * @data: buffer with words to read to the Shadow RAM * @last_command: tells the AdminQ that this is the last command * * Reads a 16 bit words buffer to the Shadow RAM using the admin command. **/ static int i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer, u32 offset, u16 words, void *data, bool last_command) { … } /** * i40e_read_nvm_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 the AdminQ **/ static int i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset, u16 *data) { … } /** * __i40e_read_nvm_word - Reads nvm word, assumes caller does the locking * @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. * * Do not use this function except in cases where the nvm lock is already * taken via i40e_acquire_nvm(). **/ static int __i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, u16 *data) { … } /** * i40e_read_nvm_word - Reads nvm word and acquire lock 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. **/ int i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, u16 *data) { … } /** * i40e_read_nvm_module_data - Reads NVM Buffer to specified memory location * @hw: Pointer to the HW structure * @module_ptr: Pointer to module in words with respect to NVM beginning * @module_offset: Offset in words from module start * @data_offset: Offset in words from reading data area start * @words_data_size: Words to read from NVM * @data_ptr: Pointer to memory location where resulting buffer will be stored **/ int i40e_read_nvm_module_data(struct i40e_hw *hw, u8 module_ptr, u16 module_offset, u16 data_offset, u16 words_data_size, u16 *data_ptr) { … } /** * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). * @words: (in) number of words to read; (out) number of words actually read * @data: words read from the Shadow RAM * * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() * method. The buffer read is preceded by the NVM ownership take * and followed by the release. **/ static int i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset, u16 *words, u16 *data) { … } /** * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). * @words: (in) number of words to read; (out) number of words actually read * @data: words read from the Shadow RAM * * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq() * method. The buffer read is preceded by the NVM ownership take * and followed by the release. **/ static int i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset, u16 *words, u16 *data) { … } /** * __i40e_read_nvm_buffer - Reads nvm buffer, caller must acquire lock * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). * @words: (in) number of words to read; (out) number of words actually read * @data: words read from the Shadow RAM * * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() * method. **/ static int __i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, u16 *words, u16 *data) { … } /** * i40e_read_nvm_buffer - Reads Shadow RAM buffer and acquire lock if necessary * @hw: pointer to the HW structure * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF). * @words: (in) number of words to read; (out) number of words actually read * @data: words read from the Shadow RAM * * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd() * method. The buffer read is preceded by the NVM ownership take * and followed by the release. **/ int i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, u16 *words, u16 *data) { … } /** * i40e_write_nvm_aq - Writes Shadow RAM. * @hw: pointer to the HW structure. * @module_pointer: module pointer location in words from the NVM beginning * @offset: offset in words from module start * @words: number of words to write * @data: buffer with words to write to the Shadow RAM * @last_command: tells the AdminQ that this is the last command * * Writes a 16 bit words buffer to the Shadow RAM using the admin command. **/ static int i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer, u32 offset, u16 words, void *data, bool last_command) { … } /** * i40e_calc_nvm_checksum - Calculates and returns the checksum * @hw: pointer to hardware structure * @checksum: pointer to the checksum * * This function calculates SW Checksum that covers the whole 64kB shadow RAM * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD * is customer specific and unknown. Therefore, this function skips all maximum * possible size of VPD (1kB). **/ static int i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum) { … } /** * i40e_update_nvm_checksum - Updates the NVM checksum * @hw: pointer to hardware structure * * NVM ownership must be acquired before calling this function and released * on ARQ completion event reception by caller. * This function will commit SR to NVM. **/ int i40e_update_nvm_checksum(struct i40e_hw *hw) { … } /** * i40e_validate_nvm_checksum - Validate EEPROM checksum * @hw: pointer to hardware structure * @checksum: calculated checksum * * Performs checksum calculation and validates the NVM SW checksum. If the * caller does not need checksum, the value can be NULL. **/ int i40e_validate_nvm_checksum(struct i40e_hw *hw, u16 *checksum) { … } static u8 i40e_nvmupd_get_module(u32 val) { … } static inline u8 i40e_nvmupd_get_transaction(u32 val) { … } static inline u8 i40e_nvmupd_get_preservation_flags(u32 val) { … } static const char * const i40e_nvm_update_state_str[] = …; /** * i40e_nvmupd_validate_command - Validate given command * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @perrno: pointer to return error code * * Return one of the valid command types or I40E_NVMUPD_INVALID **/ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw, struct i40e_nvm_access *cmd, int *perrno) { … } /** * i40e_nvmupd_nvm_erase - Erase an NVM module * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @perrno: pointer to return error code * * module, offset, data_size and data are in cmd structure **/ static int i40e_nvmupd_nvm_erase(struct i40e_hw *hw, struct i40e_nvm_access *cmd, int *perrno) { … } /** * i40e_nvmupd_nvm_write - Write NVM * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @bytes: pointer to the data buffer * @perrno: pointer to return error code * * module, offset, data_size and data are in cmd structure **/ static int i40e_nvmupd_nvm_write(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *perrno) { … } /** * i40e_nvmupd_nvm_read - Read NVM * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @bytes: pointer to the data buffer * @perrno: pointer to return error code * * cmd structure contains identifiers and data buffer **/ static int i40e_nvmupd_nvm_read(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *perrno) { … } /** * i40e_nvmupd_exec_aq - Run an AQ command * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @bytes: pointer to the data buffer * @perrno: pointer to return error code * * cmd structure contains identifiers and data buffer **/ static int i40e_nvmupd_exec_aq(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *perrno) { … } /** * i40e_nvmupd_get_aq_result - Get the results from the previous exec_aq * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @bytes: pointer to the data buffer * @perrno: pointer to return error code * * cmd structure contains identifiers and data buffer **/ static int i40e_nvmupd_get_aq_result(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *perrno) { … } /** * i40e_nvmupd_get_aq_event - Get the Admin Queue event from previous exec_aq * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @bytes: pointer to the data buffer * @perrno: pointer to return error code * * cmd structure contains identifiers and data buffer **/ static int i40e_nvmupd_get_aq_event(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *perrno) { … } /** * i40e_nvmupd_state_init - Handle NVM update state Init * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @bytes: pointer to the data buffer * @perrno: pointer to return error code * * Process legitimate commands of the Init state and conditionally set next * state. Reject all other commands. **/ static int i40e_nvmupd_state_init(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *perrno) { … } /** * i40e_nvmupd_state_reading - Handle NVM update state Reading * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @bytes: pointer to the data buffer * @perrno: pointer to return error code * * NVM ownership is already held. Process legitimate commands and set any * change in state; reject all other commands. **/ static int i40e_nvmupd_state_reading(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *perrno) { … } /** * i40e_nvmupd_state_writing - Handle NVM update state Writing * @hw: pointer to hardware structure * @cmd: pointer to nvm update command buffer * @bytes: pointer to the data buffer * @perrno: pointer to return error code * * NVM ownership is already held. Process legitimate commands and set any * change in state; reject all other commands **/ static int i40e_nvmupd_state_writing(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *perrno) { … } /** * i40e_nvmupd_command - Process an NVM update command * @hw: pointer to hardware structure * @cmd: pointer to nvm update command * @bytes: pointer to the data buffer * @perrno: pointer to return error code * * Dispatches command depending on what update state is current **/ int i40e_nvmupd_command(struct i40e_hw *hw, struct i40e_nvm_access *cmd, u8 *bytes, int *perrno) { … } /** * i40e_nvmupd_clear_wait_state - clear wait state on hw * @hw: pointer to the hardware structure **/ void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw) { … } /** * i40e_nvmupd_check_wait_event - handle NVM update operation events * @hw: pointer to the hardware structure * @opcode: the event that just happened * @desc: AdminQ descriptor **/ void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode, struct i40e_aq_desc *desc) { … }