From: Andrew Lunn <andrew@lunn.ch>
To: Igor Russkikh <Igor.Russkikh@aquantia.com>
Cc: "netdev@vger.kernel.org" <netdev@vger.kernel.org>,
"davem@davemloft.net" <davem@davemloft.net>,
"richardcochran@gmail.com" <richardcochran@gmail.com>,
Egor Pomozov <Egor.Pomozov@aquantia.com>,
Dmitry Bezrukov <Dmitry.Bezrukov@aquantia.com>,
Simon Edelhaus <sedelhaus@marvell.com>,
Nikita Danilov <Nikita.Danilov@aquantia.com>
Subject: Re: [PATCH v2 net-next 10/12] net: aquantia: add support for Phy access
Date: Tue, 15 Oct 2019 14:19:03 +0200 [thread overview]
Message-ID: <20191015121903.GK19861@lunn.ch> (raw)
In-Reply-To: <09f7d525783b31730ca3bdbaa52c962a141284a5.1570531332.git.igor.russkikh@aquantia.com>
On Tue, Oct 08, 2019 at 10:56:56AM +0000, Igor Russkikh wrote:
> From: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
>
> GPIO PIN control and access is done by direct phy manipulation.
> Here we add an aq_phy module which is able to access phy registers
> via MDIO access mailbox.
>
> Access is controlled via HW semaphore.
>
> Co-developed-by: Nikita Danilov <nikita.danilov@aquantia.com>
> Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
> Signed-off-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
> Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Hi Igor
Is the Atlantic a combined MAC and PHY in one silicon, or are there
two devices? Could the Atlantic MAC be used in combination with for
example a Marvell PHY?
> diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_phy.c b/drivers/net/ethernet/aquantia/atlantic/aq_phy.c
> new file mode 100644
> index 000000000000..51ae921e3e1f
> --- /dev/null
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_phy.c
> @@ -0,0 +1,147 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* aQuantia Corporation Network Driver
> + * Copyright (C) 2018-2019 aQuantia Corporation. All rights reserved
> + */
> +
> +#include "aq_phy.h"
> +
> +bool aq_mdio_busy_wait(struct aq_hw_s *aq_hw)
> +{
> + int err = 0;
> + u32 val;
> +
> + err = readx_poll_timeout_atomic(hw_atl_mdio_busy_get, aq_hw,
> + val, val == 0U, 10U, 100000U);
> +
> + if (err < 0)
> + return false;
> +
> + return true;
> +}
> +
> +u16 aq_mdio_read_word(struct aq_hw_s *aq_hw, u16 mmd, u16 addr)
> +{
> + u16 phy_addr = aq_hw->phy_id << 5 | mmd;
> +
> + /* Set Address register. */
> + hw_atl_glb_mdio_iface4_set(aq_hw, (addr & HW_ATL_MDIO_ADDRESS_MSK) <<
> + HW_ATL_MDIO_ADDRESS_SHIFT);
> + /* Send Address command. */
> + hw_atl_glb_mdio_iface2_set(aq_hw, HW_ATL_MDIO_EXECUTE_OPERATION_MSK |
> + (3 << HW_ATL_MDIO_OP_MODE_SHIFT) |
> + ((phy_addr & HW_ATL_MDIO_PHY_ADDRESS_MSK) <<
> + HW_ATL_MDIO_PHY_ADDRESS_SHIFT));
> +
> + aq_mdio_busy_wait(aq_hw);
> +
> + /* Send Read command. */
> + hw_atl_glb_mdio_iface2_set(aq_hw, HW_ATL_MDIO_EXECUTE_OPERATION_MSK |
> + (1 << HW_ATL_MDIO_OP_MODE_SHIFT) |
> + ((phy_addr & HW_ATL_MDIO_PHY_ADDRESS_MSK) <<
> + HW_ATL_MDIO_PHY_ADDRESS_SHIFT));
> + /* Read result. */
> + aq_mdio_busy_wait(aq_hw);
> +
> + return (u16)hw_atl_glb_mdio_iface5_get(aq_hw);
> +}
> +
> +void aq_mdio_write_word(struct aq_hw_s *aq_hw, u16 mmd, u16 addr, u16 data)
> +{
> + u16 phy_addr = aq_hw->phy_id << 5 | mmd;
> +
> + /* Set Address register. */
> + hw_atl_glb_mdio_iface4_set(aq_hw, (addr & HW_ATL_MDIO_ADDRESS_MSK) <<
> + HW_ATL_MDIO_ADDRESS_SHIFT);
> + /* Send Address command. */
> + hw_atl_glb_mdio_iface2_set(aq_hw, HW_ATL_MDIO_EXECUTE_OPERATION_MSK |
> + (3 << HW_ATL_MDIO_OP_MODE_SHIFT) |
> + ((phy_addr & HW_ATL_MDIO_PHY_ADDRESS_MSK) <<
> + HW_ATL_MDIO_PHY_ADDRESS_SHIFT));
> +
> + aq_mdio_busy_wait(aq_hw);
> +
> + hw_atl_glb_mdio_iface3_set(aq_hw, (data & HW_ATL_MDIO_WRITE_DATA_MSK) <<
> + HW_ATL_MDIO_WRITE_DATA_SHIFT);
> + /* Send Write command. */
> + hw_atl_glb_mdio_iface2_set(aq_hw, HW_ATL_MDIO_EXECUTE_OPERATION_MSK |
> + (2 << HW_ATL_MDIO_OP_MODE_SHIFT) |
> + ((phy_addr & HW_ATL_MDIO_PHY_ADDRESS_MSK) <<
> + HW_ATL_MDIO_PHY_ADDRESS_SHIFT));
> +
> + aq_mdio_busy_wait(aq_hw);
> +}
> +
> +u16 aq_phy_read_reg(struct aq_hw_s *aq_hw, u16 mmd, u16 address)
> +{
> + int err = 0;
> + u32 val;
> +
> + err = readx_poll_timeout_atomic(hw_atl_sem_mdio_get, aq_hw,
> + val, val == 1U, 10U, 100000U);
> +
> + if (err < 0) {
> + err = 0xffff;
> + goto err_exit;
> + }
> +
> + err = aq_mdio_read_word(aq_hw, mmd, address);
> +
> + hw_atl_reg_glb_cpu_sem_set(aq_hw, 1U, HW_ATL_FW_SM_MDIO);
> +
> +err_exit:
> + return err;
> +}
> +
> +void aq_phy_write_reg(struct aq_hw_s *aq_hw, u16 mmd, u16 address, u16 data)
> +{
> + int err = 0;
> + u32 val;
> +
> + err = readx_poll_timeout_atomic(hw_atl_sem_mdio_get, aq_hw,
> + val, val == 1U, 10U, 100000U);
> + if (err < 0)
> + return;
> +
> + aq_mdio_write_word(aq_hw, mmd, address, data);
> + hw_atl_reg_glb_cpu_sem_set(aq_hw, 1U, HW_ATL_FW_SM_MDIO);
> +}
You have here the code needed to implement a real Linux MDIO bus
driver. Are the MDIO pins exposed? Could somebody combine the chip
with say a Marvell Ethernet switch? You then need access to the MDIO
bus to control the switch. So by using a Linux MDIO bus driver, you
make it easy for somebody to do that. You can keep with your firmware
mostly driving the PHY.
> +
> +bool aq_phy_init_phy_id(struct aq_hw_s *aq_hw)
> +{
> + u16 val;
> +
> + for (aq_hw->phy_id = 0; aq_hw->phy_id < HW_ATL_PHY_ID_MAX;
> + ++aq_hw->phy_id) {
> + /* PMA Standard Device Identifier 2: Address 1.3 */
> + val = aq_phy_read_reg(aq_hw, MDIO_MMD_PMAPMD, 3);
> +
> + if (val != 0xffff)
> + return true;
> + }
> +
> + return false;
> +}
> +
> +bool aq_phy_init(struct aq_hw_s *aq_hw)
> +{
> + u32 dev_id;
> +
> + if (aq_hw->phy_id == HW_ATL_PHY_ID_MAX)
> + if (!aq_phy_init_phy_id(aq_hw))
> + return false;
> +
> + /* PMA Standard Device Identifier:
> + * Address 1.2 = MSW,
> + * Address 1.3 = LSW
> + */
> + dev_id = aq_phy_read_reg(aq_hw, MDIO_MMD_PMAPMD, 2);
> + dev_id <<= 16;
> + dev_id |= aq_phy_read_reg(aq_hw, MDIO_MMD_PMAPMD, 3);
> +
> + if (dev_id == 0xffffffff) {
> + aq_hw->phy_id = HW_ATL_PHY_ID_MAX;
> + return false;
> + }
For future proofing, should you not check it is actually one of your
PHYs?
Thanks
Andrew
next prev parent reply other threads:[~2019-10-15 12:46 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-08 10:56 [PATCH v2 net-next 00/12] net: aquantia: PTP support for AQC devices Igor Russkikh
2019-10-08 10:56 ` [PATCH v2 net-next 01/12] net: aquantia: PTP skeleton declarations and callbacks Igor Russkikh
2019-10-12 18:49 ` Richard Cochran
2019-10-12 18:56 ` Richard Cochran
2019-10-08 10:56 ` [PATCH v2 net-next 02/12] net: aquantia: unify styling of bit enums Igor Russkikh
2019-10-14 15:50 ` Andrew Lunn
2019-10-08 10:56 ` [PATCH v2 net-next 03/12] net: aquantia: add basic ptp_clock callbacks Igor Russkikh
2019-10-12 19:02 ` Richard Cochran
2019-10-14 11:43 ` Igor Russkikh
2019-10-08 10:56 ` [PATCH v2 net-next 04/12] net: aquantia: add PTP rings infrastructure Igor Russkikh
2019-10-14 16:14 ` Andrew Lunn
2019-10-15 9:02 ` Igor Russkikh
2019-10-08 10:56 ` [PATCH v2 net-next 05/12] net: aquantia: styling fixes on ptp related functions Igor Russkikh
2019-10-14 16:16 ` Andrew Lunn
2019-10-08 10:56 ` [PATCH v2 net-next 06/12] net: aquantia: implement data PTP datapath Igor Russkikh
2019-10-14 16:36 ` Andrew Lunn
2019-10-15 9:09 ` Igor Russkikh
2019-10-08 10:56 ` [PATCH v2 net-next 07/12] net: aquantia: rx filters for ptp Igor Russkikh
2019-10-08 10:56 ` [PATCH v2 net-next 08/12] net: aquantia: add support for ptp ioctls Igor Russkikh
2019-10-14 16:23 ` Andrew Lunn
2019-10-15 9:06 ` Igor Russkikh
2019-10-08 10:56 ` [PATCH v2 net-next 09/12] net: aquantia: implement get_ts_info ethtool Igor Russkikh
2019-10-12 19:07 ` Richard Cochran
2019-10-14 11:45 ` Igor Russkikh
2019-10-08 10:56 ` [PATCH v2 net-next 10/12] net: aquantia: add support for Phy access Igor Russkikh
2019-10-15 12:19 ` Andrew Lunn [this message]
2019-10-16 13:12 ` Igor Russkikh
2019-10-16 19:38 ` Andrew Lunn
2019-10-08 10:56 ` [PATCH v2 net-next 11/12] net: aquantia: add support for PIN funcs Igor Russkikh
2019-10-12 19:25 ` Richard Cochran
2019-10-15 12:35 ` Andrew Lunn
2019-10-08 10:57 ` [PATCH v2 net-next 12/12] net: aquantia: adding atlantic ptp maintainer Igor Russkikh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191015121903.GK19861@lunn.ch \
--to=andrew@lunn.ch \
--cc=Dmitry.Bezrukov@aquantia.com \
--cc=Egor.Pomozov@aquantia.com \
--cc=Igor.Russkikh@aquantia.com \
--cc=Nikita.Danilov@aquantia.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=richardcochran@gmail.com \
--cc=sedelhaus@marvell.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.