From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f193.google.com (mail-wr0-f193.google.com [209.85.128.193]) by dpdk.org (Postfix) with ESMTP id 46FDD1BBA4 for ; Wed, 11 Apr 2018 15:59:41 +0200 (CEST) Received: by mail-wr0-f193.google.com with SMTP id l49so1898135wrl.4 for ; Wed, 11 Apr 2018 06:59:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Mvd8wRMC14ZogPDnn2JwktszPzBhbdrtR1/kdvPuv3w=; b=WNl7LPFnnAP9PBGAqj49PGxHW83Vo1IBOt1JAM/EWXe9CdcTSarb9yLsUsdh598nBn sMvh0B/mclwvVuVPF07aMjFiGsTCaeyePSsB1pVWMcKAIqQxf+FN+xFnuJY4IBVaVQlB PLSmxAVkkO0pJtCJVUaLm41DAs3760gf1IlBTTZpWWhQrk3tLtvYj+J3/6WRIBQIy3iR EO4JKvepi+d5DvI82jNZbetw5VYrQSn9I+Rv1emABMGA/DaVNv6dpHcwmK3ziJooNMR/ rb1NquPGHPnFJSzZ85E+pDwf3rzuz3GA/SJqJ7QVVU6YrXf91Tv0LDn5OzoPb5yrvh3a t8UQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Mvd8wRMC14ZogPDnn2JwktszPzBhbdrtR1/kdvPuv3w=; b=CUc8fVYgWzkouMtdif0bcjiksAcXfANPtPy6XEPH8eQDOWQu/IlvkA9kuwU9Y7QmUn OUCfjkMeM1f4uq2RAKOUBgI0Peq2T340zCJRoqHLnRxEWNg3by+6IK3T+i59EV+jeQZz 45Cll8TS1IXvNzAinKI01EjKN/qnhWsJMKAhly4uVwlg4Dx9eVdxPVNZPm2ieMXwyPHG FGo8u73QxIfWXh4tMCyXAcvL05Sqeb2gIbNMpRlU/sXcKHFUKApMblwhqGtYQNOw9NKW 3ilBUTsD+tCBl/7AadLkTH7lMGl5Xh99+xPL2x1jWmlLsDDnwzBUaZqsNHxZz4HmQrXS zh6Q== X-Gm-Message-State: ALQs6tD5E0oMWS+yA9L0xZZ81q0je4Hul02lCVUopwcDgApuZuyW1OIt U5mV9fZW3JP5zkqjWKuLtYr4fA== X-Google-Smtp-Source: AIpwx49+uWBhWd6fP6SUdueTBJrEl5Rg69JXnN+txb1LMwUiPUyLiyBohavxyrLvQBMHE7B+t0aELw== X-Received: by 10.223.179.13 with SMTP id j13mr3668753wrd.165.1523455180600; Wed, 11 Apr 2018 06:59:40 -0700 (PDT) Received: from schoudah-dev.vyatta.net ([137.221.143.78]) by smtp.gmail.com with ESMTPSA id r109sm1716389wrb.54.2018.04.11.06.59.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Apr 2018 06:59:40 -0700 (PDT) From: Shweta Choudaha To: dev@dpdk.org Cc: wenzhuo.lu@intel.com, konstantin.ananyev@intel.com, helin.zhang@intel.com, ferruh.yigit@intel.com, shweta.choudaha@att.com Date: Wed, 11 Apr 2018 14:59:35 +0100 Message-Id: <20180411135935.61232-1-shweta.choudaha@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180321173618.74200-2-shweta.choudaha@gmail.com> References: <20180321173618.74200-2-shweta.choudaha@gmail.com> Subject: [dpdk-dev] [PATCH v3] net/ixgbe: Add access and locking APIs for MDIO X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Apr 2018 13:59:41 -0000 From: Shweta Choudaha Add ixgbe MDIO lock/unlock and access APIs to read and write registers using specific device address. This provides MDIO access to any devices that are not associated with the autoprobed PHY.Export these APIs via the map file Signed-off-by: Shweta Choudaha Reviewed-by: Chas Williams Reviewed-by: Luca Boccassi --- drivers/net/ixgbe/rte_pmd_ixgbe.c | 202 ++++++++++++++++++++++++++++ drivers/net/ixgbe/rte_pmd_ixgbe.h | 71 ++++++++++ drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 9 ++ 3 files changed, 282 insertions(+) diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.c b/drivers/net/ixgbe/rte_pmd_ixgbe.c index d8ca8ca31..b028dd401 100644 --- a/drivers/net/ixgbe/rte_pmd_ixgbe.c +++ b/drivers/net/ixgbe/rte_pmd_ixgbe.c @@ -5,6 +5,7 @@ #include #include "base/ixgbe_api.h" +#include "base/ixgbe_x550.h" #include "ixgbe_ethdev.h" #include "rte_pmd_ixgbe.h" @@ -1012,3 +1013,204 @@ rte_pmd_ixgbe_bypass_wd_reset(uint16_t port_id) return ixgbe_bypass_wd_reset(dev); } #endif + +/** + * rte_pmd_ixgbe_acquire_swfw - Acquire SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to acquire + * + * Acquires the SWFW semaphore and get the shared phy token as needed + */ +STATIC s32 rte_pmd_ixgbe_acquire_swfw(struct ixgbe_hw *hw, u32 mask) +{ + int retries = FW_PHY_TOKEN_RETRIES; + s32 status = IXGBE_SUCCESS; + + while (--retries) { + status = ixgbe_acquire_swfw_semaphore(hw, mask); + if (status) { + PMD_DRV_LOG(ERR, "Get SWFW sem failed, Status = %d\n", + status); + return status; + } + status = ixgbe_get_phy_token(hw); + if (status == IXGBE_SUCCESS) + return IXGBE_SUCCESS; + + if (status == IXGBE_ERR_TOKEN_RETRY) + PMD_DRV_LOG(ERR, "Get PHY token failed, Status = %d\n", + status); + + ixgbe_release_swfw_semaphore(hw, mask); + if (status != IXGBE_ERR_TOKEN_RETRY) { + PMD_DRV_LOG(ERR, + "Retry get PHY token failed, Status=%d\n", + status); + return status; + } + } + PMD_DRV_LOG(ERR, "swfw acquisition retries failed!: PHY ID = 0x%08X\n", + hw->phy.id); + return status; +} + +/** + * rte_pmd_ixgbe_release_swfw_sync - Release SWFW semaphore + * @hw: pointer to hardware structure + * @mask: Mask to specify which semaphore to release + * + * Releases the SWFW semaphore and puts the shared phy token as needed + */ +STATIC void rte_pmd_ixgbe_release_swfw(struct ixgbe_hw *hw, u32 mask) +{ + ixgbe_put_phy_token(hw); + ixgbe_release_swfw_semaphore(hw, mask); +} + +int __rte_experimental +rte_pmd_ixgbe_lock_mdio(uint16_t port) +{ + struct ixgbe_hw *hw; + struct rte_eth_dev *dev; + u32 swfw_mask; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); + dev = &rte_eth_devices[port]; + if (!is_ixgbe_supported(dev)) + return -ENOTSUP; + + hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + if (!hw) + return -ENOTSUP; + + if (hw->bus.lan_id) + swfw_mask = IXGBE_GSSR_PHY1_SM; + else + swfw_mask = IXGBE_GSSR_PHY0_SM; + + if (rte_pmd_ixgbe_acquire_swfw(hw, swfw_mask)) + return IXGBE_ERR_SWFW_SYNC; + + return IXGBE_SUCCESS; +} + +int __rte_experimental +rte_pmd_ixgbe_unlock_mdio(uint16_t port) +{ + struct rte_eth_dev *dev; + struct ixgbe_hw *hw; + u32 swfw_mask; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); + + dev = &rte_eth_devices[port]; + if (!is_ixgbe_supported(dev)) + return -ENOTSUP; + + hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + if (!hw) + return -ENOTSUP; + + if (hw->bus.lan_id) + swfw_mask = IXGBE_GSSR_PHY1_SM; + else + swfw_mask = IXGBE_GSSR_PHY0_SM; + + rte_pmd_ixgbe_release_swfw(hw, swfw_mask); + + return IXGBE_SUCCESS; +} + +int __rte_experimental +rte_pmd_ixgbe_mdio_read_unlocked(uint16_t port, uint32_t reg_addr, + uint32_t dev_type, uint16_t *phy_data) +{ + struct ixgbe_hw *hw; + struct rte_eth_dev *dev; + u32 i, data, command; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); + dev = &rte_eth_devices[port]; + if (!is_ixgbe_supported(dev)) + return -ENOTSUP; + + hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + if (!hw) + return -ENOTSUP; + + /* Setup and write the read command */ + command = (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (dev_type << IXGBE_MSCA_PHY_ADDR_SHIFT) | + IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_READ_AUTOINC | + IXGBE_MSCA_MDI_COMMAND; + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* Check every 10 usec to see if the access completed. + * The MDI Command bit will clear when the operation is + * complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if (!(command & IXGBE_MSCA_MDI_COMMAND)) + break; + } + if (command & IXGBE_MSCA_MDI_COMMAND) + return IXGBE_ERR_PHY; + + /* Read operation is complete. Get the data from MSRWD */ + data = IXGBE_READ_REG(hw, IXGBE_MSRWD); + data >>= IXGBE_MSRWD_READ_DATA_SHIFT; + *phy_data = (u16)data; + + return 0; +} + +int __rte_experimental +rte_pmd_ixgbe_mdio_write_unlocked(uint16_t port, uint32_t reg_addr, + uint32_t dev_type, uint16_t phy_data) +{ + struct ixgbe_hw *hw; + u32 i, command; + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); + dev = &rte_eth_devices[port]; + if (!is_ixgbe_supported(dev)) + return -ENOTSUP; + + hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + if (!hw) + return -ENOTSUP; + + /* Put the data in the MDI single read and write data register*/ + IXGBE_WRITE_REG(hw, IXGBE_MSRWD, (u32)phy_data); + + /* Setup and write the write command */ + command = (reg_addr << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (dev_type << IXGBE_MSCA_PHY_ADDR_SHIFT) | + IXGBE_MSCA_OLD_PROTOCOL | IXGBE_MSCA_WRITE | + IXGBE_MSCA_MDI_COMMAND; + + IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); + + /* Check every 10 usec to see if the access completed. + * The MDI Command bit will clear when the operation is + * complete + */ + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { + usec_delay(10); + + command = IXGBE_READ_REG(hw, IXGBE_MSCA); + if (!(command & IXGBE_MSCA_MDI_COMMAND)) + break; + } + if (command & IXGBE_MSCA_MDI_COMMAND) { + ERROR_REPORT1(IXGBE_ERROR_POLLING, + "PHY write cmd didn't complete\n"); + return IXGBE_ERR_PHY; + } + return 0; +} diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe.h b/drivers/net/ixgbe/rte_pmd_ixgbe.h index 11a9f334b..6ba882c65 100644 --- a/drivers/net/ixgbe/rte_pmd_ixgbe.h +++ b/drivers/net/ixgbe/rte_pmd_ixgbe.h @@ -573,6 +573,77 @@ int rte_pmd_ixgbe_bypass_wd_timeout_show(uint16_t port, uint32_t *wd_timeout); */ int rte_pmd_ixgbe_bypass_wd_reset(uint16_t port); +/** + * Acquire swfw semaphore lock for MDIO access + * + * @param port + * The port identifier of the Ethernet device. + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. + * - (-ENODEV) if *port* invalid. + * - (IXGBE_ERR_SWFW_SYNC) If sw/fw semaphore acquisition failed + */ +int __rte_experimental +rte_pmd_ixgbe_lock_mdio(uint16_t port); + +/** + * Release swfw semaphore lock used for MDIO access + * + * @param port + * The port identifier of the Ethernet device. + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. + * - (-ENODEV) if *port* invalid. + */ +int __rte_experimental +rte_pmd_ixgbe_unlock_mdio(uint16_t port); + +/** + * Read PHY register using MDIO without MDIO lock + * The lock must be taken separately before calling this + * API + * @param port + * The port identifier of the Ethernet device. + * @param reg_addr + * 32 bit PHY Register + * @param dev_type + * Used to define device base address + * @param phy_data + * Pointer for reading PHY register data + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. + * - (-ENODEV) if *port* invalid. + * - (IXGBE_ERR_PHY) If PHY read command failed + */ +int __rte_experimental +rte_pmd_ixgbe_mdio_read_unlocked(uint16_t port, uint32_t reg_addr, + uint32_t dev_type, uint16_t *phy_data); + +/** + * Write data to PHY register using without MDIO lock + * The lock must be taken separately before calling this + * API + * + * @param port + * The port identifier of the Ethernet device. + * @param reg_addr + * 32 bit PHY Register + * @param dev_type + * Used to define device base address + * @param phy_data + * Data to write to PHY register + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support. + * - (-ENODEV) if *port* invalid. + * - (IXGBE_ERR_PHY) If PHY read command failed + */ +int __rte_experimental +rte_pmd_ixgbe_mdio_write_unlocked(uint16_t port, uint32_t reg_addr, + uint32_t dev_type, uint16_t phy_data); /** * Response sent back to ixgbe driver from user app after callback diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map index bf776742c..d36f90e74 100644 --- a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map +++ b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map @@ -52,3 +52,12 @@ DPDK_17.08 { rte_pmd_ixgbe_bypass_wd_timeout_show; rte_pmd_ixgbe_bypass_wd_timeout_store; } DPDK_17.05; + +EXPERIMENTAL { + global: + + rte_pmd_ixgbe_lock_mdio; + rte_pmd_ixgbe_unlock_mdio; + rte_pmd_ixgbe_mdio_read_unlocked; + rte_pmd_ixgbe_mdio_write_unlocked; +} DPDK_18.05; -- 2.11.0