@@ -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
new file mode 100644
@@ -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(®, addr);
+ regGlobalMdioInterface4Set(hw, reg);
+
+ /* Set MDIO Address Operation and PHY Address (0x284) */
+ reg = 0;
+ valGlobalMdioInterface2MdioExecuteOperationSet(®, 1);
+ valGlobalMdioInterface2MdioOpModeSet(®, MDIO_OP_ADDR);
+ valGlobalMdioInterface2MdioPhyAddressSet(®, mdio_phy_addr | mmd);
+ regGlobalMdioInterface2Set(hw, reg);
+}
+
+static void mSendDummyWriteCmd(struct aq_hw_s *hw)
+{
+ uint32_t reg;
+
+ // Set data (0x288)
+ reg = 0;
+ valGlobalMdioInterface3MdioWriteDataSet(®, 0);
+ regGlobalMdioInterface3Set(hw, reg);
+
+ // Write operation (0x284)
+ reg = 0;
+ valGlobalMdioInterface2MdioExecuteOperationSet(®, 1);
+ valGlobalMdioInterface2MdioOpModeSet(®, MDIO_OP_WRITE);
+ valGlobalMdioInterface2MdioPhyAddressSet(®, 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(®, 1);
+ valGlobalMdioInterface2MdioOpModeSet(®, MDIO_OP_READ);
+ valGlobalMdioInterface2MdioPhyAddressSet(®, 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(®, 1);
+ valGlobalMdioInterface2MdioOpModeSet(®, MDIO_OP_WRITE);
+ valGlobalMdioInterface2MdioPhyAddressSet(®, 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(®, 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(®, 0);
+ regGlobalMdioInterface1Set(hw, reg);
+
+ ret = __mdioRead(hw, mmd, addr, data);
+
+ // Disable MDIO Clock (0x280)
+ reg = regGlobalMdioInterface1Get(hw);
+ valGlobalMdioInterface1MdioClockEnableSet(®, 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(®, 0);
+ regGlobalMdioInterface1Set(hw, reg);
+
+ ret = __mdioWrite(hw, mmd, addr, data);
+
+ // Disable MDIO Clock (0x280)
+ reg = regGlobalMdioInterface1Get(hw);
+ valGlobalMdioInterface1MdioClockEnableSet(®, 1);
+ regGlobalMdioInterface1Set(hw, reg);
+
+ return ret;
+}
+
+
new file mode 100644
@@ -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
@@ -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',
)