[PATCH net-next V3] net: phy: Add TJA1100 BroadR-Reach PHY driver.

2018-06-09 Thread 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 

---

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.

2018-06-09 Thread Kirill Kranke
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.

2018-06-08 Thread 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..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.

2018-06-08 Thread Kirill Kranke
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