diff mbox series

[v1,1/4] mdio-bitbang: add SMI0 mode support

Message ID 20191107110030.25199-2-m.grzeschik@pengutronix.de
State Not Applicable
Delegated to: David Miller
Headers show
Series microchip: add support for ksz88x3 driver family | expand

Commit Message

Michael Grzeschik Nov. 7, 2019, 11 a.m. UTC
Some microchip phys support the Serial Management Interface Protocol
(SMI) for the configuration of the extended register set. We add
MII_ADDR_SMI0 as an available interface to the mdiobb write and read
functions, as this interface can be easy realized using the bitbang mdio
driver.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
RFC -> v1: - moved the Protocol description to mdio-bitbang
           - renamed the protocol to SMI_KSZ88X3...

 drivers/net/phy/mdio-bitbang.c | 21 +++++++++++++++++++++
 include/linux/phy.h            |  2 ++
 2 files changed, 23 insertions(+)

Comments

Andrew Lunn Nov. 7, 2019, 3:42 p.m. UTC | #1
On Thu, Nov 07, 2019 at 12:00:27PM +0100, Michael Grzeschik wrote:
> Some microchip phys support the Serial Management Interface Protocol
> (SMI) for the configuration of the extended register set. We add
> MII_ADDR_SMI0 as an available interface to the mdiobb write and read
> functions, as this interface can be easy realized using the bitbang mdio
> driver.
> 
> Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>

Hi Michael

I don't like adding vendor proprietary stuff to generic code like
this. Please could you see if you can make use of mdiobb_ops in some
way? Move all this junk out into a mdio-kzs88x3.c?

Thanks
	Andrew
diff mbox series

Patch

diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index 5136275c8e739..9f6fb84f92f60 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -22,6 +22,21 @@ 
 #define MDIO_READ 2
 #define MDIO_WRITE 1
 
+/* KSZ8863 Serial Management Interface (SMI) uses the following frame format:
+ *
+ *       preamble|start|Read/Write|  PHY   |  REG  |TA|   Data bits      | Idle
+ *               |frame| OP code  |address |address|  |                  |
+ * read | 32x1´s | 01  |    00    | 1xRRR  | RRRRR |Z0| 00000000DDDDDDDD |  Z
+ * write| 32x1´s | 01  |    00    | 0xRRR  | RRRRR |10| xxxxxxxxDDDDDDDD |  Z
+ *
+ * The register number is encoded with the 5 least significant bits in REG
+ * and the 3 most significant bits in PHY
+ */
+
+#define SMI_KSZ88X3_RW_OPCODE	0
+#define SMI_KSZ88X3_READ_PHY	(1 << 4)
+#define SMI_KSZ88X3_WRITE_PHY	(0 << 4)
+
 #define MDIO_C45 (1<<15)
 #define MDIO_C45_ADDR (MDIO_C45 | 0)
 #define MDIO_C45_READ (MDIO_C45 | 3)
@@ -157,6 +172,9 @@  static int mdiobb_read(struct mii_bus *bus, int phy, int reg)
 	if (reg & MII_ADDR_C45) {
 		reg = mdiobb_cmd_addr(ctrl, phy, reg);
 		mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
+	} else if (reg & MII_ADDR_SMI_KSZ88X3) {
+		mdiobb_cmd(ctrl, SMI_KSZ88X3_RW_OPCODE,
+			   (reg & 0xE0) >> 5 | SMI_KSZ88X3_READ_PHY, reg);
 	} else
 		mdiobb_cmd(ctrl, MDIO_READ, phy, reg);
 
@@ -188,6 +206,9 @@  static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
 	if (reg & MII_ADDR_C45) {
 		reg = mdiobb_cmd_addr(ctrl, phy, reg);
 		mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
+	} else if (reg & MII_ADDR_SMI_KSZ88X3) {
+		mdiobb_cmd(ctrl, SMI_KSZ88X3_RW_OPCODE,
+			   (reg & 0xE0) >> 5 | SMI_KSZ88X3_WRITE_PHY, reg);
 	} else
 		mdiobb_cmd(ctrl, MDIO_WRITE, phy, reg);
 
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 78436d58ce7ce..e569aa92ac6c8 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -201,6 +201,8 @@  static inline const char *phy_modes(phy_interface_t interface)
 #define MII_DEVADDR_C45_SHIFT	16
 #define MII_REGADDR_C45_MASK	GENMASK(15, 0)
 
+#define MII_ADDR_SMI_KSZ88X3 (1<<31)
+
 struct device;
 struct phylink;
 struct sk_buff;