From patchwork Wed Oct 28 22:14:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 316146 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9257FC55179 for ; Wed, 28 Oct 2020 22:16:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4148624743 for ; Wed, 28 Oct 2020 22:16:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923405; bh=Bdty51XWzk6jO/aWNkHRzG6EWiPUWekeVoOLv6M3Mag=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=PZVdgnoNn3WBKZ3YHo3uwRi2oYo0qIlFlofsyFciF8ZiRymrkt7T5sXjtiM55sWTw zUUEP68+Qw63nddt5V3BTv2gwcxitTmmX6O/JqJO89AtaU4BNHzdqm+S7BeuUau8MU UYt2Z/3QfdHcHc8LvB8mAX05jvv/SL3lJCKj6VMA= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731232AbgJ1WOh (ORCPT ); Wed, 28 Oct 2020 18:14:37 -0400 Received: from mail.kernel.org ([198.145.29.99]:58076 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730698AbgJ1WOf (ORCPT ); Wed, 28 Oct 2020 18:14:35 -0400 Received: from dellmb.labs.office.nic.cz (nat-1.nic.cz [217.31.205.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id DC866246CD; Wed, 28 Oct 2020 22:14:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923274; bh=Bdty51XWzk6jO/aWNkHRzG6EWiPUWekeVoOLv6M3Mag=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jGi1Z2Hzd4CKp2Owk59WozYl7O+t4okJvE5NBBJVGo4MophXjrbWyoYTDR6QkprrN 49xIQ6PqiVLk1Aptg43hHWZajQ7sOEwoCL6veDBI4VD0bE5Z3YBZ8x92ZlMqdDcp49 ZpERP4yh52RTGi7/dsHynO4YtrCaEtBBKydqjyiQ= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: netdev@vger.kernel.org Cc: davem@davemloft.net, =?utf-8?q?Marek_Beh=C3=BAn?= , Andrew Lunn , Russell King Subject: [PATCH net-next 1/5] net: phy: mdio-i2c: support I2C MDIO protocol for RollBall SFP modules Date: Wed, 28 Oct 2020 23:14:23 +0100 Message-Id: <20201028221427.22968-2-kabel@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201028221427.22968-1-kabel@kernel.org> References: <20201028221427.22968-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Some multigig SFPs from RollBall and Hilink do not expose functional MDIO access to the internal PHY of the SFP via I2C address 0x56 (although there seems to be read-only clause 22 access on this address). Instead these SFPs PHY can be accessed via I2C via the SFP Enhanced Digital Diagnostic Interface - I2C address 0x51. This extends the mdio-i2c driver to support this protocol by adding a special parameter to mdio_i2c_alloc function via which this RollBall protocol can be selected. Signed-off-by: Marek Behún Cc: Andrew Lunn Cc: Russell King --- drivers/net/mdio/mdio-i2c.c | 180 +++++++++++++++++++++++++++++++++- drivers/net/phy/sfp.c | 2 +- include/linux/mdio/mdio-i2c.h | 8 +- 3 files changed, 183 insertions(+), 7 deletions(-) diff --git a/drivers/net/mdio/mdio-i2c.c b/drivers/net/mdio/mdio-i2c.c index 09200a70b315..1f5d653a4e22 100644 --- a/drivers/net/mdio/mdio-i2c.c +++ b/drivers/net/mdio/mdio-i2c.c @@ -3,6 +3,7 @@ * MDIO I2C bridge * * Copyright (C) 2015-2016 Russell King + * Copyright (C) 2020 Marek Behun * * Network PHYs can appear on I2C buses when they are part of SFP module. * This driver exposes these PHYs to the networking PHY code, allowing @@ -28,7 +29,7 @@ static unsigned int i2c_mii_phy_addr(int phy_id) return phy_id + 0x40; } -static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg) +static int i2c_mii_read_default(struct mii_bus *bus, int phy_id, int reg) { struct i2c_adapter *i2c = bus->priv; struct i2c_msg msgs[2]; @@ -62,7 +63,7 @@ static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg) return data[0] << 8 | data[1]; } -static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val) +static int i2c_mii_write_default(struct mii_bus *bus, int phy_id, int reg, u16 val) { struct i2c_adapter *i2c = bus->priv; struct i2c_msg msg; @@ -91,7 +92,167 @@ static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val) return ret < 0 ? ret : 0; } -struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c) +/* RollBall SFPs do not access internal PHY via I2C address 0x56, but + * instead via address 0x51, when SFP page is set to 0x03 and password to + * 0xffffffff: + * + * address size contents description + * ------- ---- -------- ----------- + * 0x80 1 CMD 0x01/0x02/0x04 for write/read/done + * 0x81 1 DEV Clause 45 device + * 0x82 2 REG Clause 45 register + * 0x84 2 VAL Register value + */ +#define ROLLBALL_PHY_I2C_ADDR 0x51 + +#define ROLLBALL_CMD_ADDR 0x80 +#define ROLLBALL_DATA_ADDR 0x81 + +#define ROLLBALL_CMD_WRITE 0x01 +#define ROLLBALL_CMD_READ 0x02 +#define ROLLBALL_CMD_DONE 0x04 + +static int i2c_rollball_mii_poll(struct mii_bus *bus, int bus_addr, u8 *buf, size_t len) +{ + struct i2c_adapter *i2c = bus->priv; + struct i2c_msg msgs[2]; + u8 buf0[2], *res; + int i, ret; + + buf0[0] = ROLLBALL_CMD_ADDR; + + msgs[0].addr = bus_addr; + msgs[0].flags = 0; + msgs[0].len = 1; + msgs[0].buf = &buf0[0]; + + res = buf ? buf : &buf0[1]; + + msgs[1].addr = bus_addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = buf ? len : 1; + msgs[1].buf = res; + + /* By experiment it takes up to 70 ms to access a register for these SFPs. Sleep 20ms + * between iteratios and try 10 times. + */ + i = 10; + do { + msleep(20); + + ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) + return ret; + else if (ret != ARRAY_SIZE(msgs)) + return -EIO; + + if (*res == ROLLBALL_CMD_DONE) + return 0; + } while (i-- > 0); + + dev_dbg(&bus->dev, "poll timed out\n"); + + return -ETIMEDOUT; +} + +static int i2c_rollball_mii_cmd(struct mii_bus *bus, int bus_addr, u8 cmd, u8 *data, size_t len) +{ + struct i2c_adapter *i2c = bus->priv; + struct i2c_msg msgs[2]; + u8 cmdbuf[2]; + int ret; + + msgs[0].addr = bus_addr; + msgs[0].flags = 0; + msgs[0].len = len; + msgs[0].buf = data; + + cmdbuf[0] = ROLLBALL_CMD_ADDR; + cmdbuf[1] = cmd; + + msgs[1].addr = bus_addr; + msgs[1].flags = 0; + msgs[1].len = sizeof(cmdbuf); + msgs[1].buf = cmdbuf; + + ret = i2c_transfer(i2c, msgs, 2); + if (ret < 0) + return ret; + + return ret == ARRAY_SIZE(msgs) ? 0 : -EIO; +} + +static int i2c_mii_read_rollball(struct mii_bus *bus, int phy_id, int reg) +{ + u8 buf[4], res[6]; + int bus_addr, ret; + u16 val; + + if (!(reg & MII_ADDR_C45)) + return -EOPNOTSUPP; + + bus_addr = i2c_mii_phy_addr(phy_id); + if (bus_addr != ROLLBALL_PHY_I2C_ADDR) + return 0xffff; + + buf[0] = ROLLBALL_DATA_ADDR; + buf[1] = (reg >> 16) & 0x1f; + buf[2] = (reg >> 8) & 0xff; + buf[3] = reg & 0xff; + + ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_READ, buf, sizeof(buf)); + if (ret < 0) + return ret; + + ret = i2c_rollball_mii_poll(bus, bus_addr, res, sizeof(res)); + if (ret == -ETIMEDOUT) + return 0xffff; + else if (ret < 0) + return ret; + + val = res[4]; + val <<= 8; + val |= res[5]; + + dev_dbg(&bus->dev, "read reg %02x:%04x = %04x\n", (reg >> 16) & 0x1f, reg & 0xffff, val); + + return val; +} + +static int i2c_mii_write_rollball(struct mii_bus *bus, int phy_id, int reg, u16 val) +{ + int bus_addr, ret; + u8 buf[6]; + + if (!(reg & MII_ADDR_C45)) + return -EOPNOTSUPP; + + bus_addr = i2c_mii_phy_addr(phy_id); + if (bus_addr != ROLLBALL_PHY_I2C_ADDR) + return 0; + + buf[0] = ROLLBALL_DATA_ADDR; + buf[1] = (reg >> 16) & 0x1f; + buf[2] = (reg >> 8) & 0xff; + buf[3] = reg & 0xff; + buf[4] = val >> 8; + buf[5] = val & 0xff; + + ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_WRITE, buf, sizeof(buf)); + if (ret < 0) + return ret; + + ret = i2c_rollball_mii_poll(bus, bus_addr, NULL, 0); + if (ret < 0) + return ret; + + dev_dbg(&bus->dev, "write reg %02x:%04x = %04x\n", (reg >> 16) & 0x1f, reg & 0xffff, val); + + return 0; +} + +struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c, + enum mdio_i2c_type type) { struct mii_bus *mii; @@ -104,10 +265,19 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c) snprintf(mii->id, MII_BUS_ID_SIZE, "i2c:%s", dev_name(parent)); mii->parent = parent; - mii->read = i2c_mii_read; - mii->write = i2c_mii_write; mii->priv = i2c; + switch (type) { + case MDIO_I2C_ROLLBALL: + mii->read = i2c_mii_read_rollball; + mii->write = i2c_mii_write_rollball; + break; + default: + mii->read = i2c_mii_read_default; + mii->write = i2c_mii_write_default; + break; + } + return mii; } EXPORT_SYMBOL_GPL(mdio_i2c_alloc); diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 1d18c10e8f82..b1f9fc3a5584 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -409,7 +409,7 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) sfp->read = sfp_i2c_read; sfp->write = sfp_i2c_write; - i2c_mii = mdio_i2c_alloc(sfp->dev, i2c); + i2c_mii = mdio_i2c_alloc(sfp->dev, i2c, MDIO_I2C_DEFAULT); if (IS_ERR(i2c_mii)) return PTR_ERR(i2c_mii); diff --git a/include/linux/mdio/mdio-i2c.h b/include/linux/mdio/mdio-i2c.h index b1d27f7cd23f..b65a80938806 100644 --- a/include/linux/mdio/mdio-i2c.h +++ b/include/linux/mdio/mdio-i2c.h @@ -11,6 +11,12 @@ struct device; struct i2c_adapter; struct mii_bus; -struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c); +enum mdio_i2c_type { + MDIO_I2C_DEFAULT, + MDIO_I2C_ROLLBALL, +}; + +struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c, + enum mdio_i2c_type type); #endif From patchwork Wed Oct 28 22:14:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 311328 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6BE8C4363A for ; Wed, 28 Oct 2020 22:14:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7BC2224171 for ; Wed, 28 Oct 2020 22:14:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923279; bh=/Y1YcgJEnITrM+UgkNFYD7JnHEHOoxCPlRY/J1OzAZA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=Y+JdoUPQ1Da6hTWouGoJiYeyR64Finoj22WRsm8ZTmYyIKGH5OQRPGCFlwI14zqPz NQt0/Hi97OBIXZ3Rt8PLluv1FLkBMCHU8mjN+gQS5hb1r5BvSJTOijP43dRNpTSIDi +hmx6xo2+ze/pJCQcUpjvH9bi1eCPcGCjLNZKcCY= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731245AbgJ1WOi (ORCPT ); Wed, 28 Oct 2020 18:14:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:58110 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731223AbgJ1WOg (ORCPT ); Wed, 28 Oct 2020 18:14:36 -0400 Received: from dellmb.labs.office.nic.cz (nat-1.nic.cz [217.31.205.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 67F2324743; Wed, 28 Oct 2020 22:14:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923275; bh=/Y1YcgJEnITrM+UgkNFYD7JnHEHOoxCPlRY/J1OzAZA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DeznzlD0RfhA9GQvgUcCKGZa9hAxHYxcYwK0X8TDO4mdq4CQKeavFb+kkAlktY1Sf NjX6L4L/Trvho+ZrVozSX9vcF96BofpIi/Z7vU764Wk5Nt0jk5eLFfxY+YQV66HfzD aNIe0APoXJhrftTqiM7D8R4kafGq4HXE2QtSzhxE= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: netdev@vger.kernel.org Cc: davem@davemloft.net, =?utf-8?q?Marek_Beh=C3=BAn?= , Andrew Lunn , Russell King Subject: [PATCH net-next 2/5] net: phylink: allow attaching phy for SFP modules on 802.3z mode Date: Wed, 28 Oct 2020 23:14:24 +0100 Message-Id: <20201028221427.22968-3-kabel@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201028221427.22968-1-kabel@kernel.org> References: <20201028221427.22968-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Some SFPs may contain an internal PHY which may in some cases want to connect with the host interface in 1000base-x/2500base-x mode. Do not fail if such PHY is being attached in one of these PHY interface modes. Signed-off-by: Marek Behún Cc: Andrew Lunn Cc: Russell King --- drivers/net/phy/phylink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 5d8c015bc9f2..52954f12ca5e 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -1018,7 +1018,7 @@ static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy, { if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || (pl->cfg_link_an_mode == MLO_AN_INBAND && - phy_interface_mode_is_8023z(interface)))) + phy_interface_mode_is_8023z(interface) && !pl->sfp_bus))) return -EINVAL; if (pl->phydev) From patchwork Wed Oct 28 22:14:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 311325 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0431EC388F7 for ; Wed, 28 Oct 2020 22:16:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A34BD246CD for ; Wed, 28 Oct 2020 22:16:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923377; bh=ju0jOrjbeRMwPzDrMrdXOwOtizflfQHNTwne0k956po=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=rbDJqzvl+BfWETJLHRbRqzTXOjiQ2fcm/cNe0idzTf00UpqkX8L6v6zehrMm1Jngz FAg2azvbeTD0eRhO/ywsJfyWCnF6V6MQsvNQsSwk2l6yqAGi/11o4eKhlLmnVPHJTo XxgNrYCBaf9o40F1k84+/llTt8SbXlBhrYJqsUSI= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730957AbgJ1WOo (ORCPT ); Wed, 28 Oct 2020 18:14:44 -0400 Received: from mail.kernel.org ([198.145.29.99]:58152 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731233AbgJ1WOh (ORCPT ); Wed, 28 Oct 2020 18:14:37 -0400 Received: from dellmb.labs.office.nic.cz (nat-1.nic.cz [217.31.205.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E93932474F; Wed, 28 Oct 2020 22:14:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923277; bh=ju0jOrjbeRMwPzDrMrdXOwOtizflfQHNTwne0k956po=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VoWyDrwJT6gbIJNh9S9Jrq4e5iGIPsVSG1UzxWAdr2JrOSSeDjCNox64MF6fDdPkB nFu6/2Ik72ZjaWqcG1ydzphFd2TmK+J8aNKQzk29yPPGQAk/mzMKGKq7IzsPTilmYD F0mTkxz0fIoLFmMfc2f9AGRe9TEZN42rF6kTEJh0= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: netdev@vger.kernel.org Cc: davem@davemloft.net, =?utf-8?q?Marek_Beh=C3=BAn?= , Andrew Lunn , Russell King Subject: [PATCH net-next 3/5] net: sfp: configure/destroy I2C mdiobus on transceiver plug/unplug Date: Wed, 28 Oct 2020 23:14:25 +0100 Message-Id: <20201028221427.22968-4-kabel@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201028221427.22968-1-kabel@kernel.org> References: <20201028221427.22968-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Instead of configuring the I2C mdiobus when SFP driver is probed, configure/destroy the mdiobus when SFP transceiver is plugged/unplugged. This way we can tell the mdio-i2c code which protocol to use for each SFP transceiver. Signed-off-by: Marek Behún Cc: Andrew Lunn Cc: Russell King --- drivers/net/phy/sfp.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index b1f9fc3a5584..a392d5fc6ab4 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -399,9 +399,6 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf, static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) { - struct mii_bus *i2c_mii; - int ret; - if (!i2c_check_functionality(i2c, I2C_FUNC_I2C)) return -EINVAL; @@ -409,7 +406,15 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) sfp->read = sfp_i2c_read; sfp->write = sfp_i2c_write; - i2c_mii = mdio_i2c_alloc(sfp->dev, i2c, MDIO_I2C_DEFAULT); + return 0; +} + +static int sfp_i2c_mdiobus_configure(struct sfp *sfp, enum mdio_i2c_type type) +{ + struct mii_bus *i2c_mii; + int ret; + + i2c_mii = mdio_i2c_alloc(sfp->dev, sfp->i2c, type); if (IS_ERR(i2c_mii)) return PTR_ERR(i2c_mii); @@ -427,6 +432,12 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) return 0; } +static void sfp_i2c_mdiobus_destroy(struct sfp *sfp) +{ + mdiobus_unregister(sfp->i2c_mii); + sfp->i2c_mii = NULL; +} + /* Interface */ static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) { @@ -1768,6 +1779,11 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report) else sfp->module_t_start_up = T_START_UP; + /* Configure mdiobus */ + ret = sfp_i2c_mdiobus_configure(sfp, MDIO_I2C_DEFAULT); + if (ret < 0) + return ret; + return 0; } @@ -1778,6 +1794,8 @@ static void sfp_sm_mod_remove(struct sfp *sfp) sfp_hwmon_remove(sfp); + sfp_i2c_mdiobus_destroy(sfp); + memset(&sfp->id, 0, sizeof(sfp->id)); sfp->module_power_mW = 0; From patchwork Wed Oct 28 22:14:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 311327 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 82F47C55179 for ; Wed, 28 Oct 2020 22:14:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2AF2A246CD for ; Wed, 28 Oct 2020 22:14:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923284; bh=C0AJ+ZLPZUyrlH7UNBZgTfeflDN7cswS0QlQC5XiO4A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=ykReaEuyYsXmgMEnskKGd9wD0NQaS1c4QMFnm/D/uGkUHkdpTr08kjvUMDKM+EVbH KJvrwJHkk/v4APEne5StCFkmSZVPqpUzLJUujn4MTIIyzZ2Ide4MPy63NcR0llsbY3 lsqiuNcF6/7E9djpvf5lgiZiGq7KxlDqCYOsoxUY= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731248AbgJ1WOm (ORCPT ); Wed, 28 Oct 2020 18:14:42 -0400 Received: from mail.kernel.org ([198.145.29.99]:58218 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731247AbgJ1WOj (ORCPT ); Wed, 28 Oct 2020 18:14:39 -0400 Received: from dellmb.labs.office.nic.cz (nat-1.nic.cz [217.31.205.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 74AC124753; Wed, 28 Oct 2020 22:14:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923278; bh=C0AJ+ZLPZUyrlH7UNBZgTfeflDN7cswS0QlQC5XiO4A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NJggBhlE55kzlLJT1xbC/70aalBQ6KKo47UtzsRtYXlUcOUsPwn0XvQDRnbeM9Lhd QchbvuaBSdP5a+fGvS3Yx7o+AwWQhJsnP5ZUbV+AgG7khxyZ/E71TbQKrrI6ciYLA5 1pNbwekmcasVJ01x/ObASFBA6pd45L54pdG1pyXw= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: netdev@vger.kernel.org Cc: davem@davemloft.net, =?utf-8?q?Marek_Beh=C3=BAn?= , Andrew Lunn , Russell King Subject: [PATCH net-next 4/5] net: phy: marvell10g: change MACTYPE if underlying MAC does not support it Date: Wed, 28 Oct 2020 23:14:26 +0100 Message-Id: <20201028221427.22968-5-kabel@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201028221427.22968-1-kabel@kernel.org> References: <20201028221427.22968-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org RollBall SFPs contain a Marvell 88X3310 PHY, but by default the MACTYPE is set to 10GBASE-R with Rate Matching. Some devices (for example those based on Armada 38x) only support up to 2500base-x SerDes modes. Change the PHY's MACTYPE to 4 (which means changing between 10gbase-r, 5gbase-r, 2500base-x ans SGMII depending on copper speed) if this is the case (which is infered from phydev->interface). Signed-off-by: Marek Behún Cc: Andrew Lunn Cc: Russell King --- drivers/net/phy/marvell10g.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c index 1901ba277413..9e8e9aa66972 100644 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@ -453,6 +453,33 @@ static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev) MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV; } +static int mv3310_select_mactype(struct phy_device *phydev) +{ + int mac_type, ret; + + /* On some devices the MAC does not support 10G mode, but may support + * lower modes, such as SGMII or 2500base-x. + * By changing MACTYPE of the PHY to 4 in this case, we ensure that + * the MAC will link with the PHY at least for these lower speeds. + */ + switch (phydev->interface) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_2500BASEX: + mac_type = 4; + break; + default: + return 0; + } + + ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, + MV_V2_PORT_MAC_TYPE_MASK, mac_type); + if (ret <= 0) + return ret; + + return phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, + MV_V2_PORT_CTRL_SWRST, MV_V2_PORT_CTRL_SWRST); +} + static int mv3310_config_init(struct phy_device *phydev) { struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); @@ -474,6 +501,10 @@ static int mv3310_config_init(struct phy_device *phydev) if (err) return err; + err = mv3310_select_mactype(phydev); + if (err) + return err; + val = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL); if (val < 0) return val; From patchwork Wed Oct 28 22:14:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 316151 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4647C55179 for ; Wed, 28 Oct 2020 22:14:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8849124724 for ; Wed, 28 Oct 2020 22:14:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923287; bh=6VF/lnLwH+/bEXWRfT1dm3LJfdZF7pZqfllV2YFD/1o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=KTp3tUhPQFXcoGiY1p6d85Esb4IlDu4yF0pChklTbIlpsCOunZRSqQL9sC0P6iODb DlnDFOeGFAJBfVaZMRJ03qZhBe4jTPK3NAFX/CddGWk26ahI5/dJM2dBjXpEzbC0Fj eV2FZ0hKrFLcFxrKZyWbmqSoeHnTjf6FogXIcxYE= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731038AbgJ1WOq (ORCPT ); Wed, 28 Oct 2020 18:14:46 -0400 Received: from mail.kernel.org ([198.145.29.99]:58244 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731222AbgJ1WOl (ORCPT ); Wed, 28 Oct 2020 18:14:41 -0400 Received: from dellmb.labs.office.nic.cz (nat-1.nic.cz [217.31.205.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id F34D424754; Wed, 28 Oct 2020 22:14:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603923280; bh=6VF/lnLwH+/bEXWRfT1dm3LJfdZF7pZqfllV2YFD/1o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BhQAR6fUyPTYWVbinUDJi2ynsaF3LZ3lHsaW/M9PP3myjmBZwcpY/U3V6XI2eC9uF dr6G/BDwD2PdeKfDfM1L88KqlyfiqkTGSqmPcV4TVtDSZhOdcNmnHS3X4K2RQ36TGP /Aa68xVIF42jC8KO8hZShuTeymCuvSMmZBaRQRdc= From: =?utf-8?q?Marek_Beh=C3=BAn?= To: netdev@vger.kernel.org Cc: davem@davemloft.net, =?utf-8?q?Marek_Beh=C3=BAn?= , Andrew Lunn , Russell King Subject: [PATCH net-next 5/5] net: sfp: add support for multigig RollBall transceivers Date: Wed, 28 Oct 2020 23:14:27 +0100 Message-Id: <20201028221427.22968-6-kabel@kernel.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201028221427.22968-1-kabel@kernel.org> References: <20201028221427.22968-1-kabel@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This adds support for multigig copper SFP modules from RollBall/Hilink. These modules have a specific way to access clause 45 registers of the internal PHY. We also need to wait at least 25 seconds after deasserting TX disable before accessing the PHY. The code waits for 30 seconds just to be sure. Signed-off-by: Marek Behún Cc: Andrew Lunn Cc: Russell King --- drivers/net/phy/sfp.c | 72 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 7 deletions(-) diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index a392d5fc6ab4..379358f194ee 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -165,6 +165,7 @@ static const enum gpiod_flags gpio_flags[] = { * on board (for a copper SFP) time to initialise. */ #define T_WAIT msecs_to_jiffies(50) +#define T_WAIT_LONG_PHY msecs_to_jiffies(30000) #define T_START_UP msecs_to_jiffies(300) #define T_START_UP_BAD_GPON msecs_to_jiffies(60000) @@ -204,8 +205,11 @@ static const enum gpiod_flags gpio_flags[] = { /* SFP modules appear to always have their PHY configured for bus address * 0x56 (which with mdio-i2c, translates to a PHY address of 22). + * RollBall SFPs access phy via SFP Enhanced Digital Diagnostic Interface + * via address 0x51 (mdio-i2c will use RollBall protocol on this address). */ -#define SFP_PHY_ADDR 22 +#define SFP_PHY_ADDR 22 +#define SFP_PHY_ADDR_ROLLBALL 17 struct sff_data { unsigned int gpios; @@ -220,6 +224,7 @@ struct sfp { struct phy_device *mod_phy; const struct sff_data *type; u32 max_power_mW; + int phy_addr; unsigned int (*get_state)(struct sfp *); void (*set_state)(struct sfp *, unsigned int); @@ -248,6 +253,7 @@ struct sfp { struct sfp_eeprom_id id; unsigned int module_power_mW; unsigned int module_t_start_up; + unsigned int module_t_wait; #if IS_ENABLED(CONFIG_HWMON) struct sfp_diag diag; @@ -1442,7 +1448,7 @@ static int sfp_sm_probe_phy(struct sfp *sfp, bool is_c45) struct phy_device *phy; int err; - phy = get_phy_device(sfp->i2c_mii, SFP_PHY_ADDR, is_c45); + phy = get_phy_device(sfp->i2c_mii, sfp->phy_addr, is_c45); if (phy == ERR_PTR(-ENODEV)) return PTR_ERR(phy); if (IS_ERR(phy)) { @@ -1675,12 +1681,40 @@ static int sfp_cotsworks_fixup_check(struct sfp *sfp, struct sfp_eeprom_id *id) return 0; } +static int sfp_rollball_init_mdio(struct sfp *sfp) +{ + u8 page, password[4]; + int err; + + page = 3; + + err = sfp_write(sfp, true, SFP_PAGE, &page, 1); + if (err != 1) { + dev_err(sfp->dev, "Failed to set SFP page for RollBall MDIO access: %d\n", err); + return err; + } + + password[0] = 0xff; + password[1] = 0xff; + password[2] = 0xff; + password[3] = 0xff; + + err = sfp_write(sfp, true, 0x7b, password, 4); + if (err != 4) { + dev_err(sfp->dev, "Failed to write password for RollBall MDIO access: %d\n", err); + return err; + } + + return 0; +} + static int sfp_sm_mod_probe(struct sfp *sfp, bool report) { /* SFP module inserted - read I2C data */ struct sfp_eeprom_id id; bool cotsworks_sfbg; bool cotsworks; + bool rollball; u8 check; int ret; @@ -1755,6 +1789,24 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report) (int)sizeof(id.ext.vendor_sn), id.ext.vendor_sn, (int)sizeof(id.ext.datecode), id.ext.datecode); + sfp->phy_addr = SFP_PHY_ADDR; + + rollball = ((!memcmp(id.base.vendor_name, "OEM ", 16) || + !memcmp(id.base.vendor_name, "Turris ", 16)) && + (!memcmp(id.base.vendor_pn, "SFP-10G-T ", 16) || + !memcmp(id.base.vendor_pn, "RTSFP-10", 8))); + if (rollball) { + sfp->phy_addr = SFP_PHY_ADDR_ROLLBALL; + ret = sfp_rollball_init_mdio(sfp); + if (ret < 0) + return ret; + + /* RollBall SFPs may have wrong (zero) extended compliacne code burned in EEPROM. + * For PHY probing we need the correct one. + */ + id.base.extended_cc = SFF8024_ECC_10GBASE_T_SFI; + } + /* Check whether we support this module */ if (!sfp->type->module_supported(&id)) { dev_err(sfp->dev, @@ -1779,8 +1831,13 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report) else sfp->module_t_start_up = T_START_UP; + if (rollball) + sfp->module_t_wait = T_WAIT_LONG_PHY; + else + sfp->module_t_wait = T_WAIT; + /* Configure mdiobus */ - ret = sfp_i2c_mdiobus_configure(sfp, MDIO_I2C_DEFAULT); + ret = sfp_i2c_mdiobus_configure(sfp, rollball ? MDIO_I2C_ROLLBALL : MDIO_I2C_DEFAULT); if (ret < 0) return ret; @@ -1979,9 +2036,10 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event) /* We need to check the TX_FAULT state, which is not defined * while TX_DISABLE is asserted. The earliest we want to do - * anything (such as probe for a PHY) is 50ms. + * anything (such as probe for a PHY) is 50ms (or more on + * specific modules). */ - sfp_sm_next(sfp, SFP_S_WAIT, T_WAIT); + sfp_sm_next(sfp, SFP_S_WAIT, sfp->module_t_wait); break; case SFP_S_WAIT: @@ -1995,8 +2053,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event) * deasserting. */ timeout = sfp->module_t_start_up; - if (timeout > T_WAIT) - timeout -= T_WAIT; + if (timeout > sfp->module_t_wait) + timeout -= sfp->module_t_wait; else timeout = 1;