Received: by 2002:a89:2c3:0:b0:1ed:23cc:44d1 with SMTP id d3csp935231lqs; Wed, 6 Mar 2024 00:55:05 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXiRFJf6NUoEvO/x4BDDsFjnrwbLCtRzQ0WotrZy94DKG8Y+J8BwLSVckKBYWl9nQqtbaFSqlDVyLKbMT4mHwZR74N2DjPZlSDfTFE+kQ== X-Google-Smtp-Source: AGHT+IGPQY8ktd0rvcfzk4E+7r/bLfO9vXP+R+0Sn+oQoClEUKmQZx3mfmeevG4di8XIDWmVBFnZ X-Received: by 2002:a05:6808:151f:b0:3c1:b7ce:1e1 with SMTP id u31-20020a056808151f00b003c1b7ce01e1mr5363199oiw.23.1709715305140; Wed, 06 Mar 2024 00:55:05 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1709715305; cv=pass; d=google.com; s=arc-20160816; b=Em6q/AGKjnZvgB0MA+j6pYmFjPxUCe4VTMKlaJvzWIuCO5+e1/1Hq7jSzRrBLLhz6X /rjVPVK8GCKSSrKvvcwdrAyrzQTysi8SxngS0mzh2cYlb0O2DUYhmEPcaHrFhDFOP0Bk 7azujSNJ1VInJHiVcKYSYCMoLLrb/DD9OC90EqbIEogcXyun4sONhDgZSW19GIsaqLz1 Z96myr1FAPPxslR9ofIdcC9NnZD73sWm4HX6Vn9K0h9FFSFyGwz0ooyDgMxm7dSoWeY2 N4I8qEDGSNa51VQkmSbkixcICnNDuoDi5ip0x9LngrRSTNzX37w37RWi/pMPIjSxEgO4 Ge4Q== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=u2piy/+jVRQqw8YQolN1qeEgRwdLSJpGhymbICUUres=; fh=Yek51KtWkuS8F9wIb61YhKBdNUJJ2f/R79g/JeL1hhg=; b=POrAbhunBXts5yrke01XTvcyggAKIG4Ah2GWQuluXlyJFePAbfbCmJ5YMu6U+nh7B3 DLdAcLNMz47mD36oyFk1UopabuNmdH4EkUtKYZtcED1EjZ1Avx0RN+460Y12q+eBjToG 9pHxEelpVGTn9APfoApkhQmeo6rps/yn8dh4Fxces7Mc+TOm3Tgk448CU17x0NhgHDJE ZmPLaGQVN1HulVuaik+Up0K9KhrLDU4x6bRyOd7GLINEnPWbnxKc8+3sM244lKVFzyWr nBD8ywTSaX78pU8wwcudVPwmsALy0cK7VnDUda6daVl8e/0KUJe26B6M+pdq2WLBOCK7 GUBQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b="dph/qRyA"; arc=pass (i=1 spf=pass spfdomain=microchip.com dkim=pass dkdomain=microchip.com dmarc=pass fromdomain=microchip.com); spf=pass (google.com: domain of linux-kernel+bounces-93544-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-93544-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=REJECT dis=NONE) header.from=microchip.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id l185-20020a633ec2000000b005cdfa589cfbsi11506441pga.148.2024.03.06.00.55.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Mar 2024 00:55:05 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-93544-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@microchip.com header.s=mchp header.b="dph/qRyA"; arc=pass (i=1 spf=pass spfdomain=microchip.com dkim=pass dkdomain=microchip.com dmarc=pass fromdomain=microchip.com); spf=pass (google.com: domain of linux-kernel+bounces-93544-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-93544-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=REJECT dis=NONE) header.from=microchip.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id A3E7D28ADAB for ; Wed, 6 Mar 2024 08:53:53 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3633960273; Wed, 6 Mar 2024 08:51:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="dph/qRyA" Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B0955FDAD; Wed, 6 Mar 2024 08:51:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709715094; cv=none; b=dKQi/9LsRuJtDVh/Ezj5aDoCySn8jsBUVXBn2m0CIo17A0ZALhLe4z2QIgs7fq6Y6vlFB8Jy565gz0w8hU2QOGvGihRvMGI1bl2Cfw4vwoR7Pyjk3JMzkxO3rieDd4AsZ1TOs8cKRBl0z9dPMKhMsSW8Y5cTEDOFcLQpa0shkVE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709715094; c=relaxed/simple; bh=Mwpdd2KU05HBEyJ3fOew43CT4iawiXS6dxOBjxj34MY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=p9OtQN9/bd1Bm6S4MFNwMoAIbU+fZGZt8m96ZeDDe/UBBtDUsr7kyYW+xJ+tlvretfLejbrI8o5m1EsAB3O8m/LVODP7zQnxuKQ0OrOX9CS93md1jJ4b84KteI0fOGC6jNhL4TalMKQX9Dm03GmtxoWu6ZyXxQmjgxvCuur0ELM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=dph/qRyA; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1709715093; x=1741251093; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Mwpdd2KU05HBEyJ3fOew43CT4iawiXS6dxOBjxj34MY=; b=dph/qRyA6K6rTtTEAvoLcBnWed3v2XPvAhTNwqpN5nIxiVyvWUbbbWB4 F15Mx6KLtmz7BVY+IDFYKHgOdl9XcsQc0SUh/CZyennx2D05wvNKaqxex 80q4LZ22XoJVRSTVE3LU5EKvcm4O5X+/XoZ2OUxI7nYEAOFU+IB53Jv2y KFJ+91XrHF4kdHFwh8rsld+g18XYIcuqxLmC83lMbpfU/ZsPfxbvvJPYH MEeqedPq+G10DOzHYmBrClJ4PuHjjqCp/7Q1VPKX3KkuVx6+f/yYuMVZi Psfc7jvr/J0oKrHpKVvTaFN5xSiJ6yuHx9OozjciCJ1GlD/mT/pkXVFvS w==; X-CSE-ConnectionGUID: ploPbevzQGew6QQo7Y/c+g== X-CSE-MsgGUID: vajZCZ0tTY2nECpsHnSg7A== X-IronPort-AV: E=Sophos;i="6.06,207,1705388400"; d="scan'208";a="17278633" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa3.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 06 Mar 2024 01:51:31 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Wed, 6 Mar 2024 01:51:31 -0700 Received: from CHE-LT-I17164LX.microchip.com (10.10.85.11) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Wed, 6 Mar 2024 01:51:22 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v3 06/12] net: ethernet: oa_tc6: implement internal PHY initialization Date: Wed, 6 Mar 2024 14:20:11 +0530 Message-ID: <20240306085017.21731-7-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240306085017.21731-1-Parthiban.Veerasooran@microchip.com> References: <20240306085017.21731-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit Internal PHY is initialized as per the PHY register capability supported by the MAC-PHY. Direct PHY Register Access Capability indicates if PHY registers are directly accessible within the SPI register memory space. Indirect PHY Register Access Capability indicates if PHY registers are indirectly accessible through the MDIO/MDC registers MDIOACCn defined in OPEN Alliance specification. Currently the direct register access is only supported. Signed-off-by: Parthiban Veerasooran --- drivers/net/ethernet/oa_tc6.c | 160 +++++++++++++++++++++++++++++++++- include/linux/oa_tc6.h | 4 +- 2 files changed, 162 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c index f8593b793291..82b4de13438f 100644 --- a/drivers/net/ethernet/oa_tc6.c +++ b/drivers/net/ethernet/oa_tc6.c @@ -7,9 +7,15 @@ #include #include +#include +#include #include /* OPEN Alliance TC6 registers */ +/* Standard Capabilities Register */ +#define OA_TC6_REG_STDCAP 0x0002 +#define STDCAP_DIRECT_PHY_REG_ACCESS BIT(8) + /* Reset Control and Status Register */ #define OA_TC6_REG_RESET 0x0003 #define RESET_SWRESET BIT(0) /* Software Reset */ @@ -25,6 +31,10 @@ #define INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK BIT(3) #define INT_MASK0_TX_PROTOCOL_ERR_MASK BIT(0) +/* PHY Clause 22 and 29 registers base address and mask */ +#define OA_TC6_PHY_STD_REG_ADDR_BASE 0xFF00 +#define OA_TC6_PHY_STD_REG_ADDR_MASK 0x3F + /* Control command header */ #define OA_TC6_CTRL_HEADER_DATA_NOT_CTRL BIT(31) #define OA_TC6_CTRL_HEADER_WRITE BIT(29) @@ -46,6 +56,10 @@ /* Internal structure for MAC-PHY drivers */ struct oa_tc6 { + struct device *dev; + struct net_device *netdev; + struct phy_device *phydev; + struct mii_bus *mdiobus; struct spi_device *spi; struct mutex spi_ctrl_lock; /* Protects spi control transfer */ void *spi_ctrl_tx_buf; @@ -298,6 +312,130 @@ int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value) } EXPORT_SYMBOL_GPL(oa_tc6_write_register); +static int oa_tc6_check_phy_reg_direct_access_capability(struct oa_tc6 *tc6) +{ + u32 regval; + int ret; + + ret = oa_tc6_read_register(tc6, OA_TC6_REG_STDCAP, ®val); + if (ret) + return ret; + + if (!(regval & STDCAP_DIRECT_PHY_REG_ACCESS)) + return -ENODEV; + + return 0; +} + +static void oa_tc6_handle_link_change(struct net_device *netdev) +{ + phy_print_status(netdev->phydev); +} + +static int oa_tc6_mdiobus_direct_read(struct mii_bus *bus, int addr, int regnum) +{ + struct oa_tc6 *tc6 = bus->priv; + u32 regval; + bool ret; + + ret = oa_tc6_read_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE | + (regnum & OA_TC6_PHY_STD_REG_ADDR_MASK), + ®val); + if (ret) + return -ENODEV; + + return regval; +} + +static int oa_tc6_mdiobus_direct_write(struct mii_bus *bus, int addr, int regnum, + u16 val) +{ + struct oa_tc6 *tc6 = bus->priv; + + return oa_tc6_write_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE | + (regnum & OA_TC6_PHY_STD_REG_ADDR_MASK), + val); +} + +static int oa_tc6_mdiobus_register(struct oa_tc6 *tc6) +{ + int ret; + + tc6->mdiobus = mdiobus_alloc(); + if (!tc6->mdiobus) { + netdev_err(tc6->netdev, "MDIO bus alloc failed\n"); + return -ENODEV; + } + + tc6->mdiobus->priv = tc6; + tc6->mdiobus->read = oa_tc6_mdiobus_direct_read; + tc6->mdiobus->write = oa_tc6_mdiobus_direct_write; + tc6->mdiobus->name = "oa-tc6-mdiobus"; + tc6->mdiobus->parent = tc6->dev; + + snprintf(tc6->mdiobus->id, ARRAY_SIZE(tc6->mdiobus->id), "%s", + dev_name(&tc6->spi->dev)); + + ret = mdiobus_register(tc6->mdiobus); + if (ret) { + netdev_err(tc6->netdev, "Could not register MDIO bus\n"); + mdiobus_free(tc6->mdiobus); + return ret; + } + + return 0; +} + +static void oa_tc6_mdiobus_unregister(struct oa_tc6 *tc6) +{ + mdiobus_unregister(tc6->mdiobus); + mdiobus_free(tc6->mdiobus); +} + +static int oa_tc6_phy_init(struct oa_tc6 *tc6) +{ + int ret; + + ret = oa_tc6_check_phy_reg_direct_access_capability(tc6); + if (ret) { + netdev_err(tc6->netdev, + "Direct PHY register access is not supported by the MAC-PHY\n"); + return ret; + } + + ret = oa_tc6_mdiobus_register(tc6); + if (ret) + return ret; + + tc6->phydev = phy_find_first(tc6->mdiobus); + if (!tc6->phydev) { + netdev_err(tc6->netdev, "No PHY found\n"); + oa_tc6_mdiobus_unregister(tc6); + return -ENODEV; + } + + tc6->phydev->is_internal = true; + ret = phy_connect_direct(tc6->netdev, tc6->phydev, + &oa_tc6_handle_link_change, + PHY_INTERFACE_MODE_INTERNAL); + if (ret) { + netdev_err(tc6->netdev, "Can't attach PHY to %s\n", + tc6->mdiobus->id); + oa_tc6_mdiobus_unregister(tc6); + return ret; + } + + phy_attached_info(tc6->netdev->phydev); + + return 0; +} + +static void oa_tc6_phy_exit(struct oa_tc6 *tc6) +{ + phy_disconnect(tc6->phydev); + oa_tc6_mdiobus_unregister(tc6); +} + static int oa_tc6_read_sw_reset_status(struct oa_tc6 *tc6) { u32 regval; @@ -351,11 +489,12 @@ static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6) /** * oa_tc6_init - allocates and initializes oa_tc6 structure. * @spi: device with which data will be exchanged. + * @netdev: network device interface structure. * * Returns pointer reference to the oa_tc6 structure if the MAC-PHY * initialization is successful otherwise NULL. */ -struct oa_tc6 *oa_tc6_init(struct spi_device *spi) +struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev) { struct oa_tc6 *tc6; int ret; @@ -365,6 +504,8 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi) return NULL; tc6->spi = spi; + tc6->netdev = netdev; + SET_NETDEV_DEV(netdev, &spi->dev); mutex_init(&tc6->spi_ctrl_lock); /* Set the SPI controller to pump at realtime priority */ @@ -395,10 +536,27 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi) return NULL; } + ret = oa_tc6_phy_init(tc6); + if (ret) { + dev_err(&tc6->spi->dev, + "MAC internal PHY initialization failed: %d\n", ret); + return NULL; + } + return tc6; } EXPORT_SYMBOL_GPL(oa_tc6_init); +/** + * oa_tc6_exit - exit function. + * @tc6: oa_tc6 struct. + */ +void oa_tc6_exit(struct oa_tc6 *tc6) +{ + oa_tc6_phy_exit(tc6); +} +EXPORT_SYMBOL_GPL(oa_tc6_exit); + MODULE_DESCRIPTION("OPEN Alliance 10BASE‑T1x MAC‑PHY Serial Interface Lib"); MODULE_AUTHOR("Parthiban Veerasooran "); MODULE_LICENSE("GPL"); diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h index 85aeecf87306..606ba9f1e663 100644 --- a/include/linux/oa_tc6.h +++ b/include/linux/oa_tc6.h @@ -7,11 +7,13 @@ * Author: Parthiban Veerasooran */ +#include #include struct oa_tc6; -struct oa_tc6 *oa_tc6_init(struct spi_device *spi); +struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev); +void oa_tc6_exit(struct oa_tc6 *tc6); int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value); int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[], u8 length); -- 2.34.1