update
This commit is contained in:
parent
0552fe6f15
commit
f87f0f95b2
2667
drivers/net/phy/jlsemi-core.c
Normal file
2667
drivers/net/phy/jlsemi-core.c
Normal file
File diff suppressed because it is too large
Load Diff
439
drivers/net/phy/jlsemi-core.h
Normal file
439
drivers/net/phy/jlsemi-core.h
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0+
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 JLSemi Corporation
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation version 2.
|
||||||
|
*
|
||||||
|
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||||
|
* kind, whether express or implied; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef _JLSEMI_CORE_H
|
||||||
|
#define _JLSEMI_CORE_H
|
||||||
|
|
||||||
|
#define JLSEMI_KERNEL_DEVICE_TREE_USE 1
|
||||||
|
|
||||||
|
#include <linux/phy.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#if (JLSEMI_KERNEL_DEVICE_TREE_USE)
|
||||||
|
#include <dt-bindings/phy/jlsemi-dt-phy.h>
|
||||||
|
#else
|
||||||
|
#include "jlsemi-dt-phy.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define JL1XXX_PHY_ID 0x937c4023
|
||||||
|
#define JL2XXX_PHY_ID 0x937c4032
|
||||||
|
#define JLSEMI_PHY_ID_MASK 0xfffffff0
|
||||||
|
|
||||||
|
#define JL1XXX_PAGE0 0
|
||||||
|
#define JL1XXX_PAGE7 7
|
||||||
|
#define JL1XXX_INTR_REG 19
|
||||||
|
#define JL1XXX_INTR_LINK BIT(13)
|
||||||
|
#define JL1XXX_INTR_AN_ERR BIT(11)
|
||||||
|
#define JL1XXX_LED_REG 19
|
||||||
|
#define JL1XXX_LED_EN BIT(3)
|
||||||
|
#define JL1XXX_INTR_STATUS_REG 30
|
||||||
|
|
||||||
|
#define JL1XXX_PAGE7 7
|
||||||
|
#define JL1XXX_RMII_CTRL_REG 16
|
||||||
|
#define JL1XXX_RMII_OUT BIT(12)
|
||||||
|
#define JL1XXX_RMII_MODE BIT(3)
|
||||||
|
|
||||||
|
#define JL1XXX_PAGE129 129
|
||||||
|
#define JL1XXX_LED_MODE_REG 24
|
||||||
|
#define JL1XXX_MAC_ADDR0_REG 25
|
||||||
|
#define JL1XXX_MAC_ADDR1_REG 26
|
||||||
|
#define JL1XXX_MAC_ADDR2_REG 27
|
||||||
|
#define JL1XXX_WOL_CTRL_REG 28
|
||||||
|
#define JL1XXX_WOL_DIS BIT(15)
|
||||||
|
#define JL1XXX_WOL_CLEAR BIT(1)
|
||||||
|
#define JL1xxx_WOL_RECEIVE BIT(0)
|
||||||
|
#define ADDR8_HIGH_TO_LOW(n) ((n >> 4) | (n << 4))
|
||||||
|
|
||||||
|
#define JL1XXX_PAGE24 24
|
||||||
|
#define JL1XXX_REG24 24
|
||||||
|
#define JL1XXX_MDI_TX_BM_MASK 0x1c00
|
||||||
|
#define JL1XXX_MDI_TX_BM(n) (n << 10)
|
||||||
|
#define JL1XXX_MDI_TX_SRN BIT(0)
|
||||||
|
|
||||||
|
#define JL1XXX_PAGE7 7
|
||||||
|
#define JL1XXX_REG16 16
|
||||||
|
#define JL1XXX_RMII_MODE BIT(3)
|
||||||
|
#define JL1XXX_RMII_CLK_50M_INPUT BIT(12)
|
||||||
|
#define JL1XXX_RMII_TX_SKEW_MASK (0xf << 8)
|
||||||
|
#define JL1XXX_RMII_TX_SKEW(n) ((n << 8) & JL1XXX_RMII_TX_SKEW_MASK)
|
||||||
|
#define JL1XXX_RMII_RX_SKEW_MASK (0xf << 4)
|
||||||
|
#define JL1XXX_RMII_RX_SKEW(n) ((n << 4) & JL1XXX_RMII_RX_SKEW_MASK)
|
||||||
|
#define JL1XXX_RMII_CRS_DV BIT(2)
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE0 0
|
||||||
|
#define JL2XXX_BMCR_REG 0x0000
|
||||||
|
#define JL2XXX_SOFT_RESET BIT(15)
|
||||||
|
#define JL2XXX_SPEED_LSB BIT(13)
|
||||||
|
#define JL2XXX_AUTONEG_EN BIT(12)
|
||||||
|
#define JL2XXX_SPEED_MSB BIT(6)
|
||||||
|
#define JL2XXX_DSFT_CTRL_REG 17
|
||||||
|
#define JL2XXX_DSFT_EN BIT(12)
|
||||||
|
#define JL2XXX_DSFT_SMART_EN BIT(13)
|
||||||
|
#define JL2XXX_DSFT_TWO_WIRE_EN BIT(14)
|
||||||
|
#define JL2XXX_DSFT_AN_ERR_EN BIT(15)
|
||||||
|
#define JL2XXX_DSFT_STL_MASK 0x03e0
|
||||||
|
#define JL2XXX_DSFT_STL_CNT(n) (((n << 5) & JL2XXX_DSFT_STL_MASK))
|
||||||
|
#define JL2XXX_DSFT_AN_MASK 0x001f
|
||||||
|
#define JL2XXX_DSFT_CNT_MAX 32
|
||||||
|
#define JL2XXX_PHY_INFO_REG 29
|
||||||
|
#define JL2XXX_PATCH_MASK 0xffff
|
||||||
|
#define JL2XXX_SW_MASK 0xffff
|
||||||
|
#define JL2XXX_AUTO_GAIN_DIS BIT(6)
|
||||||
|
|
||||||
|
#define JLSEMI_PAGE31 0x001f
|
||||||
|
#define JL2XXX_WOL_CTRL_PAGE 0x0012
|
||||||
|
#define JL2XXX_WOL_CTRL_REG 0x0015
|
||||||
|
#define JL2XXX_WOL_STAS_PAGE 0x1200
|
||||||
|
#define JL2XXX_WOL_STAS_REG 0x0010
|
||||||
|
#define JL2XXX_MAC_ADDR2_REG 0x0011
|
||||||
|
#define JL2XXX_MAC_ADDR1_REG 0x0012
|
||||||
|
#define JL2XXX_MAC_ADDR0_REG 0x0013
|
||||||
|
#define JL2XXX_WOL_EVENT BIT(1)
|
||||||
|
#define JL2XXX_WOL_POLARITY BIT(14)
|
||||||
|
#define JL2XXX_WOL_EN BIT(15)
|
||||||
|
#define JL2XXX_WOL_GLB_EN BIT(6)
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE2626 2626
|
||||||
|
#define JL2XXX_INTR_CTRL_REG 18
|
||||||
|
#define JL2XXX_INTR_LINK_CHANGE BIT(4)
|
||||||
|
#define JL2XXX_INTR_AN_COMPLETE BIT(3)
|
||||||
|
#define JL2XXX_INTR_AN_PAGE BIT(2)
|
||||||
|
#define JL2XXX_INTR_AN_ERR BIT(0)
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE2627 2627
|
||||||
|
#define JL2XXX_INTR_STATUS_REG 29
|
||||||
|
#define JL2XXX_CLK_CTRL_REG 25
|
||||||
|
#define JL2XXX_CLK_OUT_PIN BIT(0)
|
||||||
|
#define JL2XXX_CLK_SSC_EN BIT(3)
|
||||||
|
#define JL2XXX_CLK_125M_OUT BIT(11)
|
||||||
|
#define JL2XXXX_CLK_SRC BIT(12)
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE158 158
|
||||||
|
#define JL2XXX_INTR_PIN_REG 16
|
||||||
|
#define JL2XXX_INTR_PIN_EN BIT(14)
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE160 160
|
||||||
|
#define JL2XXX_PIN_EN_REG 21
|
||||||
|
#define JL2XXX_PIN_OUTPUT BIT(11)
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE3336 3336
|
||||||
|
#define JL2XXX_RGMII_CTRL_REG 17
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE18 18
|
||||||
|
#define JL2XXX_RXC_OUT_REG 21
|
||||||
|
#define JL2XXX_RXC_OUT BIT(14)
|
||||||
|
|
||||||
|
#define JL2XXX_WORK_MODE_REG 21
|
||||||
|
#define JL2XXX_WORK_MODE_MASK 0x7
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE160 160
|
||||||
|
#define JL2XXX_REG25 25
|
||||||
|
#define JL2XXX_CPU_RESET BIT(3)
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE173 173
|
||||||
|
#define JL2XXX_PATCH_REG 0x0010
|
||||||
|
#define JL2XXX_REG16 16
|
||||||
|
#define JL2XXX_REG17 17
|
||||||
|
#define JL2XXX_LOAD_GO 0
|
||||||
|
#define JL2XXX_LOAD_DATA0 0x3a01
|
||||||
|
#define JL2XXX_REG20 20
|
||||||
|
#define JL2XXX_REG21 21
|
||||||
|
#define JL2XXX_LPBK_MODE_MASK 0x6
|
||||||
|
#define JL2XXX_LPBK_PMD_MODE BIT(2)
|
||||||
|
#define JL2XXX_LPBK_EXT_MODE BIT(1)
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE174 174
|
||||||
|
|
||||||
|
#define JL2XXX_REG29 29
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE191 191
|
||||||
|
#define JL2XXX_RGMII_CFG BIT(3)
|
||||||
|
|
||||||
|
#define JL2XXX_PAGE258 258
|
||||||
|
#define JL2XXX_SLEW_RATE_CTRL_REG 23
|
||||||
|
#define JL2XXX_SLEW_RATE_EN BIT(12)
|
||||||
|
#define JL2XXX_SLEW_RATE_REF_CLK BIT(13)
|
||||||
|
#define JL2XXX_SLEW_RATE_SEL_CLK BIT(14)
|
||||||
|
|
||||||
|
#define JL2XXX_REG20 20
|
||||||
|
#define JL2XXX_SPEED1000_NO_AN (BIT(11) | BIT(10))
|
||||||
|
|
||||||
|
#define LED_PERIOD_MASK 0xff00
|
||||||
|
#define LEDPERIOD(n) ((n << 8) & LED_PERIOD_MASK)
|
||||||
|
#define LED_ON_MASK 0x00ff
|
||||||
|
#define LEDON(n) ((n << 0) & LED_ON_MASK)
|
||||||
|
|
||||||
|
#define ADVERTISE_FIBER_1000HALF 0x40
|
||||||
|
#define ADVERTISE_FIBER_1000FULL 0x20
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
struct jl_hw_stat {
|
||||||
|
const char *string;
|
||||||
|
u8 reg;
|
||||||
|
u16 page;
|
||||||
|
u16 mask;
|
||||||
|
u16 enable;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct jl_hw_stat jl_phy[] = {
|
||||||
|
{
|
||||||
|
.string = "page0,reg0",
|
||||||
|
.enable = true,
|
||||||
|
.page = 0,
|
||||||
|
.reg = 0,
|
||||||
|
}, {
|
||||||
|
.string = "page0,reg1",
|
||||||
|
.enable = false,
|
||||||
|
.page = 0,
|
||||||
|
.reg = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct jl_hw_stat jl2xxx_hw_stats[] = {
|
||||||
|
{
|
||||||
|
.string = "phy_patch_version",
|
||||||
|
.reg = JL2XXX_PATCH_REG,
|
||||||
|
.page = JL2XXX_PAGE174,
|
||||||
|
.mask = JL2XXX_PATCH_MASK,
|
||||||
|
}, {
|
||||||
|
.string = "phy_software_version",
|
||||||
|
.reg = JL2XXX_PHY_INFO_REG,
|
||||||
|
.page = JL2XXX_PAGE0,
|
||||||
|
.mask = JL2XXX_SW_MASK,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_led_ctrl {
|
||||||
|
u32 enable; /* LED control enable */
|
||||||
|
u32 mode; /* LED work mode */
|
||||||
|
u32 global_period; /* LED global twinkle period */
|
||||||
|
u32 global_on; /* LED global twinkle hold on time */
|
||||||
|
u32 gpio_output; /* LED is used as gpio output */
|
||||||
|
u32 polarity; /* LED polarity */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_fld_ctrl {
|
||||||
|
u32 enable; /* Fast link down control enable */
|
||||||
|
u32 delay; /* Fast link down time */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_wol_ctrl {
|
||||||
|
u32 enable; /* Wake On LAN control enable */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_intr_ctrl {
|
||||||
|
u32 enable; /* Interrupt control enable */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_downshift_ctrl {
|
||||||
|
u32 enable; /* Downshift control enable */
|
||||||
|
u32 count; /* Downshift control count */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_rgmii_ctrl {
|
||||||
|
u32 enable; /* Rgmii control enable */
|
||||||
|
u32 rx_delay; /* Rgmii control rx delay */
|
||||||
|
u32 tx_delay; /* Rgmii control tx delay */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_patch_ctrl {
|
||||||
|
u32 enable; /* Patch control enable */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_clk_ctrl {
|
||||||
|
u32 enable; /* Clock 125M control enable */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_work_mode_ctrl {
|
||||||
|
u32 enable; /* Work mode control enable */
|
||||||
|
u32 mode; /* Work mode select mode */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_loopback_ctrl {
|
||||||
|
u32 enable; /* Loopback control enable */
|
||||||
|
u32 mode; /* Loopback select mode */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_mdi_ctrl {
|
||||||
|
u32 enable; /* Mdi control enable */
|
||||||
|
u32 rate; /* Mdi select Rate */
|
||||||
|
u32 amplitude; /* Mdi select amplitude */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_rmii_ctrl {
|
||||||
|
u32 enable; /* Rmii control enable */
|
||||||
|
u32 tx_timing; /* Rmii modify tx timing */
|
||||||
|
u32 rx_timing; /* Rmii modify rx timing */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_slew_rate_ctrl {
|
||||||
|
u32 enable; /* Slew rate control enable */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl_rxc_out_ctrl {
|
||||||
|
u32 enable; /* Rx clock out control enable */
|
||||||
|
bool ethtool; /* Whether the ethtool is supported */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl1xxx_priv {
|
||||||
|
struct jl_led_ctrl led;
|
||||||
|
struct jl_wol_ctrl wol;
|
||||||
|
struct jl_intr_ctrl intr;
|
||||||
|
bool static_inited; /* Initialization flag */
|
||||||
|
struct jl_mdi_ctrl mdi;
|
||||||
|
struct jl_rmii_ctrl rmii;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jl2xxx_priv {
|
||||||
|
struct jl_led_ctrl led;
|
||||||
|
struct jl_fld_ctrl fld;
|
||||||
|
struct jl_wol_ctrl wol;
|
||||||
|
struct jl_intr_ctrl intr;
|
||||||
|
struct jl_downshift_ctrl downshift;
|
||||||
|
struct jl_rgmii_ctrl rgmii;
|
||||||
|
struct jl_patch_ctrl patch;
|
||||||
|
struct jl_clk_ctrl clk;
|
||||||
|
const struct jl_hw_stat *hw_stats;
|
||||||
|
bool static_inited; /* Initialization flag */
|
||||||
|
int nstats; /* Record for dynamic operation */
|
||||||
|
u64 *stats; /* Pointer for dynamic operation */
|
||||||
|
struct jl_work_mode_ctrl work_mode;
|
||||||
|
struct jl_loopback_ctrl lpbk;
|
||||||
|
struct jl_slew_rate_ctrl slew_rate;
|
||||||
|
struct jl_rxc_out_ctrl rxc_out;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* macros to simplify debug checking */
|
||||||
|
#define JLSEMI_PHY_MSG(msg, args...) printk(msg, ## args)
|
||||||
|
|
||||||
|
/************************* JLSemi iteration code *************************/
|
||||||
|
struct device *jlsemi_get_mdio(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl2xxx_downshift_dynamic_op_get(struct phy_device *phydev, u8 *data);
|
||||||
|
|
||||||
|
int jl2xxx_downshift_dynamic_op_set(struct phy_device *phydev, u8 cnt);
|
||||||
|
|
||||||
|
int jlsemi_read_paged(struct phy_device *phydev, int page, u32 regnum);
|
||||||
|
|
||||||
|
int jl2xxx_intr_ack_event(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl2xxx_intr_static_op_set(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl1xxx_intr_ack_event(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl1xxx_intr_static_op_set(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl2xxx_wol_dynamic_op_get(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl2xxx_wol_dynamic_op_set(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl1xxx_wol_dynamic_op_get(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl1xxx_wol_dynamic_op_set(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl2xxx_fld_dynamic_op_get(struct phy_device *phydev, u8 *msecs);
|
||||||
|
|
||||||
|
int jl2xxx_fld_dynamic_op_set(struct phy_device *phydev, const u8 *msecs);
|
||||||
|
|
||||||
|
int jl1xxx_operation_args_get(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl1xxx_static_op_init(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl2xxx_operation_args_get(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl2xxx_static_op_init(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jlsemi_soft_reset(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl2xxx_pre_init(struct phy_device *phydev,
|
||||||
|
u32 *init_data, u16 data_len,
|
||||||
|
u16 *patch_fw_versions, u16 versions_len,
|
||||||
|
u16 patch_version);
|
||||||
|
|
||||||
|
bool jl2xxx_read_fiber_status(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jl2xxx_config_aneg_fiber(struct phy_device *phydev);
|
||||||
|
|
||||||
|
/********************** Convenience function for phy **********************/
|
||||||
|
|
||||||
|
/* Notice: You should change page 0 when you When you call it after */
|
||||||
|
int jlsemi_write_page(struct phy_device *phydev, int page);
|
||||||
|
|
||||||
|
int jlsemi_read_page(struct phy_device *phydev);
|
||||||
|
|
||||||
|
int jlsemi_modify_paged_reg(struct phy_device *phydev,
|
||||||
|
int page, u32 regnum,
|
||||||
|
u16 mask, u16 set);
|
||||||
|
|
||||||
|
int jlsemi_set_bits(struct phy_device *phydev,
|
||||||
|
int page, u32 regnum, u16 val);
|
||||||
|
|
||||||
|
int jlsemi_clear_bits(struct phy_device *phydev,
|
||||||
|
int page, u32 regnum, u16 val);
|
||||||
|
|
||||||
|
int jlsemi_fetch_bit(struct phy_device *phydev,
|
||||||
|
int page, u32 regnum, u16 val);
|
||||||
|
|
||||||
|
int jlsemi_drivers_register(struct phy_driver *phydrvs, int size);
|
||||||
|
|
||||||
|
void jlsemi_drivers_unregister(struct phy_driver *phydrvs, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* module_jlsemi_driver() - Helper macro for registering PHY drivers
|
||||||
|
* @__phy_drivers: array of PHY drivers to register
|
||||||
|
*
|
||||||
|
* Helper macro for PHY drivers which do not do anything special in module
|
||||||
|
* init/exit. Each module may only use this macro once, and calling it
|
||||||
|
* replaces module_init() and module_exit().
|
||||||
|
*/
|
||||||
|
#if (KERNEL_VERSION(4, 0, 0) > LINUX_VERSION_CODE)
|
||||||
|
|
||||||
|
#define jlsemi_module_driver(__phy_drivers, __count) \
|
||||||
|
static int __init phy_module_init(void) \
|
||||||
|
{ \
|
||||||
|
return jlsemi_drivers_register(__phy_drivers, __count); \
|
||||||
|
} \
|
||||||
|
module_init(phy_module_init); \
|
||||||
|
static void __exit phy_module_exit(void) \
|
||||||
|
{ \
|
||||||
|
jlsemi_drivers_unregister(__phy_drivers, __count); \
|
||||||
|
} \
|
||||||
|
module_exit(phy_module_exit)
|
||||||
|
|
||||||
|
#define module_jlsemi_driver(__phy_drivers) \
|
||||||
|
jlsemi_module_driver(__phy_drivers, ARRAY_SIZE(__phy_drivers))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define module_jlsemi_driver(__phy_drivers) \
|
||||||
|
module_phy_driver(__phy_drivers)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _JLSEMI_CORE_H */
|
||||||
|
|
||||||
341
drivers/net/phy/jlsemi-dt-phy.h
Normal file
341
drivers/net/phy/jlsemi-dt-phy.h
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Device Tree constants for JLSemi PHY
|
||||||
|
*
|
||||||
|
* Author: Gangqiao Kuang
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 JLSemi Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DT_BINDINGS_JLSEMI_PHY_H
|
||||||
|
#define _DT_BINDINGS_JLSEMI_PHY_H
|
||||||
|
|
||||||
|
/**************************** Linux Version Compatible ********************/
|
||||||
|
#define JLSEMI_DEV_COMPATIBLE (KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
|
||||||
|
#define JL2XXX_GET_STRING (KERNEL_VERSION(4, 5, 0) <= LINUX_VERSION_CODE)
|
||||||
|
#define JL2XXX_GET_STAT (KERNEL_VERSION(4, 5, 0) <= LINUX_VERSION_CODE)
|
||||||
|
#define JL2XXX_PHY_TUNABLE (KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE)
|
||||||
|
#define JLSEMI_PHY_WOL (KERNEL_VERSION(3, 10, 0) < LINUX_VERSION_CODE)
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JLSemi Debug *******************************/
|
||||||
|
#define JLSEMI_DEBUG_INFO 0
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/************************* JLSemi Phy Init Reentrant *********************/
|
||||||
|
#define JLSEMI_PHY_NOT_REENTRANT false
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL1XXX-LED *********************************/
|
||||||
|
/* PHY LED Modes Select */
|
||||||
|
#define JL1XXX_LED0_STRAP (1 << 0)
|
||||||
|
#define JL1XXX_LED0_EEE (1 << 1)
|
||||||
|
#define JL1XXX_LED0_100_ACTIVITY (1 << 2)
|
||||||
|
#define JL1XXX_LED0_10_ACTIVITY (1 << 3)
|
||||||
|
#define JL1XXX_LED0_100_LINK (1 << 4)
|
||||||
|
#define JL1XXX_LED0_10_LINK (1 << 5)
|
||||||
|
#define JL1XXX_LED1_STRAP (1 << 8)
|
||||||
|
#define JL1XXX_LED1_EEE (1 << 9)
|
||||||
|
#define JL1XXX_LED1_100_ACTIVITY (1 << 10)
|
||||||
|
#define JL1XXX_LED1_10_ACTIVITY (1 << 11)
|
||||||
|
#define JL1XXX_LED1_100_LINK (1 << 12)
|
||||||
|
#define JL1XXX_LED1_10_LINK (1 << 13)
|
||||||
|
|
||||||
|
/* PHY LED As Gpio Output Select */
|
||||||
|
#define JL1XXX_GPIO_LED0_OUT (1 << 2)
|
||||||
|
#define JL1XXX_GPIO_LED1_OUT (1 << 3)
|
||||||
|
#define JL1XXX_GPIO_LED0_EN (1 << 14)
|
||||||
|
#define JL1XXX_GPIO_LED1_EN (1 << 15)
|
||||||
|
|
||||||
|
/* PHY LED Control Enable Mask Select */
|
||||||
|
#define JL1XXX_LED_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL1XXX_LED_MODE_EN (1 << 1)
|
||||||
|
#define JL1XXX_LED_GLOABL_PERIOD_EN (1 << 2)
|
||||||
|
#define JL1XXX_LED_GLOBAL_ON_EN (1 << 3)
|
||||||
|
#define JL1XXX_LED_GPIO_OUT_EN (1 << 4)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY LED Control Enable Mask Config */
|
||||||
|
#define JL1XXX_LED_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY LED Modes Config */
|
||||||
|
#define JL1XXX_CFG_LED_MODE (JL1XXX_LED0_100_LINK | \
|
||||||
|
JL1XXX_LED0_10_LINK | \
|
||||||
|
JL1XXX_LED1_100_ACTIVITY | \
|
||||||
|
JL1XXX_LED1_10_ACTIVITY)
|
||||||
|
|
||||||
|
/* PHY LED As Gpio Output Config */
|
||||||
|
#define JL1XXX_CFG_GPIO (JL1XXX_GPIO_LED0_EN | \
|
||||||
|
JL1XXX_GPIO_LED0_OUT | \
|
||||||
|
JL1XXX_GPIO_LED1_EN | \
|
||||||
|
JL1XXX_GPIO_LED1_OUT)
|
||||||
|
|
||||||
|
/* PHY LED Global Period Config */
|
||||||
|
#define JL1XXX_GLOBAL_PERIOD_MS 0x10
|
||||||
|
|
||||||
|
/* PHY LED Global Hold On Config */
|
||||||
|
#define JL1XXX_GLOBAL_ON_MS 0x8
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
/****************************** JL1XXX-WOL ********************************/
|
||||||
|
/* PHY WOL Control Enable Mask Select */
|
||||||
|
#define JL1XXX_WOL_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY WOL Control Enable Mask Config */
|
||||||
|
#define JL1XXX_WOL_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/***************************** JL1XXX-INTR *******************************/
|
||||||
|
/* PHY Interrupt Control Enable Mask Select */
|
||||||
|
#define JL1XXX_INTR_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL1XXX_INTR_LINK_CHANGE_EN (1 << 1)
|
||||||
|
#define JL1XXX_INTR_AN_ERR_EN (1 << 2)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Interrupt Irq Number Config */
|
||||||
|
#define JL1XXX_INTR_IRQ -1
|
||||||
|
|
||||||
|
/* PHY Interrupt Control Enable Mask Config */
|
||||||
|
#define JL1XXX_INTR_CTRL_EN (0)
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL1XXX-MDI *********************************/
|
||||||
|
/* PHY MDI Control Mode Enable Mask Select */
|
||||||
|
#define JL1XXX_MDI_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL1XXX_MDI_RATE_EN (1 << 1)
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE_EN (1 << 2)
|
||||||
|
|
||||||
|
/* PHY MDI Rate Select */
|
||||||
|
#define JL1XXX_MDI_RATE_STANDARD 0
|
||||||
|
#define JL1XXX_MDI_RATE_ACCELERATE 1
|
||||||
|
|
||||||
|
/* PHY MDI Amplitude Select */
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE0 0
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE1 1
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE2 2
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE3 3
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE4 4
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE5 5
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE6 6
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE7 7
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY MDI Control Mode Enable Mask Config */
|
||||||
|
#define JL1XXX_MDI_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY MDI Rate Config */
|
||||||
|
#define JL1XXX_MDI_RATE JL1XXX_MDI_RATE_ACCELERATE
|
||||||
|
|
||||||
|
/* PHY MDI Amplitude Config */
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE JL1XXX_MDI_AMPLITUDE4
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL1XXX-RMII ********************************/
|
||||||
|
/* PHY RMII Control Mode Enable Mask Select */
|
||||||
|
#define JL1XXX_RMII_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL1XXX_RMII_MODE_EN (1 << 1)
|
||||||
|
#define JL1XXX_RMII_CLK_50M_INPUT_EN (1 << 2)
|
||||||
|
#define JL1XXX_RMII_TX_SKEW_EN (1 << 3)
|
||||||
|
#define JL1XXX_RMII_RX_SKEW_EN (1 << 4)
|
||||||
|
#define JL1XXX_RMII_CRS_DV_EN (1 << 5)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY RMII Control Mode Enable Mask Config */
|
||||||
|
#define JL1XXX_RMII_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY RMII Timing Config */
|
||||||
|
#define JL1XXX_RMII_TX_TIMING 0xf
|
||||||
|
#define JL1XXX_RMII_RX_TIMING 0xf
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-LED *********************************/
|
||||||
|
/* PHY LED Modes Select*/
|
||||||
|
#define JL2XXX_LED0_LINK10 (1 << 0)
|
||||||
|
#define JL2XXX_LED0_LINK100 (1 << 1)
|
||||||
|
#define JL2XXX_LED0_LINK1000 (1 << 3)
|
||||||
|
#define JL2XXX_LED0_ACTIVITY (1 << 4)
|
||||||
|
#define JL2XXX_LED1_LINK10 (1 << 5)
|
||||||
|
#define JL2XXX_LED1_LINK100 (1 << 6)
|
||||||
|
#define JL2XXX_LED1_LINK1000 (1 << 8)
|
||||||
|
#define JL2XXX_LED1_ACTIVITY (1 << 9)
|
||||||
|
#define JL2XXX_LED2_LINK10 (1 << 10)
|
||||||
|
#define JL2XXX_LED2_LINK100 (1 << 11)
|
||||||
|
#define JL2XXX_LED2_LINK1000 (1 << 13)
|
||||||
|
#define JL2XXX_LED2_ACTIVITY (1 << 14)
|
||||||
|
/* mode_A = 0 and mode_B = 1 default mode_A */
|
||||||
|
#define JL2XXX_LED_GLB_MODE_B (1 << 15)
|
||||||
|
|
||||||
|
/* PHY LED Polarity Select */
|
||||||
|
#define JL2XXX_LED0_POLARITY (1 << 12)
|
||||||
|
#define JL2XXX_LED1_POLARITY (1 << 11)
|
||||||
|
#define JL2XXX_LED2_POLARITY (1 << 10)
|
||||||
|
|
||||||
|
/* PHY LED Control Enable Mask Select */
|
||||||
|
#define JL2XXX_LED_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL2XXX_LED_MODE_EN (1 << 1)
|
||||||
|
#define JL2XXX_LED_GLOABL_PERIOD_EN (1 << 2)
|
||||||
|
#define JL2XXX_LED_GLOBAL_ON_EN (1 << 3)
|
||||||
|
#define JL2XXX_LED_POLARITY_EN (1 << 4)
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY LED Control Enable Mask Config */
|
||||||
|
#define JL2XXX_LED_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY LED Modes Config */
|
||||||
|
#define JL2XXX_CFG_LED_MODE (JL2XXX_LED0_LINK10 | \
|
||||||
|
JL2XXX_LED0_ACTIVITY | \
|
||||||
|
JL2XXX_LED1_LINK100 | \
|
||||||
|
JL2XXX_LED1_ACTIVITY | \
|
||||||
|
JL2XXX_LED2_LINK1000 | \
|
||||||
|
JL2XXX_LED2_ACTIVITY)
|
||||||
|
|
||||||
|
/* PHY LED Polarity Config */
|
||||||
|
#define JL2XXX_LED_POLARITY (JL2XXX_LED0_POLARITY | \
|
||||||
|
JL2XXX_LED1_POLARITY | \
|
||||||
|
JL2XXX_LED2_POLARITY)
|
||||||
|
|
||||||
|
/* PHY LED Global Period Config */
|
||||||
|
#define JL2XXX_GLOBAL_PERIOD_MS 0x3
|
||||||
|
|
||||||
|
/* PHY LED Global Hold On Config */
|
||||||
|
#define JL2XXX_GLOBAL_ON_MS 0x2
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-FLD *********************************/
|
||||||
|
/* PHY Fast Link Down Control Enable Mask Select */
|
||||||
|
#define JL2XXX_FLD_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Fast Link Down Control Enable Mask Config */
|
||||||
|
#define JL2XXX_FLD_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY Fast Link Down Delay Config */
|
||||||
|
#define JL2XXX_FLD_DELAY 0
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-WOL *********************************/
|
||||||
|
/* PHY WOL Control Enable Mask Select */
|
||||||
|
#define JL2XXX_WOL_STATIC_OP_EN (1 << 0)
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY WOL Control Enable Mask Config */
|
||||||
|
#define JL2XXX_WOL_CTRL_EN (0)
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-INTR ********************************/
|
||||||
|
/* PHY Interrupt Control Enable Mask Select */
|
||||||
|
#define JL2XXX_INTR_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL2XXX_INTR_LINK_CHANGE_EN (1 << 1)
|
||||||
|
#define JL2XXX_INTR_AN_ERR_EN (1 << 2)
|
||||||
|
#define JL2XXX_INTR_AN_COMPLETE_EN (1 << 3)
|
||||||
|
#define JL2XXX_INTR_AN_PAGE_RECE (1 << 4)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Interrupt Irq Number Config */
|
||||||
|
#define JL2XXX_INTR_IRQ -1
|
||||||
|
|
||||||
|
/* PHY Interrupt Control Enable Mask Config */
|
||||||
|
#define JL2XXX_INTR_CTRL_EN (0)
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-DSFT ********************************/
|
||||||
|
/* PHY Downshift Control Enable Mask */
|
||||||
|
#define JL2XXX_DSFT_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Downshift Control Enable Config */
|
||||||
|
#define JL2XXX_DSFT_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY Downshift Count Config */
|
||||||
|
#define JL2XXX_DSFT_AN_CNT 4
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-RGMII *******************************/
|
||||||
|
/* PHY RGMII Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_RGMII_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL2XXX_RGMII_TX_DLY_EN (1 << 1)
|
||||||
|
#define JL2XXX_RGMII_RX_DLY_EN (1 << 2)
|
||||||
|
/* PHY RGMII DELAY BIT */
|
||||||
|
#define JL2XXX_RGMII_TX_DLY_2NS (1 << 8)
|
||||||
|
#define JL2XXX_RGMII_RX_DLY_2NS (1 << 9)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY RGMII Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_RGMII_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-PATCH *******************************/
|
||||||
|
/* PHY Patch Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_PATCH_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Patch Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_PATCH_CTRL_EN (JL2XXX_PATCH_STATIC_OP_EN)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-CLOCK *******************************/
|
||||||
|
/* PHY Clock Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_CLK_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL2XXX_25M_CLK_OUT_EN (1 << 1)
|
||||||
|
#define JL2XXX_125M_CLK_OUT_EN (1 << 2)
|
||||||
|
#define JL2XXX_CLK_OUT_DIS (1 << 3)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Clock Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_CLK_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-WORK_MODE ***************************/
|
||||||
|
/* PHY Work Mode Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_WORK_MODE_STATIC_OP_EN (1 << 0)
|
||||||
|
|
||||||
|
/* PHY Work Mode Select */
|
||||||
|
#define JL2XXX_UTP_RGMII_MODE 0
|
||||||
|
#define JL2XXX_FIBER_RGMII_MODE 1
|
||||||
|
#define JL2XXX_UTP_FIBER_RGMII_MODE 2
|
||||||
|
#define JL2XXX_UTP_SGMII_MODE 3
|
||||||
|
#define JL2XXX_PHY_SGMII_RGMII_MODE 4
|
||||||
|
#define JL2XXX_MAC_SGMII_RGMII_MODE 5
|
||||||
|
#define JL2XXX_UTP_FIBER_FORCE_MODE1 6
|
||||||
|
#define JL2XXX_UTP_FIBER_FORCE_MODE2 7
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Work Mode Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_WORK_MODE_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY Work Mode Config */
|
||||||
|
#define JL2XXX_WORK_MODE_MODE JL2XXX_UTP_RGMII_MODE
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-LOOPBACK ****************************/
|
||||||
|
/* PHY Loopback Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_LPBK_STATIC_OP_EN (1 << 0)
|
||||||
|
|
||||||
|
/* PHY Loopback Mode Select */
|
||||||
|
#define JL2XXX_LPBK_PCS_10M 0
|
||||||
|
#define JL2XXX_LPBK_PCS_100M 1
|
||||||
|
#define JL2XXX_LPBK_PCS_1000M 2
|
||||||
|
#define JL2XXX_LPBK_PMD_1000M 3
|
||||||
|
#define JL2XXX_LPBK_EXT_STUB_1000M 4
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Loopback Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_LPBK_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY Loopback Mode Config */
|
||||||
|
#define JL2XXX_LPBK_MODE JL2XXX_LPBK_PCS_1000M
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-SLEW_RATE ****************************/
|
||||||
|
/* PHY Slew Rate Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_SLEW_RATE_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Slew Rate Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_SLEW_RATE_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-RXC_OUT *****************************/
|
||||||
|
/* PHY Rx Clock Out Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_RXC_OUT_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Rx Clock Out Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_RXC_OUT_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
#endif
|
||||||
577
drivers/net/phy/jlsemi.c
Normal file
577
drivers/net/phy/jlsemi.c
Normal file
@ -0,0 +1,577 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* drivers/net/phy/jlsemi.c
|
||||||
|
*
|
||||||
|
* Driver for JLSemi PHYs
|
||||||
|
*
|
||||||
|
* Author: Gangqiao Kuang <gqkuang@jlsemi.com>
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 JingLue Semiconductor, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "jlsemi-core.h"
|
||||||
|
#include <linux/phy.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
|
||||||
|
#define DRIVER_VERSION "1.2.9"
|
||||||
|
#define DRIVER_NAME_100M "JL1xxx Fast Ethernet " DRIVER_VERSION
|
||||||
|
#define DRIVER_NAME_1000M "JL2xxx Gigabit Ethernet " DRIVER_VERSION
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("JLSemi PHY driver");
|
||||||
|
MODULE_AUTHOR("Gangqiao Kuang");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
#if (JLSEMI_DEBUG_INFO)
|
||||||
|
static int jlsemi_phy_reg_print(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(jl_phy); i++) {
|
||||||
|
if (jl_phy[i].enable) {
|
||||||
|
ret = jlsemi_read_paged(phydev, jl_phy[i].page,
|
||||||
|
jl_phy[i].reg);
|
||||||
|
JLSEMI_PHY_MSG("%s: 0x%x\n", jl_phy[i].string, ret);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int jl1xxx_probe(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct device *dev = jlsemi_get_mdio(phydev);
|
||||||
|
struct jl1xxx_priv *jl1xxx = NULL;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
jl1xxx = devm_kzalloc(dev, sizeof(*jl1xxx), GFP_KERNEL);
|
||||||
|
if (!jl1xxx)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
phydev->priv = jl1xxx;
|
||||||
|
|
||||||
|
#if (JLSEMI_KERNEL_DEVICE_TREE_USE)
|
||||||
|
if (!dev->of_node)
|
||||||
|
JLSEMI_PHY_MSG("%s: Find device node failed\n", __func__);
|
||||||
|
#endif
|
||||||
|
err = jl1xxx_operation_args_get(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (jl1xxx->intr.enable & JL1XXX_INTR_STATIC_OP_EN)
|
||||||
|
phydev->irq = JL1XXX_INTR_IRQ;
|
||||||
|
|
||||||
|
jl1xxx->static_inited = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl1xxx_config_init(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct jl1xxx_priv *priv = phydev->priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!priv->static_inited) {
|
||||||
|
#if (JLSEMI_DEBUG_INFO)
|
||||||
|
JLSEMI_PHY_MSG("jl1xxx_config_init_before:\n");
|
||||||
|
ret = jlsemi_phy_reg_print(phydev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
ret = jl1xxx_static_op_init(phydev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
#if (JLSEMI_DEBUG_INFO)
|
||||||
|
JLSEMI_PHY_MSG("jl1xxx_config_init_after:\n");
|
||||||
|
ret = jlsemi_phy_reg_print(phydev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
priv->static_inited = JLSEMI_PHY_NOT_REENTRANT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl1xxx_ack_interrupt(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = jl1xxx_intr_ack_event(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl1xxx_config_intr(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct jl1xxx_priv *priv = phydev->priv;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (priv->intr.enable & JL1XXX_INTR_STATIC_OP_EN) {
|
||||||
|
err = jl1xxx_ack_interrupt(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = jl1xxx_intr_static_op_set(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl1xxx_read_status(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct jl1xxx_priv *priv = phydev->priv;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (priv->intr.enable & JL1XXX_INTR_STATIC_OP_EN) {
|
||||||
|
err = jl1xxx_ack_interrupt(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return genphy_read_status(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void jl1xxx_remove(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct device *dev = jlsemi_get_mdio(phydev);
|
||||||
|
struct jl1xxx_priv *priv = phydev->priv;
|
||||||
|
|
||||||
|
if (priv)
|
||||||
|
devm_kfree(dev, priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (JLSEMI_PHY_WOL)
|
||||||
|
static void jl1xxx_get_wol(struct phy_device *phydev,
|
||||||
|
struct ethtool_wolinfo *wol)
|
||||||
|
{
|
||||||
|
struct jl1xxx_priv *priv = phydev->priv;
|
||||||
|
int wol_en;
|
||||||
|
|
||||||
|
if (priv->wol.ethtool) {
|
||||||
|
wol->supported = WAKE_MAGIC;
|
||||||
|
wol->wolopts = 0;
|
||||||
|
|
||||||
|
wol_en = jl1xxx_wol_dynamic_op_get(phydev);
|
||||||
|
|
||||||
|
if (!wol_en)
|
||||||
|
wol->wolopts |= WAKE_MAGIC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl1xxx_set_wol(struct phy_device *phydev,
|
||||||
|
struct ethtool_wolinfo *wol)
|
||||||
|
{
|
||||||
|
struct jl1xxx_priv *priv = phydev->priv;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (priv->wol.ethtool) {
|
||||||
|
if (wol->wolopts & WAKE_MAGIC) {
|
||||||
|
err = jl1xxx_wol_dynamic_op_set(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int jl1xxx_suspend(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
return genphy_suspend(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl1xxx_resume(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
return genphy_resume(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_probe(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct device *dev = jlsemi_get_mdio(phydev);
|
||||||
|
struct jl2xxx_priv *jl2xxx = NULL;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
jl2xxx = devm_kzalloc(dev, sizeof(*jl2xxx), GFP_KERNEL);
|
||||||
|
if (!jl2xxx)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
phydev->priv = jl2xxx;
|
||||||
|
|
||||||
|
#if (JLSEMI_KERNEL_DEVICE_TREE_USE)
|
||||||
|
if (!dev->of_node)
|
||||||
|
JLSEMI_PHY_MSG("%s: Find device node failed\n", __func__);
|
||||||
|
#endif
|
||||||
|
err = jl2xxx_operation_args_get(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (jl2xxx->intr.enable & JL2XXX_INTR_STATIC_OP_EN)
|
||||||
|
phydev->irq = JL2XXX_INTR_IRQ;
|
||||||
|
|
||||||
|
jl2xxx->static_inited = false;
|
||||||
|
jl2xxx->nstats = ARRAY_SIZE(jl2xxx_hw_stats);
|
||||||
|
jl2xxx->hw_stats = jl2xxx_hw_stats;
|
||||||
|
jl2xxx->stats = kcalloc(jl2xxx->nstats, sizeof(u64), GFP_KERNEL);
|
||||||
|
if (!jl2xxx->stats)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_config_init(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!priv->static_inited) {
|
||||||
|
#if (JLSEMI_DEBUG_INFO)
|
||||||
|
JLSEMI_PHY_MSG("jl2xxx_config_init_before:\n");
|
||||||
|
ret = jlsemi_phy_reg_print(phydev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
ret = jl2xxx_static_op_init(phydev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
#if (JLSEMI_DEBUG_INFO)
|
||||||
|
JLSEMI_PHY_MSG("jl2xxx_config_init_after:\n");
|
||||||
|
ret = jlsemi_phy_reg_print(phydev);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
priv->static_inited = JLSEMI_PHY_NOT_REENTRANT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_ack_interrupt(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = jl2xxx_intr_ack_event(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_config_intr(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (priv->intr.enable & JL2XXX_INTR_STATIC_OP_EN) {
|
||||||
|
err = jl2xxx_ack_interrupt(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = jl2xxx_intr_static_op_set(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_read_status(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
bool fiber_mode;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (priv->intr.enable & JL2XXX_INTR_STATIC_OP_EN) {
|
||||||
|
err = jl2xxx_ack_interrupt(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber_mode = jl2xxx_read_fiber_status(phydev);
|
||||||
|
if (fiber_mode)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return genphy_read_status(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl1xxx_config_aneg(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
return genphy_config_aneg(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_config_aneg(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
u16 phy_mode;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
val = jlsemi_read_paged(phydev, JL2XXX_PAGE18,
|
||||||
|
JL2XXX_WORK_MODE_REG);
|
||||||
|
phy_mode = val & JL2XXX_WORK_MODE_MASK;
|
||||||
|
|
||||||
|
if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((phydev->interface != PHY_INTERFACE_MODE_SGMII) &&
|
||||||
|
((phy_mode == JL2XXX_FIBER_RGMII_MODE) ||
|
||||||
|
(phy_mode == JL2XXX_UTP_FIBER_RGMII_MODE)))
|
||||||
|
return jl2xxx_config_aneg_fiber(phydev);
|
||||||
|
|
||||||
|
return genphy_config_aneg(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_suspend(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
return genphy_suspend(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_resume(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
return genphy_resume(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (JLSEMI_PHY_WOL)
|
||||||
|
static void jl2xxx_get_wol(struct phy_device *phydev,
|
||||||
|
struct ethtool_wolinfo *wol)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
int wol_en;
|
||||||
|
|
||||||
|
if (priv->wol.ethtool) {
|
||||||
|
wol->supported = WAKE_MAGIC;
|
||||||
|
wol->wolopts = 0;
|
||||||
|
|
||||||
|
wol_en = jl2xxx_wol_dynamic_op_get(phydev);
|
||||||
|
|
||||||
|
if (wol_en)
|
||||||
|
wol->wolopts |= WAKE_MAGIC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_set_wol(struct phy_device *phydev,
|
||||||
|
struct ethtool_wolinfo *wol)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (priv->wol.ethtool) {
|
||||||
|
if (wol->wolopts & WAKE_MAGIC) {
|
||||||
|
err = jl2xxx_wol_dynamic_op_set(phydev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (JL2XXX_PHY_TUNABLE)
|
||||||
|
static int jl2xxx_get_tunable(struct phy_device *phydev,
|
||||||
|
struct ethtool_tunable *tuna, void *data)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
|
||||||
|
switch (tuna->id) {
|
||||||
|
case ETHTOOL_PHY_FAST_LINK_DOWN:
|
||||||
|
if (priv->fld.ethtool)
|
||||||
|
return jl2xxx_fld_dynamic_op_get(phydev, data);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
case ETHTOOL_PHY_DOWNSHIFT:
|
||||||
|
if (priv->downshift.ethtool)
|
||||||
|
return jl2xxx_downshift_dynamic_op_get(phydev, data);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_set_tunable(struct phy_device *phydev,
|
||||||
|
struct ethtool_tunable *tuna, const void *data)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
|
||||||
|
switch (tuna->id) {
|
||||||
|
case ETHTOOL_PHY_FAST_LINK_DOWN:
|
||||||
|
if (priv->fld.ethtool)
|
||||||
|
return jl2xxx_fld_dynamic_op_set(phydev, data);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
case ETHTOOL_PHY_DOWNSHIFT:
|
||||||
|
if (priv->downshift.ethtool)
|
||||||
|
return jl2xxx_downshift_dynamic_op_set(phydev,
|
||||||
|
*(const u8 *)data);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (JL2XXX_GET_STAT)
|
||||||
|
static u64 get_stat(struct phy_device *phydev, int i)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
val = jlsemi_read_paged(phydev, priv->hw_stats[i].page,
|
||||||
|
priv->hw_stats[i].reg);
|
||||||
|
if (val < 0)
|
||||||
|
return U64_MAX;
|
||||||
|
|
||||||
|
val = val & priv->hw_stats[i].mask;
|
||||||
|
priv->stats[i] += val;
|
||||||
|
|
||||||
|
return priv->stats[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void jl2xxx_get_stats(struct phy_device *phydev,
|
||||||
|
struct ethtool_stats *stats, u64 *data)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!priv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < priv->nstats; i++)
|
||||||
|
data[i] = get_stat(phydev, i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (JL2XXX_GET_STRING)
|
||||||
|
static void jl2xxx_get_strings(struct phy_device *phydev, u8 *data)
|
||||||
|
{
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!priv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < priv->nstats; i++)
|
||||||
|
strlcpy(data + i * ETH_GSTRING_LEN,
|
||||||
|
priv->hw_stats[i].string, ETH_GSTRING_LEN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void jl2xxx_remove(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
struct device *dev = jlsemi_get_mdio(phydev);
|
||||||
|
struct jl2xxx_priv *priv = phydev->priv;
|
||||||
|
|
||||||
|
kfree(priv->stats);
|
||||||
|
if (priv)
|
||||||
|
devm_kfree(dev, priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int jlsemi_aneg_done(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
int retval = phy_read(phydev, MII_BMSR);
|
||||||
|
|
||||||
|
return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int jl2xxx_aneg_done(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
u16 phy_mode;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
val = jlsemi_read_paged(phydev, JL2XXX_PAGE18,
|
||||||
|
JL2XXX_WORK_MODE_REG);
|
||||||
|
phy_mode = val & JL2XXX_WORK_MODE_MASK;
|
||||||
|
|
||||||
|
if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// fiber not an complite
|
||||||
|
if ((phydev->interface != PHY_INTERFACE_MODE_SGMII) &&
|
||||||
|
((phy_mode == JL2XXX_FIBER_RGMII_MODE) ||
|
||||||
|
(phy_mode == JL2XXX_UTP_FIBER_RGMII_MODE)))
|
||||||
|
return BMSR_ANEGCOMPLETE;
|
||||||
|
|
||||||
|
return jlsemi_aneg_done(phydev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct phy_driver jlsemi_drivers[] = {
|
||||||
|
{
|
||||||
|
.phy_id = JL1XXX_PHY_ID,
|
||||||
|
.phy_id_mask = JLSEMI_PHY_ID_MASK,
|
||||||
|
.name = DRIVER_NAME_100M,
|
||||||
|
/* PHY_BASIC_FEATURES */
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.probe = jl1xxx_probe,
|
||||||
|
.config_intr = jl1xxx_config_intr,
|
||||||
|
.read_status = jl1xxx_read_status,
|
||||||
|
.config_init = jl1xxx_config_init,
|
||||||
|
.config_aneg = jl1xxx_config_aneg,
|
||||||
|
.aneg_done = jlsemi_aneg_done,
|
||||||
|
.suspend = jl1xxx_suspend,
|
||||||
|
.resume = jl1xxx_resume,
|
||||||
|
.remove = jl1xxx_remove,
|
||||||
|
#if (JLSEMI_PHY_WOL)
|
||||||
|
.get_wol = jl1xxx_get_wol,
|
||||||
|
.set_wol = jl1xxx_set_wol,
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.phy_id = JL2XXX_PHY_ID,
|
||||||
|
.phy_id_mask = JLSEMI_PHY_ID_MASK,
|
||||||
|
.name = DRIVER_NAME_1000M,
|
||||||
|
/* PHY_BASIC_FEATURES */
|
||||||
|
.features = PHY_GBIT_FEATURES,
|
||||||
|
.probe = jl2xxx_probe,
|
||||||
|
.config_intr = jl2xxx_config_intr,
|
||||||
|
.read_status = jl2xxx_read_status,
|
||||||
|
.config_init = jl2xxx_config_init,
|
||||||
|
.config_aneg = jl2xxx_config_aneg,
|
||||||
|
.aneg_done = jl2xxx_aneg_done,
|
||||||
|
.suspend = jl2xxx_suspend,
|
||||||
|
.resume = jl2xxx_resume,
|
||||||
|
.remove = jl2xxx_remove,
|
||||||
|
#if (JLSEMI_PHY_WOL)
|
||||||
|
.get_wol = jl2xxx_get_wol,
|
||||||
|
.set_wol = jl2xxx_set_wol,
|
||||||
|
#endif
|
||||||
|
#if (JL2XXX_PHY_TUNABLE)
|
||||||
|
.get_tunable = jl2xxx_get_tunable,
|
||||||
|
.set_tunable = jl2xxx_set_tunable,
|
||||||
|
#endif
|
||||||
|
#if (JL2XXX_GET_STAT)
|
||||||
|
.get_stats = jl2xxx_get_stats,
|
||||||
|
#endif
|
||||||
|
#if (JL2XXX_GET_STRING)
|
||||||
|
.get_strings = jl2xxx_get_strings,
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module_jlsemi_driver(jlsemi_drivers);
|
||||||
|
|
||||||
|
static struct mdio_device_id __maybe_unused jlsemi_tbl[] = {
|
||||||
|
{JL1XXX_PHY_ID, JLSEMI_PHY_ID_MASK},
|
||||||
|
{JL2XXX_PHY_ID, JLSEMI_PHY_ID_MASK},
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(mdio, jlsemi_tbl);
|
||||||
341
include/dt-bindings/phy/jlsemi-dt-phy.h
Normal file
341
include/dt-bindings/phy/jlsemi-dt-phy.h
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0
|
||||||
|
*
|
||||||
|
* Device Tree constants for JLSemi PHY
|
||||||
|
*
|
||||||
|
* Author: Gangqiao Kuang
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 JLSemi Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DT_BINDINGS_JLSEMI_PHY_H
|
||||||
|
#define _DT_BINDINGS_JLSEMI_PHY_H
|
||||||
|
|
||||||
|
/**************************** Linux Version Compatible ********************/
|
||||||
|
#define JLSEMI_DEV_COMPATIBLE (KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
|
||||||
|
#define JL2XXX_GET_STRING (KERNEL_VERSION(4, 5, 0) <= LINUX_VERSION_CODE)
|
||||||
|
#define JL2XXX_GET_STAT (KERNEL_VERSION(4, 5, 0) <= LINUX_VERSION_CODE)
|
||||||
|
#define JL2XXX_PHY_TUNABLE (KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE)
|
||||||
|
#define JLSEMI_PHY_WOL (KERNEL_VERSION(3, 10, 0) < LINUX_VERSION_CODE)
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JLSemi Debug *******************************/
|
||||||
|
#define JLSEMI_DEBUG_INFO 0
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/************************* JLSemi Phy Init Reentrant *********************/
|
||||||
|
#define JLSEMI_PHY_NOT_REENTRANT false
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL1XXX-LED *********************************/
|
||||||
|
/* PHY LED Modes Select */
|
||||||
|
#define JL1XXX_LED0_STRAP (1 << 0)
|
||||||
|
#define JL1XXX_LED0_EEE (1 << 1)
|
||||||
|
#define JL1XXX_LED0_100_ACTIVITY (1 << 2)
|
||||||
|
#define JL1XXX_LED0_10_ACTIVITY (1 << 3)
|
||||||
|
#define JL1XXX_LED0_100_LINK (1 << 4)
|
||||||
|
#define JL1XXX_LED0_10_LINK (1 << 5)
|
||||||
|
#define JL1XXX_LED1_STRAP (1 << 8)
|
||||||
|
#define JL1XXX_LED1_EEE (1 << 9)
|
||||||
|
#define JL1XXX_LED1_100_ACTIVITY (1 << 10)
|
||||||
|
#define JL1XXX_LED1_10_ACTIVITY (1 << 11)
|
||||||
|
#define JL1XXX_LED1_100_LINK (1 << 12)
|
||||||
|
#define JL1XXX_LED1_10_LINK (1 << 13)
|
||||||
|
|
||||||
|
/* PHY LED As Gpio Output Select */
|
||||||
|
#define JL1XXX_GPIO_LED0_OUT (1 << 2)
|
||||||
|
#define JL1XXX_GPIO_LED1_OUT (1 << 3)
|
||||||
|
#define JL1XXX_GPIO_LED0_EN (1 << 14)
|
||||||
|
#define JL1XXX_GPIO_LED1_EN (1 << 15)
|
||||||
|
|
||||||
|
/* PHY LED Control Enable Mask Select */
|
||||||
|
#define JL1XXX_LED_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL1XXX_LED_MODE_EN (1 << 1)
|
||||||
|
#define JL1XXX_LED_GLOABL_PERIOD_EN (1 << 2)
|
||||||
|
#define JL1XXX_LED_GLOBAL_ON_EN (1 << 3)
|
||||||
|
#define JL1XXX_LED_GPIO_OUT_EN (1 << 4)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY LED Control Enable Mask Config */
|
||||||
|
#define JL1XXX_LED_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY LED Modes Config */
|
||||||
|
#define JL1XXX_CFG_LED_MODE (JL1XXX_LED0_100_LINK | \
|
||||||
|
JL1XXX_LED0_10_LINK | \
|
||||||
|
JL1XXX_LED1_100_ACTIVITY | \
|
||||||
|
JL1XXX_LED1_10_ACTIVITY)
|
||||||
|
|
||||||
|
/* PHY LED As Gpio Output Config */
|
||||||
|
#define JL1XXX_CFG_GPIO (JL1XXX_GPIO_LED0_EN | \
|
||||||
|
JL1XXX_GPIO_LED0_OUT | \
|
||||||
|
JL1XXX_GPIO_LED1_EN | \
|
||||||
|
JL1XXX_GPIO_LED1_OUT)
|
||||||
|
|
||||||
|
/* PHY LED Global Period Config */
|
||||||
|
#define JL1XXX_GLOBAL_PERIOD_MS 0x10
|
||||||
|
|
||||||
|
/* PHY LED Global Hold On Config */
|
||||||
|
#define JL1XXX_GLOBAL_ON_MS 0x8
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
/****************************** JL1XXX-WOL ********************************/
|
||||||
|
/* PHY WOL Control Enable Mask Select */
|
||||||
|
#define JL1XXX_WOL_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY WOL Control Enable Mask Config */
|
||||||
|
#define JL1XXX_WOL_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/***************************** JL1XXX-INTR *******************************/
|
||||||
|
/* PHY Interrupt Control Enable Mask Select */
|
||||||
|
#define JL1XXX_INTR_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL1XXX_INTR_LINK_CHANGE_EN (1 << 1)
|
||||||
|
#define JL1XXX_INTR_AN_ERR_EN (1 << 2)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Interrupt Irq Number Config */
|
||||||
|
#define JL1XXX_INTR_IRQ -1
|
||||||
|
|
||||||
|
/* PHY Interrupt Control Enable Mask Config */
|
||||||
|
#define JL1XXX_INTR_CTRL_EN (0)
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL1XXX-MDI *********************************/
|
||||||
|
/* PHY MDI Control Mode Enable Mask Select */
|
||||||
|
#define JL1XXX_MDI_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL1XXX_MDI_RATE_EN (1 << 1)
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE_EN (1 << 2)
|
||||||
|
|
||||||
|
/* PHY MDI Rate Select */
|
||||||
|
#define JL1XXX_MDI_RATE_STANDARD 0
|
||||||
|
#define JL1XXX_MDI_RATE_ACCELERATE 1
|
||||||
|
|
||||||
|
/* PHY MDI Amplitude Select */
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE0 0
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE1 1
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE2 2
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE3 3
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE4 4
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE5 5
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE6 6
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE7 7
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY MDI Control Mode Enable Mask Config */
|
||||||
|
#define JL1XXX_MDI_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY MDI Rate Config */
|
||||||
|
#define JL1XXX_MDI_RATE JL1XXX_MDI_RATE_ACCELERATE
|
||||||
|
|
||||||
|
/* PHY MDI Amplitude Config */
|
||||||
|
#define JL1XXX_MDI_AMPLITUDE JL1XXX_MDI_AMPLITUDE4
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL1XXX-RMII ********************************/
|
||||||
|
/* PHY RMII Control Mode Enable Mask Select */
|
||||||
|
#define JL1XXX_RMII_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL1XXX_RMII_MODE_EN (1 << 1)
|
||||||
|
#define JL1XXX_RMII_CLK_50M_INPUT_EN (1 << 2)
|
||||||
|
#define JL1XXX_RMII_TX_SKEW_EN (1 << 3)
|
||||||
|
#define JL1XXX_RMII_RX_SKEW_EN (1 << 4)
|
||||||
|
#define JL1XXX_RMII_CRS_DV_EN (1 << 5)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY RMII Control Mode Enable Mask Config */
|
||||||
|
#define JL1XXX_RMII_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY RMII Timing Config */
|
||||||
|
#define JL1XXX_RMII_TX_TIMING 0xf
|
||||||
|
#define JL1XXX_RMII_RX_TIMING 0xf
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-LED *********************************/
|
||||||
|
/* PHY LED Modes Select*/
|
||||||
|
#define JL2XXX_LED0_LINK10 (1 << 0)
|
||||||
|
#define JL2XXX_LED0_LINK100 (1 << 1)
|
||||||
|
#define JL2XXX_LED0_LINK1000 (1 << 3)
|
||||||
|
#define JL2XXX_LED0_ACTIVITY (1 << 4)
|
||||||
|
#define JL2XXX_LED1_LINK10 (1 << 5)
|
||||||
|
#define JL2XXX_LED1_LINK100 (1 << 6)
|
||||||
|
#define JL2XXX_LED1_LINK1000 (1 << 8)
|
||||||
|
#define JL2XXX_LED1_ACTIVITY (1 << 9)
|
||||||
|
#define JL2XXX_LED2_LINK10 (1 << 10)
|
||||||
|
#define JL2XXX_LED2_LINK100 (1 << 11)
|
||||||
|
#define JL2XXX_LED2_LINK1000 (1 << 13)
|
||||||
|
#define JL2XXX_LED2_ACTIVITY (1 << 14)
|
||||||
|
/* mode_A = 0 and mode_B = 1 default mode_A */
|
||||||
|
#define JL2XXX_LED_GLB_MODE_B (1 << 15)
|
||||||
|
|
||||||
|
/* PHY LED Polarity Select */
|
||||||
|
#define JL2XXX_LED0_POLARITY (1 << 12)
|
||||||
|
#define JL2XXX_LED1_POLARITY (1 << 11)
|
||||||
|
#define JL2XXX_LED2_POLARITY (1 << 10)
|
||||||
|
|
||||||
|
/* PHY LED Control Enable Mask Select */
|
||||||
|
#define JL2XXX_LED_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL2XXX_LED_MODE_EN (1 << 1)
|
||||||
|
#define JL2XXX_LED_GLOABL_PERIOD_EN (1 << 2)
|
||||||
|
#define JL2XXX_LED_GLOBAL_ON_EN (1 << 3)
|
||||||
|
#define JL2XXX_LED_POLARITY_EN (1 << 4)
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY LED Control Enable Mask Config */
|
||||||
|
#define JL2XXX_LED_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY LED Modes Config */
|
||||||
|
#define JL2XXX_CFG_LED_MODE (JL2XXX_LED0_LINK10 | \
|
||||||
|
JL2XXX_LED0_ACTIVITY | \
|
||||||
|
JL2XXX_LED1_LINK100 | \
|
||||||
|
JL2XXX_LED1_ACTIVITY | \
|
||||||
|
JL2XXX_LED2_LINK1000 | \
|
||||||
|
JL2XXX_LED2_ACTIVITY)
|
||||||
|
|
||||||
|
/* PHY LED Polarity Config */
|
||||||
|
#define JL2XXX_LED_POLARITY (JL2XXX_LED0_POLARITY | \
|
||||||
|
JL2XXX_LED1_POLARITY | \
|
||||||
|
JL2XXX_LED2_POLARITY)
|
||||||
|
|
||||||
|
/* PHY LED Global Period Config */
|
||||||
|
#define JL2XXX_GLOBAL_PERIOD_MS 0x3
|
||||||
|
|
||||||
|
/* PHY LED Global Hold On Config */
|
||||||
|
#define JL2XXX_GLOBAL_ON_MS 0x2
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-FLD *********************************/
|
||||||
|
/* PHY Fast Link Down Control Enable Mask Select */
|
||||||
|
#define JL2XXX_FLD_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Fast Link Down Control Enable Mask Config */
|
||||||
|
#define JL2XXX_FLD_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY Fast Link Down Delay Config */
|
||||||
|
#define JL2XXX_FLD_DELAY 0
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-WOL *********************************/
|
||||||
|
/* PHY WOL Control Enable Mask Select */
|
||||||
|
#define JL2XXX_WOL_STATIC_OP_EN (1 << 0)
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY WOL Control Enable Mask Config */
|
||||||
|
#define JL2XXX_WOL_CTRL_EN (0)
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-INTR ********************************/
|
||||||
|
/* PHY Interrupt Control Enable Mask Select */
|
||||||
|
#define JL2XXX_INTR_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL2XXX_INTR_LINK_CHANGE_EN (1 << 1)
|
||||||
|
#define JL2XXX_INTR_AN_ERR_EN (1 << 2)
|
||||||
|
#define JL2XXX_INTR_AN_COMPLETE_EN (1 << 3)
|
||||||
|
#define JL2XXX_INTR_AN_PAGE_RECE (1 << 4)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Interrupt Irq Number Config */
|
||||||
|
#define JL2XXX_INTR_IRQ -1
|
||||||
|
|
||||||
|
/* PHY Interrupt Control Enable Mask Config */
|
||||||
|
#define JL2XXX_INTR_CTRL_EN (0)
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-DSFT ********************************/
|
||||||
|
/* PHY Downshift Control Enable Mask */
|
||||||
|
#define JL2XXX_DSFT_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Downshift Control Enable Config */
|
||||||
|
#define JL2XXX_DSFT_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY Downshift Count Config */
|
||||||
|
#define JL2XXX_DSFT_AN_CNT 4
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-RGMII *******************************/
|
||||||
|
/* PHY RGMII Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_RGMII_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL2XXX_RGMII_TX_DLY_EN (1 << 1)
|
||||||
|
#define JL2XXX_RGMII_RX_DLY_EN (1 << 2)
|
||||||
|
/* PHY RGMII DELAY BIT */
|
||||||
|
#define JL2XXX_RGMII_TX_DLY_2NS (1 << 8)
|
||||||
|
#define JL2XXX_RGMII_RX_DLY_2NS (1 << 9)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY RGMII Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_RGMII_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-PATCH *******************************/
|
||||||
|
/* PHY Patch Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_PATCH_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Patch Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_PATCH_CTRL_EN (JL2XXX_PATCH_STATIC_OP_EN)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-CLOCK *******************************/
|
||||||
|
/* PHY Clock Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_CLK_STATIC_OP_EN (1 << 0)
|
||||||
|
#define JL2XXX_25M_CLK_OUT_EN (1 << 1)
|
||||||
|
#define JL2XXX_125M_CLK_OUT_EN (1 << 2)
|
||||||
|
#define JL2XXX_CLK_OUT_DIS (1 << 3)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Clock Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_CLK_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-WORK_MODE ***************************/
|
||||||
|
/* PHY Work Mode Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_WORK_MODE_STATIC_OP_EN (1 << 0)
|
||||||
|
|
||||||
|
/* PHY Work Mode Select */
|
||||||
|
#define JL2XXX_UTP_RGMII_MODE 0
|
||||||
|
#define JL2XXX_FIBER_RGMII_MODE 1
|
||||||
|
#define JL2XXX_UTP_FIBER_RGMII_MODE 2
|
||||||
|
#define JL2XXX_UTP_SGMII_MODE 3
|
||||||
|
#define JL2XXX_PHY_SGMII_RGMII_MODE 4
|
||||||
|
#define JL2XXX_MAC_SGMII_RGMII_MODE 5
|
||||||
|
#define JL2XXX_UTP_FIBER_FORCE_MODE1 6
|
||||||
|
#define JL2XXX_UTP_FIBER_FORCE_MODE2 7
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Work Mode Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_WORK_MODE_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY Work Mode Config */
|
||||||
|
#define JL2XXX_WORK_MODE_MODE JL2XXX_UTP_RGMII_MODE
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-LOOPBACK ****************************/
|
||||||
|
/* PHY Loopback Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_LPBK_STATIC_OP_EN (1 << 0)
|
||||||
|
|
||||||
|
/* PHY Loopback Mode Select */
|
||||||
|
#define JL2XXX_LPBK_PCS_10M 0
|
||||||
|
#define JL2XXX_LPBK_PCS_100M 1
|
||||||
|
#define JL2XXX_LPBK_PCS_1000M 2
|
||||||
|
#define JL2XXX_LPBK_PMD_1000M 3
|
||||||
|
#define JL2XXX_LPBK_EXT_STUB_1000M 4
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Loopback Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_LPBK_CTRL_EN (0)
|
||||||
|
|
||||||
|
/* PHY Loopback Mode Config */
|
||||||
|
#define JL2XXX_LPBK_MODE JL2XXX_LPBK_PCS_1000M
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-SLEW_RATE ****************************/
|
||||||
|
/* PHY Slew Rate Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_SLEW_RATE_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Slew Rate Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_SLEW_RATE_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
/**************************** JL2XXX-RXC_OUT *****************************/
|
||||||
|
/* PHY Rx Clock Out Control Mode Enable Mask Select */
|
||||||
|
#define JL2XXX_RXC_OUT_STATIC_OP_EN (1 << 0)
|
||||||
|
//-----------------------------------------------------------------------//
|
||||||
|
/* PHY Rx Clock Out Control Mode Enable Mask Config */
|
||||||
|
#define JL2XXX_RXC_OUT_CTRL_EN (0)
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
#endif
|
||||||
Loading…
x
Reference in New Issue
Block a user