From patchwork Thu Sep 16 09:53:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qi Zhang X-Patchwork-Id: 99018 X-Patchwork-Delegate: qi.z.zhang@intel.com 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 9BD7DA0C41; Thu, 16 Sep 2021 11:50:59 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8B8BD410EC; Thu, 16 Sep 2021 11:50:26 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by mails.dpdk.org (Postfix) with ESMTP id 0B21D410E8 for ; Thu, 16 Sep 2021 11:50:23 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10108"; a="222185895" X-IronPort-AV: E=Sophos;i="5.85,298,1624345200"; d="scan'208";a="222185895" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Sep 2021 02:50:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.85,298,1624345200"; d="scan'208";a="509247045" Received: from dpdk51.sh.intel.com ([10.67.111.142]) by fmsmga008.fm.intel.com with ESMTP; 16 Sep 2021 02:50:21 -0700 From: Qi Zhang To: qiming.yang@intel.com Cc: junfeng.guo@intel.com, dev@dpdk.org, Qi Zhang , Maciej Machnikowski Date: Thu, 16 Sep 2021 17:53:03 +0800 Message-Id: <20210916095304.3058210-12-qi.z.zhang@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210916095304.3058210-1-qi.z.zhang@intel.com> References: <20210916095304.3058210-1-qi.z.zhang@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH 11/12] net/ice/base: implement support for SMA controller 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 Sender: "dev" Add support for controlling SMA connectors using GPIO get/set AQs. Signed-off-by: Maciej Machnikowski Signed-off-by: Qi Zhang --- drivers/net/ice/base/ice_ptp_hw.c | 213 ++++++++++++++++++++++++++++++ drivers/net/ice/base/ice_ptp_hw.h | 11 ++ drivers/net/ice/base/ice_type.h | 1 + 3 files changed, 225 insertions(+) diff --git a/drivers/net/ice/base/ice_ptp_hw.c b/drivers/net/ice/base/ice_ptp_hw.c index 9ed335349b..7e797c9511 100644 --- a/drivers/net/ice/base/ice_ptp_hw.c +++ b/drivers/net/ice/base/ice_ptp_hw.c @@ -3077,6 +3077,219 @@ ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, return ICE_SUCCESS; } +/* E810T SMA functions + * + * The following functions operate specifically on E810T hardware and are used + * to access the extended GPIOs available. + */ + +/** + * ice_get_pca9575_handle + * @hw: pointer to the hw struct + * @pca9575_handle: GPIO controller's handle + * + * Find and return the GPIO controller's handle in the netlist. + * When found - the value will be cached in the hw structure and following calls + * will return cached value + */ +static enum ice_status +ice_get_pca9575_handle(struct ice_hw *hw, __le16 *pca9575_handle) +{ + struct ice_aqc_get_link_topo *cmd; + struct ice_aq_desc desc; + enum ice_status status; + u8 idx; + + if (!hw || !pca9575_handle) + return ICE_ERR_PARAM; + + /* If handle was read previously return cached value */ + if (hw->io_expander_handle) { + *pca9575_handle = hw->io_expander_handle; + return ICE_SUCCESS; + } + + /* If handle was not detected read it from the netlist */ + cmd = &desc.params.get_link_topo; + ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo); + + /* Set node type to GPIO controller */ + cmd->addr.topo_params.node_type_ctx = + (ICE_AQC_LINK_TOPO_NODE_TYPE_M & + ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL); + +#define SW_PCA9575_SFP_TOPO_IDX 2 +#define SW_PCA9575_QSFP_TOPO_IDX 1 + + /* Check if the SW IO expander controlling SMA exists in the netlist. */ + if (hw->device_id == ICE_DEV_ID_E810C_SFP) + idx = SW_PCA9575_SFP_TOPO_IDX; + else if (hw->device_id == ICE_DEV_ID_E810C_QSFP) + idx = SW_PCA9575_QSFP_TOPO_IDX; + else + return ICE_ERR_NOT_SUPPORTED; + + cmd->addr.topo_params.index = idx; + + status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); + if (status) + return ICE_ERR_NOT_SUPPORTED; + + /* Verify if we found the right IO expander type */ + if (desc.params.get_link_topo.node_part_num != + ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575) + return ICE_ERR_NOT_SUPPORTED; + + /* If present save the handle and return it */ + hw->io_expander_handle = desc.params.get_link_topo.addr.handle; + *pca9575_handle = hw->io_expander_handle; + + return ICE_SUCCESS; +} + +/** + * ice_read_e810t_pca9575_reg + * @hw: pointer to the hw struct + * @offset: GPIO controller register offset + * @data: pointer to data to be read from the GPIO controller + * + * Read the register from the GPIO controller + */ +enum ice_status +ice_read_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data) +{ + struct ice_aqc_link_topo_addr link_topo; + enum ice_status status; + __le16 addr; + + memset(&link_topo, 0, sizeof(link_topo)); + + status = ice_get_pca9575_handle(hw, &link_topo.handle); + if (status) + return status; + + link_topo.topo_params.node_type_ctx = + (ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED << + ICE_AQC_LINK_TOPO_NODE_CTX_S); + + addr = CPU_TO_LE16((u16)offset); + + return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL); +} + +/** + * ice_write_e810t_pca9575_reg + * @hw: pointer to the hw struct + * @offset: GPIO controller register offset + * @data: data to be written to the GPIO controller + * + * Write the data to the GPIO controller register + */ +enum ice_status +ice_write_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 data) +{ + struct ice_aqc_link_topo_addr link_topo; + enum ice_status status; + __le16 addr; + + memset(&link_topo, 0, sizeof(link_topo)); + + status = ice_get_pca9575_handle(hw, &link_topo.handle); + if (status) + return status; + + link_topo.topo_params.node_type_ctx = + (ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED << + ICE_AQC_LINK_TOPO_NODE_CTX_S); + + addr = CPU_TO_LE16((u16)offset); + + return ice_aq_write_i2c(hw, link_topo, 0, addr, 1, &data, NULL); +} + +/** + * ice_read_sma_ctrl_e810t + * @hw: pointer to the hw struct + * @data: pointer to data to be read from the GPIO controller + * + * Read the SMA controller state. Only bits 3-7 in data are valid. + */ +enum ice_status ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data) +{ + enum ice_status status; + u16 handle; + u8 i; + + status = ice_get_pca9575_handle(hw, &handle); + if (status) + return status; + + *data = 0; + + for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) { + bool pin; + + status = ice_aq_get_gpio(hw, handle, i + ICE_E810T_P1_OFFSET, + &pin, NULL); + if (status) + break; + *data |= (u8)(!pin) << i; + } + + return status; +} + +/** + * ice_write_sma_ctrl_e810t + * @hw: pointer to the hw struct + * @data: data to be written to the GPIO controller + * + * Write the data to the SMA controller. Only bits 3-7 in data are valid. + */ +enum ice_status ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data) +{ + enum ice_status status; + u16 handle; + u8 i; + + status = ice_get_pca9575_handle(hw, &handle); + if (status) + return status; + + for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) { + bool pin; + + pin = !(data & (1 << i)); + status = ice_aq_set_gpio(hw, handle, i + ICE_E810T_P1_OFFSET, + pin, NULL); + if (status) + break; + } + + return status; +} + +/** + * ice_e810t_is_pca9575_present + * @hw: pointer to the hw struct + * + * Check if the SW IO expander is present in the netlist + */ +bool ice_e810t_is_pca9575_present(struct ice_hw *hw) +{ + enum ice_status status; + __le16 handle = 0; + + if (!ice_is_e810t(hw)) + return false; + + status = ice_get_pca9575_handle(hw, &handle); + if (!status && handle) + return true; + + return false; +} + /* Device agnostic functions * * The following functions implement shared behavior common to both E822 and diff --git a/drivers/net/ice/base/ice_ptp_hw.h b/drivers/net/ice/base/ice_ptp_hw.h index c804085095..ee3366e83c 100644 --- a/drivers/net/ice/base/ice_ptp_hw.h +++ b/drivers/net/ice/base/ice_ptp_hw.h @@ -222,6 +222,13 @@ enum ice_status ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port); /* E810 family functions */ enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw); +enum ice_status +ice_read_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data); +enum ice_status +ice_write_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 data); +enum ice_status ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data); +enum ice_status ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data); +bool ice_e810t_is_pca9575_present(struct ice_hw *hw); #define PFTSYN_SEM_BYTES 4 @@ -470,4 +477,8 @@ enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw); #define ICE_E810T_P1_SMA2_DIR_EN BIT(6) #define ICE_E810T_P1_SMA2_TX_EN BIT(7) +#define ICE_E810T_SMA_MIN_BIT 3 +#define ICE_E810T_SMA_MAX_BIT 7 +#define ICE_E810T_P1_OFFSET 8 + #endif /* _ICE_PTP_HW_H_ */ diff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h index b2b3291fb7..72cda11a4f 100644 --- a/drivers/net/ice/base/ice_type.h +++ b/drivers/net/ice/base/ice_type.h @@ -1261,6 +1261,7 @@ struct ice_hw { struct LIST_HEAD_TYPE rss_list_head; ice_declare_bitmap(hw_ptype, ICE_FLOW_PTYPE_MAX); u8 dvm_ena; + __le16 io_expander_handle; }; /* Statistics collected by each port, VSI, VEB, and S-channel */