// SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 1999 - 2018 Intel Corporation. */ #include <linux/pci.h> #include <linux/delay.h> #include <linux/sched.h> #include "ixgbe.h" #include "ixgbe_phy.h" #include "ixgbe_mbx.h" #define IXGBE_82599_MAX_TX_QUEUES … #define IXGBE_82599_MAX_RX_QUEUES … #define IXGBE_82599_RAR_ENTRIES … #define IXGBE_82599_MC_TBL_SIZE … #define IXGBE_82599_VFT_TBL_SIZE … #define IXGBE_82599_RX_PB_SIZE … static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); static void ixgbe_set_hard_rate_select_speed(struct ixgbe_hw *, ixgbe_link_speed); static int ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg_wait_to_complete); static void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw); static int ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, bool autoneg_wait_to_complete); static int ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg_wait_to_complete); static int ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg_wait_to_complete); static int ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); static int ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data); static int ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 data); static int ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw); static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw); bool ixgbe_mng_enabled(struct ixgbe_hw *hw) { … } static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) { … } static int ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) { … } /** * prot_autoc_read_82599 - Hides MAC differences needed for AUTOC read * @hw: pointer to hardware structure * @locked: Return the if we locked for this read. * @reg_val: Value we read from AUTOC * * For this part (82599) we need to wrap read-modify-writes with a possible * FW/SW lock. It is assumed this lock will be freed with the next * prot_autoc_write_82599(). Note, that locked can only be true in cases * where this function doesn't return an error. **/ static int prot_autoc_read_82599(struct ixgbe_hw *hw, bool *locked, u32 *reg_val) { … } /** * prot_autoc_write_82599 - Hides MAC differences needed for AUTOC write * @hw: pointer to hardware structure * @autoc: value to write to AUTOC * @locked: bool to indicate whether the SW/FW lock was already taken by * previous proc_autoc_read_82599. * * This part (82599) may need to hold a the SW/FW lock around all writes to * AUTOC. Likewise after a write we need to do a pipeline reset. **/ static int prot_autoc_write_82599(struct ixgbe_hw *hw, u32 autoc, bool locked) { … } static int ixgbe_get_invariants_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_init_phy_ops_82599 - PHY/SFP specific init * @hw: pointer to hardware structure * * Initialize any function pointers that were not able to be * set during get_invariants because the PHY/SFP type was * not known. Perform the SFP init if necessary. * **/ static int ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_get_link_capabilities_82599 - Determines link capabilities * @hw: pointer to hardware structure * @speed: pointer to link speed * @autoneg: true when autoneg or autotry is enabled * * Determines the link capabilities by reading the AUTOC register. **/ static int ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *autoneg) { … } /** * ixgbe_get_media_type_82599 - Get media type * @hw: pointer to hardware structure * * Returns the media type (fiber, copper, backplane) **/ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_stop_mac_link_on_d3_82599 - Disables link on D3 * @hw: pointer to hardware structure * * Disables link, should be called during D3 power down sequence. * **/ static void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_start_mac_link_82599 - Setup MAC link settings * @hw: pointer to hardware structure * @autoneg_wait_to_complete: true when waiting for completion is needed * * Configures link settings based on values in the ixgbe_hw struct. * Restarts the link. Performs autonegotiation if needed. **/ static int ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, bool autoneg_wait_to_complete) { … } /** * ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser * @hw: pointer to hardware structure * * The base drivers may require better control over SFP+ module * PHY states. This includes selectively shutting down the Tx * laser on the PHY, effectively halting physical link. **/ static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { … } /** * ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser * @hw: pointer to hardware structure * * The base drivers may require better control over SFP+ module * PHY states. This includes selectively turning on the Tx * laser on the PHY, effectively starting physical link. **/ static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { … } /** * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser * @hw: pointer to hardware structure * * When the driver changes the link speeds that it can support, * it sets autotry_restart to true to indicate that we need to * initiate a new autotry session with the link partner. To do * so, we set the speed then disable and re-enable the tx laser, to * alert the link partner that it also needs to restart autotry on its * end. This is consistent with true clause 37 autoneg, which also * involves a loss of signal. **/ static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { … } /** * ixgbe_set_hard_rate_select_speed - Set module link speed * @hw: pointer to hardware structure * @speed: link speed to set * * Set module link speed via RS0/RS1 rate select pins. */ static void ixgbe_set_hard_rate_select_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed) { … } /** * ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed * @hw: pointer to hardware structure * @speed: new link speed * @autoneg_wait_to_complete: true when waiting for completion is needed * * Implements the Intel SmartSpeed algorithm. **/ static int ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg_wait_to_complete) { … } /** * ixgbe_setup_mac_link_82599 - Set MAC link speed * @hw: pointer to hardware structure * @speed: new link speed * @autoneg_wait_to_complete: true when waiting for completion is needed * * Set the link speed in the AUTOC register and restarts link. **/ static int ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg_wait_to_complete) { … } /** * ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field * @hw: pointer to hardware structure * @speed: new link speed * @autoneg_wait_to_complete: true if waiting is needed to complete * * Restarts link on PHY and MAC based on settings passed in. **/ static int ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg_wait_to_complete) { … } /** * ixgbe_reset_hw_82599 - Perform hardware reset * @hw: pointer to hardware structure * * Resets the hardware by resetting the transmit and receive units, masks * and clears all interrupts, perform a PHY reset, and perform a link (MAC) * reset. **/ static int ixgbe_reset_hw_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_fdir_check_cmd_complete - poll to check whether FDIRCMD is complete * @hw: pointer to hardware structure * @fdircmd: current value of FDIRCMD register */ static int ixgbe_fdir_check_cmd_complete(struct ixgbe_hw *hw, u32 *fdircmd) { … } /** * ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables. * @hw: pointer to hardware structure **/ int ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_fdir_enable_82599 - Initialize Flow Director control registers * @hw: pointer to hardware structure * @fdirctrl: value to write to flow director control register **/ static void ixgbe_fdir_enable_82599(struct ixgbe_hw *hw, u32 fdirctrl) { … } /** * ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters * @hw: pointer to hardware structure * @fdirctrl: value to write to flow director control register, initially * contains just the value of the Rx packet buffer allocation **/ int ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl) { … } /** * ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters * @hw: pointer to hardware structure * @fdirctrl: value to write to flow director control register, initially * contains just the value of the Rx packet buffer allocation **/ int ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 fdirctrl) { … } /* * These defines allow us to quickly generate all of the necessary instructions * in the function below by simply calling out IXGBE_COMPUTE_SIG_HASH_ITERATION * for values 0 through 15 */ #define IXGBE_ATR_COMMON_HASH_KEY … #define IXGBE_COMPUTE_SIG_HASH_ITERATION(_n) … /** * ixgbe_atr_compute_sig_hash_82599 - Compute the signature hash * @input: input bitstream to compute the hash on * @common: compressed common input dword * * This function is almost identical to the function above but contains * several optimizations such as unwinding all of the loops, letting the * compiler work out all of the conditional ifs since the keys are static * defines, and computing two keys at once since the hashed dword stream * will be the same for both keys. **/ static u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input, union ixgbe_atr_hash_dword common) { … } /** * ixgbe_fdir_add_signature_filter_82599 - Adds a signature hash filter * @hw: pointer to hardware structure * @input: unique input dword * @common: compressed common input dword * @queue: queue index to direct traffic to * * Note that the tunnel bit in input must not be set when the hardware * tunneling support does not exist. **/ int ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, union ixgbe_atr_hash_dword input, union ixgbe_atr_hash_dword common, u8 queue) { … } #define IXGBE_COMPUTE_BKT_HASH_ITERATION(_n) … /** * ixgbe_atr_compute_perfect_hash_82599 - Compute the perfect filter hash * @input: input bitstream to compute the hash on * @input_mask: mask for the input bitstream * * This function serves two main purposes. First it applies the input_mask * to the atr_input resulting in a cleaned up atr_input data stream. * Secondly it computes the hash and stores it in the bkt_hash field at * the end of the input byte stream. This way it will be available for * future use without needing to recompute the hash. **/ void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, union ixgbe_atr_input *input_mask) { … } /** * ixgbe_get_fdirtcpm_82599 - generate a tcp port from atr_input_masks * @input_mask: mask to be bit swapped * * The source and destination port masks for flow director are bit swapped * in that bit 15 effects bit 0, 14 effects 1, 13, 2 etc. In order to * generate a correctly swapped value we need to bit swap the mask and that * is what is accomplished by this function. **/ static u32 ixgbe_get_fdirtcpm_82599(union ixgbe_atr_input *input_mask) { … } /* * These two macros are meant to address the fact that we have registers * that are either all or in part big-endian. As a result on big-endian * systems we will end up byte swapping the value to little-endian before * it is byte swapped again and written to the hardware in the original * big-endian format. */ #define IXGBE_STORE_AS_BE32(_value) … #define IXGBE_WRITE_REG_BE32(a, reg, value) … #define IXGBE_STORE_AS_BE16(_value) … int ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, union ixgbe_atr_input *input_mask) { … } int ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw, union ixgbe_atr_input *input, u16 soft_id, u8 queue) { … } int ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, union ixgbe_atr_input *input, u16 soft_id) { … } /** * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register * @hw: pointer to hardware structure * @reg: analog register to read * @val: read value * * Performs read operation to Omer analog register specified. **/ static int ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val) { … } /** * ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register * @hw: pointer to hardware structure * @reg: atlas register to write * @val: value to write * * Performs write operation to Omer analog register specified. **/ static int ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val) { … } /** * ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx * @hw: pointer to hardware structure * * Starts the hardware using the generic start_hw function * and the generation start_hw function. * Then performs revision-specific operations, if any. **/ static int ixgbe_start_hw_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_identify_phy_82599 - Get physical layer module * @hw: pointer to hardware structure * * Determines the physical layer module found on the current adapter. * If PHY already detected, maintains current PHY type in hw struct, * otherwise executes the PHY detection routine. **/ static int ixgbe_identify_phy_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599 * @hw: pointer to hardware structure * @regval: register value to write to RXCTRL * * Enables the Rx DMA unit for 82599 **/ static int ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval) { … } /** * ixgbe_verify_fw_version_82599 - verify fw version for 82599 * @hw: pointer to hardware structure * * Verifies that installed the firmware version is 0.6 or higher * for SFI devices. All 82599 SFI devices should have version 0.6 or higher. * * Return: -EACCES if the FW is not present or if the FW version is * not supported. **/ static int ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state. * @hw: pointer to hardware structure * * Returns true if the LESM FW module is present and enabled. Otherwise * returns false. Smart Speed must be disabled if LESM FW module is enabled. **/ static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_read_eeprom_buffer_82599 - Read EEPROM word(s) using * fastest available method * * @hw: pointer to hardware structure * @offset: offset of word in EEPROM to read * @words: number of words * @data: word(s) read from the EEPROM * * Retrieves 16 bit word(s) read from EEPROM **/ static int ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset, u16 words, u16 *data) { … } /** * ixgbe_read_eeprom_82599 - Read EEPROM word using * fastest available method * * @hw: pointer to hardware structure * @offset: offset of word in the EEPROM to read * @data: word read from the EEPROM * * Reads a 16 bit word from the EEPROM **/ static int ixgbe_read_eeprom_82599(struct ixgbe_hw *hw, u16 offset, u16 *data) { … } /** * ixgbe_reset_pipeline_82599 - perform pipeline reset * * @hw: pointer to hardware structure * * Reset pipeline by asserting Restart_AN together with LMS change to ensure * full pipeline reset. Note - We must hold the SW/FW semaphore before writing * to AUTOC, so this function assumes the semaphore is held. **/ static int ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw) { … } /** * ixgbe_read_i2c_byte_82599 - Reads 8 bit word over I2C * @hw: pointer to hardware structure * @byte_offset: byte offset to read * @dev_addr: address to read from * @data: value read * * Performs byte read operation to SFP module's EEPROM over I2C interface at * a specified device address. **/ static int ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data) { … } /** * ixgbe_write_i2c_byte_82599 - Writes 8 bit word over I2C * @hw: pointer to hardware structure * @byte_offset: byte offset to write * @dev_addr: address to write to * @data: value to write * * Performs byte write operation to SFP module's EEPROM over I2C interface at * a specified device address. **/ static int ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 data) { … } static const struct ixgbe_mac_operations mac_ops_82599 = …; static const struct ixgbe_eeprom_operations eeprom_ops_82599 = …; static const struct ixgbe_phy_operations phy_ops_82599 = …; const struct ixgbe_info ixgbe_82599_info = …;