[PATCH net-next V3] net: phy: Add TJA1100 BroadR-Reach PHY driver.
Current generic PHY driver does not work with TJA1100 BroadR-REACH PHY properly. TJA1100 does not have any standard ability enabled at MII_BMSR register. Instead it has BroadR-REACH ability at MII_ESTATUS enabled, which is not handled by generic driver yet. Therefore generic driver is unable to guess required link speed, duplex etc. Device is started up with 10Mbps halfduplex which is incorrect. BroadR-REACH able flag is not specified in IEEE802.3-2015. Which is why I did not add BroadR-REACH able flag support at generic driver. Once BroadR-REACH able flag gets into IEEE802.3 it should be reasonable to support it in the generic PHY driver. Signed-off-by: Kirill Kranke --- Notes: Second edition of the patch miss changes list and V2 flag. Changes are included here. Changes from V1 to V2: - Remove unused #define from tja1100.c - Do not touch phydev->supported and phydev->advertising at tja1100_phy_config_init - Use proper error codes at tja1100_phy_config_aneg - Use phydev_err instead of pr_err - Do not specify read_status and soft_reset while they are default to required value - Correct wrong Signed-off-by email address Changes from V2 to V3: - Add 'net-next' tree - Add this notes - Rename config option from TJA1100_PHY to NXP_TJA1100_PHY - Minor update to config help message: specify that able flag is TJA1100's custom - Add SUPPORTED_TP feature diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 343989f..ec30de4 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -387,6 +387,15 @@ config NATIONAL_PHY ---help--- Currently supports the DP83865 PHY. +config NXP_TJA1100_PHY + tristate "NXP TJA1100 PHY" + help + Support of NXP TJA1100 BroadR-REACH ethernet PHY. + Generic driver is not suitable for TJA1100 PHY while the PHY does not + advertise any standard IEEE capabilities. It uses custom BroadR-REACH + able flag instead. This driver configures capabilities of the PHY + properly. + config QSEMI_PHY tristate "Quality Semiconductor PHYs" ---help--- diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 5805c0b..c1bc14d4 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_MICROCHIP_PHY) += microchip.o obj-$(CONFIG_MICROCHIP_T1_PHY) += microchip_t1.o obj-$(CONFIG_MICROSEMI_PHY)+= mscc.o obj-$(CONFIG_NATIONAL_PHY) += national.o +obj-$(CONFIG_NXP_TJA1100_PHY) += tja1100.o obj-$(CONFIG_QSEMI_PHY)+= qsemi.o obj-$(CONFIG_REALTEK_PHY) += realtek.o obj-$(CONFIG_RENESAS_PHY) += uPD60620.o diff --git a/drivers/net/phy/tja1100.c b/drivers/net/phy/tja1100.c new file mode 100644 index 000..2b03057 --- /dev/null +++ b/drivers/net/phy/tja1100.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0 +/* tja1100.c: TJA1100 BoardR-REACH PHY driver. + * + * Copyright (c) 2017 Kirill Kranke + * Author: Kirill Kranke + */ + +#include +#include +#include + +static int tja1100_phy_config_init(struct phy_device *phydev) +{ + phydev->autoneg = AUTONEG_DISABLE; + phydev->speed = SPEED_100; + phydev->duplex = DUPLEX_FULL; + + return 0; +} + +static int tja1100_phy_config_aneg(struct phy_device *phydev) +{ + if (phydev->autoneg == AUTONEG_ENABLE) { + phydev_err(phydev, "autonegotiation is not supported\n"); + return -EINVAL; + } + + if (phydev->speed != SPEED_100 || phydev->duplex != DUPLEX_FULL) { + phydev_err(phydev, "only 100MBps Full Duplex allowed\n"); + return -EINVAL; + } + + return 0; +} + +static struct phy_driver tja1100_phy_driver[] = { + { + .phy_id = 0x0180dc48, + .phy_id_mask = 0xfff0, + .name = "NXP TJA1100", + + /* TJA1100 has only 100BASE-BroadR-REACH ability specified +* at MII_ESTATUS register. Standard modes are not +* supported. Therefore BroadR-REACH allow only 100Mbps +* full duplex without autoneg. +*/ + .features = SUPPORTED_100baseT_Full | SUPPORTED_MII + | SUPPORTED_TP, + + .config_aneg = tja1100_phy_config_aneg, + .config_init = tja1100_phy_config_init, + + .suspend = genphy_suspend, + .resume = genphy_resume, + } +}; + +module_phy_driver(tja1100_phy_driver); + +MODULE_DESCRIPTION("NXP TJA1100 driver"); +MODULE_AUTHOR("Kirill Kranke "); +MODULE_LICENSE("GPL"); + +static struct mdio_device_id __maybe_unused nxp_tbl[] = { + { 0x0180dc48, 0xfff0 }, + {} +}; + +MODULE_DEVICE_TABLE(mdio, nxp_tbl);
Re: [PATCH] net: phy: Add TJA1100 BroadR-Reach PHY driver.
Hi Andrew. Thanks for your comments. I will update the patch a bit later. > > Does 100Base-T1/cause 96 define a way to identify a PHY which > implements this? I'm just wondering if we can do this in the generic > code, for devices which correctly implement the standard? > Well, I did research IEEE 802.3 standards before implementing the Patch. Initially I wanted to update generic phy driver. I did not find a way to identify 100Base-T1 PHY using Clause 22 MDIO. This section is completely missing at IEEE 802.3bw, which describe 100Base-T1. There are some updates to Clause 45 registers at IEEE 802.3bw. They add "BASE-T1 PMA/PMD extended ability" to PMA/PMD registers. At Clause 96 they state following: "The MDIO capability described in Clause 45 defines several variables that provide control and status information for and about the PMA and PCS." In the same time I have played with a two different 100Base-T1 PHYs. Both use different Clause 22 registers to advertise their abilities, both are incompatible. None use Clause 45 for this purpose. It seems that this is going to be 100Base-T1 mess while IEEE 802.3bw miss Clause 22 updates. Clause 45 is rarely used from my experience. Probably IEEE expected 100Base-T1 PHYs to go for Clause 45 MDIO and this did not work so far. > > This is the second T1 driver we have had recently. It might make sense to add > a > PHY_T1_FEATURES macro the include/linux/phy.h > This seems reasonable, indeed. > > Don't you also want SUPPORTED_TP? > True, I will add SUPPORTED_TP in next revision of the Patch. Kirill
[PATCH] net: phy: Add TJA1100 BroadR-Reach PHY driver.
Current generic PHY driver does not work with TJA1100 BroadR-REACH PHY properly. TJA1100 does not have any standard ability enabled at MII_BMSR register. Instead it has BroadR-REACH ability at MII_ESTATUS enabled, which is not handled by generic driver yet. Therefore generic driver is unable to guess required link speed, duplex etc. Device is started up with 10Mbps halfduplex which is incorrect. BroadR-REACH able flag is not specified in IEEE802.3-2015. Which is why I did not add BroadR-REACH able flag support at generic driver. Once BroadR-REACH able flag gets into IEEE802.3 it should be reasonable to support it in the generic PHY driver. Signed-off-by: Kirill Kranke diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 343989f..7014eb7 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -422,6 +422,14 @@ config TERANETICS_PHY ---help--- Currently supports the Teranetics TN2020 +config TJA1100_PHY + tristate "NXP TJA1100 PHY" + help + Support of NXP TJA1100 BroadR-REACH ethernet PHY. + Generic driver is not suitable for TJA1100 PHY while the PHY does not + advertise any standard IEEE capabilities. It uses BroadR-REACH able + flag instead. This driver configures capabilities of the PHY properly. + config VITESSE_PHY tristate "Vitesse PHYs" ---help--- diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 5805c0b..4d2a69d 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -83,5 +83,6 @@ obj-$(CONFIG_ROCKCHIP_PHY)+= rockchip.o obj-$(CONFIG_SMSC_PHY) += smsc.o obj-$(CONFIG_STE10XP) += ste10Xp.o obj-$(CONFIG_TERANETICS_PHY) += teranetics.o +obj-$(CONFIG_TJA1100_PHY) += tja1100.o obj-$(CONFIG_VITESSE_PHY) += vitesse.o obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o diff --git a/drivers/net/phy/tja1100.c b/drivers/net/phy/tja1100.c new file mode 100644 index 000..cddf4d7 --- /dev/null +++ b/drivers/net/phy/tja1100.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +/* tja1100.c: TJA1100 BoardR-REACH PHY driver. + * + * Copyright (c) 2017 Kirill Kranke + * Author: Kirill Kranke + */ + +#include +#include +#include + +static int tja1100_phy_config_init(struct phy_device *phydev) +{ + phydev->autoneg = AUTONEG_DISABLE; + phydev->speed = SPEED_100; + phydev->duplex = DUPLEX_FULL; + + return 0; +} + +static int tja1100_phy_config_aneg(struct phy_device *phydev) +{ + if (phydev->autoneg == AUTONEG_ENABLE) { + phydev_err(phydev, "autonegotiation is not supported\n"); + return -EINVAL; + } + + if (phydev->speed != SPEED_100 || phydev->duplex != DUPLEX_FULL) { + phydev_err(phydev, "only 100MBps Full Duplex allowed\n"); + return -EINVAL; + } + + return 0; +} + +static struct phy_driver tja1100_phy_driver[] = { + { + .phy_id = 0x0180dc48, + .phy_id_mask = 0xfff0, + .name = "NXP TJA1100", + + /* TJA1100 has only 100BASE-BroadR-REACH ability specified +* at MII_ESTATUS register. Standard modes are not +* supported. Therefore BroadR-REACH allow only 100Mbps +* full duplex without autoneg. +*/ + .features = SUPPORTED_100baseT_Full | SUPPORTED_MII, + + .config_aneg = tja1100_phy_config_aneg, + .config_init = tja1100_phy_config_init, + + .suspend = genphy_suspend, + .resume = genphy_resume, + } +}; + +module_phy_driver(tja1100_phy_driver); + +MODULE_DESCRIPTION("NXP TJA1100 driver"); +MODULE_AUTHOR("Kirill Kranke "); +MODULE_LICENSE("GPL"); + +static struct mdio_device_id __maybe_unused nxp_tbl[] = { + { 0x0180dc48, 0xfff0 }, + {} +}; + +MODULE_DEVICE_TABLE(mdio, nxp_tbl);
[PATCH] net: phy: Add TJA1100 BroadR-Reach PHY driver.
From: Kirill Kranke Current generic PHY driver does not work with TJA1100 BroadR-REACH PHY properly. TJA1100 does not have any standard ability enabled at MII_BMSR register. Instead it has BroadR-REACH ability at MII_ESTATUS enabled, which is not handled by generic driver yet. Therefore generic driver is unable to guess required link speed, duplex etc. Device is started up with 10Mbps halfduplex which is incorrect. BroadR-REACH able flag is not specified in IEEE802.3-2015. Which is why I did not add BroadR-REACH able flag support at generic driver. Once BroadR-REACH able flag gets into IEEE802.3 it should be reasonable to support it in the generic PHY driver. Signed-off-by: Kirill Kranke diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 343989f..7014eb7 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -422,6 +422,14 @@ config TERANETICS_PHY ---help--- Currently supports the Teranetics TN2020 +config TJA1100_PHY + tristate "NXP TJA1100 PHY" + help + Support of NXP TJA1100 BroadR-REACH ethernet PHY. + Generic driver is not suitable for TJA1100 PHY while the PHY does not + advertise any standard IEEE capabilities. It uses BroadR-REACH able + flag instead. This driver configures capabilities of the PHY properly. + config VITESSE_PHY tristate "Vitesse PHYs" ---help--- diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 5805c0b..4d2a69d 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -83,5 +83,6 @@ obj-$(CONFIG_ROCKCHIP_PHY)+= rockchip.o obj-$(CONFIG_SMSC_PHY) += smsc.o obj-$(CONFIG_STE10XP) += ste10Xp.o obj-$(CONFIG_TERANETICS_PHY) += teranetics.o +obj-$(CONFIG_TJA1100_PHY) += tja1100.o obj-$(CONFIG_VITESSE_PHY) += vitesse.o obj-$(CONFIG_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o diff --git a/drivers/net/phy/tja1100.c b/drivers/net/phy/tja1100.c new file mode 100644 index 000..081b580 --- /dev/null +++ b/drivers/net/phy/tja1100.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0 +/* tja1100.c: TJA1100 BoardR-REACH PHY driver. + * + * Copyright (c) 2017 Kirill Kranke + * Author: Kirill Kranke + */ + +#include +#include +#include + +/* TJA1100 specific registers */ +#define TJA1100_ECTRL 0x11/* Extended control register */ +#define TJA1100_CFG1 0x12/* Configuration register 1 */ +#define TJA1100_CFG2 0x13/* Configuration register 2 */ +#define TJA1100_SERRCNT0x14/* Symbol error counter register 2 */ +#define TJA1100_INTST 0x15/* Interrupt status register */ +#define TJA1100_INTEN 0x16/* Interrupt enable register */ +#define TJA1100_COMST 0x17/* Communication status register */ +#define TJA1100_GST0x18/* General status register */ +#define TJA1100_EXTST 0x19/* External status register */ +#define TJA1100_LFCNT 0x1a/* Link fail counter register */ + +/* Extended control register */ +#define ECTRL_LC 0x8000 /* link control enable */ +#define ECTRL_PM 0x7800 /* operating mode select */ +#define ECTRL_PM_NOCNG 0x /* PM == : no change */ +#define ECTRL_PM_NORMAL0x1800 /* PM == 0011: Normal mode */ +#define ECTRL_PM_STANBY0x6000 /* PM == 1100: Standby mode */ +#define ECTRL_PM_SREQ 0x5800 /* PM == 1011: Sleep Request mode */ +#define ECTRL_SJ_TST 0x0400 /* enable/disable Slave jitter test */ +#define ECTRL_TR_RST 0x0200 /* Autonegotiation process restart */ +#define ECTRL_TST_MODE 0x01c0 /* test mode selection */ +#define ECTRL_C_TST0x0020 /* TDR-based cable test */ +#define ECTRL_LOOPBACK 0x0018 /* loopback mode select */ +#define ECTRL_CFGEN0x0004 /* configuration register access */ +#define ECTRL_CFGINH 0x0002 /* INH configuration */ +#define ECTRL_WAKE_REQ 0x0001 /* wake-up request configuration */ + +/* Configuration register 1 */ +#define CFG1_MS0x8000 /* PHY Master/Slave configuration */ +#define CFG1_AUTO_OP 0x4000 /* managed/autonomous operation */ +#define CFG1_LINKLEN 0x2000 /* cable length: 0 < 15 m; 1 > 15 m */ +#define CFG1_TXAMP 0x0c00 /* nominal transmit amplitude */ +#define CFG1_TXAMP_050 0x /* TXAMP == 00: 500 mV */ +#define CFG1_TXAMP_075 0x0200 /* TXAMP == 01: 750 mV */ +#define CFG1_TXAMP_100 0x0400 /* TXAMP == 10: 1000 mV */ +#define CFG1_TXAMP_125 0x0c00 /* TXAMP == 11: 1250 mV */ +#define CFG1_MODE 0x0300 /* MII/RMII mode */ +#define CFG1_DRIVER0x0080 /* MII output driver strength */ +#define CFG1_SC0x0040 /* sleep confirmation setting */ +#define CFG1_LED_MODE 0x0030 /* LED mode */ +#define CFG1_LED_EN0x0008 /* LED enable */ +#define CFG1_CFG_WAKE 0x0004 /* local wake configuration */ +#define CFG1_APWD 0x0002 /* autonomous power down */ +#define CFG1_LPS 0x0001 /* LPS code group reception */ + +/* Configuration register 2 */ +#define CFG