From patchwork Fri May 3 13:57:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Burakov, Anatoly" X-Patchwork-Id: 139855 Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 0FB4E43F76; Fri, 3 May 2024 16:01:45 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 86A1C41104; Fri, 3 May 2024 15:59:20 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) by mails.dpdk.org (Postfix) with ESMTP id 2896D4064A for ; Fri, 3 May 2024 15:59:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1714744758; x=1746280758; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tdRFVxmHRaMb/Zr4Y7K4k+qKm/dpQbPQI99wkaffQfQ=; b=frhh6GNCo1iTwZHlDGQtzjbEg5DEgm4FsShwHzl0FHi+6Blly9Na0R13 +b9+FtZKzYl83OSUzxFbHicMROHjxNFNIQDBl9O6x78Ezw1PmGH+Y27b3 AUWYbN2iv+ID4KpafxYV3NRY2xkcSvFg5ssFfgqov2XeW+1X8gNepFmCz 3h49cfuJTT64ag0TVm7bfDdjTm9a4XSSaGHovFP3q+qMtKaiQ7DlqJRuo S15PcbS2aPGrRdnU3Kn8jsLkTEF0/7K/rd0RxIhD9fdgZp4gPyraH8Wq6 qH2nZmFvkneM40VpoU4J+jPSVE52qDfHazNW1d4EcbSypCGQl/tfAKwzO g==; X-CSE-ConnectionGUID: rz4IIWapQoawGH2e9ShAGw== X-CSE-MsgGUID: HDRp7CmmTe68QcoI42ziCg== X-IronPort-AV: E=McAfee;i="6600,9927,11063"; a="10714989" X-IronPort-AV: E=Sophos;i="6.07,251,1708416000"; d="scan'208";a="10714989" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 May 2024 06:59:17 -0700 X-CSE-ConnectionGUID: GcwmhRi5QQCxvM81FKY0Cg== X-CSE-MsgGUID: RTtru96FQ9m4Sl/lP5Ve7Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,251,1708416000"; d="scan'208";a="50642075" Received: from silpixa00401119.ir.intel.com ([10.55.129.167]) by fmviesa002.fm.intel.com with ESMTP; 03 May 2024 06:59:16 -0700 From: Anatoly Burakov To: dev@dpdk.org Cc: bruce.richardson@intel.com, vladimir.medvedkin@intel.com Subject: [PATCH v2 27/27] net/ixgbe/base: add various miscellaneous features Date: Fri, 3 May 2024 14:57:58 +0100 Message-ID: <93795571c98db29f975ee12675246b5169c7082e.1714744629.git.anatoly.burakov@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add various features to the base driver that are not specifically about packet I/O but are present in the shared code snapshot. Also, update documentation to reflect new base code snapshot version, as well as document new hardware support. Signed-off-by: Anatoly Burakov --- doc/guides/rel_notes/release_24_07.rst | 4 + drivers/net/ixgbe/base/README | 6 +- drivers/net/ixgbe/base/ixgbe_e610.c | 1089 ++++++++++++++++++++++ drivers/net/ixgbe/base/ixgbe_e610.h | 58 ++ drivers/net/ixgbe/base/ixgbe_type_e610.h | 402 ++++++++ 5 files changed, 1557 insertions(+), 2 deletions(-) diff --git a/doc/guides/rel_notes/release_24_07.rst b/doc/guides/rel_notes/release_24_07.rst index a69f24cf99..9499352c46 100644 --- a/doc/guides/rel_notes/release_24_07.rst +++ b/doc/guides/rel_notes/release_24_07.rst @@ -55,6 +55,10 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Updated IXGBE base code.** + + * Updated shared code to more recent version. + * Added support for E610 device family. Removed Items ------------- diff --git a/drivers/net/ixgbe/base/README b/drivers/net/ixgbe/base/README index 2c74693924..98353ba26f 100644 --- a/drivers/net/ixgbe/base/README +++ b/drivers/net/ixgbe/base/README @@ -1,12 +1,12 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2020 Intel Corporation + * Copyright(c) 2010-2024 Intel Corporation */ Intel® IXGBE driver =================== This directory contains source code of FreeBSD ixgbe driver of version -not-released-cid-ixgbe.2020.06.09.tar.gz released by the team which develop +not-released-cid-ixgbe.2024.04.24.tar.gz released by the team which develop basic drivers for any ixgbe NIC. The sub-directory of base/ contains the original source package. This driver is valid for the product(s) listed below @@ -24,6 +24,7 @@ This driver is valid for the product(s) listed below * Intel® Ethernet Server Adapter X520 Series * Intel® Ethernet Server Adapter X520-T2 * Intel® Ethernet Controller X550 Series +* Intel® Ethernet Controller E610 Series Updating the driver =================== @@ -32,3 +33,4 @@ NOTE: The source code in this directory should not be modified apart from the following file(s): ixgbe_osdep.h + ixgbe_osdep.c diff --git a/drivers/net/ixgbe/base/ixgbe_e610.c b/drivers/net/ixgbe/base/ixgbe_e610.c index 6618c21cef..ae9bc70de8 100644 --- a/drivers/net/ixgbe/base/ixgbe_e610.c +++ b/drivers/net/ixgbe/base/ixgbe_e610.c @@ -1207,6 +1207,25 @@ s32 ixgbe_discover_func_caps(struct ixgbe_hw *hw, return status; } +/** + * ixgbe_get_caps - get info about the HW + * @hw: pointer to the hardware structure + * + * Retrieve both device and function capabilities. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_caps(struct ixgbe_hw *hw) +{ + s32 status; + + status = ixgbe_discover_dev_caps(hw, &hw->dev_caps); + if (status) + return status; + + return ixgbe_discover_func_caps(hw, &hw->func_caps); +} + /** * ixgbe_aci_disable_rxen - disable RX * @hw: pointer to the HW struct @@ -1275,6 +1294,45 @@ s32 ixgbe_aci_get_phy_caps(struct ixgbe_hw *hw, bool qual_mods, u8 report_mode, return status; } +/** + * ixgbe_phy_caps_equals_cfg - check if capabilities match the PHY config + * @phy_caps: PHY capabilities + * @phy_cfg: PHY configuration + * + * Helper function to determine if PHY capabilities match PHY + * configuration + * + * Return: true if PHY capabilities match PHY configuration. + */ +bool +ixgbe_phy_caps_equals_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *phy_caps, + struct ixgbe_aci_cmd_set_phy_cfg_data *phy_cfg) +{ + u8 caps_mask, cfg_mask; + + if (!phy_caps || !phy_cfg) + return false; + + /* These bits are not common between capabilities and configuration. + * Do not use them to determine equality. + */ + caps_mask = IXGBE_ACI_PHY_CAPS_MASK & ~(IXGBE_ACI_PHY_AN_MODE | + IXGBE_ACI_PHY_EN_MOD_QUAL); + cfg_mask = IXGBE_ACI_PHY_ENA_VALID_MASK & + ~IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT; + + if (phy_caps->phy_type_low != phy_cfg->phy_type_low || + phy_caps->phy_type_high != phy_cfg->phy_type_high || + ((phy_caps->caps & caps_mask) != (phy_cfg->caps & cfg_mask)) || + phy_caps->low_power_ctrl_an != phy_cfg->low_power_ctrl_an || + phy_caps->eee_cap != phy_cfg->eee_cap || + phy_caps->eeer_value != phy_cfg->eeer_value || + phy_caps->link_fec_options != phy_cfg->link_fec_opt) + return false; + + return true; +} + /** * ixgbe_copy_phy_caps_to_cfg - Copy PHY ability data to configuration data * @caps: PHY ability structure to copy data from @@ -1726,6 +1784,239 @@ s32 ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw, return IXGBE_SUCCESS; } +/** + * ixgbe_aci_get_netlist_node_pin - get a node pin handle + * @hw: pointer to the hw struct + * @cmd: get_link_topo_pin AQ structure + * @node_handle: output node handle parameter if node found + * + * Get the netlist node pin and assign it to + * the provided handle using ACI command (0x06E1). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_netlist_node_pin(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_get_link_topo_pin *cmd, + u16 *node_handle) +{ + struct ixgbe_aci_desc desc; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo_pin); + desc.params.get_link_topo_pin = *cmd; + + if (ixgbe_aci_send_cmd(hw, &desc, NULL, 0)) + return IXGBE_ERR_NOT_SUPPORTED; + + if (node_handle) + *node_handle = + IXGBE_LE16_TO_CPU(desc.params.get_link_topo_pin.addr.handle); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_find_netlist_node - find a node handle + * @hw: pointer to the hw struct + * @node_type_ctx: type of netlist node to look for + * @node_part_number: node part number to look for + * @node_handle: output parameter if node found - optional + * + * Find and return the node handle for a given node type and part number in the + * netlist. When found IXGBE_SUCCESS is returned, IXGBE_ERR_NOT_SUPPORTED + * otherwise. If @node_handle provided, it would be set to found node handle. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_find_netlist_node(struct ixgbe_hw *hw, u8 node_type_ctx, + u8 node_part_number, u16 *node_handle) +{ + struct ixgbe_aci_cmd_get_link_topo cmd; + u8 rec_node_part_number; + u16 rec_node_handle; + s32 status; + u8 idx; + + for (idx = 0; idx < IXGBE_MAX_NETLIST_SIZE; idx++) { + memset(&cmd, 0, sizeof(cmd)); + + cmd.addr.topo_params.node_type_ctx = + (node_type_ctx << IXGBE_ACI_LINK_TOPO_NODE_TYPE_S); + cmd.addr.topo_params.index = idx; + + status = ixgbe_aci_get_netlist_node(hw, &cmd, + &rec_node_part_number, + &rec_node_handle); + if (status) + return status; + + if (rec_node_part_number == node_part_number) { + if (node_handle) + *node_handle = rec_node_handle; + return IXGBE_SUCCESS; + } + } + + return IXGBE_ERR_NOT_SUPPORTED; +} + +/** + * ixgbe_aci_read_i2c - read I2C register value + * @hw: pointer to the hw struct + * @topo_addr: topology address for a device to communicate with + * @bus_addr: 7-bit I2C bus address + * @addr: I2C memory address (I2C offset) with up to 16 bits + * @params: I2C parameters: bit [7] - Repeated start, + * bits [6:5] data offset size, + * bit [4] - I2C address type, bits [3:0] - data size + * to read (0-16 bytes) + * @data: pointer to data (0 to 16 bytes) to be read from the I2C device + * + * Read the value of the I2C pin register using ACI command (0x06E2). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_read_i2c(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_addr topo_addr, + u16 bus_addr, __le16 addr, u8 params, u8 *data) +{ + struct ixgbe_aci_desc desc = { 0 }; + struct ixgbe_aci_cmd_i2c *cmd; + u8 data_size; + s32 status; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_read_i2c); + cmd = &desc.params.read_write_i2c; + + if (!data) + return IXGBE_ERR_PARAM; + + data_size = (params & IXGBE_ACI_I2C_DATA_SIZE_M) >> + IXGBE_ACI_I2C_DATA_SIZE_S; + + cmd->i2c_bus_addr = IXGBE_CPU_TO_LE16(bus_addr); + cmd->topo_addr = topo_addr; + cmd->i2c_params = params; + cmd->i2c_addr = addr; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (!status) { + struct ixgbe_aci_cmd_read_i2c_resp *resp; + u8 i; + + resp = &desc.params.read_i2c_resp; + for (i = 0; i < data_size; i++) { + *data = resp->i2c_data[i]; + data++; + } + } + + return status; +} + +/** + * ixgbe_aci_write_i2c - write a value to I2C register + * @hw: pointer to the hw struct + * @topo_addr: topology address for a device to communicate with + * @bus_addr: 7-bit I2C bus address + * @addr: I2C memory address (I2C offset) with up to 16 bits + * @params: I2C parameters: bit [4] - I2C address type, bits [3:0] - data size + * to write (0-7 bytes) + * @data: pointer to data (0 to 4 bytes) to be written to the I2C device + * + * Write a value to the I2C pin register using ACI command (0x06E3). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_write_i2c(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_addr topo_addr, + u16 bus_addr, __le16 addr, u8 params, u8 *data) +{ + struct ixgbe_aci_desc desc = { 0 }; + struct ixgbe_aci_cmd_i2c *cmd; + u8 i, data_size; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_write_i2c); + cmd = &desc.params.read_write_i2c; + + data_size = (params & IXGBE_ACI_I2C_DATA_SIZE_M) >> + IXGBE_ACI_I2C_DATA_SIZE_S; + + /* data_size limited to 4 */ + if (data_size > 4) + return IXGBE_ERR_PARAM; + + cmd->i2c_bus_addr = IXGBE_CPU_TO_LE16(bus_addr); + cmd->topo_addr = topo_addr; + cmd->i2c_params = params; + cmd->i2c_addr = addr; + + for (i = 0; i < data_size; i++) { + cmd->i2c_data[i] = *data; + data++; + } + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_aci_set_gpio - set GPIO pin state + * @hw: pointer to the hw struct + * @gpio_ctrl_handle: GPIO controller node handle + * @pin_idx: IO Number of the GPIO that needs to be set + * @value: SW provide IO value to set in the LSB + * + * Set the GPIO pin state that is a part of the topology + * using ACI command (0x06EC). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_set_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, + bool value) +{ + struct ixgbe_aci_cmd_gpio *cmd; + struct ixgbe_aci_desc desc; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_gpio); + cmd = &desc.params.read_write_gpio; + cmd->gpio_ctrl_handle = IXGBE_CPU_TO_LE16(gpio_ctrl_handle); + cmd->gpio_num = pin_idx; + cmd->gpio_val = value ? 1 : 0; + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_aci_get_gpio - get GPIO pin state + * @hw: pointer to the hw struct + * @gpio_ctrl_handle: GPIO controller node handle + * @pin_idx: IO Number of the GPIO that needs to be set + * @value: IO value read + * + * Get the value of a GPIO signal which is part of the topology + * using ACI command (0x06ED). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, + bool *value) +{ + struct ixgbe_aci_cmd_gpio *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_gpio); + cmd = &desc.params.read_write_gpio; + cmd->gpio_ctrl_handle = IXGBE_CPU_TO_LE16(gpio_ctrl_handle); + cmd->gpio_num = pin_idx; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (status) + return status; + + *value = !!cmd->gpio_val; + return IXGBE_SUCCESS; +} + /** * ixgbe_aci_sff_eeprom - read/write SFF EEPROM * @hw: pointer to the HW struct @@ -1772,6 +2063,72 @@ s32 ixgbe_aci_sff_eeprom(struct ixgbe_hw *hw, u16 lport, u8 bus_addr, return status; } +/** + * ixgbe_aci_prog_topo_dev_nvm - program Topology Device NVM + * @hw: pointer to the hardware structure + * @topo_params: pointer to structure storing topology parameters for a device + * + * Program Topology Device NVM using ACI command (0x06F2). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_prog_topo_dev_nvm(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_params *topo_params) +{ + struct ixgbe_aci_cmd_prog_topo_dev_nvm *cmd; + struct ixgbe_aci_desc desc; + + cmd = &desc.params.prog_topo_dev_nvm; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_prog_topo_dev_nvm); + + memcpy(&cmd->topo_params, topo_params, sizeof(*topo_params)); + + return ixgbe_aci_send_cmd(hw, &desc, NULL, 0); +} + +/** + * ixgbe_aci_read_topo_dev_nvm - read Topology Device NVM + * @hw: pointer to the hardware structure + * @topo_params: pointer to structure storing topology parameters for a device + * @start_address: byte offset in the topology device NVM + * @data: pointer to data buffer + * @data_size: number of bytes to be read from the topology device NVM + * Read Topology Device NVM (0x06F3) + * + * Read Topology of Device NVM using ACI command (0x06F3). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_read_topo_dev_nvm(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_params *topo_params, + u32 start_address, u8 *data, u8 data_size) +{ + struct ixgbe_aci_cmd_read_topo_dev_nvm *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + if (!data || data_size == 0 || + data_size > IXGBE_ACI_READ_TOPO_DEV_NVM_DATA_READ_SIZE) + return IXGBE_ERR_PARAM; + + cmd = &desc.params.read_topo_dev_nvm; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_read_topo_dev_nvm); + + desc.datalen = IXGBE_CPU_TO_LE16(data_size); + memcpy(&cmd->topo_params, topo_params, sizeof(*topo_params)); + cmd->start_address = IXGBE_CPU_TO_LE32(start_address); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (status) + return status; + + memcpy(data, cmd->data_read, data_size); + + return IXGBE_SUCCESS; +} + /** * ixgbe_acquire_nvm - Generic request for acquiring the NVM ownership * @hw: pointer to the HW structure @@ -1896,6 +2253,37 @@ s32 ixgbe_nvm_validate_checksum(struct ixgbe_hw *hw) return status; } +/** + * ixgbe_nvm_recalculate_checksum - recalculate checksum + * @hw: pointer to the HW struct + * + * Recalculate NVM PFA checksum using ACI command (0x0706). + * The function acquires and then releases the NVM ownership. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_nvm_recalculate_checksum(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_cmd_nvm_checksum *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + cmd = &desc.params.nvm_checksum; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_checksum); + cmd->flags = IXGBE_ACI_NVM_CHECKSUM_RECALC; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + ixgbe_release_nvm(hw); + + return status; +} + /** * ixgbe_get_flash_bank_offset - Get offset into requested flash bank * @hw: pointer to the HW structure @@ -2100,6 +2488,60 @@ static s32 ixgbe_read_nvm_sr_copy(struct ixgbe_hw *hw, return ixgbe_read_nvm_module(hw, bank, hdr_len + offset, data); } +/** + * ixgbe_get_nvm_minsrevs - Get the minsrevs values from flash + * @hw: pointer to the HW struct + * @minsrevs: structure to store NVM and OROM minsrev values + * + * Read the Minimum Security Revision TLV and extract + * the revision values from the flash image + * into a readable structure for processing. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_nvm_minsrevs(struct ixgbe_hw *hw, + struct ixgbe_minsrev_info *minsrevs) +{ + struct ixgbe_aci_cmd_nvm_minsrev data; + s32 status; + u16 valid; + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + status = ixgbe_aci_read_nvm(hw, IXGBE_ACI_NVM_MINSREV_MOD_ID, + 0, sizeof(data), &data, + true, false); + + ixgbe_release_nvm(hw); + + if (status) + return status; + + valid = IXGBE_LE16_TO_CPU(data.validity); + + /* Extract NVM minimum security revision */ + if (valid & IXGBE_ACI_NVM_MINSREV_NVM_VALID) { + u16 minsrev_l = IXGBE_LE16_TO_CPU(data.nvm_minsrev_l); + u16 minsrev_h = IXGBE_LE16_TO_CPU(data.nvm_minsrev_h); + + minsrevs->nvm = minsrev_h << 16 | minsrev_l; + minsrevs->nvm_valid = true; + } + + /* Extract the OROM minimum security revision */ + if (valid & IXGBE_ACI_NVM_MINSREV_OROM_VALID) { + u16 minsrev_l = IXGBE_LE16_TO_CPU(data.orom_minsrev_l); + u16 minsrev_h = IXGBE_LE16_TO_CPU(data.orom_minsrev_h); + + minsrevs->orom = minsrev_h << 16 | minsrev_l; + minsrevs->orom_valid = true; + } + + return IXGBE_SUCCESS; +} + /** * ixgbe_get_nvm_srev - Read the security revision from the NVM CSS header * @hw: pointer to the HW struct @@ -2175,6 +2617,22 @@ static s32 ixgbe_get_nvm_ver_info(struct ixgbe_hw *hw, return IXGBE_SUCCESS; } +/** + * ixgbe_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. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_get_inactive_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm) +{ + return ixgbe_get_nvm_ver_info(hw, IXGBE_INACTIVE_FLASH_BANK, nvm); +} + /** * ixgbe_get_active_nvm_ver - Read Option ROM version from the active bank * @hw: pointer to the HW structure @@ -2190,6 +2648,308 @@ s32 ixgbe_get_active_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm) return ixgbe_get_nvm_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK, nvm); } +/** + * ixgbe_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. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_read_sr_pointer(struct ixgbe_hw *hw, u16 offset, u32 *pointer) +{ + s32 status; + u16 value; + + status = ixgbe_read_ee_aci_E610(hw, offset, &value); + if (status) + return status; + + /* Determine if the pointer is in 4KB or word units */ + if (value & IXGBE_SR_NVM_PTR_4KB_UNITS) + *pointer = (value & ~IXGBE_SR_NVM_PTR_4KB_UNITS) * 4 * 1024; + else + *pointer = value * 2; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_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. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_read_sr_area_size(struct ixgbe_hw *hw, u16 offset, u32 *size) +{ + s32 status; + u16 value; + + status = ixgbe_read_ee_aci_E610(hw, offset, &value); + if (status) + return status; + + /* Area sizes are always specified in 4KB units */ + *size = value * 4 * 1024; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_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. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_discover_flash_size(struct ixgbe_hw *hw) +{ + u32 min_size = 0, max_size = IXGBE_ACI_NVM_MAX_OFFSET + 1; + s32 status; + + status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ); + if (status) + return status; + + while ((max_size - min_size) > 1) { + u32 offset = (max_size + min_size) / 2; + u32 len = 1; + u8 data; + + status = ixgbe_read_flat_nvm(hw, offset, &len, &data, false); + if (status == IXGBE_ERR_ACI_ERROR && + hw->aci.last_status == IXGBE_ACI_RC_EINVAL) { + status = IXGBE_SUCCESS; + max_size = offset; + } else if (!status) { + min_size = offset; + } else { + /* an unexpected error occurred */ + goto err_read_flat_nvm; + } + } + + hw->flash.flash_size = max_size; + +err_read_flat_nvm: + ixgbe_release_nvm(hw); + + return status; +} + +/** + * ixgbe_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 ixgbe_flash_info + * structure for later use in order to calculate the correct offset to read + * from the active module. + * + * Return: the exit code of the operation. + */ +static s32 ixgbe_determine_active_flash_banks(struct ixgbe_hw *hw) +{ + struct ixgbe_bank_info *banks = &hw->flash.banks; + u16 ctrl_word; + s32 status; + + status = ixgbe_read_ee_aci_E610(hw, E610_SR_NVM_CTRL_WORD, &ctrl_word); + if (status) { + return status; + } + + /* Check that the control word indicates validity */ + if ((ctrl_word & IXGBE_SR_CTRL_WORD_1_M) >> IXGBE_SR_CTRL_WORD_1_S != + IXGBE_SR_CTRL_WORD_VALID) { + return IXGBE_ERR_CONFIG; + } + + if (!(ctrl_word & IXGBE_SR_CTRL_WORD_NVM_BANK)) + banks->nvm_bank = IXGBE_1ST_FLASH_BANK; + else + banks->nvm_bank = IXGBE_2ND_FLASH_BANK; + + if (!(ctrl_word & IXGBE_SR_CTRL_WORD_OROM_BANK)) + banks->orom_bank = IXGBE_1ST_FLASH_BANK; + else + banks->orom_bank = IXGBE_2ND_FLASH_BANK; + + if (!(ctrl_word & IXGBE_SR_CTRL_WORD_NETLIST_BANK)) + banks->netlist_bank = IXGBE_1ST_FLASH_BANK; + else + banks->netlist_bank = IXGBE_2ND_FLASH_BANK; + + status = ixgbe_read_sr_pointer(hw, E610_SR_1ST_NVM_BANK_PTR, + &banks->nvm_ptr); + if (status) { + return status; + } + + status = ixgbe_read_sr_area_size(hw, E610_SR_NVM_BANK_SIZE, + &banks->nvm_size); + if (status) { + return status; + } + + status = ixgbe_read_sr_pointer(hw, E610_SR_1ST_OROM_BANK_PTR, + &banks->orom_ptr); + if (status) { + return status; + } + + status = ixgbe_read_sr_area_size(hw, E610_SR_OROM_BANK_SIZE, + &banks->orom_size); + if (status) { + return status; + } + + status = ixgbe_read_sr_pointer(hw, E610_SR_NETLIST_BANK_PTR, + &banks->netlist_ptr); + if (status) { + return status; + } + + status = ixgbe_read_sr_area_size(hw, E610_SR_NETLIST_BANK_SIZE, + &banks->netlist_size); + if (status) { + return status; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_init_nvm - initializes NVM setting + * @hw: pointer to the HW struct + * + * Read and populate NVM settings such as Shadow RAM size, + * max_timeout, and blank_nvm_mode + * + * Return: the exit code of the operation. + */ +s32 ixgbe_init_nvm(struct ixgbe_hw *hw) +{ + struct ixgbe_flash_info *flash = &hw->flash; + u32 fla, gens_stat, status; + u8 sr_size; + + /* The SR size is stored regardless of the NVM programming mode + * as the blank mode may be used in the factory line. + */ + gens_stat = IXGBE_READ_REG(hw, GLNVM_GENS); + sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S; + + /* Switching to words (sr_size contains power of 2) */ + flash->sr_words = BIT(sr_size) * IXGBE_SR_WORDS_IN_1KB; + + /* Check if we are in the normal or blank NVM programming mode */ + fla = IXGBE_READ_REG(hw, GLNVM_FLA); + if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */ + flash->blank_nvm_mode = false; + } else { + /* Blank programming mode */ + flash->blank_nvm_mode = true; + return IXGBE_ERR_NVM_BLANK_MODE; + } + + status = ixgbe_discover_flash_size(hw); + if (status) { + return status; + } + + status = ixgbe_determine_active_flash_banks(hw); + if (status) { + return status; + } + + status = ixgbe_get_nvm_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK, + &flash->nvm); + if (status) { + return status; + } + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_sanitize_operate - Clear the user data + * @hw: pointer to the HW struct + * + * Clear user data from NVM using ACI command (0x070C). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_sanitize_operate(struct ixgbe_hw *hw) +{ + s32 status; + u8 values; + + u8 cmd_flags = IXGBE_ACI_SANITIZE_REQ_OPERATE | + IXGBE_ACI_SANITIZE_OPERATE_SUBJECT_CLEAR; + + status = ixgbe_sanitize_nvm(hw, cmd_flags, &values); + if (status) + return status; + if ((!(values & IXGBE_ACI_SANITIZE_OPERATE_HOST_CLEAN_DONE) && + !(values & IXGBE_ACI_SANITIZE_OPERATE_BMC_CLEAN_DONE)) || + ((values & IXGBE_ACI_SANITIZE_OPERATE_HOST_CLEAN_DONE) && + !(values & IXGBE_ACI_SANITIZE_OPERATE_HOST_CLEAN_SUCCESS)) || + ((values & IXGBE_ACI_SANITIZE_OPERATE_BMC_CLEAN_DONE) && + !(values & IXGBE_ACI_SANITIZE_OPERATE_BMC_CLEAN_SUCCESS))) + return IXGBE_ERR_ACI_ERROR; + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_sanitize_nvm - Sanitize NVM + * @hw: pointer to the HW struct + * @cmd_flags: flag to the ACI command + * @values: values returned from the command + * + * Sanitize NVM using ACI command (0x070C). + * + * Return: the exit code of the operation. + */ +s32 ixgbe_sanitize_nvm(struct ixgbe_hw *hw, u8 cmd_flags, u8 *values) +{ + struct ixgbe_aci_desc desc; + struct ixgbe_aci_cmd_nvm_sanitization *cmd; + s32 status; + + cmd = &desc.params.nvm_sanitization; + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_sanitization); + cmd->cmd_flags = cmd_flags; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (values) + *values = cmd->values; + + return status; +} + /** * ixgbe_read_sr_word_aci - Reads Shadow RAM via ACI * @hw: pointer to the HW structure @@ -2310,6 +3070,335 @@ s32 ixgbe_read_flat_nvm(struct ixgbe_hw *hw, u32 offset, u32 *length, return status; } +/** + * ixgbe_aci_alternate_write - write to alternate structure + * @hw: pointer to the hardware structure + * @reg_addr0: address of first dword to be written + * @reg_val0: value to be written under 'reg_addr0' + * @reg_addr1: address of second dword to be written + * @reg_val1: value to be written under 'reg_addr1' + * + * Write one or two dwords to alternate structure using ACI command (0x0900). + * Fields are indicated by 'reg_addr0' and 'reg_addr1' register numbers. + * + * Return: 0 on success and error code on failure. + */ +s32 ixgbe_aci_alternate_write(struct ixgbe_hw *hw, u32 reg_addr0, + u32 reg_val0, u32 reg_addr1, u32 reg_val1) +{ + struct ixgbe_aci_cmd_read_write_alt_direct *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.read_write_alt_direct; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_write_alt_direct); + cmd->dword0_addr = IXGBE_CPU_TO_LE32(reg_addr0); + cmd->dword1_addr = IXGBE_CPU_TO_LE32(reg_addr1); + cmd->dword0_value = IXGBE_CPU_TO_LE32(reg_val0); + cmd->dword1_value = IXGBE_CPU_TO_LE32(reg_val1); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + return status; +} + +/** + * ixgbe_aci_alternate_read - read from alternate structure + * @hw: pointer to the hardware structure + * @reg_addr0: address of first dword to be read + * @reg_val0: pointer for data read from 'reg_addr0' + * @reg_addr1: address of second dword to be read + * @reg_val1: pointer for data read from 'reg_addr1' + * + * Read one or two dwords from alternate structure using ACI command (0x0902). + * Fields are indicated by 'reg_addr0' and 'reg_addr1' register numbers. + * If 'reg_val1' pointer is not passed then only register at 'reg_addr0' + * is read. + * + * Return: 0 on success and error code on failure. + */ +s32 ixgbe_aci_alternate_read(struct ixgbe_hw *hw, u32 reg_addr0, + u32 *reg_val0, u32 reg_addr1, u32 *reg_val1) +{ + struct ixgbe_aci_cmd_read_write_alt_direct *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.read_write_alt_direct; + + if (!reg_val0) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_read_alt_direct); + cmd->dword0_addr = IXGBE_CPU_TO_LE32(reg_addr0); + cmd->dword1_addr = IXGBE_CPU_TO_LE32(reg_addr1); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + if (status == IXGBE_SUCCESS) { + *reg_val0 = IXGBE_LE32_TO_CPU(cmd->dword0_value); + + if (reg_val1) + *reg_val1 = IXGBE_LE32_TO_CPU(cmd->dword1_value); + } + + return status; +} + +/** + * ixgbe_aci_alternate_write_done - check if writing to alternate structure + * is done + * @hw: pointer to the HW structure. + * @bios_mode: indicates whether the command is executed by UEFI or legacy BIOS + * @reset_needed: indicates the SW should trigger GLOBAL reset + * + * Indicates to the FW that alternate structures have been changed. + * + * Return: 0 on success and error code on failure. + */ +s32 ixgbe_aci_alternate_write_done(struct ixgbe_hw *hw, u8 bios_mode, + bool *reset_needed) +{ + struct ixgbe_aci_cmd_done_alt_write *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.done_alt_write; + + if (!reset_needed) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_done_alt_write); + cmd->flags = bios_mode; + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + if (!status) + *reset_needed = (IXGBE_LE16_TO_CPU(cmd->flags) & + IXGBE_ACI_RESP_RESET_NEEDED) != 0; + + return status; +} + +/** + * ixgbe_aci_alternate_clear - clear alternate structure + * @hw: pointer to the HW structure. + * + * Clear the alternate structures of the port from which the function + * is called. + * + * Return: 0 on success and error code on failure. + */ +s32 ixgbe_aci_alternate_clear(struct ixgbe_hw *hw) +{ + struct ixgbe_aci_desc desc; + s32 status; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, + ixgbe_aci_opc_clear_port_alt_write); + + status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0); + + return status; +} + +/** + * ixgbe_aci_get_internal_data - get internal FW/HW data + * @hw: pointer to the hardware structure + * @cluster_id: specific cluster to dump + * @table_id: table ID within cluster + * @start: index of line in the block to read + * @buf: dump buffer + * @buf_size: dump buffer size + * @ret_buf_size: return buffer size (returned by FW) + * @ret_next_cluster: next cluster to read (returned by FW) + * @ret_next_table: next block to read (returned by FW) + * @ret_next_index: next index to read (returned by FW) + * + * Get internal FW/HW data using ACI command (0xFF08) for debug purposes. + * + * Return: the exit code of the operation. + */ +s32 ixgbe_aci_get_internal_data(struct ixgbe_hw *hw, u16 cluster_id, + u16 table_id, u32 start, void *buf, + u16 buf_size, u16 *ret_buf_size, + u16 *ret_next_cluster, u16 *ret_next_table, + u32 *ret_next_index) +{ + struct ixgbe_aci_cmd_debug_dump_internals *cmd; + struct ixgbe_aci_desc desc; + s32 status; + + cmd = &desc.params.debug_dump; + + if (buf_size == 0 || !buf) + return IXGBE_ERR_PARAM; + + ixgbe_fill_dflt_direct_cmd_desc(&desc, + ixgbe_aci_opc_debug_dump_internals); + + cmd->cluster_id = IXGBE_CPU_TO_LE16(cluster_id); + cmd->table_id = IXGBE_CPU_TO_LE16(table_id); + cmd->idx = IXGBE_CPU_TO_LE32(start); + + status = ixgbe_aci_send_cmd(hw, &desc, buf, buf_size); + + if (!status) { + if (ret_buf_size) + *ret_buf_size = IXGBE_LE16_TO_CPU(desc.datalen); + if (ret_next_cluster) + *ret_next_cluster = IXGBE_LE16_TO_CPU(cmd->cluster_id); + if (ret_next_table) + *ret_next_table = IXGBE_LE16_TO_CPU(cmd->table_id); + if (ret_next_index) + *ret_next_index = IXGBE_LE32_TO_CPU(cmd->idx); + } + + return status; +} + +/** + * ixgbe_validate_nvm_rw_reg - Check that an NVM access request is valid + * @cmd: NVM access command structure + * + * Validates that an NVM access structure is request to read or write a valid + * register offset. First validates that the module and flags are correct, and + * then ensures that the register offset is one of the accepted registers. + * + * Return: 0 if the register access is valid, out of range error code otherwise. + */ +static s32 +ixgbe_validate_nvm_rw_reg(struct ixgbe_nvm_access_cmd *cmd) +{ + u16 i; + + switch (cmd->offset) { + case GL_HICR: + case GL_HICR_EN: /* Note, this register is read only */ + case GL_FWSTS: + case GL_MNG_FWSM: + case GLNVM_GENS: + case GLNVM_FLA: + case GL_FWRESETCNT: + return 0; + default: + break; + } + + for (i = 0; i <= GL_HIDA_MAX_INDEX; i++) + if (cmd->offset == (u32)GL_HIDA(i)) + return 0; + + for (i = 0; i <= GL_HIBA_MAX_INDEX; i++) + if (cmd->offset == (u32)GL_HIBA(i)) + return 0; + + /* All other register offsets are not valid */ + return IXGBE_ERR_OUT_OF_RANGE; +} + +/** + * ixgbe_nvm_access_read - Handle an NVM read request + * @hw: pointer to the HW struct + * @cmd: NVM access command to process + * @data: storage for the register value read + * + * Process an NVM access request to read a register. + * + * Return: 0 if the register read is valid and successful, + * out of range error code otherwise. + */ +static s32 ixgbe_nvm_access_read(struct ixgbe_hw *hw, + struct ixgbe_nvm_access_cmd *cmd, + struct ixgbe_nvm_access_data *data) +{ + s32 status; + + /* Always initialize the output data, even on failure */ + memset(&data->regval, 0, cmd->data_size); + + /* Make sure this is a valid read/write access request */ + status = ixgbe_validate_nvm_rw_reg(cmd); + if (status) + return status; + + DEBUGOUT1("NVM access: reading register %08x\n", cmd->offset); + + /* Read the register and store the contents in the data field */ + data->regval = IXGBE_READ_REG(hw, cmd->offset); + + return 0; +} + +/** + * ixgbe_nvm_access_write - Handle an NVM write request + * @hw: pointer to the HW struct + * @cmd: NVM access command to process + * @data: NVM access data to write + * + * Process an NVM access request to write a register. + * + * Return: 0 if the register write is valid and successful, + * out of range error code otherwise. + */ +static s32 ixgbe_nvm_access_write(struct ixgbe_hw *hw, + struct ixgbe_nvm_access_cmd *cmd, + struct ixgbe_nvm_access_data *data) +{ + s32 status; + + /* Make sure this is a valid read/write access request */ + status = ixgbe_validate_nvm_rw_reg(cmd); + if (status) + return status; + + /* Reject requests to write to read-only registers */ + switch (cmd->offset) { + case GL_HICR_EN: + return IXGBE_ERR_OUT_OF_RANGE; + default: + break; + } + + DEBUGOUT2("NVM access: writing register %08x with value %08x\n", + cmd->offset, data->regval); + + /* Write the data field to the specified register */ + IXGBE_WRITE_REG(hw, cmd->offset, data->regval); + + return 0; +} + +/** + * ixgbe_handle_nvm_access - Handle an NVM access request + * @hw: pointer to the HW struct + * @cmd: NVM access command info + * @data: pointer to read or return data + * + * Process an NVM access request. Read the command structure information and + * determine if it is valid. If not, report an error indicating the command + * was invalid. + * + * For valid commands, perform the necessary function, copying the data into + * the provided data buffer. + * + * Return: 0 if the nvm access request is valid and successful, + * error code otherwise. + */ +s32 ixgbe_handle_nvm_access(struct ixgbe_hw *hw, + struct ixgbe_nvm_access_cmd *cmd, + struct ixgbe_nvm_access_data *data) +{ + switch (cmd->command) { + case IXGBE_NVM_CMD_READ: + return ixgbe_nvm_access_read(hw, cmd, data); + case IXGBE_NVM_CMD_WRITE: + return ixgbe_nvm_access_write(hw, cmd, data); + default: + return IXGBE_ERR_PARAM; + } +} + /** * ixgbe_init_ops_E610 - Inits func ptrs and MAC type * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/base/ixgbe_e610.h b/drivers/net/ixgbe/base/ixgbe_e610.h index 608d60bfee..81e75a6e17 100644 --- a/drivers/net/ixgbe/base/ixgbe_e610.h +++ b/drivers/net/ixgbe/base/ixgbe_e610.h @@ -20,6 +20,8 @@ void ixgbe_fill_dflt_direct_cmd_desc(struct ixgbe_aci_desc *desc, u16 opcode); s32 ixgbe_aci_get_fw_ver(struct ixgbe_hw *hw); s32 ixgbe_aci_send_driver_ver(struct ixgbe_hw *hw, struct ixgbe_driver_ver *dv); +s32 ixgbe_aci_set_pf_context(struct ixgbe_hw *hw, u8 pf_id); + s32 ixgbe_acquire_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res, enum ixgbe_aci_res_access_type access, u32 timeout); void ixgbe_release_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res); @@ -29,9 +31,12 @@ s32 ixgbe_discover_dev_caps(struct ixgbe_hw *hw, struct ixgbe_hw_dev_caps *dev_caps); s32 ixgbe_discover_func_caps(struct ixgbe_hw* hw, struct ixgbe_hw_func_caps* func_caps); +s32 ixgbe_get_caps(struct ixgbe_hw *hw); s32 ixgbe_aci_disable_rxen(struct ixgbe_hw *hw); s32 ixgbe_aci_get_phy_caps(struct ixgbe_hw *hw, bool qual_mods, u8 report_mode, struct ixgbe_aci_cmd_get_phy_caps_data *pcaps); +bool ixgbe_phy_caps_equals_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *caps, + struct ixgbe_aci_cmd_set_phy_cfg_data *cfg); void ixgbe_copy_phy_caps_to_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *caps, struct ixgbe_aci_cmd_set_phy_cfg_data *cfg); s32 ixgbe_aci_set_phy_cfg(struct ixgbe_hw *hw, @@ -43,9 +48,34 @@ s32 ixgbe_aci_get_link_info(struct ixgbe_hw *hw, bool ena_lse, struct ixgbe_link_status *link); s32 ixgbe_aci_set_event_mask(struct ixgbe_hw *hw, u8 port_num, u16 mask); s32 ixgbe_configure_lse(struct ixgbe_hw *hw, bool activate, u16 mask); + +s32 ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_get_link_topo *cmd, + u8 *node_part_number, u16 *node_handle); +s32 ixgbe_aci_get_netlist_node_pin(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_get_link_topo_pin *cmd, + u16 *node_handle); +s32 ixgbe_find_netlist_node(struct ixgbe_hw *hw, u8 node_type_ctx, + u8 node_part_number, u16 *node_handle); +s32 ixgbe_aci_read_i2c(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_addr topo_addr, + u16 bus_addr, __le16 addr, u8 params, u8 *data); +s32 ixgbe_aci_write_i2c(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_addr topo_addr, + u16 bus_addr, __le16 addr, u8 params, u8 *data); +s32 ixgbe_aci_set_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, + bool value); +s32 ixgbe_aci_get_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, + bool *value); s32 ixgbe_aci_sff_eeprom(struct ixgbe_hw *hw, u16 lport, u8 bus_addr, u16 mem_addr, u8 page, u8 page_bank_ctrl, u8 *data, u8 length, bool write); +s32 ixgbe_aci_prog_topo_dev_nvm(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_params *topo_params); +s32 ixgbe_aci_read_topo_dev_nvm(struct ixgbe_hw *hw, + struct ixgbe_aci_cmd_link_topo_params *topo_params, + u32 start_address, u8 *data, u8 data_size); + s32 ixgbe_acquire_nvm(struct ixgbe_hw *hw, enum ixgbe_aci_res_access_type access); void ixgbe_release_nvm(struct ixgbe_hw *hw); @@ -55,11 +85,39 @@ s32 ixgbe_aci_read_nvm(struct ixgbe_hw *hw, u16 module_typeid, u32 offset, bool read_shadow_ram); s32 ixgbe_nvm_validate_checksum(struct ixgbe_hw *hw); +s32 ixgbe_nvm_recalculate_checksum(struct ixgbe_hw *hw); + +s32 ixgbe_get_nvm_minsrevs(struct ixgbe_hw *hw, struct ixgbe_minsrev_info *minsrevs); +s32 ixgbe_get_inactive_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm); s32 ixgbe_get_active_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm); +s32 ixgbe_init_nvm(struct ixgbe_hw *hw); + +s32 ixgbe_sanitize_operate(struct ixgbe_hw *hw); +s32 ixgbe_sanitize_nvm(struct ixgbe_hw *hw, u8 cmd_flags, u8 *values); + s32 ixgbe_read_sr_word_aci(struct ixgbe_hw *hw, u16 offset, u16 *data); s32 ixgbe_read_sr_buf_aci(struct ixgbe_hw *hw, u16 offset, u16 *words, u16 *data); s32 ixgbe_read_flat_nvm(struct ixgbe_hw *hw, u32 offset, u32 *length, u8 *data, bool read_shadow_ram); + +s32 ixgbe_aci_alternate_write(struct ixgbe_hw *hw, u32 reg_addr0, + u32 reg_val0, u32 reg_addr1, u32 reg_val1); +s32 ixgbe_aci_alternate_read(struct ixgbe_hw *hw, u32 reg_addr0, + u32 *reg_val0, u32 reg_addr1, u32 *reg_val1); +s32 ixgbe_aci_alternate_write_done(struct ixgbe_hw *hw, u8 bios_mode, + bool *reset_needed); +s32 ixgbe_aci_alternate_clear(struct ixgbe_hw *hw); + +s32 ixgbe_aci_get_internal_data(struct ixgbe_hw *hw, u16 cluster_id, + u16 table_id, u32 start, void *buf, + u16 buf_size, u16 *ret_buf_size, + u16 *ret_next_cluster, u16 *ret_next_table, + u32 *ret_next_index); + +s32 ixgbe_handle_nvm_access(struct ixgbe_hw *hw, + struct ixgbe_nvm_access_cmd *cmd, + struct ixgbe_nvm_access_data *data); + /* E610 operations */ s32 ixgbe_reset_hw_E610(struct ixgbe_hw *hw); s32 ixgbe_start_hw_E610(struct ixgbe_hw *hw); diff --git a/drivers/net/ixgbe/base/ixgbe_type_e610.h b/drivers/net/ixgbe/base/ixgbe_type_e610.h index b366ea571a..35134cdae9 100644 --- a/drivers/net/ixgbe/base/ixgbe_type_e610.h +++ b/drivers/net/ixgbe/base/ixgbe_type_e610.h @@ -119,6 +119,14 @@ #define E610_SR_NVM_CTRL_WORD 0x00 #define E610_SR_PBA_BLOCK_PTR 0x16 +/* The Orom version topology */ +#define IXGBE_OROM_VER_PATCH_SHIFT 0 +#define IXGBE_OROM_VER_PATCH_MASK (0xff << IXGBE_OROM_VER_PATCH_SHIFT) +#define IXGBE_OROM_VER_BUILD_SHIFT 8 +#define IXGBE_OROM_VER_BUILD_MASK (0xffff << IXGBE_OROM_VER_BUILD_SHIFT) +#define IXGBE_OROM_VER_SHIFT 24 +#define IXGBE_OROM_VER_MASK (0xff << IXGBE_OROM_VER_SHIFT) + /* CSS Header words */ #define IXGBE_NVM_CSS_HDR_LEN_L 0x02 #define IXGBE_NVM_CSS_HDR_LEN_H 0x03 @@ -128,6 +136,39 @@ /* Length of Authentication header section in words */ #define IXGBE_NVM_AUTH_HEADER_LEN 0x08 +/* The Netlist ID Block is located after all of the Link Topology nodes. */ +#define IXGBE_NETLIST_ID_BLK_SIZE 0x30 +#define IXGBE_NETLIST_ID_BLK_OFFSET(n) IXGBE_NETLIST_LINK_TOPO_OFFSET(0x0004 + 2 * (n)) + +/* netlist ID block field offsets (word offsets) */ +#define IXGBE_NETLIST_ID_BLK_MAJOR_VER_LOW 0x02 +#define IXGBE_NETLIST_ID_BLK_MAJOR_VER_HIGH 0x03 +#define IXGBE_NETLIST_ID_BLK_MINOR_VER_LOW 0x04 +#define IXGBE_NETLIST_ID_BLK_MINOR_VER_HIGH 0x05 +#define IXGBE_NETLIST_ID_BLK_TYPE_LOW 0x06 +#define IXGBE_NETLIST_ID_BLK_TYPE_HIGH 0x07 +#define IXGBE_NETLIST_ID_BLK_REV_LOW 0x08 +#define IXGBE_NETLIST_ID_BLK_REV_HIGH 0x09 +#define IXGBE_NETLIST_ID_BLK_SHA_HASH_WORD(n) (0x0A + (n)) +#define IXGBE_NETLIST_ID_BLK_CUST_VER 0x2F + +/* The Link Topology Netlist section is stored as a series of words. It is + * stored in the NVM as a TLV, with the first two words containing the type + * and length. + */ +#define IXGBE_NETLIST_LINK_TOPO_MOD_ID 0x011B +#define IXGBE_NETLIST_TYPE_OFFSET 0x0000 +#define IXGBE_NETLIST_LEN_OFFSET 0x0001 + +/* The Link Topology section follows the TLV header. When reading the netlist + * using ixgbe_read_netlist_module, we need to account for the 2-word TLV + * header. + */ +#define IXGBE_NETLIST_LINK_TOPO_OFFSET(n) ((n) + 2) +#define IXGBE_LINK_TOPO_MODULE_LEN IXGBE_NETLIST_LINK_TOPO_OFFSET(0x0000) +#define IXGBE_LINK_TOPO_NODE_COUNT IXGBE_NETLIST_LINK_TOPO_OFFSET(0x0001) +#define IXGBE_LINK_TOPO_NODE_COUNT_M MAKEMASK(0x3FF, 0) + /* Auxiliary field, mask and shift definition for Shadow RAM and NVM Flash */ #define IXGBE_SR_CTRL_WORD_1_S 0x06 #define IXGBE_SR_CTRL_WORD_1_M (0x03 << IXGBE_SR_CTRL_WORD_1_S) @@ -152,6 +193,9 @@ */ #define IXGBE_SR_SW_CHECKSUM_BASE 0xBABA +/* Netlist */ +#define IXGBE_MAX_NETLIST_SIZE 10 + /* General registers */ /* Firmware Status Register (GL_FWSTS) */ @@ -227,17 +271,81 @@ #define GLNVM_FLA_LOCKED_S 6 #define GLNVM_FLA_LOCKED_M BIT(6) +/* Bit Bang registers */ +#define RDASB_MSGCTL 0x000B6820 +#define RDASB_MSGCTL_HDR_DWS_S 0 +#define RDASB_MSGCTL_EXP_RDW_S 8 +#define RDASB_MSGCTL_CMDV_M BIT(31) +#define RDASB_RSPCTL 0x000B6824 +#define RDASB_RSPCTL_BAD_LENGTH_M BIT(30) +#define RDASB_RSPCTL_NOT_SUCCESS_M BIT(31) +#define RDASB_WHDR0 0x000B68F4 +#define RDASB_WHDR1 0x000B68F8 +#define RDASB_WHDR2 0x000B68FC +#define RDASB_WHDR3 0x000B6900 +#define RDASB_WHDR4 0x000B6904 +#define RDASB_RHDR0 0x000B6AFC +#define RDASB_RHDR0_RESPONSE_S 27 +#define RDASB_RHDR0_RESPONSE_M MAKEMASK(0x7, 27) +#define RDASB_RDATA0 0x000B6B00 +#define RDASB_RDATA1 0x000B6B04 + +/* SPI Registers */ +#define SPISB_MSGCTL 0x000B7020 +#define SPISB_MSGCTL_HDR_DWS_S 0 +#define SPISB_MSGCTL_EXP_RDW_S 8 +#define SPISB_MSGCTL_MSG_MODE_S 26 +#define SPISB_MSGCTL_TOKEN_MODE_S 28 +#define SPISB_MSGCTL_BARCLR_S 30 +#define SPISB_MSGCTL_CMDV_S 31 +#define SPISB_MSGCTL_CMDV_M BIT(31) +#define SPISB_RSPCTL 0x000B7024 +#define SPISB_RSPCTL_BAD_LENGTH_M BIT(30) +#define SPISB_RSPCTL_NOT_SUCCESS_M BIT(31) +#define SPISB_WHDR0 0x000B70F4 +#define SPISB_WHDR0_DEST_SEL_S 12 +#define SPISB_WHDR0_OPCODE_SEL_S 16 +#define SPISB_WHDR0_TAG_S 24 +#define SPISB_WHDR1 0x000B70F8 +#define SPISB_WHDR2 0x000B70FC +#define SPISB_RDATA 0x000B7300 +#define SPISB_WDATA 0x000B7100 + +/* Firmware Reset Count register */ +#define GL_FWRESETCNT 0x00083100 /* Reset Source: POR */ +#define GL_FWRESETCNT_FWRESETCNT_S 0 +#define GL_FWRESETCNT_FWRESETCNT_M MAKEMASK(0xFFFFFFFF, 0) + /* Admin Command Interface (ACI) registers */ #define PF_HIDA(_i) (0x00085000 + ((_i) * 4)) #define PF_HIDA_2(_i) (0x00085020 + ((_i) * 4)) #define PF_HIBA(_i) (0x00084000 + ((_i) * 4)) #define PF_HICR 0x00082048 +#define PF_HIDA_MAX_INDEX 15 +#define PF_HIBA_MAX_INDEX 1023 + #define PF_HICR_EN BIT(0) #define PF_HICR_C BIT(1) #define PF_HICR_SV BIT(2) #define PF_HICR_EV BIT(3) +#define GL_HIDA(_i) (0x00082000 + ((_i) * 4)) +#define GL_HIDA_2(_i) (0x00082020 + ((_i) * 4)) +#define GL_HIBA(_i) (0x00081000 + ((_i) * 4)) +#define GL_HICR 0x00082040 + +#define GL_HIDA_MAX_INDEX 15 +#define GL_HIBA_MAX_INDEX 1023 + +#define GL_HICR_C BIT(1) +#define GL_HICR_SV BIT(2) +#define GL_HICR_EV BIT(3) + +#define GL_HICR_EN 0x00082044 + +#define GL_HICR_EN_CHECK BIT(0) + /* Admin Command Interface (ACI) defines */ /* Defines that help manage the driver vs FW API checks. */ @@ -260,6 +368,14 @@ /* [ms] timeout of waiting for resource release */ #define IXGBE_ACI_RELEASE_RES_TIMEOUT 10000 +/* Timestamp spacing for Tools ACI: queue is active if spacing is within the range [LO..HI] */ +#define IXGBE_TOOLS_ACI_ACTIVE_STAMP_SPACING_LO 0 +#define IXGBE_TOOLS_ACI_ACTIVE_STAMP_SPACING_HI 200 + +/* Timestamp spacing for Tools ACI: queue is expired if spacing is outside the range [LO..HI] */ +#define IXGBE_TOOLS_ACI_EXPIRED_STAMP_SPACING_LO -5 +#define IXGBE_TOOLS_ACI_EXPIRED_STAMP_SPACING_HI 205 + /* FW defined boundary for a large buffer, 4k >= Large buffer > 512 bytes */ #define IXGBE_ACI_LG_BUF 512 @@ -488,6 +604,8 @@ IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_exp_err); /* FW update timeout definitions are in milliseconds */ #define IXGBE_NVM_TIMEOUT 180000 +#define IXGBE_CHANGE_LOCK_TIMEOUT 1000 +#define IXGBE_GLOBAL_CFG_LOCK_TIMEOUT 3000 enum ixgbe_aci_res_access_type { IXGBE_RES_READ = 1, @@ -1234,10 +1352,48 @@ struct ixgbe_aci_cmd_nvm { }; /* NVM Module_Type ID, needed offset and read_len for struct ixgbe_aci_cmd_nvm. */ +#define IXGBE_ACI_NVM_SECTOR_UNIT 4096 /* In Bytes */ +#define IXGBE_ACI_NVM_WORD_UNIT 2 /* In Bytes */ + #define IXGBE_ACI_NVM_START_POINT 0 +#define IXGBE_ACI_NVM_EMP_SR_PTR_OFFSET 0x90 +#define IXGBE_ACI_NVM_EMP_SR_PTR_RD_LEN 2 /* In Bytes */ +#define IXGBE_ACI_NVM_EMP_SR_PTR_M MAKEMASK(0x7FFF, 0) +#define IXGBE_ACI_NVM_EMP_SR_PTR_TYPE_S 15 +#define IXGBE_ACI_NVM_EMP_SR_PTR_TYPE_M BIT(15) +#define IXGBE_ACI_NVM_EMP_SR_PTR_TYPE_SECTOR 1 + +#define IXGBE_ACI_NVM_LLDP_CFG_PTR_OFFSET 0x46 +#define IXGBE_ACI_NVM_LLDP_CFG_HEADER_LEN 2 /* In Bytes */ +#define IXGBE_ACI_NVM_LLDP_CFG_PTR_RD_LEN 2 /* In Bytes */ + +#define IXGBE_ACI_NVM_LLDP_PRESERVED_MOD_ID 0x129 +#define IXGBE_ACI_NVM_CUR_LLDP_PERSIST_RD_OFFSET 2 /* In Bytes */ +#define IXGBE_ACI_NVM_LLDP_STATUS_M MAKEMASK(0xF, 0) +#define IXGBE_ACI_NVM_LLDP_STATUS_M_LEN 4 /* In Bits */ +#define IXGBE_ACI_NVM_LLDP_STATUS_RD_LEN 4 /* In Bytes */ + +#define IXGBE_ACI_NVM_MINSREV_MOD_ID 0x130 IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_nvm); +/* Used for reading and writing MinSRev using 0x0701 and 0x0703. Note that the + * type field is excluded from the section when reading and writing from + * a module using the module_typeid field with these AQ commands. + */ +struct ixgbe_aci_cmd_nvm_minsrev { + __le16 length; + __le16 validity; +#define IXGBE_ACI_NVM_MINSREV_NVM_VALID BIT(0) +#define IXGBE_ACI_NVM_MINSREV_OROM_VALID BIT(1) + __le16 nvm_minsrev_l; + __le16 nvm_minsrev_h; + __le16 orom_minsrev_l; + __le16 orom_minsrev_h; +}; + +IXGBE_CHECK_STRUCT_LEN(12, ixgbe_aci_cmd_nvm_minsrev); + /* Used for 0x0704 as well as for 0x0705 commands */ struct ixgbe_aci_cmd_nvm_cfg { u8 cmd_flags; @@ -1254,6 +1410,14 @@ struct ixgbe_aci_cmd_nvm_cfg { IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_nvm_cfg); +struct ixgbe_aci_cmd_nvm_cfg_data { + __le16 field_id; + __le16 field_options; + __le16 field_value; +}; + +IXGBE_CHECK_STRUCT_LEN(6, ixgbe_aci_cmd_nvm_cfg_data); + /* NVM Checksum Command (direct, 0x0706) */ struct ixgbe_aci_cmd_nvm_checksum { u8 flags; @@ -1329,6 +1493,211 @@ struct ixgbe_aci_cmd_clear_port_alt_write { IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_clear_port_alt_write); +/* Get CGU abilities command response data structure (indirect 0x0C61) */ +struct ixgbe_aci_cmd_get_cgu_abilities { + u8 num_inputs; + u8 num_outputs; + u8 pps_dpll_idx; + u8 synce_dpll_idx; + __le32 max_in_freq; + __le32 max_in_phase_adj; + __le32 max_out_freq; + __le32 max_out_phase_adj; + u8 cgu_part_num; + u8 rsvd[3]; +}; + +IXGBE_CHECK_STRUCT_LEN(24, ixgbe_aci_cmd_get_cgu_abilities); + +#define IXGBE_ACI_NODE_HANDLE_VALID BIT(10) +#define IXGBE_ACI_NODE_HANDLE MAKEMASK(0x3FF, 0) +#define IXGBE_ACI_DRIVING_CLK_NUM_SHIFT 10 +#define IXGBE_ACI_DRIVING_CLK_NUM MAKEMASK(0x3F, IXGBE_ACI_DRIVING_CLK_NUM_SHIFT) + +/* Set CGU input config (direct 0x0C62) */ +struct ixgbe_aci_cmd_set_cgu_input_config { + u8 input_idx; + u8 flags1; +#define IXGBE_ACI_SET_CGU_IN_CFG_FLG1_UPDATE_FREQ BIT(6) +#define IXGBE_ACI_SET_CGU_IN_CFG_FLG1_UPDATE_DELAY BIT(7) + u8 flags2; +#define IXGBE_ACI_SET_CGU_IN_CFG_FLG2_INPUT_EN BIT(5) +#define IXGBE_ACI_SET_CGU_IN_CFG_FLG2_ESYNC_EN BIT(6) + u8 rsvd; + __le32 freq; + __le32 phase_delay; + u8 rsvd2[2]; + __le16 node_handle; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_set_cgu_input_config); + +/* Get CGU input config response descriptor structure (direct 0x0C63) */ +struct ixgbe_aci_cmd_get_cgu_input_config { + u8 input_idx; + u8 status; +#define IXGBE_ACI_GET_CGU_IN_CFG_STATUS_LOS BIT(0) +#define IXGBE_ACI_GET_CGU_IN_CFG_STATUS_SCM_FAIL BIT(1) +#define IXGBE_ACI_GET_CGU_IN_CFG_STATUS_CFM_FAIL BIT(2) +#define IXGBE_ACI_GET_CGU_IN_CFG_STATUS_GST_FAIL BIT(3) +#define IXGBE_ACI_GET_CGU_IN_CFG_STATUS_PFM_FAIL BIT(4) +#define IXGBE_ACI_GET_CGU_IN_CFG_STATUS_ESYNC_FAIL BIT(6) +#define IXGBE_ACI_GET_CGU_IN_CFG_STATUS_ESYNC_CAP BIT(7) + u8 type; +#define IXGBE_ACI_GET_CGU_IN_CFG_TYPE_READ_ONLY BIT(0) +#define IXGBE_ACI_GET_CGU_IN_CFG_TYPE_GPS BIT(4) +#define IXGBE_ACI_GET_CGU_IN_CFG_TYPE_EXTERNAL BIT(5) +#define IXGBE_ACI_GET_CGU_IN_CFG_TYPE_PHY BIT(6) + u8 flags1; +#define IXGBE_ACI_GET_CGU_IN_CFG_FLG1_PHASE_DELAY_SUPP BIT(0) +#define IXGBE_ACI_GET_CGU_IN_CFG_FLG1_1PPS_SUPP BIT(2) +#define IXGBE_ACI_GET_CGU_IN_CFG_FLG1_10MHZ_SUPP BIT(3) +#define IXGBE_ACI_GET_CGU_IN_CFG_FLG1_ANYFREQ BIT(7) + __le32 freq; + __le32 phase_delay; + u8 flags2; +#define IXGBE_ACI_GET_CGU_IN_CFG_FLG2_INPUT_EN BIT(5) +#define IXGBE_ACI_GET_CGU_IN_CFG_FLG2_ESYNC_EN BIT(6) + u8 rsvd[1]; + __le16 node_handle; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_cgu_input_config); + +/* Set CGU output config (direct 0x0C64) */ +struct ixgbe_aci_cmd_set_cgu_output_config { + u8 output_idx; + u8 flags; +#define IXGBE_ACI_SET_CGU_OUT_CFG_OUT_EN BIT(0) +#define IXGBE_ACI_SET_CGU_OUT_CFG_ESYNC_EN BIT(1) +#define IXGBE_ACI_SET_CGU_OUT_CFG_UPDATE_FREQ BIT(2) +#define IXGBE_ACI_SET_CGU_OUT_CFG_UPDATE_PHASE BIT(3) +#define IXGBE_ACI_SET_CGU_OUT_CFG_UPDATE_SRC_SEL BIT(4) + u8 src_sel; +#define IXGBE_ACI_SET_CGU_OUT_CFG_DPLL_SRC_SEL MAKEMASK(0x1F, 0) + u8 rsvd; + __le32 freq; + __le32 phase_delay; + u8 rsvd2[2]; + __le16 node_handle; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_set_cgu_output_config); + +/* Get CGU output config (direct 0x0C65) */ +struct ixgbe_aci_cmd_get_cgu_output_config { + u8 output_idx; + u8 flags; +#define IXGBE_ACI_GET_CGU_OUT_CFG_OUT_EN BIT(0) +#define IXGBE_ACI_GET_CGU_OUT_CFG_ESYNC_EN BIT(1) +#define IXGBE_ACI_GET_CGU_OUT_CFG_ESYNC_ABILITY BIT(2) + u8 src_sel; +#define IXGBE_ACI_GET_CGU_OUT_CFG_DPLL_SRC_SEL_SHIFT 0 +#define IXGBE_ACI_GET_CGU_OUT_CFG_DPLL_SRC_SEL \ + MAKEMASK(0x1F, IXGBE_ACI_GET_CGU_OUT_CFG_DPLL_SRC_SEL_SHIFT) +#define IXGBE_ACI_GET_CGU_OUT_CFG_DPLL_MODE_SHIFT 5 +#define IXGBE_ACI_GET_CGU_OUT_CFG_DPLL_MODE \ + MAKEMASK(0x7, IXGBE_ACI_GET_CGU_OUT_CFG_DPLL_MODE_SHIFT) + u8 rsvd; + __le32 freq; + __le32 src_freq; + u8 rsvd2[2]; + __le16 node_handle; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_cgu_output_config); + +/* Get CGU DPLL status (direct 0x0C66) */ +struct ixgbe_aci_cmd_get_cgu_dpll_status { + u8 dpll_num; + u8 ref_state; +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_REF_SW_LOS BIT(0) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_REF_SW_SCM BIT(1) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_REF_SW_CFM BIT(2) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_REF_SW_GST BIT(3) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_REF_SW_PFM BIT(4) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_FAST_LOCK_EN BIT(5) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_REF_SW_ESYNC BIT(6) + __le16 dpll_state; +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_LOCK BIT(0) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_HO BIT(1) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_HO_READY BIT(2) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_FLHIT BIT(5) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_PSLHIT BIT(7) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_CLK_REF_SHIFT 8 +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_CLK_REF_SEL \ + MAKEMASK(0x1F, IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_CLK_REF_SHIFT) +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_MODE_SHIFT 13 +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_MODE \ + MAKEMASK(0x7, IXGBE_ACI_GET_CGU_DPLL_STATUS_STATE_MODE_SHIFT) + __le32 phase_offset_h; + __le32 phase_offset_l; + u8 eec_mode; +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_EEC_MODE_1 0xA +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_EEC_MODE_2 0xB +#define IXGBE_ACI_GET_CGU_DPLL_STATUS_EEC_MODE_UNKNOWN 0xF + u8 rsvd[1]; + __le16 node_handle; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_cgu_dpll_status); + +/* Set CGU DPLL config (direct 0x0C67) */ +struct ixgbe_aci_cmd_set_cgu_dpll_config { + u8 dpll_num; + u8 ref_state; +#define IXGBE_ACI_SET_CGU_DPLL_CONFIG_REF_SW_LOS BIT(0) +#define IXGBE_ACI_SET_CGU_DPLL_CONFIG_REF_SW_SCM BIT(1) +#define IXGBE_ACI_SET_CGU_DPLL_CONFIG_REF_SW_CFM BIT(2) +#define IXGBE_ACI_SET_CGU_DPLL_CONFIG_REF_SW_GST BIT(3) +#define IXGBE_ACI_SET_CGU_DPLL_CONFIG_REF_SW_PFM BIT(4) +#define IXGBE_ACI_SET_CGU_DPLL_CONFIG_REF_FLOCK_EN BIT(5) +#define IXGBE_ACI_SET_CGU_DPLL_CONFIG_REF_SW_ESYNC BIT(6) + u8 rsvd; + u8 config; +#define IXGBE_ACI_SET_CGU_DPLL_CONFIG_CLK_REF_SEL MAKEMASK(0x1F, 0) +#define IXGBE_ACI_SET_CGU_DPLL_CONFIG_MODE MAKEMASK(0x7, 5) + u8 rsvd2[8]; + u8 eec_mode; + u8 rsvd3[1]; + __le16 node_handle; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_set_cgu_dpll_config); + +/* Set CGU reference priority (direct 0x0C68) */ +struct ixgbe_aci_cmd_set_cgu_ref_prio { + u8 dpll_num; + u8 ref_idx; + u8 ref_priority; + u8 rsvd[11]; + __le16 node_handle; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_set_cgu_ref_prio); + +/* Get CGU reference priority (direct 0x0C69) */ +struct ixgbe_aci_cmd_get_cgu_ref_prio { + u8 dpll_num; + u8 ref_idx; + u8 ref_priority; /* Valid only in response */ + u8 rsvd[13]; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_cgu_ref_prio); + +/* Get CGU info (direct 0x0C6A) */ +struct ixgbe_aci_cmd_get_cgu_info { + __le32 cgu_id; + __le32 cgu_cfg_ver; + __le32 cgu_fw_ver; + u8 node_part_num; + u8 dev_rev; + __le16 node_handle; +}; + +IXGBE_CHECK_PARAM_LEN(ixgbe_aci_cmd_get_cgu_info); + /* Debug Dump Internal Data (indirect 0xFF08) */ struct ixgbe_aci_cmd_debug_dump_internals { __le16 cluster_id; /* Expresses next cluster ID in response */ @@ -1694,6 +2063,16 @@ struct ixgbe_ts_dev_info { u8 tmr1_ena; }; +#pragma pack(1) +struct ixgbe_orom_civd_info { + u8 signature[4]; /* Must match ASCII '$CIV' characters */ + u8 checksum; /* Simple modulo 256 sum of all structure bytes must equal 0 */ + __le32 combo_ver; /* Combo Image Version number */ + u8 combo_name_len; /* Length of the unicode combo image version string, max of 32 */ + __le16 combo_name[32]; /* Unicode string representing the Combo Image version */ +}; +#pragma pack() + /* Function specific capabilities */ struct ixgbe_hw_func_caps { struct ixgbe_hw_common_caps common_cap; @@ -1724,6 +2103,14 @@ struct ixgbe_aci_info { struct ixgbe_lock lock; /* admin command interface lock */ }; +/* Minimum Security Revision information */ +struct ixgbe_minsrev_info { + u32 nvm; + u32 orom; + u8 nvm_valid : 1; + u8 orom_valid : 1; +}; + /* Enumeration of which flash bank is desired to read from, either the active * bank or the inactive bank. Used to abstract 1st and 2nd bank notion from * code which just wants to read the active or inactive flash bank. @@ -1781,4 +2168,19 @@ struct ixgbe_flash_info { u8 blank_nvm_mode; /* is NVM empty (no FW present) */ }; +#define IXGBE_NVM_CMD_READ 0x0000000B +#define IXGBE_NVM_CMD_WRITE 0x0000000C + +/* NVM Access command */ +struct ixgbe_nvm_access_cmd { + u32 command; /* NVM command: READ or WRITE */ + u32 offset; /* Offset to read/write, in bytes */ + u32 data_size; /* Size of data field, in bytes */ +}; + +/* NVM Access data */ +struct ixgbe_nvm_access_data { + u32 regval; /* Storage for register value */ +}; + #endif /* _IXGBE_TYPE_E610_H_ */