net/ngbe: identify and reset PHY
authorJiawen Wu <jiawenwu@trustnetic.com>
Thu, 8 Jul 2021 09:32:28 +0000 (17:32 +0800)
committerAndrew Rybchenko <Andrew.Rybchenko@oktetlabs.ru>
Mon, 12 Jul 2021 15:55:21 +0000 (17:55 +0200)
Identify PHY to get the PHY type, and perform a PHY reset.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
13 files changed:
drivers/net/ngbe/base/meson.build
drivers/net/ngbe/base/ngbe_dummy.h
drivers/net/ngbe/base/ngbe_hw.c
drivers/net/ngbe/base/ngbe_hw.h
drivers/net/ngbe/base/ngbe_phy.c [new file with mode: 0644]
drivers/net/ngbe/base/ngbe_phy.h [new file with mode: 0644]
drivers/net/ngbe/base/ngbe_phy_mvl.c [new file with mode: 0644]
drivers/net/ngbe/base/ngbe_phy_mvl.h [new file with mode: 0644]
drivers/net/ngbe/base/ngbe_phy_rtl.c [new file with mode: 0644]
drivers/net/ngbe/base/ngbe_phy_rtl.h [new file with mode: 0644]
drivers/net/ngbe/base/ngbe_phy_yt.c [new file with mode: 0644]
drivers/net/ngbe/base/ngbe_phy_yt.h [new file with mode: 0644]
drivers/net/ngbe/base/ngbe_type.h

index 34f7556..a1a9c2f 100644 (file)
@@ -5,6 +5,10 @@ sources = [
         'ngbe_eeprom.c',
         'ngbe_hw.c',
         'ngbe_mng.c',
+        'ngbe_phy.c',
+        'ngbe_phy_rtl.c',
+        'ngbe_phy_mvl.c',
+        'ngbe_phy_yt.c',
 ]
 
 error_cflags = []
index 3445e74..51ae0ac 100644 (file)
@@ -64,6 +64,39 @@ static inline s32 ngbe_mac_init_thermal_ssth_dummy(struct ngbe_hw *TUP0)
 {
        return NGBE_ERR_OPS_DUMMY;
 }
+static inline s32 ngbe_mac_check_overtemp_dummy(struct ngbe_hw *TUP0)
+{
+       return NGBE_ERR_OPS_DUMMY;
+}
+/* struct ngbe_phy_operations */
+static inline s32 ngbe_phy_identify_dummy(struct ngbe_hw *TUP0)
+{
+       return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_reset_hw_dummy(struct ngbe_hw *TUP0)
+{
+       return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_read_reg_dummy(struct ngbe_hw *TUP0, u32 TUP1,
+                                       u32 TUP2, u16 *TUP3)
+{
+       return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_write_reg_dummy(struct ngbe_hw *TUP0, u32 TUP1,
+                                       u32 TUP2, u16 TUP3)
+{
+       return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_read_reg_unlocked_dummy(struct ngbe_hw *TUP0,
+                                       u32 TUP1, u32 TUP2, u16 *TUP3)
+{
+       return NGBE_ERR_OPS_DUMMY;
+}
+static inline s32 ngbe_phy_write_reg_unlocked_dummy(struct ngbe_hw *TUP0,
+                                       u32 TUP1, u32 TUP2, u16 TUP3)
+{
+       return NGBE_ERR_OPS_DUMMY;
+}
 static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw)
 {
        hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy;
@@ -75,6 +108,13 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw)
        hw->mac.acquire_swfw_sync = ngbe_mac_acquire_swfw_sync_dummy;
        hw->mac.release_swfw_sync = ngbe_mac_release_swfw_sync_dummy;
        hw->mac.init_thermal_sensor_thresh = ngbe_mac_init_thermal_ssth_dummy;
+       hw->mac.check_overtemp = ngbe_mac_check_overtemp_dummy;
+       hw->phy.identify = ngbe_phy_identify_dummy;
+       hw->phy.reset_hw = ngbe_phy_reset_hw_dummy;
+       hw->phy.read_reg = ngbe_phy_read_reg_dummy;
+       hw->phy.write_reg = ngbe_phy_write_reg_dummy;
+       hw->phy.read_reg_unlocked = ngbe_phy_read_reg_unlocked_dummy;
+       hw->phy.write_reg_unlocked = ngbe_phy_write_reg_unlocked_dummy;
 }
 
 #endif /* _NGBE_TYPE_DUMMY_H_ */
index 446f4b5..662fb17 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include "ngbe_type.h"
+#include "ngbe_phy.h"
 #include "ngbe_eeprom.h"
 #include "ngbe_mng.h"
 #include "ngbe_hw.h"
@@ -124,6 +125,15 @@ s32 ngbe_reset_hw_em(struct ngbe_hw *hw)
        if (status != 0)
                return status;
 
+       /* Identify PHY and related function pointers */
+       status = ngbe_init_phy(hw);
+       if (status)
+               return status;
+
+       /* Reset PHY */
+       if (!hw->phy.reset_disable)
+               hw->phy.reset_hw(hw);
+
        wr32(hw, NGBE_RST, NGBE_RST_LAN(hw->bus.lan_id));
        ngbe_flush(hw);
        msec_delay(50);
@@ -307,6 +317,24 @@ s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw)
        return 0;
 }
 
+s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw)
+{
+       s32 status = 0;
+       u32 ts_state;
+
+       DEBUGFUNC("ngbe_mac_check_overtemp");
+
+       /* Check that the LASI temp alarm status was triggered */
+       ts_state = rd32(hw, NGBE_TSALM);
+
+       if (ts_state & NGBE_TSALM_HI)
+               status = NGBE_ERR_UNDERTEMP;
+       else if (ts_state & NGBE_TSALM_LO)
+               status = NGBE_ERR_OVERTEMP;
+
+       return status;
+}
+
 void ngbe_disable_rx(struct ngbe_hw *hw)
 {
        u32 pfdtxgswc;
@@ -434,6 +462,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
 {
        struct ngbe_bus_info *bus = &hw->bus;
        struct ngbe_mac_info *mac = &hw->mac;
+       struct ngbe_phy_info *phy = &hw->phy;
        struct ngbe_rom_info *rom = &hw->rom;
 
        DEBUGFUNC("ngbe_init_ops_pf");
@@ -441,6 +470,14 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
        /* BUS */
        bus->set_lan_id = ngbe_set_lan_id_multi_port;
 
+       /* PHY */
+       phy->identify = ngbe_identify_phy;
+       phy->read_reg = ngbe_read_phy_reg;
+       phy->write_reg = ngbe_write_phy_reg;
+       phy->read_reg_unlocked = ngbe_read_phy_reg_mdi;
+       phy->write_reg_unlocked = ngbe_write_phy_reg_mdi;
+       phy->reset_hw = ngbe_reset_phy;
+
        /* MAC */
        mac->init_hw = ngbe_init_hw;
        mac->reset_hw = ngbe_reset_hw_em;
@@ -450,6 +487,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
 
        /* Manageability interface */
        mac->init_thermal_sensor_thresh = ngbe_init_thermal_sensor_thresh;
+       mac->check_overtemp = ngbe_mac_check_overtemp;
 
        /* EEPROM */
        rom->init_params = ngbe_init_eeprom_params;
index 207d4b2..2205156 100644 (file)
@@ -21,10 +21,12 @@ s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask);
 void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask);
 
 s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw);
+s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw);
 void ngbe_disable_rx(struct ngbe_hw *hw);
 s32 ngbe_init_shared_code(struct ngbe_hw *hw);
 s32 ngbe_set_mac_type(struct ngbe_hw *hw);
 s32 ngbe_init_ops_pf(struct ngbe_hw *hw);
+s32 ngbe_init_phy(struct ngbe_hw *hw);
 void ngbe_map_device_id(struct ngbe_hw *hw);
 
 #endif /* _NGBE_HW_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_phy.c b/drivers/net/ngbe/base/ngbe_phy.c
new file mode 100644 (file)
index 0000000..61bb953
--- /dev/null
@@ -0,0 +1,426 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#include "ngbe_hw.h"
+#include "ngbe_phy.h"
+
+s32 ngbe_mdi_map_register(mdi_reg_t *reg, mdi_reg_22_t *reg22)
+{
+       bool match = 1;
+       switch (reg->device_type) {
+       case NGBE_MD_DEV_PMA_PMD:
+               switch (reg->addr) {
+               case NGBE_MD_PHY_ID_HIGH:
+               case NGBE_MD_PHY_ID_LOW:
+                       reg22->page = 0;
+                       reg22->addr = reg->addr;
+                       reg22->device_type = 0;
+                       break;
+               default:
+                       match = 0;
+               }
+               break;
+       default:
+               match = 0;
+               break;
+       }
+
+       if (!match) {
+               reg22->page = reg->device_type;
+               reg22->device_type = reg->device_type;
+               reg22->addr = reg->addr;
+       }
+
+       return 0;
+}
+
+/**
+ * ngbe_probe_phy - Identify a single address for a PHY
+ * @hw: pointer to hardware structure
+ * @phy_addr: PHY address to probe
+ *
+ * Returns true if PHY found
+ */
+static bool ngbe_probe_phy(struct ngbe_hw *hw, u16 phy_addr)
+{
+       if (!ngbe_validate_phy_addr(hw, phy_addr)) {
+               DEBUGOUT("Unable to validate PHY address 0x%04X\n",
+                       phy_addr);
+               return false;
+       }
+
+       if (ngbe_get_phy_id(hw))
+               return false;
+
+       hw->phy.type = ngbe_get_phy_type_from_id(hw);
+       if (hw->phy.type == ngbe_phy_unknown)
+               return false;
+
+       return true;
+}
+
+/**
+ *  ngbe_identify_phy - Get physical layer module
+ *  @hw: pointer to hardware structure
+ *
+ *  Determines the physical layer module found on the current adapter.
+ **/
+s32 ngbe_identify_phy(struct ngbe_hw *hw)
+{
+       s32 err = NGBE_ERR_PHY_ADDR_INVALID;
+       u16 phy_addr;
+
+       DEBUGFUNC("ngbe_identify_phy");
+
+       if (hw->phy.type != ngbe_phy_unknown)
+               return 0;
+
+       /* select clause22 */
+       wr32(hw, NGBE_MDIOMODE, NGBE_MDIOMODE_MASK);
+
+       for (phy_addr = 0; phy_addr < NGBE_MAX_PHY_ADDR; phy_addr++) {
+               if (ngbe_probe_phy(hw, phy_addr)) {
+                       err = 0;
+                       break;
+               }
+       }
+
+       return err;
+}
+
+/**
+ * ngbe_check_reset_blocked - check status of MNG FW veto bit
+ * @hw: pointer to the hardware structure
+ *
+ * This function checks the STAT.MNGVETO bit to see if there are
+ * any constraints on link from manageability.  For MAC's that don't
+ * have this bit just return faluse since the link can not be blocked
+ * via this method.
+ **/
+s32 ngbe_check_reset_blocked(struct ngbe_hw *hw)
+{
+       u32 mmngc;
+
+       DEBUGFUNC("ngbe_check_reset_blocked");
+
+       mmngc = rd32(hw, NGBE_STAT);
+       if (mmngc & NGBE_STAT_MNGVETO) {
+               DEBUGOUT("MNG_VETO bit detected.\n");
+               return true;
+       }
+
+       return false;
+}
+
+/**
+ *  ngbe_validate_phy_addr - Determines phy address is valid
+ *  @hw: pointer to hardware structure
+ *  @phy_addr: PHY address
+ *
+ **/
+bool ngbe_validate_phy_addr(struct ngbe_hw *hw, u32 phy_addr)
+{
+       u16 phy_id = 0;
+       bool valid = false;
+
+       DEBUGFUNC("ngbe_validate_phy_addr");
+
+       if (hw->sub_device_id == NGBE_SUB_DEV_ID_EM_YT8521S_SFP)
+               return true;
+
+       hw->phy.addr = phy_addr;
+       hw->phy.read_reg(hw, NGBE_MD_PHY_ID_HIGH,
+                            NGBE_MD_DEV_PMA_PMD, &phy_id);
+
+       if (phy_id != 0xFFFF && phy_id != 0x0)
+               valid = true;
+
+       DEBUGOUT("PHY ID HIGH is 0x%04X\n", phy_id);
+
+       return valid;
+}
+
+/**
+ *  ngbe_get_phy_id - Get the phy ID
+ *  @hw: pointer to hardware structure
+ *
+ **/
+s32 ngbe_get_phy_id(struct ngbe_hw *hw)
+{
+       u32 err;
+       u16 phy_id_high = 0;
+       u16 phy_id_low = 0;
+
+       DEBUGFUNC("ngbe_get_phy_id");
+
+       err = hw->phy.read_reg(hw, NGBE_MD_PHY_ID_HIGH,
+                                     NGBE_MD_DEV_PMA_PMD,
+                                     &phy_id_high);
+       hw->phy.id = (u32)(phy_id_high << 16);
+
+       err = hw->phy.read_reg(hw, NGBE_MD_PHY_ID_LOW,
+                               NGBE_MD_DEV_PMA_PMD,
+                               &phy_id_low);
+       hw->phy.id |= (u32)(phy_id_low & NGBE_PHY_REVISION_MASK);
+       hw->phy.revision = (u32)(phy_id_low & ~NGBE_PHY_REVISION_MASK);
+
+       DEBUGOUT("PHY_ID_HIGH 0x%04X, PHY_ID_LOW 0x%04X\n",
+                 phy_id_high, phy_id_low);
+
+       return err;
+}
+
+/**
+ *  ngbe_get_phy_type_from_id - Get the phy type
+ *  @phy_id: PHY ID information
+ *
+ **/
+enum ngbe_phy_type ngbe_get_phy_type_from_id(struct ngbe_hw *hw)
+{
+       enum ngbe_phy_type phy_type;
+
+       DEBUGFUNC("ngbe_get_phy_type_from_id");
+
+       switch (hw->phy.id) {
+       case NGBE_PHYID_RTL:
+               phy_type = ngbe_phy_rtl;
+               break;
+       case NGBE_PHYID_MVL:
+               if (hw->phy.media_type == ngbe_media_type_fiber)
+                       phy_type = ngbe_phy_mvl_sfi;
+               else
+                       phy_type = ngbe_phy_mvl;
+               break;
+       case NGBE_PHYID_YT:
+               if (hw->phy.media_type == ngbe_media_type_fiber)
+                       phy_type = ngbe_phy_yt8521s_sfi;
+               else
+                       phy_type = ngbe_phy_yt8521s;
+               break;
+       default:
+               phy_type = ngbe_phy_unknown;
+               break;
+       }
+
+       return phy_type;
+}
+
+/**
+ *  ngbe_reset_phy - Performs a PHY reset
+ *  @hw: pointer to hardware structure
+ **/
+s32 ngbe_reset_phy(struct ngbe_hw *hw)
+{
+       s32 err = 0;
+
+       DEBUGFUNC("ngbe_reset_phy");
+
+       if (hw->phy.type == ngbe_phy_unknown)
+               err = ngbe_identify_phy(hw);
+
+       if (err != 0 || hw->phy.type == ngbe_phy_none)
+               return err;
+
+       /* Don't reset PHY if it's shut down due to overtemp. */
+       if (hw->mac.check_overtemp(hw) == NGBE_ERR_OVERTEMP)
+               return err;
+
+       /* Blocked by MNG FW so bail */
+       if (ngbe_check_reset_blocked(hw))
+               return err;
+
+       switch (hw->phy.type) {
+       case ngbe_phy_rtl:
+               err = ngbe_reset_phy_rtl(hw);
+               break;
+       case ngbe_phy_mvl:
+       case ngbe_phy_mvl_sfi:
+               err = ngbe_reset_phy_mvl(hw);
+               break;
+       case ngbe_phy_yt8521s:
+       case ngbe_phy_yt8521s_sfi:
+               err = ngbe_reset_phy_yt(hw);
+               break;
+       default:
+               break;
+       }
+
+       return err;
+}
+
+/**
+ *  ngbe_read_phy_mdi - Reads a value from a specified PHY register without
+ *  the SWFW lock
+ *  @hw: pointer to hardware structure
+ *  @reg_addr: 32 bit address of PHY register to read
+ *  @device_type: 5 bit device type
+ *  @phy_data: Pointer to read data from PHY register
+ **/
+s32 ngbe_read_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+                          u16 *phy_data)
+{
+       u32 command, data;
+
+       /* Setup and write the address cycle command */
+       command = NGBE_MDIOSCA_REG(reg_addr) |
+                 NGBE_MDIOSCA_DEV(device_type) |
+                 NGBE_MDIOSCA_PORT(hw->phy.addr);
+       wr32(hw, NGBE_MDIOSCA, command);
+
+       command = NGBE_MDIOSCD_CMD_READ |
+                 NGBE_MDIOSCD_BUSY |
+                 NGBE_MDIOSCD_CLOCK(6);
+       wr32(hw, NGBE_MDIOSCD, command);
+
+       /*
+        * Check every 10 usec to see if the address cycle completed.
+        * The MDI Command bit will clear when the operation is
+        * complete
+        */
+       if (!po32m(hw, NGBE_MDIOSCD, NGBE_MDIOSCD_BUSY,
+               0, NULL, 100, 100)) {
+               DEBUGOUT("PHY address command did not complete\n");
+               return NGBE_ERR_PHY;
+       }
+
+       data = rd32(hw, NGBE_MDIOSCD);
+       *phy_data = (u16)NGBE_MDIOSCD_DAT_R(data);
+
+       return 0;
+}
+
+/**
+ *  ngbe_read_phy_reg - Reads a value from a specified PHY register
+ *  using the SWFW lock - this function is needed in most cases
+ *  @hw: pointer to hardware structure
+ *  @reg_addr: 32 bit address of PHY register to read
+ *  @device_type: 5 bit device type
+ *  @phy_data: Pointer to read data from PHY register
+ **/
+s32 ngbe_read_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
+                              u32 device_type, u16 *phy_data)
+{
+       s32 err;
+       u32 gssr = hw->phy.phy_semaphore_mask;
+
+       DEBUGFUNC("ngbe_read_phy_reg");
+
+       if (hw->mac.acquire_swfw_sync(hw, gssr))
+               return NGBE_ERR_SWFW_SYNC;
+
+       err = hw->phy.read_reg_unlocked(hw, reg_addr, device_type,
+                                       phy_data);
+
+       hw->mac.release_swfw_sync(hw, gssr);
+
+       return err;
+}
+
+/**
+ *  ngbe_write_phy_reg_mdi - Writes a value to specified PHY register
+ *  without SWFW lock
+ *  @hw: pointer to hardware structure
+ *  @reg_addr: 32 bit PHY register to write
+ *  @device_type: 5 bit device type
+ *  @phy_data: Data to write to the PHY register
+ **/
+s32 ngbe_write_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u16 phy_data)
+{
+       u32 command;
+
+       /* write command */
+       command = NGBE_MDIOSCA_REG(reg_addr) |
+                 NGBE_MDIOSCA_DEV(device_type) |
+                 NGBE_MDIOSCA_PORT(hw->phy.addr);
+       wr32(hw, NGBE_MDIOSCA, command);
+
+       command = NGBE_MDIOSCD_CMD_WRITE |
+                 NGBE_MDIOSCD_DAT(phy_data) |
+                 NGBE_MDIOSCD_BUSY |
+                 NGBE_MDIOSCD_CLOCK(6);
+       wr32(hw, NGBE_MDIOSCD, command);
+
+       /* wait for completion */
+       if (!po32m(hw, NGBE_MDIOSCD, NGBE_MDIOSCD_BUSY,
+               0, NULL, 100, 100)) {
+               TLOG_DEBUG("PHY write cmd didn't complete\n");
+               return NGBE_ERR_PHY;
+       }
+
+       return 0;
+}
+
+/**
+ *  ngbe_write_phy_reg - Writes a value to specified PHY register
+ *  using SWFW lock- this function is needed in most cases
+ *  @hw: pointer to hardware structure
+ *  @reg_addr: 32 bit PHY register to write
+ *  @device_type: 5 bit device type
+ *  @phy_data: Data to write to the PHY register
+ **/
+s32 ngbe_write_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u16 phy_data)
+{
+       s32 err;
+       u32 gssr = hw->phy.phy_semaphore_mask;
+
+       DEBUGFUNC("ngbe_write_phy_reg");
+
+       if (hw->mac.acquire_swfw_sync(hw, gssr))
+               err = NGBE_ERR_SWFW_SYNC;
+
+       err = hw->phy.write_reg_unlocked(hw, reg_addr, device_type,
+                                        phy_data);
+
+       hw->mac.release_swfw_sync(hw, gssr);
+
+       return err;
+}
+
+/**
+ *  ngbe_init_phy - PHY specific init
+ *  @hw: pointer to hardware structure
+ *
+ *  Initialize any function pointers that were not able to be
+ *  set during init_shared_code because the PHY type was
+ *  not known.
+ *
+ **/
+s32 ngbe_init_phy(struct ngbe_hw *hw)
+{
+       struct ngbe_phy_info *phy = &hw->phy;
+       s32 err = 0;
+
+       DEBUGFUNC("ngbe_init_phy");
+
+       hw->phy.addr = 0;
+
+       switch (hw->sub_device_id) {
+       case NGBE_SUB_DEV_ID_EM_RTL_SGMII:
+               hw->phy.read_reg_unlocked = ngbe_read_phy_reg_rtl;
+               hw->phy.write_reg_unlocked = ngbe_write_phy_reg_rtl;
+               break;
+       case NGBE_SUB_DEV_ID_EM_MVL_RGMII:
+       case NGBE_SUB_DEV_ID_EM_MVL_SFP:
+               hw->phy.read_reg_unlocked = ngbe_read_phy_reg_mvl;
+               hw->phy.write_reg_unlocked = ngbe_write_phy_reg_mvl;
+               break;
+       case NGBE_SUB_DEV_ID_EM_YT8521S_SFP:
+               hw->phy.read_reg_unlocked = ngbe_read_phy_reg_yt;
+               hw->phy.write_reg_unlocked = ngbe_write_phy_reg_yt;
+               break;
+       default:
+               break;
+       }
+
+       hw->phy.phy_semaphore_mask = NGBE_MNGSEM_SWPHY;
+
+       /* Identify the PHY */
+       err = phy->identify(hw);
+
+       return err;
+}
+
diff --git a/drivers/net/ngbe/base/ngbe_phy.h b/drivers/net/ngbe/base/ngbe_phy.h
new file mode 100644 (file)
index 0000000..226e018
--- /dev/null
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ * Copyright(c) 2010-2017 Intel Corporation
+ */
+
+#ifndef _NGBE_PHY_H_
+#define _NGBE_PHY_H_
+
+#include "ngbe_type.h"
+#include "ngbe_phy_rtl.h"
+#include "ngbe_phy_mvl.h"
+#include "ngbe_phy_yt.h"
+
+/******************************************************************************
+ * PHY MDIO Registers:
+ ******************************************************************************/
+#define NGBE_MAX_PHY_ADDR              32
+
+/* (dev_type = 1) */
+#define NGBE_MD_DEV_PMA_PMD            0x1
+#define NGBE_MD_PHY_ID_HIGH            0x2 /* PHY ID High Reg*/
+#define NGBE_MD_PHY_ID_LOW             0x3 /* PHY ID Low Reg*/
+#define   NGBE_PHY_REVISION_MASK       0xFFFFFFF0
+
+/* IEEE 802.3 Clause 22 */
+struct mdi_reg_22 {
+       u16 page;
+       u16 addr;
+       u16 device_type;
+};
+typedef struct mdi_reg_22 mdi_reg_22_t;
+
+/* IEEE 802.3ae Clause 45 */
+struct mdi_reg {
+       u16 device_type;
+       u16 addr;
+};
+typedef struct mdi_reg mdi_reg_t;
+
+#define NGBE_MD22_PHY_ID_HIGH          0x2 /* PHY ID High Reg*/
+#define NGBE_MD22_PHY_ID_LOW           0x3 /* PHY ID Low Reg*/
+
+s32 ngbe_mdi_map_register(mdi_reg_t *reg, mdi_reg_22_t *reg22);
+
+bool ngbe_validate_phy_addr(struct ngbe_hw *hw, u32 phy_addr);
+enum ngbe_phy_type ngbe_get_phy_type_from_id(struct ngbe_hw *hw);
+s32 ngbe_get_phy_id(struct ngbe_hw *hw);
+s32 ngbe_identify_phy(struct ngbe_hw *hw);
+s32 ngbe_reset_phy(struct ngbe_hw *hw);
+s32 ngbe_read_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+                          u16 *phy_data);
+s32 ngbe_write_phy_reg_mdi(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+                           u16 phy_data);
+s32 ngbe_read_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
+                              u32 device_type, u16 *phy_data);
+s32 ngbe_write_phy_reg(struct ngbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u16 phy_data);
+s32 ngbe_check_reset_blocked(struct ngbe_hw *hw);
+
+#endif /* _NGBE_PHY_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.c b/drivers/net/ngbe/base/ngbe_phy_mvl.c
new file mode 100644 (file)
index 0000000..1248478
--- /dev/null
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy_mvl.h"
+
+#define MVL_PHY_RST_WAIT_PERIOD  5
+
+s32 ngbe_read_phy_reg_mvl(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 *phy_data)
+{
+       mdi_reg_t reg;
+       mdi_reg_22_t reg22;
+
+       reg.device_type = device_type;
+       reg.addr = reg_addr;
+
+       if (hw->phy.media_type == ngbe_media_type_fiber)
+               ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 1);
+       else
+               ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 0);
+
+       ngbe_mdi_map_register(&reg, &reg22);
+
+       ngbe_read_phy_reg_mdi(hw, reg22.addr, reg22.device_type, phy_data);
+
+       return 0;
+}
+
+s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 phy_data)
+{
+       mdi_reg_t reg;
+       mdi_reg_22_t reg22;
+
+       reg.device_type = device_type;
+       reg.addr = reg_addr;
+
+       if (hw->phy.media_type == ngbe_media_type_fiber)
+               ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 1);
+       else
+               ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 0);
+
+       ngbe_mdi_map_register(&reg, &reg22);
+
+       ngbe_write_phy_reg_mdi(hw, reg22.addr, reg22.device_type, phy_data);
+
+       return 0;
+}
+
+s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw)
+{
+       u32 i;
+       u16 ctrl = 0;
+       s32 status = 0;
+
+       DEBUGFUNC("ngbe_reset_phy_mvl");
+
+       if (hw->phy.type != ngbe_phy_mvl && hw->phy.type != ngbe_phy_mvl_sfi)
+               return NGBE_ERR_PHY_TYPE;
+
+       /* select page 18 reg 20 */
+       status = ngbe_write_phy_reg_mdi(hw, MVL_PAGE_SEL, 0, 18);
+
+       /* mode select to RGMII-to-copper or RGMII-to-sfi*/
+       if (hw->phy.type == ngbe_phy_mvl)
+               ctrl = MVL_GEN_CTL_MODE_COPPER;
+       else
+               ctrl = MVL_GEN_CTL_MODE_FIBER;
+       status = ngbe_write_phy_reg_mdi(hw, MVL_GEN_CTL, 0, ctrl);
+       /* mode reset */
+       ctrl |= MVL_GEN_CTL_RESET;
+       status = ngbe_write_phy_reg_mdi(hw, MVL_GEN_CTL, 0, ctrl);
+
+       for (i = 0; i < MVL_PHY_RST_WAIT_PERIOD; i++) {
+               status = ngbe_read_phy_reg_mdi(hw, MVL_GEN_CTL, 0, &ctrl);
+               if (!(ctrl & MVL_GEN_CTL_RESET))
+                       break;
+               msleep(1);
+       }
+
+       if (i == MVL_PHY_RST_WAIT_PERIOD) {
+               DEBUGOUT("PHY reset polling failed to complete.\n");
+               return NGBE_ERR_RESET_FAILED;
+       }
+
+       return status;
+}
+
diff --git a/drivers/net/ngbe/base/ngbe_phy_mvl.h b/drivers/net/ngbe/base/ngbe_phy_mvl.h
new file mode 100644 (file)
index 0000000..ca39f3c
--- /dev/null
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy.h"
+
+#ifndef _NGBE_PHY_MVL_H_
+#define _NGBE_PHY_MVL_H_
+
+#define NGBE_PHYID_MVL                 0x01410DD0U
+
+/* Page 0 for Copper, Page 1 for Fiber */
+#define MVL_CTRL                       0x0
+#define   MVL_CTRL_RESET               MS16(15, 0x1)
+#define   MVL_CTRL_ANE                 MS16(12, 0x1)
+#define   MVL_CTRL_RESTART_AN          MS16(9, 0x1)
+#define MVL_ANA                                0x4
+/* copper */
+#define   MVL_CANA_ASM_PAUSE           MS16(11, 0x1)
+#define   MVL_CANA_PAUSE               MS16(10, 0x1)
+#define   MVL_PHY_100BASET_FULL                MS16(8, 0x1)
+#define   MVL_PHY_100BASET_HALF                MS16(7, 0x1)
+#define   MVL_PHY_10BASET_FULL         MS16(6, 0x1)
+#define   MVL_PHY_10BASET_HALF         MS16(5, 0x1)
+/* fiber */
+#define   MVL_FANA_PAUSE_MASK          MS16(7, 0x3)
+#define     MVL_FANA_SYM_PAUSE         LS16(1, 7, 0x3)
+#define     MVL_FANA_ASM_PAUSE         LS16(2, 7, 0x3)
+#define   MVL_PHY_1000BASEX_HALF       MS16(6, 0x1)
+#define   MVL_PHY_1000BASEX_FULL       MS16(5, 0x1)
+#define MVL_LPAR                       0x5
+#define   MVL_CLPAR_ASM_PAUSE          MS(11, 0x1)
+#define   MVL_CLPAR_PAUSE              MS(10, 0x1)
+#define   MVL_FLPAR_PAUSE_MASK         MS(7, 0x3)
+#define MVL_PHY_1000BASET              0x9
+#define   MVL_PHY_1000BASET_FULL       MS16(9, 0x1)
+#define   MVL_PHY_1000BASET_HALF       MS16(8, 0x1)
+#define MVL_CTRL1                      0x10
+#define   MVL_CTRL1_INTR_POL           MS16(2, 0x1)
+#define MVL_PHYSR                      0x11
+#define   MVL_PHYSR_SPEED_MASK         MS16(14, 0x3)
+#define     MVL_PHYSR_SPEED_1000M      LS16(2, 14, 0x3)
+#define     MVL_PHYSR_SPEED_100M       LS16(1, 14, 0x3)
+#define     MVL_PHYSR_SPEED_10M                LS16(0, 14, 0x3)
+#define   MVL_PHYSR_LINK               MS16(10, 0x1)
+#define MVL_INTR_EN                    0x12
+#define   MVL_INTR_EN_ANC              MS16(11, 0x1)
+#define   MVL_INTR_EN_LSC              MS16(10, 0x1)
+#define MVL_INTR                       0x13
+#define   MVL_INTR_ANC                 MS16(11, 0x1)
+#define   MVL_INTR_LSC                 MS16(10, 0x1)
+
+/* Page 2 */
+#define MVL_RGM_CTL2                   0x15
+#define   MVL_RGM_CTL2_TTC             MS16(4, 0x1)
+#define   MVL_RGM_CTL2_RTC             MS16(5, 0x1)
+/* Page 3 */
+#define MVL_LEDFCR                     0x10
+#define   MVL_LEDFCR_CTL1              MS16(4, 0xF)
+#define     MVL_LEDFCR_CTL1_CONF       LS16(6, 4, 0xF)
+#define   MVL_LEDFCR_CTL0              MS16(0, 0xF)
+#define     MVL_LEDFCR_CTL0_CONF       LS16(1, 0, 0xF)
+#define MVL_LEDPCR                     0x11
+#define   MVL_LEDPCR_CTL1              MS16(2, 0x3)
+#define     MVL_LEDPCR_CTL1_CONF       LS16(1, 2, 0x3)
+#define   MVL_LEDPCR_CTL0              MS16(0, 0x3)
+#define     MVL_LEDPCR_CTL0_CONF       LS16(1, 0, 0x3)
+#define MVL_LEDTCR                     0x12
+#define   MVL_LEDTCR_INTR_POL          MS16(11, 0x1)
+#define   MVL_LEDTCR_INTR_EN           MS16(7, 0x1)
+/* Page 18 */
+#define MVL_GEN_CTL                    0x14
+#define   MVL_GEN_CTL_RESET            MS16(15, 0x1)
+#define   MVL_GEN_CTL_MODE(v)          LS16(v, 0, 0x7)
+#define     MVL_GEN_CTL_MODE_COPPER    LS16(0, 0, 0x7)
+#define     MVL_GEN_CTL_MODE_FIBER     LS16(2, 0, 0x7)
+
+/* reg 22 */
+#define MVL_PAGE_SEL                   22
+
+/* reg 19_0 INT status*/
+#define MVL_PHY_ANC                      0x0800
+#define MVL_PHY_LSC                      0x0400
+
+s32 ngbe_read_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+                       u16 *phy_data);
+s32 ngbe_write_phy_reg_mvl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+                       u16 phy_data);
+
+s32 ngbe_reset_phy_mvl(struct ngbe_hw *hw);
+
+#endif /* _NGBE_PHY_MVL_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.c b/drivers/net/ngbe/base/ngbe_phy_rtl.c
new file mode 100644 (file)
index 0000000..400fbe8
--- /dev/null
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy_rtl.h"
+
+#define RTL_PHY_RST_WAIT_PERIOD               5
+
+s32 ngbe_read_phy_reg_rtl(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 *phy_data)
+{
+       mdi_reg_t reg;
+       mdi_reg_22_t reg22;
+
+       reg.device_type = device_type;
+       reg.addr = reg_addr;
+       ngbe_mdi_map_register(&reg, &reg22);
+
+       wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page);
+       *phy_data = 0xFFFF & rd32(hw, NGBE_PHY_CONFIG(reg22.addr));
+
+       return 0;
+}
+
+s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 phy_data)
+{
+       mdi_reg_t reg;
+       mdi_reg_22_t reg22;
+
+       reg.device_type = device_type;
+       reg.addr = reg_addr;
+       ngbe_mdi_map_register(&reg, &reg22);
+
+       wr32(hw, NGBE_PHY_CONFIG(RTL_PAGE_SELECT), reg22.page);
+       wr32(hw, NGBE_PHY_CONFIG(reg22.addr), phy_data);
+
+       return 0;
+}
+
+s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw)
+{
+       u16 value = 0, i;
+       s32 status = 0;
+
+       DEBUGFUNC("ngbe_reset_phy_rtl");
+
+       value |= RTL_BMCR_RESET;
+       status = hw->phy.write_reg(hw, RTL_BMCR, RTL_DEV_ZERO, value);
+
+       for (i = 0; i < RTL_PHY_RST_WAIT_PERIOD; i++) {
+               status = hw->phy.read_reg(hw, RTL_BMCR, RTL_DEV_ZERO, &value);
+               if (!(value & RTL_BMCR_RESET))
+                       break;
+               msleep(1);
+       }
+
+       if (i == RTL_PHY_RST_WAIT_PERIOD) {
+               DEBUGOUT("PHY reset polling failed to complete.\n");
+               return NGBE_ERR_RESET_FAILED;
+       }
+
+       return status;
+}
+
diff --git a/drivers/net/ngbe/base/ngbe_phy_rtl.h b/drivers/net/ngbe/base/ngbe_phy_rtl.h
new file mode 100644 (file)
index 0000000..2da5c7b
--- /dev/null
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy.h"
+
+#ifndef _NGBE_PHY_RTL_H_
+#define _NGBE_PHY_RTL_H_
+
+#define NGBE_PHYID_RTL                 0x001CC800U
+
+/* Page 0 */
+#define RTL_DEV_ZERO                   0
+#define RTL_BMCR                       0x0
+#define   RTL_BMCR_RESET               MS16(15, 0x1)
+#define          RTL_BMCR_SPEED_SELECT0        MS16(13, 0x1)
+#define   RTL_BMCR_ANE                 MS16(12, 0x1)
+#define   RTL_BMCR_RESTART_AN          MS16(9, 0x1)
+#define   RTL_BMCR_DUPLEX              MS16(8, 0x1)
+#define   RTL_BMCR_SPEED_SELECT1       MS16(6, 0x1)
+#define RTL_BMSR                       0x1
+#define   RTL_BMSR_ANC                 MS16(5, 0x1)
+#define RTL_ID1_OFFSET                 0x2
+#define RTL_ID2_OFFSET                 0x3
+#define RTL_ID_MASK                    0xFFFFFC00U
+#define RTL_ANAR                       0x4
+#define   RTL_ANAR_APAUSE              MS16(11, 0x1)
+#define   RTL_ANAR_PAUSE               MS16(10, 0x1)
+#define   RTL_ANAR_100F                        MS16(8, 0x1)
+#define   RTL_ANAR_100H                        MS16(7, 0x1)
+#define   RTL_ANAR_10F                 MS16(6, 0x1)
+#define   RTL_ANAR_10H                 MS16(5, 0x1)
+#define RTL_ANLPAR                     0x5
+#define   RTL_ANLPAR_LP                        MS16(10, 0x3)
+#define RTL_GBCR                       0x9
+#define   RTL_GBCR_1000F               MS16(9, 0x1)
+/* Page 0xa42*/
+#define RTL_GSR                                0x10
+#define   RTL_GSR_ST                   MS16(0, 0x7)
+#define   RTL_GSR_ST_LANON             MS16(0, 0x3)
+#define RTL_INER                       0x12
+#define   RTL_INER_LSC                 MS16(4, 0x1)
+#define   RTL_INER_ANC                 MS16(3, 0x1)
+/* Page 0xa43*/
+#define RTL_PHYSR                      0x1A
+#define   RTL_PHYSR_SPEED_MASK         MS16(4, 0x3)
+#define     RTL_PHYSR_SPEED_RES                LS16(3, 4, 0x3)
+#define     RTL_PHYSR_SPEED_1000M      LS16(2, 4, 0x3)
+#define     RTL_PHYSR_SPEED_100M       LS16(1, 4, 0x3)
+#define     RTL_PHYSR_SPEED_10M                LS16(0, 4, 0x3)
+#define   RTL_PHYSR_DP                 MS16(3, 0x1)
+#define   RTL_PHYSR_RTLS               MS16(2, 0x1)
+#define RTL_INSR                       0x1D
+#define   RTL_INSR_ACCESS              MS16(5, 0x1)
+#define   RTL_INSR_LSC                 MS16(4, 0x1)
+#define   RTL_INSR_ANC                 MS16(3, 0x1)
+/* Page 0xa46*/
+#define RTL_SCR                                0x14
+#define   RTL_SCR_EXTINI               MS16(1, 0x1)
+#define   RTL_SCR_EFUSE                        MS16(0, 0x1)
+/* Page 0xa47*/
+/* Page 0xd04*/
+#define RTL_LCR                                0x10
+#define RTL_EEELCR                     0x11
+#define RTL_LPCR                       0x12
+
+/* INTERNAL PHY CONTROL */
+#define RTL_PAGE_SELECT                        31
+#define NGBE_INTERNAL_PHY_OFFSET_MAX   32
+#define NGBE_INTERNAL_PHY_ID           0x000732
+
+#define NGBE_INTPHY_LED0               0x0010
+#define NGBE_INTPHY_LED1               0x0040
+#define NGBE_INTPHY_LED2               0x2000
+
+s32 ngbe_read_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+                       u16 *phy_data);
+s32 ngbe_write_phy_reg_rtl(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+                       u16 phy_data);
+
+s32 ngbe_reset_phy_rtl(struct ngbe_hw *hw);
+
+#endif /* _NGBE_PHY_RTL_H_ */
diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.c b/drivers/net/ngbe/base/ngbe_phy_yt.c
new file mode 100644 (file)
index 0000000..a5b0322
--- /dev/null
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy_yt.h"
+
+#define YT_PHY_RST_WAIT_PERIOD         5
+
+s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 *phy_data)
+{
+       mdi_reg_t reg;
+       mdi_reg_22_t reg22;
+
+       reg.device_type = device_type;
+       reg.addr = reg_addr;
+
+       ngbe_mdi_map_register(&reg, &reg22);
+
+       /* Read MII reg according to media type */
+       if (hw->phy.media_type == ngbe_media_type_fiber) {
+               ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
+                                       reg22.device_type, YT_SMI_PHY_SDS);
+               ngbe_read_phy_reg_mdi(hw, reg22.addr,
+                                       reg22.device_type, phy_data);
+               ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
+                                       reg22.device_type, 0);
+       } else {
+               ngbe_read_phy_reg_mdi(hw, reg22.addr,
+                                       reg22.device_type, phy_data);
+       }
+
+       return 0;
+}
+
+s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 phy_data)
+{
+       mdi_reg_t reg;
+       mdi_reg_22_t reg22;
+
+       reg.device_type = device_type;
+       reg.addr = reg_addr;
+
+       ngbe_mdi_map_register(&reg, &reg22);
+
+       /* Write MII reg according to media type */
+       if (hw->phy.media_type == ngbe_media_type_fiber) {
+               ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
+                                       reg22.device_type, YT_SMI_PHY_SDS);
+               ngbe_write_phy_reg_mdi(hw, reg22.addr,
+                                       reg22.device_type, phy_data);
+               ngbe_write_phy_reg_ext_yt(hw, YT_SMI_PHY,
+                                       reg22.device_type, 0);
+       } else {
+               ngbe_write_phy_reg_mdi(hw, reg22.addr,
+                                       reg22.device_type, phy_data);
+       }
+
+       return 0;
+}
+
+s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 *phy_data)
+{
+       ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
+       ngbe_read_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
+
+       return 0;
+}
+
+s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 phy_data)
+{
+       ngbe_write_phy_reg_mdi(hw, 0x1E, device_type, reg_addr);
+       ngbe_write_phy_reg_mdi(hw, 0x1F, device_type, phy_data);
+
+       return 0;
+}
+
+s32 ngbe_reset_phy_yt(struct ngbe_hw *hw)
+{
+       u32 i;
+       u16 ctrl = 0;
+       s32 status = 0;
+
+       DEBUGFUNC("ngbe_reset_phy_yt");
+
+       if (hw->phy.type != ngbe_phy_yt8521s &&
+               hw->phy.type != ngbe_phy_yt8521s_sfi)
+               return NGBE_ERR_PHY_TYPE;
+
+       status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
+       /* sds software reset */
+       ctrl |= YT_BCR_RESET;
+       status = hw->phy.write_reg(hw, YT_BCR, 0, ctrl);
+
+       for (i = 0; i < YT_PHY_RST_WAIT_PERIOD; i++) {
+               status = hw->phy.read_reg(hw, YT_BCR, 0, &ctrl);
+               if (!(ctrl & YT_BCR_RESET))
+                       break;
+               msleep(1);
+       }
+
+       if (i == YT_PHY_RST_WAIT_PERIOD) {
+               DEBUGOUT("PHY reset polling failed to complete.\n");
+               return NGBE_ERR_RESET_FAILED;
+       }
+
+       return status;
+}
+
diff --git a/drivers/net/ngbe/base/ngbe_phy_yt.h b/drivers/net/ngbe/base/ngbe_phy_yt.h
new file mode 100644 (file)
index 0000000..6d49464
--- /dev/null
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
+ */
+
+#include "ngbe_phy.h"
+
+#ifndef _NGBE_PHY_YT_H_
+#define _NGBE_PHY_YT_H_
+
+#define NGBE_PHYID_YT                  0x00000110U
+
+/* Common EXT */
+#define YT_SMI_PHY                     0xA000
+#define   YT_SMI_PHY_SDS               MS16(1, 0x1) /* 0 for UTP */
+#define YT_CHIP                                0xA001
+#define   YT_CHIP_SW_RST               MS16(15, 0x1)
+#define   YT_CHIP_SW_LDO_EN            MS16(6, 0x1)
+#define   YT_CHIP_MODE_SEL(v)          LS16(v, 0, 0x7)
+#define YT_RGMII_CONF1                 0xA003
+#define   YT_RGMII_CONF1_RXDELAY       MS16(10, 0xF)
+#define   YT_RGMII_CONF1_TXDELAY_FE    MS16(4, 0xF)
+#define   YT_RGMII_CONF1_TXDELAY       MS16(0, 0x1)
+#define YT_MISC                                0xA006
+#define   YT_MISC_FIBER_PRIO           MS16(8, 0x1) /* 0 for UTP */
+
+/* MII common registers in UTP and SDS */
+#define YT_BCR                         0x0
+#define   YT_BCR_RESET                 MS16(15, 0x1)
+#define   YT_BCR_PWDN                  MS16(11, 0x1)
+#define YT_ANA                         0x4
+/* copper */
+#define   YT_ANA_100BASET_FULL         MS16(8, 0x1)
+#define   YT_ANA_10BASET_FULL          MS16(6, 0x1)
+/* fiber */
+#define   YT_FANA_PAUSE_MASK           MS16(7, 0x3)
+
+#define YT_LPAR                                0x5
+#define   YT_CLPAR_ASM_PAUSE           MS(11, 0x1)
+#define   YT_CLPAR_PAUSE               MS(10, 0x1)
+#define   YT_FLPAR_PAUSE_MASK          MS(7, 0x3)
+
+#define YT_MS_CTRL                     0x9
+#define   YT_MS_1000BASET_FULL         MS16(9, 0x1)
+#define YT_SPST                                0x11
+#define   YT_SPST_SPEED_MASK           MS16(14, 0x3)
+#define            YT_SPST_SPEED_1000M         LS16(2, 14, 0x3)
+#define            YT_SPST_SPEED_100M          LS16(1, 14, 0x3)
+#define            YT_SPST_SPEED_10M           LS16(0, 14, 0x3)
+#define   YT_SPST_LINK                 MS16(10, 0x1)
+
+/* UTP only */
+#define YT_INTR                                0x12
+#define   YT_INTR_ENA_MASK             MS16(2, 0x3)
+#define YT_INTR_STATUS                 0x13
+
+s32 ngbe_read_phy_reg_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+                       u16 *phy_data);
+s32 ngbe_write_phy_reg_yt(struct ngbe_hw *hw, u32 reg_addr, u32 device_type,
+                       u16 phy_data);
+s32 ngbe_read_phy_reg_ext_yt(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 *phy_data);
+s32 ngbe_write_phy_reg_ext_yt(struct ngbe_hw *hw,
+               u32 reg_addr, u32 device_type, u16 phy_data);
+
+s32 ngbe_reset_phy_yt(struct ngbe_hw *hw);
+
+#endif /* _NGBE_PHY_YT_H_ */
index 9741cb7..0eabc21 100644 (file)
@@ -94,6 +94,7 @@ struct ngbe_mac_info {
 
        /* Manageability interface */
        s32 (*init_thermal_sensor_thresh)(struct ngbe_hw *hw);
+       s32 (*check_overtemp)(struct ngbe_hw *hw);
 
        enum ngbe_mac_type type;
        u32 max_tx_queues;
@@ -103,8 +104,24 @@ struct ngbe_mac_info {
 };
 
 struct ngbe_phy_info {
+       s32 (*identify)(struct ngbe_hw *hw);
+       s32 (*reset_hw)(struct ngbe_hw *hw);
+       s32 (*read_reg)(struct ngbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u16 *phy_data);
+       s32 (*write_reg)(struct ngbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u16 phy_data);
+       s32 (*read_reg_unlocked)(struct ngbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u16 *phy_data);
+       s32 (*write_reg_unlocked)(struct ngbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u16 phy_data);
+
        enum ngbe_media_type media_type;
        enum ngbe_phy_type type;
+       u32 addr;
+       u32 id;
+       u32 revision;
+       u32 phy_semaphore_mask;
+       bool reset_disable;
 };
 
 struct ngbe_hw {