DPDK patches and discussions
 help / color / mirror / Atom feed
From: Pavel Belous <Pavel.Belous@aquantia.com>
To: "dev@dpdk.org" <dev@dpdk.org>
Cc: Ferruh Yigit <ferruh.yigit@intel.com>,
	Akhil Goyal <akhil.goyal@nxp.com>,
	 John McNamara <john.mcnamara@intel.com>,
	Declan Doherty <declan.doherty@intel.com>,
	Konstantin Ananyev <konstantin.ananyev@intel.com>,
	Thomas Monjalon <thomas@monjalon.net>,
	Igor Russkikh <Igor.Russkikh@aquantia.com>,
	Fenilkumar Patel <fenpatel@cisco.com>,
	 Hitesh K Maisheri <hmaisher@cisco.com>,
	Pavel Belous <Pavel.Belous@aquantia.com>,
	Pavel Belous <Pavel.Belous@aquantia.com>
Subject: [dpdk-dev] [RFC v2 3/7] net/atlantic: Add helper functions for PHY access
Date: Fri, 25 Oct 2019 17:53:58 +0000	[thread overview]
Message-ID: <3df482b37f015591e4d121e859d0c412879b233c.1571928488.git.Pavel.Belous@aquantia.com> (raw)
In-Reply-To: <cover.1571928488.git.Pavel.Belous@aquantia.com>

From: Pavel Belous <Pavel.Belous@aquantia.com>

Aquantia AQC107/AQC108 ethernet controllers includes MAC and PHY part.
Some network features, like MACSec, are configured directly in the PHY part.

This patch adds helper functions for accessing PHY part via internal MDIO interface.

Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
---
 drivers/net/atlantic/Makefile      |   2 +
 drivers/net/atlantic/macsec/mdio.c | 328 +++++++++++++++++++++++++++++++++++++
 drivers/net/atlantic/macsec/mdio.h |  19 +++
 drivers/net/atlantic/meson.build   |   1 +
 4 files changed, 350 insertions(+)
 create mode 100644 drivers/net/atlantic/macsec/mdio.c
 create mode 100644 drivers/net/atlantic/macsec/mdio.h

diff --git a/drivers/net/atlantic/Makefile b/drivers/net/atlantic/Makefile
index fc12e6a..6340588 100644
--- a/drivers/net/atlantic/Makefile
+++ b/drivers/net/atlantic/Makefile
@@ -21,6 +21,7 @@ LDLIBS += -lrte_ethdev -lrte_net
 LDLIBS += -lrte_bus_pci
 
 VPATH += $(SRCDIR)/hw_atl
+VPATH += $(SRCDIR)/macsec
 
 #
 # all source are stored in SRCS-y
@@ -33,5 +34,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_llh.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_utils_fw2x.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += hw_atl_b0.c
 SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += rte_pmd_atlantic.c
+SRCS-$(CONFIG_RTE_LIBRTE_ATLANTIC_PMD) += mdio.c
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/atlantic/macsec/mdio.c b/drivers/net/atlantic/macsec/mdio.c
new file mode 100644
index 0000000..a662f58
--- /dev/null
+++ b/drivers/net/atlantic/macsec/mdio.c
@@ -0,0 +1,328 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Aquantia Corporation
+ */
+
+#include "errno.h"
+#include "../atl_hw_regs.h"
+#include "../atl_logs.h"
+#include "../hw_atl/hw_atl_llh.h"
+#include "../hw_atl/hw_atl_b0.h"
+#include "../hw_atl/hw_atl_b0_internal.h"
+#include "mdio.h"
+
+static inline uint32_t macValRead(uint32_t reg, uint32_t msk, uint32_t shift)
+{
+    return (reg & msk) >> shift;
+}
+
+static inline void macValWrite(uint32_t* reg, uint32_t msk, uint32_t shift, uint32_t val)
+{
+    *reg = (*reg & ~msk) | (val << shift);
+}
+
+static inline uint32_t macBitRead(uint32_t reg, uint32_t msk)
+{
+    return reg & msk;
+}
+
+static inline uint32_t regGlobalMdioInterface1Get(void *hw)
+{
+    return aq_hw_read_reg(hw, 0x280);
+}
+
+static inline void valGlobalMdioInterface1MdioClockEnableSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x00004000, 14, val);
+}
+
+static inline void regGlobalMdioInterface1Set(void *hw, uint32_t val)
+{
+    aq_hw_write_reg(hw, 0x280, val);
+}
+
+static inline void valGlobalMdioInterface4MdioAddressSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x0000FFFF, 0, val);
+}
+
+static inline void regGlobalMdioInterface4Set(void *hw, uint32_t val)
+{
+    aq_hw_write_reg(hw, 0x28C, val);
+}
+
+static inline void valGlobalMdioInterface2MdioExecuteOperationSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x00008000, 15, val);
+}
+
+static inline void valGlobalMdioInterface2MdioOpModeSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x00003000, 12, val);
+}
+
+static inline void valGlobalMdioInterface2MdioPhyAddressSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x000003FF, 0, val);
+}
+
+static inline void regGlobalMdioInterface2Set(void *hw, uint32_t val)
+{
+    aq_hw_write_reg(hw, 0x284, val);
+}
+
+static inline uint32_t regGlobalMdioInterface2Get(void *hw)
+{
+    return aq_hw_read_reg(hw, 0x284);
+}
+
+static inline void valGlobalMdioInterface3MdioWriteDataSet(uint32_t *reg, uint32_t val)
+{
+    macValWrite(reg, 0x0000FFFF, 0, val);
+}
+
+static inline void regGlobalMdioInterface3Set(void *hw, uint32_t val)
+{
+    aq_hw_write_reg(hw, 0x288, val);
+}
+
+static inline uint32_t regGlobalMdioInterface5Get(void *hw)
+{
+    return aq_hw_read_reg(hw, 0x290);
+}
+
+static inline uint32_t valGlobalMdioInterface5MdioReadDataGet(uint32_t reg)
+{
+    return macValRead(reg, 0x0000FFFF, 0);
+}
+
+static inline uint32_t bitGlobalMdioInterface2MdioBusyGet(uint32_t reg)
+{
+    return macBitRead(reg, 0x80000000);
+}
+
+
+/* Operation Mode for MDIO */
+#define MDIO_OP_NO 0 /* No Op */
+#define MDIO_OP_READ 1 /* Read Op */
+#define MDIO_OP_WRITE 2 /* Write Op */
+#define MDIO_OP_ADDR 3 /* Address Op */
+
+#define MDIO_COMMAND_TIMEOUT 100
+#define MDIO_SEMAPHORE_TIMEOUT_MS 30 /* msec. */
+
+
+/* 32 bits command + 32 bits preamble = 64 */
+#define MDIO_ONE_CMD_CLOCK_TICKS     64
+/* Wait 10 MDIO transactions */
+#define TIMEOUT_BUSY_WAIT_COUNT     ((MIPS_COUNT_HZ * MDIO_ONE_CMD_CLOCK_TICKS / MDIO_HZ) * 10)
+
+static int mdio_phy_addr = (0 << 5);
+
+
+static inline unsigned int mMdioBusyCheck(void *hw)
+{
+    return bitGlobalMdioInterface2MdioBusyGet(regGlobalMdioInterface2Get(hw));
+}
+
+static int mBusyWait(struct aq_hw_s *hw)
+{
+    unsigned i = 0;
+
+    for (i = 1000U; mMdioBusyCheck(hw) && i; i--){};
+
+    if (i == 0) {
+	PMD_DRV_LOG(ERR, "Mdio busy!!");
+	return 1;
+    }
+
+    return 0;
+}
+
+
+static inline void mSendPhyAddress(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr)
+{
+    uint32_t reg;
+
+    /* Set MDIO Address (0x28c) */
+    reg = 0;
+    valGlobalMdioInterface4MdioAddressSet(&reg, addr);
+    regGlobalMdioInterface4Set(hw, reg);
+
+    /* Set MDIO Address Operation and PHY Address (0x284) */
+    reg = 0;
+    valGlobalMdioInterface2MdioExecuteOperationSet(&reg, 1);
+    valGlobalMdioInterface2MdioOpModeSet(&reg, MDIO_OP_ADDR);
+    valGlobalMdioInterface2MdioPhyAddressSet(&reg, mdio_phy_addr | mmd);
+    regGlobalMdioInterface2Set(hw, reg);
+}
+
+static void mSendDummyWriteCmd(struct aq_hw_s *hw)
+{
+    uint32_t reg;
+
+    // Set data (0x288)
+    reg = 0;
+    valGlobalMdioInterface3MdioWriteDataSet(&reg, 0);
+    regGlobalMdioInterface3Set(hw, reg);
+
+    // Write operation (0x284)
+    reg = 0;
+    valGlobalMdioInterface2MdioExecuteOperationSet(&reg, 1);
+    valGlobalMdioInterface2MdioOpModeSet(&reg, MDIO_OP_WRITE);
+    valGlobalMdioInterface2MdioPhyAddressSet(&reg, 0);
+    regGlobalMdioInterface2Set(hw, reg);
+}
+
+static inline void mSendReadCmd(struct aq_hw_s *hw, unsigned int mmd)
+{
+    uint32_t reg;
+
+    // Execute Read Operation (0x284)
+    reg = 0;
+    valGlobalMdioInterface2MdioExecuteOperationSet(&reg, 1);
+    valGlobalMdioInterface2MdioOpModeSet(&reg, MDIO_OP_READ);
+    valGlobalMdioInterface2MdioPhyAddressSet(&reg, mdio_phy_addr | mmd);
+    regGlobalMdioInterface2Set(hw, reg);
+}
+
+static inline void mSendWriteCmd(struct aq_hw_s *hw, unsigned int mmd)
+{
+    uint32_t reg;
+
+    // Execute Read Operation (0x284)
+    reg = 0;
+    valGlobalMdioInterface2MdioExecuteOperationSet(&reg, 1);
+    valGlobalMdioInterface2MdioOpModeSet(&reg, MDIO_OP_WRITE);
+    valGlobalMdioInterface2MdioPhyAddressSet(&reg, mdio_phy_addr | mmd);
+    regGlobalMdioInterface2Set(hw, reg);
+}
+
+static inline unsigned short int mReadData(struct aq_hw_s *hw)
+{
+    // Register 0x290
+    return valGlobalMdioInterface5MdioReadDataGet(regGlobalMdioInterface5Get(hw));
+}
+
+static inline void mWriteData(struct aq_hw_s *hw, unsigned short int val)
+{
+    uint32_t reg;
+
+    // Register 0x288
+    reg = 0;
+    valGlobalMdioInterface3MdioWriteDataSet(&reg, val);
+    regGlobalMdioInterface3Set(hw, reg);
+}
+
+
+static int __mdioRead(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int* data)
+{
+    int ret = -1;
+
+    /* Execute Address Operation */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendPhyAddress(hw, mmd, addr);
+
+    /* Dummy write transaction */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendDummyWriteCmd(hw);
+
+    /* Read command */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendReadCmd(hw, mmd);
+
+    /* Read MDIO Data */
+    if (mBusyWait(hw))
+        goto _exit;
+    *data = mReadData(hw);
+
+    ret = 0;
+
+_exit:
+    return ret;
+}
+
+static
+int __mdioWrite(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int data)
+{
+    int ret = -1;
+
+    /* Execute Address Operation */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendPhyAddress(hw, mmd, addr);
+
+    /* Dummy write transaction */
+    if (mBusyWait(hw))
+        goto _exit;
+    mSendDummyWriteCmd(hw);
+
+    /* Write command */
+    if (mBusyWait(hw))
+        goto _exit;
+    mWriteData(hw, data);
+    mSendWriteCmd(hw, mmd);
+
+    /* Expect completion of the operation */
+    if (mBusyWait(hw))
+        goto _exit;
+
+    ret = 0;
+
+_exit:
+    return ret;
+}
+
+int mdioRead(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int* data)
+{
+    uint32_t reg;
+    int ret;
+
+    // Send Dummy Transaction
+    if (mBusyWait(hw))
+        return -1;
+    mSendDummyWriteCmd(hw);
+
+    // Enable MDIO Clock (active low) (0x280)
+    reg = regGlobalMdioInterface1Get(hw);
+    valGlobalMdioInterface1MdioClockEnableSet(&reg, 0);
+    regGlobalMdioInterface1Set(hw, reg);
+
+    ret = __mdioRead(hw, mmd, addr, data);
+
+    // Disable MDIO Clock (0x280)
+    reg = regGlobalMdioInterface1Get(hw);
+    valGlobalMdioInterface1MdioClockEnableSet(&reg, 1);
+    regGlobalMdioInterface1Set(hw, reg);
+
+    return ret;
+}
+
+int mdioWrite(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int data)
+{
+    uint32_t reg;
+    int ret;
+
+    // Send Dummy Transaction
+    if (mBusyWait(hw))
+        return -1;
+    mSendDummyWriteCmd(hw);
+
+    // Enable MDIO Clock (active low) (0x280)
+    reg = regGlobalMdioInterface1Get(hw);
+    valGlobalMdioInterface1MdioClockEnableSet(&reg, 0);
+    regGlobalMdioInterface1Set(hw, reg);
+
+    ret = __mdioWrite(hw, mmd, addr, data);
+
+    // Disable MDIO Clock (0x280)
+    reg = regGlobalMdioInterface1Get(hw);
+    valGlobalMdioInterface1MdioClockEnableSet(&reg, 1);
+    regGlobalMdioInterface1Set(hw, reg);
+
+    return ret;
+}
+
+
diff --git a/drivers/net/atlantic/macsec/mdio.h b/drivers/net/atlantic/macsec/mdio.h
new file mode 100644
index 0000000..907f04f
--- /dev/null
+++ b/drivers/net/atlantic/macsec/mdio.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Aquantia Corporation
+ */
+
+#ifndef __MDIO_HH__
+#define __MDIO_HH__
+
+
+#include "../atl_types.h"
+#include "../hw_atl/hw_atl_utils.h"
+
+
+#define MMD_GLOBAL 0x1E
+
+
+int mdioRead(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int* data);
+int mdioWrite(struct aq_hw_s *hw, unsigned int mmd, unsigned int addr, unsigned short int data);
+
+#endif
diff --git a/drivers/net/atlantic/meson.build b/drivers/net/atlantic/meson.build
index 919d741..d1c66f4 100644
--- a/drivers/net/atlantic/meson.build
+++ b/drivers/net/atlantic/meson.build
@@ -12,4 +12,5 @@ sources = files(
 	'hw_atl/hw_atl_utils_fw2x.c',
 	'hw_atl/hw_atl_utils.c',
 	'rte_pmd_atlantic.c',
+	'macsec/mdio.c',
 )
-- 
2.7.4


  parent reply	other threads:[~2019-10-25 17:54 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-25 17:53 [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Pavel Belous
2019-10-25 17:53 ` [dpdk-dev] [RFC v2 1/7] security: MACSEC infrastructure data declarations Pavel Belous
2019-10-25 17:53 ` [dpdk-dev] [RFC v2 2/7] security: Update rte_security documentation Pavel Belous
2019-10-25 17:53 ` Pavel Belous [this message]
2019-10-25 17:54 ` [dpdk-dev] [RFC v2 4/7] net/atlantic: add MACSEC internal HW data declaration and functions Pavel Belous
2019-10-25 17:54 ` [dpdk-dev] [RFC v2 5/7] net/atlantic: implementation of the MACSEC using rte_security interface Pavel Belous
2019-10-25 17:54 ` [dpdk-dev] [RFC v2 6/7] app/testpmd: macsec on/off commands " Pavel Belous
2019-10-25 19:01   ` Stephen Hemminger
2019-10-25 19:02   ` Stephen Hemminger
2019-10-25 17:54 ` [dpdk-dev] [RFC v2 7/7] app/testpmd: macsec adding RX/TX SC " Pavel Belous
2020-01-27 11:25 ` [dpdk-dev] [RFC v2 0/7] RFC: Support MACSEC offload in the RTE_SECURITY infrastructure Akhil Goyal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3df482b37f015591e4d121e859d0c412879b233c.1571928488.git.Pavel.Belous@aquantia.com \
    --to=pavel.belous@aquantia.com \
    --cc=Igor.Russkikh@aquantia.com \
    --cc=akhil.goyal@nxp.com \
    --cc=declan.doherty@intel.com \
    --cc=dev@dpdk.org \
    --cc=fenpatel@cisco.com \
    --cc=ferruh.yigit@intel.com \
    --cc=hmaisher@cisco.com \
    --cc=john.mcnamara@intel.com \
    --cc=konstantin.ananyev@intel.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).