From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 8F4C03A6B6A; Fri, 24 Jul 2026 07:36:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878611; cv=none; b=HIMPn1W+t9ABhWXcNKM4JP9wid/MzNeE5DfOCIO3fPr+ADG++tak3clWTd95wcO1svaSqt+xtWyZJLuKl2RvIShQdyb/1+IK8LA3hOSKagWArZ9jqvMQZgAjTYyzOvzUOCfeUYU3GUYir2nEjnBLv/lGpr7EV366KP2P0/NeGmo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878611; c=relaxed/simple; bh=jPEvzusVPEfUiuA40O/vV9QA3GcIbRMF7toahqxAlc4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jhWVJieJHbPMke6FTej/Ap1v2k7d6SWOIIlt0mQ19FjWgF5k667cIiUE8SgG0Bn3QzY5ELmyfiGiXFk2lk8pEWL9zJyoN11KFt01tfTljkpUR7gG3I6lg2eYLfviLKiEulX9G6DF8GoJyU7bSsOcoWqd5pYsuPaZDXMrESZozi0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=Nrp1LE3p; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=qwSb/1He; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="Nrp1LE3p"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="qwSb/1He" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878608; bh=jPEvzusVPEfUiuA40O/vV9QA3GcIbRMF7toahqxAlc4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Nrp1LE3pN75MyMxxOtLKCj2Pp3unN9g39dFzq3c5ex9sSIOwXVeMqgTpCmEQMUC8j GdvfB/BMUVnYoG7k7cUIr3kRQPfBEakfTDWywCwvQT3yVTEcHY3XH3cWCz3TNzuTlD 3kTPncgjSUQX2INNPkL29i5xE09Wf1cm5gpZltwEFYxqeICM7pQr81+O5ahrpVp7ZI p7z/EhYdZEroFNkYKvE/phqcfNhS728BLW5iJAX/0De1tr1OPOQc5fGdsG3Uz+aZEE rHG7yWyFjf1g7Csdmbwerx+5fKWgu+nFOYglRExH9Ou1kFwy/jVOK9iAgUy50u2K9x uSgbJrl2Czh+Q== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 7D6CE493BB; Fri, 24 Jul 2026 07:36:48 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878607; bh=jPEvzusVPEfUiuA40O/vV9QA3GcIbRMF7toahqxAlc4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qwSb/1Heu8g1J4XFsvsBuZdZHkdYtNMu4FIb7bCabpRmh+SRNx5O2eZ0fjxnouBI9 rAOjfmNJnIk+eG06/He/IPADA5krVSN8Rp8qUSDAQGiW2UANWICXd0btEhz/fgVNFw DfZ8EP0JvLV3P7NOSuOihf2j2Rmwm3D24fry79PjtkY9og0sYczyIanYVX5Gu8CIUT 61ETcTEH18mBXc8QyK8FkYeH9tJUTobGKoRXXNoBj37gdVh3IUOpdphYuyPoKILrZe FBr8MR2NmSv5M10gqZrS9aQ8S9s5oHPJZhT0NmE6KknQhvulD94rm4iCtgNOKL2Qy0 BPmFLz7OrYE/Q== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id C6E4C48F41; Fri, 24 Jul 2026 07:36:46 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:44 +0200 Subject: [PATCH net-next v3 01/13] ax88179_178a: Fix endianness of pause watermark register 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: quoted-printable Message-Id: <20260724-ax88179a-v3-1-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 The 16-bit pause watermark register is little endian as described in the ASIX 4.1.0 out-of-tree driver. Correct the register byte sequence but also swap the configuration values used in the code in order to keep the current behaviour. The endianness is relevant for 16-bit writes to the register. Signed-off-by: Birger Koblitz Reviewed-by: Andrew Lunn --- drivers/net/usb/ax88179_178a.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 98f899ea2e9462f1ba99281a875385241745458b..945c071dfd1d2f0816c779e1a40= 1ac158adc8d99 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -32,8 +32,8 @@ #define AX_ACCESS_EEPROM 0x04 #define AX_ACCESS_EFUS 0x05 #define AX_RELOAD_EEPROM_EFUSE 0x06 -#define AX_PAUSE_WATERLVL_HIGH 0x54 -#define AX_PAUSE_WATERLVL_LOW 0x55 +#define AX_PAUSE_WATERLVL_LOW 0x54 +#define AX_PAUSE_WATERLVL_HIGH 0x55 =20 #define PHYSICAL_LINK_STATUS 0x02 #define AX_USB_SS 0x04 @@ -1617,11 +1617,10 @@ static int ax88179_reset(struct usbnet *dev) dev->rx_urb_size =3D 1024 * 20; =20 *tmp =3D 0x34; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, 1, 1, tmp); =20 *tmp =3D 0x52; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, - 1, 1, tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); =20 /* Enable checksum offload */ *tmp =3D AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 E61F63A9632; Fri, 24 Jul 2026 07:36:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878621; cv=none; b=IqPbZ2fML7Jz+iCFbqn6hz+dFphoK/goN6Gwqy5IKCCRsmn2Z7qVi9iciYcM7r+P9wj+LXMPzubSSBnV7dtTgEmvAPcTIDLICEuOFcOjFSriYVS05JpI7UM2svxLdDzis0bMA4D4WKG9jrkC2zbEP52Ig8Jdaic8/U5nABAVM74= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878621; c=relaxed/simple; bh=bhXskfl2mgPImDXEI88XAaOaJzZKd7/qzVhZvQbQ/RU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=n6q1FGrUnKS4Er1gFWV4yPS90SBVZIEfwvDM5JRoME2V/oZBynzdDnCnNH+ozqbPsscgSnO0r1LnvCHZLjNeSdND8SMxZ/V08OkSDtJJYo/iH6F9rqIVzuChx8f1niuXLrKSyQ7diZ5HO6w6wDKYAvNEkdRkR/FdWTOdotT5aNE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=lK1R6JL/; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=yF4/PSuR; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="lK1R6JL/"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="yF4/PSuR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878616; bh=bhXskfl2mgPImDXEI88XAaOaJzZKd7/qzVhZvQbQ/RU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=lK1R6JL/NMwjd5gH2bSolXxZ6RDsZTqliKWD/pmSwgbK5Zq0otLZgtcNHMXtq6KHY QjZjjb41RFQUWtGFS3e90PgAvC7Xfq1NiudNOidFS96Uc9SYqSIqUFiDN47hP5gdNa xbnsBW2LDjZ7uHP5vwCI7gI7XPr6QmxbCZuLl4GPmCMn0JzTyAnwk2Tv5gXQ2YNkcF ggDfgUm3seM4Pevb8D8/eJnjbJs7IB2otDmk8Yl1/YxGuu93JHdIptLcaPWsxaQydn 1LxgRqBk3J/pA5Lj1YA15+hSCQ3TDAKk9icGKFA/UBAOY3O3h/LVkeEAqNyZnS7an0 Flhz2ve93q3Bg== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 23280493E2; Fri, 24 Jul 2026 07:36:56 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878607; bh=bhXskfl2mgPImDXEI88XAaOaJzZKd7/qzVhZvQbQ/RU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=yF4/PSuRhqojUFU8geyGXd/wR9gMSX1UdV4MLRrFuPEl+nITbEze9WCxmrMF8kT6/ AwhYL/2lV+aDUD9wSUW6dy7yiTgkxIOY3lgrT0oYFlilUJl3wtPvH4mAYen+pK/cig PiKqTu3I6BKMRTPrKGiXx92acHOYTmw11K5TTqv199xkVS+4LtiV2/WWJffzmzuFJ6 RARLoRJiDQUCm7J0Ij+0g2j/vBNddcrs0Kehgt9K65W5Y0sJNW1ArzWLFipoEDTSIH PSRmcpw83EkzK/rvDgpR9n4efczdcsgFeUpZBdqIVSaEoHzhDL1E/iKifzS5YgMgdh 84LGUnE9u3ibQ== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id 1941849277; Fri, 24 Jul 2026 07:36:47 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:45 +0200 Subject: [PATCH net-next v3 02/13] ax88179_178a: Add HW support for AX179A-based chips 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: quoted-printable Message-Id: <20260724-ax88179a-v3-2-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 This adds bindings and HW support for AX179A-based USB-Ethernet controllers. The AX179A-family of chips consists of the AX88279 (2.5GBit PHY) AX88179A/B (1GBit PHY, B variant has wider temperature range) AX772D/E (100Mbit PHY) The controllers all have the same vendor and device ID (0x0b95, 0x1790) and are distinguished by their BCD device versions, which are 2.00 AX88179A/B 3.00 AX88772D/E 4.00 AX88279 For all chips, the driver calls the same ax88179a_bind() function and the chips are then distinguished by the chip version and BCD device ID. The AX179A-based chips all provide both a CDC-NCM compatible USB interface, and a proprietary vendor interface. By default, the proprietary vendor interface is not active and Linux will load the CDC-NCM driver to support the devices. If the ax88179_178a module is configured by the OS to have precedence over CDC-NCM, then this driver will switch the device to use the vendor interface, and the device will be controlled by the ax88179_178a driver when the device is probed again after an automatic reset by the device. Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 1159 ++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 1124 insertions(+), 35 deletions(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 945c071dfd1d2f0816c779e1a401ac158adc8d99..b90a75a11024c58192bdb4a9436= 636bc9312148c 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include =20 #define AX88179_PHY_ID 0x03 #define AX_EEPROM_LEN 0x100 @@ -32,17 +34,30 @@ #define AX_ACCESS_EEPROM 0x04 #define AX_ACCESS_EFUS 0x05 #define AX_RELOAD_EEPROM_EFUSE 0x06 +#define AX88179A_WAKEUP_SETTING 0x07 +#define AX_FW_MODE 0x08 +#define AX88179A_FLASH_READ 0x21 +#define AX88179A_FLASH_WRITE 0x24 +#define AX88179A_PHY_CLAUSE45 0x27 +#define AX88179A_FLASH_ERASE_SECTION 0x28 +#define AX88179A_ACCESS_BL 0x2A +#define AX88179A_PHY_POWER 0x31 +#define AX88179A_AUTODETACH 0xC0 #define AX_PAUSE_WATERLVL_LOW 0x54 #define AX_PAUSE_WATERLVL_HIGH 0x55 =20 +#define AX_FW_MODE_179A 0x01 #define PHYSICAL_LINK_STATUS 0x02 #define AX_USB_SS 0x04 #define AX_USB_HS 0x02 + #define AX_USB_FS 0x01 =20 #define GENERAL_STATUS 0x03 /* Check AX88179 version. UA1:Bit2 =3D 0, UA2:Bit2 =3D 1 */ #define AX_SECLD 0x04 =20 +#define AX_CHIP_STATUS 0x05 + #define AX_SROM_ADDR 0x07 #define AX_SROM_CMD 0x0a #define EEP_RD 0x04 @@ -62,6 +77,15 @@ #define AX_RX_CTL_PRO 0x0001 #define AX_RX_CTL_STOP 0x0000 =20 +#define AX88179A_ETH_TX_GAP 0x0D + +#define AX88179A_BFM_DATA 0x0E + #define AX_TX_QUEUE_CFG 0x02 + #define AX_TX_QUEUE_SET 0x08 + #define AX_TX_Q1_AHB_FC_EN 0x10 + #define AX_TX_Q2_AHB_FC_EN 0x20 + #define AX_XGMII_EN 0x80 + #define AX_NODE_ID 0x10 #define AX_MULFLTARY 0x16 =20 @@ -91,6 +115,17 @@ #define AX_PHYPWR_RSTCTL_IPRL 0x0020 #define AX_PHYPWR_RSTCTL_AT 0x1000 =20 +#define AX88179A_VLAN_ID_ADDRESS 0x2A + +#define AX88179A_VLAN_ID_CONTROL 0x2B + #define AX_VLAN_CONTROL_WE 0x0001 + #define AX_VLAN_CONTROL_RD 0x0002 + #define AX_VLAN_CONTROL_VSO 0x0010 + #define AX_VLAN_CONTROL_VFE 0x0020 + +#define AX88179A_VLAN_ID_DATA0 0x2C +#define AX88179A_VLAN_ID_DATA1 0x2D + #define AX_RX_BULKIN_QCTRL 0x2e #define AX_CLK_SELECT 0x33 #define AX_CLK_SELECT_BCS 0x01 @@ -111,7 +146,51 @@ #define AX_TXCOE_TCPV6 0x20 #define AX_TXCOE_UDPV6 0x40 =20 +#define AX88179A_MAC_BM_INT_MASK 0x41 +#define AX88179A_MAC_BM_RX_DMA_CTL 0x43 +#define AX88179A_MAC_BM_TX_DMA_CTL 0x46 + +#define AX88179A_MAC_RX_STATUS_CDC 0x6D + #define AX_LSOFC_WCNT_7_ACCESS 0x03 + #define AX_GMII_CRC_APPEND 0x10 + #define AX_LEDCTRL 0x73 +#define AX88179A_MAC_ARC_CTRL 0x9E +#define AX88179A_MAC_SWP_CTRL 0xB1 + +#define AX88179A_MAC_TX_PAUSE 0xB2 + +#define AX88179A_MAC_CDC_DELAY_TX 0xB5 + +#define AX88179A_MAC_PATH 0xB7 + #define AX_MAC_RX_PATH_READY 0x01 + #define AX_MAC_TX_PATH_READY 0x02 + +#define AX88179A_NEW_PAUSE_CTRL 0xB8 + #define AX_NEW_PAUSE_EN 0x01 + +#define AX88179A_MAC_BULK_OUT_CTRL 0xB9 + #define AX_MAC_EFF_EN 0x02 + +#define AX88179A_MAC_RX_DATA_CDC_CNT 0xC0 + #define AX_MAC_LSO_ERR_EN 0x04 + #define AX_MAC_MIQFFCTRL_FORMAT 0x10 + #define AX_MAC_MIQFFCTRL_DROP_CRC 0x20 + +#define AX88179A_AUTODETACH_DELAY (5UL << 8) +#define AX88179A_AUTODETACH_EN 1 + +#define AX88179A_MAC_LSO_ENHANCE_CTRL 0xC3 + #define AX_LSO_ENHANCE_EN 0x01 + +#define AX88179A_MAC_TX_HDR_CKSUM 0xCC +#define AX88179A_EP5_EHR 0xF9 + +#define AX_PHY_POWER 0x02 + +#define EPHY_LOW_POWER_EN 0x01 +#define S5_WOL_EN 0x04 +#define S5_WOL_LOW_POWER 0x20 =20 #define GMII_PHY_PHYSR 0x11 #define GMII_PHY_PHYSR_SMASK 0xc000 @@ -164,8 +243,58 @@ #define GMII_PHY_PGSEL_PAGE3 0x0003 #define GMII_PHY_PGSEL_PAGE5 0x0005 =20 +/* TX Descriptor */ +#define AX179A_TX_DESC_LEN_MASK 0x1FFFFF +#define AX179A_TX_DESC_DROP_PADD BIT(28) +#define AX179A_TX_DESC_VLAN BIT(29) +#define AX179A_TX_DESC_MSS_MASK 0x7FFF +#define AX179A_TX_DESC_MSS_SHIFT 0x20 +#define AX179A_TX_DESC_VLAN_MASK 0xFFFF +#define AX179A_TX_DESC_VLAN_SHIFT 0x30 + +/* RX Packet Descriptor */ +#define AX179A_RX_PD_L4_ERR BIT(0) +#define AX179A_RX_PD_L3_ERR BIT(1) +#define AX179A_RX_PD_L4_TYPE_MASK 0x1C +#define AX179A_RX_PD_L4_UDP 0x04 +#define AX179A_RX_PD_L4_TCP 0x10 +#define AX179A_RX_PD_L3_TYPE_MASK 0x60 +#define AX179A_RX_PD_L3_IP 0x20 +#define AX179A_RX_PD_L3_IP6 0x40 + +#define AX179A_RX_PD_VLAN BIT(10) +#define AX179A_RX_PD_RX_OK BIT(11) +#define AX179A_RX_PD_DROP BIT(31) +#define AX179A_RX_PD_LEN_MASK 0x7FFF0000 +#define AX179A_RX_PD_LEN_SHIFT 0x10 +#define AX179A_RX_PD_VLAN_SHIFT 0x20 + +/* RX Descriptor header */ +#define AX179A_RX_DH_PKT_CNT_MASK 0x1FFF +#define AX179A_RX_DH_DESC_OFFSET_MASK 0xFFFFE000 +#define AX179A_RX_DH_DESC_OFFSET_SHIFT 0x0D + +#define AX179A_RX_HW_PAD 0x02 + +#define AX_ADVERTISE_2500 0x1000 + static int ax88179_reset(struct usbnet *dev); =20 +enum ax_ether_link_speed { + ETHER_LINK_NONE =3D 0, + ETHER_LINK_10 =3D 1, + ETHER_LINK_100 =3D 2, + ETHER_LINK_1000 =3D 3, + ETHER_LINK_2500 =3D 4, +}; + +enum ax_chip_version { + AX_VERSION_INVALID =3D 0x0, + AX_VERSION_AX88179 =3D 0x4, + AX_VERSION_AX88179A =3D 0x6, /* Also AX88772D */ + AX_VERSION_AX88279 =3D 0x7, +}; + struct ax88179_data { u8 eee_enabled; u8 eee_active; @@ -174,6 +303,23 @@ struct ax88179_data { u32 wol_supported; u32 wolopts; u8 disconnecting; + u8 chip_version; + u8 fw_version[4]; + u8 is_ax88772d; + u8 ip_align; + u8 link; + u8 speed; + u8 full_duplex; + bool pause_autoneg; + bool pause_tx; + bool pause_rx; + u8 rx_checksum; + u8 eeprom_read_cmd; + u16 eeprom_block; + struct mii_bus *mdio; + struct phy_device *phydev; + struct phylink *phylink; + struct phylink_config phylink_config; }; =20 struct ax88179_int_data { @@ -181,15 +327,48 @@ struct ax88179_int_data { __le32 intdata2; }; =20 -static const struct { +struct ax_bulkin_settings { unsigned char ctrl, timer_l, timer_h, size, ifg; -} AX88179_BULKIN_SIZE[] =3D { +}; + +static const struct ax_bulkin_settings AX88179_BULKIN_SIZE[] =3D { {7, 0x4f, 0, 0x12, 0xff}, {7, 0x20, 3, 0x16, 0xff}, {7, 0xae, 7, 0x18, 0xff}, {7, 0xcc, 0x4c, 0x18, 8}, }; =20 +static const struct ax_bulkin_settings AX88179A_BULKIN_SIZE[] =3D { + {5, 0x7B, 0x00, 0x17, 0x0F}, /* 1G, SS */ + {5, 0xC0, 0x02, 0x06, 0x0F}, /* 1G, HS */ + {7, 0xF0, 0x00, 0x0C, 0x0F}, /* 100M, Full, SS */ + {6, 0x00, 0x00, 0x06, 0x0F}, /* 100M, Half, SS */ + {5, 0xC0, 0x04, 0x06, 0x0F}, /* 100M, Full, HS */ + {7, 0xC0, 0x04, 0x06, 0x0F}, /* 100M, Half, HS */ + {7, 0x00, 0x00, 0x03, 0x3F}, /* FS */ +}; + +static const struct ax_bulkin_settings AX88772D_BULKIN_SIZE[] =3D { + {0, 0x00, 0x00, 0x00, 0x00}, /* 1G, SS (unused) */ + {0, 0x00, 0x00, 0x00, 0x00}, /* 1G, HS (unused) */ + {0, 0x00, 0x00, 0x00, 0x00}, /* 100M, Full, SS (unused) */ + {0, 0x00, 0x00, 0x00, 0x00}, /* 100M, Half, SS (unused) */ + {5, 0xC0, 0x04, 0x06, 0x0F}, /* 100M, Full, HS */ + {7, 0xC0, 0x04, 0x06, 0x0F}, /* 100M, Half, HS */ + {7, 0x00, 0x00, 0x03, 0x3F}, /* FS */ +}; + +static const struct ax_bulkin_settings AX88279_BULKIN_SIZE[] =3D { + {5, 0x10, 0x01, 0x11, 0x0F}, /* 2.5G */ + {7, 0xB3, 0x01, 0x11, 0x0F}, /* 1G, SS */ + {7, 0xC0, 0x02, 0x06, 0x0F}, /* 1G, HS */ + {7, 0x80, 0x01, 0x03, 0x0F}, /* 100M, Full, SS */ + {7, 0x80, 0x01, 0x03, 0x0F}, /* 100M, Half, SS */ + {7, 0x80, 0x01, 0x03, 0x0F}, /* 100M, Full, HS */ + {7, 0x80, 0x01, 0x03, 0x0F}, /* 100M, Half, HS */ + {7, 0x00, 0x00, 0x03, 0x3F}, /* FS */ +}; + static void ax88179_set_pm_mode(struct usbnet *dev, bool pm_mode) { struct ax88179_data *ax179_data =3D dev->driver_priv; @@ -349,6 +528,37 @@ static void ax88179_mdio_write(struct net_device *netd= ev, int phy_id, int loc, ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res); } =20 +static int ax88179_mdiobus_read(struct mii_bus *bus, int phy_id, int regnu= m) +{ + struct usbnet *dev =3D bus->priv; + struct ax88179_data *priv; + u16 res; + + priv =3D dev->driver_priv; + /* When reading PHYSID, return unused PHY-IDs from the ASIX vendor range = */ + if (phy_id =3D=3D AX88179_PHY_ID && regnum =3D=3D MII_PHYSID1) + return 0x003b; + if (phy_id =3D=3D AX88179_PHY_ID && regnum =3D=3D MII_PHYSID2) { + if (priv->chip_version =3D=3D AX_VERSION_AX88179A && priv->is_ax88772d) + return 0x772d; + else if (priv->chip_version =3D=3D AX_VERSION_AX88179A) + return 0x179a; + else if (priv->chip_version =3D=3D AX_VERSION_AX88279) + return 0x2790; + } + + ax88179_read_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)regnum, 2, &res); + return res; +} + +static int ax88179_mdiobus_write(struct mii_bus *bus, int phy_id, int regn= um, u16 val) +{ + struct usbnet *dev =3D bus->priv; + u16 res =3D (u16)val; + + return ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)regnum, 2, &r= es); +} + static inline int ax88179_phy_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad) { @@ -403,6 +613,53 @@ ax88179_phy_write_mmd_indirect(struct usbnet *dev, u16= prtad, u16 devad, return 0; } =20 +static int ax_read_mmd(struct usbnet *dev, u16 dev_addr, u16 reg) +{ + struct ax88179_data *priv =3D dev->driver_priv; + u16 res; + int ret; + + if (priv->chip_version >=3D AX_VERSION_AX88179A) { + ret =3D ax88179_read_cmd(dev, AX88179A_PHY_CLAUSE45, dev_addr, reg, 2, &= res); + if (ret < 0) + return ret; + return res; + } + + return ax88179_phy_read_mmd_indirect(dev, reg, dev_addr); +} + +static int ax_write_mmd(struct usbnet *dev, u16 dev_addr, u16 reg, u16 dat= a) +{ + struct ax88179_data *priv =3D dev->driver_priv; + + if (priv->chip_version >=3D AX_VERSION_AX88179A) + return ax88179_write_cmd(dev, AX88179A_PHY_CLAUSE45, dev_addr, reg, 2, &= data); + + return ax88179_phy_write_mmd_indirect(dev, reg, dev_addr, data); +} + +static int ax88179_mdiobus_read_c45(struct mii_bus *bus, int addr, int dev= num, int regnum) +{ + struct usbnet *dev =3D bus->priv; + + if (addr !=3D AX88179_PHY_ID) + return -EINVAL; + + return ax_read_mmd(dev, devnum, regnum); +} + +static int ax88179_mdiobus_write_c45(struct mii_bus *bus, int addr, int de= vnum, + int regnum, u16 val) +{ + struct usbnet *dev =3D bus->priv; + + if (addr !=3D AX88179_PHY_ID) + return -EINVAL; + + return ax_write_mmd(dev, devnum, regnum, val); +} + static int ax88179_suspend(struct usb_interface *intf, pm_message_t messag= e) { struct usbnet *dev =3D usb_get_intfdata(intf); @@ -425,6 +682,29 @@ static int ax88179_suspend(struct usb_interface *intf,= pm_message_t message) =20 ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, &tmp8); + + if (priv->chip_version >=3D AX_VERSION_AX88179A) { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, &tmp1= 6); + tmp16 |=3D AX_MEDIUM_RECEIVE_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, &tmp= 16); + } + + if (priv->chip_version =3D=3D AX_VERSION_AX88279) + ax88179_write_cmd(dev, AX88179A_WAKEUP_SETTING, 8, + EPHY_LOW_POWER_EN | S5_WOL_EN + | S5_WOL_LOW_POWER | 0x8000, 0, NULL); + + } else if (priv->chip_version =3D=3D AX_VERSION_AX88279) { + ax88179_write_cmd(dev, AX88179A_WAKEUP_SETTING, 8, 0x8000, 0, NULL); + } + + if (priv->chip_version >=3D AX_VERSION_AX88179A) { + rtnl_lock(); + phylink_suspend(priv->phylink, !!priv->wolopts); + rtnl_unlock(); + ax88179_write_cmd(dev, AX88179A_WAKEUP_SETTING, 0, EPHY_LOW_POWER_EN, 0,= NULL); + ax88179_set_pm_mode(dev, false); + return 0; } =20 /* Disable RX path */ @@ -456,12 +736,19 @@ static int ax88179_suspend(struct usb_interface *intf= , pm_message_t message) } =20 /* This function is used to enable the autodetach function. */ -/* This function is determined by offset 0x43 of EEPROM */ +/* This function is determined by offset 0x43 of EEPROM for the AX88179 */ static int ax88179_auto_detach(struct usbnet *dev) { + struct ax88179_data *priv =3D dev->driver_priv; u16 tmp16; u8 tmp8; =20 + if (priv->chip_version >=3D AX_VERSION_AX88179A) { + tmp16 =3D AX88179A_AUTODETACH_DELAY; + ax88179_write_cmd(dev, AX88179A_AUTODETACH, tmp16, 0, 0, NULL); + return 0; + } + if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM, 0x43, 1, 2, &tmp16) < 0) return 0; =20 @@ -484,15 +771,40 @@ static int ax88179_auto_detach(struct usbnet *dev) static int ax88179_resume(struct usb_interface *intf) { struct usbnet *dev =3D usb_get_intfdata(intf); + struct ax88179_data *ax179_data; + u8 reg8; =20 + ax179_data =3D dev->driver_priv; ax88179_set_pm_mode(dev, true); =20 usbnet_link_change(dev, 0, 0); =20 + if (ax179_data->chip_version >=3D AX_VERSION_AX88179A) { + ax88179_read_cmd(dev, AX88179A_PHY_POWER, 0, 0, 1, ®8); + if (!(reg8 & AX_PHY_POWER)) { + reg8 =3D AX_PHY_POWER; + ax88179_write_cmd(dev, AX88179A_PHY_POWER, 0, 0, 1, ®8); + msleep(250); + } + ax88179_write_cmd(dev, AX_FW_MODE, AX_FW_MODE_179A, 0, 0, NULL); + + /* Now, that AX_FW_MODE_179A is enabled, the PHY needs a power-cycle. + * PHY-power is re-enabled in ax88179_reset() + */ + reg8 =3D 0; + ax88179_write_cmd(dev, AX88179A_PHY_POWER, 0, 0, 1, ®8); + msleep(250); + } + ax88179_reset(dev); =20 ax88179_set_pm_mode(dev, false); =20 + if (ax179_data->phylink) { + rtnl_lock(); + phylink_resume(ax179_data->phylink); + rtnl_unlock(); + } return usbnet_resume(intf); } =20 @@ -1293,6 +1605,17 @@ static int ax88179_bind(struct usbnet *dev, struct u= sb_interface *intf) =20 dev->driver_priv =3D ax179_data; =20 + ret =3D ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_CHIP_STATUS, + 1, 1, &ax179_data->chip_version); + if (ret < 0) + goto err_nodev; + + ax179_data->chip_version =3D (ax179_data->chip_version & 0xf0) >> 4; + ax179_data->is_ax88772d =3D 0; + ax179_data->ip_align =3D 1; + ax179_data->eeprom_read_cmd =3D AX_ACCESS_EEPROM; + ax179_data->eeprom_block =3D 2; + dev->net->netdev_ops =3D &ax88179_netdev_ops; dev->net->ethtool_ops =3D &ax88179_ethtool_ops; dev->net->needed_headroom =3D 8; @@ -1317,6 +1640,437 @@ static int ax88179_bind(struct usbnet *dev, struct = usb_interface *intf) ax88179_reset(dev); =20 return 0; + +err_nodev: + kfree(ax179_data); + ax179_data =3D NULL; + + return ret; +} + +static void ax88179a_bulkin_config(struct usbnet *dev, u8 link_sts) +{ + struct ax88179_data *ax179_data =3D dev->driver_priv; + const struct ax_bulkin_settings *bulkin_data; + int index =3D 0; + + switch (ax179_data->speed) { + case ETHER_LINK_2500: /* AX88279 only */ + index =3D 0; + break; + + case ETHER_LINK_1000: /* AX88279 & AX88178A */ + if (ax179_data->chip_version =3D=3D AX_VERSION_AX88279) { + if (link_sts & AX_USB_SS) + index =3D 1; + else if (link_sts & AX_USB_HS) + index =3D 2; + } else { + if (link_sts & AX_USB_SS) + index =3D 0; + else if (link_sts & AX_USB_HS) + index =3D 1; + } + break; + + case ETHER_LINK_100: + if (ax179_data->chip_version =3D=3D AX_VERSION_AX88279) { + if (link_sts & AX_USB_SS) + index =3D 3; + else if (link_sts & AX_USB_HS) + index =3D 5; + if (!ax179_data->full_duplex) + index++; + } else { + /* AX88279A & AX88277D */ + if (link_sts & AX_USB_SS) + index =3D 2; + else if (link_sts & AX_USB_HS) + index =3D 4; + if (!ax179_data->full_duplex) + index++; + } + break; + + case ETHER_LINK_10: + if (ax179_data->chip_version =3D=3D AX_VERSION_AX88279) + index =3D 7; + else + index =3D 6; + break; + + default: /* No link */ + index =3D 0; + } + + if (ax179_data->chip_version =3D=3D AX_VERSION_AX88279 && (link_sts & AX_= USB_FS)) + index =3D 7; + + if (ax179_data->chip_version =3D=3D AX_VERSION_AX88279) { + bulkin_data =3D AX88279_BULKIN_SIZE; + } else { + if (ax179_data->is_ax88772d) + bulkin_data =3D AX88772D_BULKIN_SIZE; + else + bulkin_data =3D AX88179A_BULKIN_SIZE; + } + + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, &bulkin_d= ata[index]); +} + +static void ax88179a_mdio_unregister(struct ax88179_data *data) +{ + mdiobus_unregister(data->mdio); + mdiobus_free(data->mdio); +} + +static int ax88179a_init_phy(struct usbnet *dev) +{ + struct ax88179_data *data =3D dev->driver_priv; + int ret; + + data->phydev =3D mdiobus_get_phy(data->mdio, AX88179_PHY_ID); + if (!data->phydev) { + netdev_err(dev->net, "Could not find PHY\n"); + return -ENODEV; + } + + ret =3D phylink_connect_phy(data->phylink, data->phydev); + if (ret) { + netdev_err(dev->net, "Could not connect PHY\n"); + return ret; + } + + phy_suspend(data->phydev); + data->phydev->mac_managed_pm =3D true; + + phy_attached_info(data->phydev); + + return 0; +} + +static void ax88179a_mac_config(struct phylink_config *config, unsigned in= t mode, + const struct phylink_link_state *state) +{ + /* Nothing to do */ +} + +static void ax88179a_mac_link_down(struct phylink_config *config, + unsigned int mode, phy_interface_t interface) +{ + /* Nothing to do */ +} + +static void ax88179a_mac_link_up(struct phylink_config *config, + struct phy_device *phy, + unsigned int phy_mode, phy_interface_t interface, + int speed, int duplex, + bool tx_pause, bool rx_pause) +{ + struct usbnet *dev =3D netdev_priv(to_net_dev(config->dev)); + struct ax88179_data *ax179_data =3D dev->driver_priv; + u8 tmp8, link_sts, reg8[3]; + u16 tmp16, mode; + + /* Stop RX/TX for link configuration */ + tmp16 =3D AX_RX_CTL_STOP; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); + tmp8 =3D 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_PATH, 1, 1, &tmp8); + + tmp8 =3D 0xa5; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_CDC_DELAY_TX, 1, 1, &t= mp8); + + tmp16 =3D 0x0410; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 2, 2, &tmp16= ); + + tmp8 =3D 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_ETH_TX_GAP, 1, 1, &tmp8); + + tmp8 =3D 0x07; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_EP5_EHR, 1, 1, &tmp8); + + tmp8 =3D 0x28 | AX_NEW_PAUSE_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_NEW_PAUSE_CTRL, 1, 1, &tmp= 8); + + mode =3D AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | AX_MEDIUM_RXFLO= W_CTRLEN; + + switch (speed) { + case SPEED_2500: + reg8[0] =3D 0x00; + reg8[1] =3D 0xF8; + reg8[2] =3D 0x07; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_TX_PAUSE, 3, 3, reg8); + + reg8[0] =3D 0x78; + reg8[1] =3D (AX_LSOFC_WCNT_7_ACCESS << 5); + reg8[2] =3D 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_RX_STATUS_CDC, 3, 3, = reg8); + + reg8[0] =3D 0x40; + reg8[1] =3D AX_MAC_MIQFFCTRL_FORMAT | AX_MAC_MIQFFCTRL_DROP_CRC | AX_MAC= _LSO_ERR_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_RX_DATA_CDC_CNT, 2, 2= , reg8); + + tmp8 =3D AX_XGMII_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_BFM_DATA, 1, 1, &tmp8); + + tmp8 =3D 0x1C | AX_LSO_ENHANCE_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_LSO_ENHANCE_CTRL, 1, = 1, &tmp8); + + mode |=3D AX_MEDIUM_GIGAMODE | AX_MEDIUM_FULL_DUPLEX; + + break; + + case SPEED_1000: + mode |=3D AX_MEDIUM_GIGAMODE; + fallthrough; + + case SPEED_100: + reg8[0] =3D 0x78; + reg8[1] =3D (AX_LSOFC_WCNT_7_ACCESS << 5) | AX_GMII_CRC_APPEND; + reg8[2] =3D 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_RX_STATUS_CDC, 3, 3, = reg8); + + tmp8 =3D 0x40; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_RX_DATA_CDC_CNT, 1, 1= , &tmp8); + break; + + case SPEED_10: + reg8[0] =3D 0xFA; + reg8[1] =3D (AX_LSOFC_WCNT_7_ACCESS << 5) | AX_GMII_CRC_APPEND; + reg8[2] =3D 0xFF; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_RX_STATUS_CDC, 3, 3, = reg8); + + tmp8 =3D 0xFA; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_RX_DATA_CDC_CNT, 1, 1= , &tmp8); + + speed =3D 10; + break; + } + + ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS, 1, 1, &link_st= s); + ax88179a_bulkin_config(dev, link_sts); + + if (ax179_data->chip_version < AX_VERSION_AX88279) { + tmp8 =3D 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_BFM_DATA, 1, 1, &tmp8); + } + + if (duplex) + mode |=3D AX_MEDIUM_FULL_DUPLEX; + + if (dev->net->mtu > 1500) + mode |=3D AX_MEDIUM_JUMBO_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, &mode); + + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &ax179_data->rxctl= ); + + tmp8 =3D AX_MAC_RX_PATH_READY | AX_MAC_TX_PATH_READY; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_PATH, 1, 1, &tmp8); + + ax179_data->eee_enabled =3D ax88179_chk_eee(dev); + + netif_carrier_on(dev->net); + + netdev_info(dev->net, "ax88179a - Link status is: 1, Link speed: %d, Dupl= ex: %d\n", + speed, duplex); +} + +static const struct phylink_mac_ops ax88179a_phylink_mac_ops =3D { + .mac_config =3D ax88179a_mac_config, + .mac_link_down =3D ax88179a_mac_link_down, + .mac_link_up =3D ax88179a_mac_link_up, +}; + +static int ax88179a_phylink_setup(struct usbnet *dev) +{ + struct ax88179_data *data =3D dev->driver_priv; + phy_interface_t phy_if_mode; + struct phylink *phylink; + + data->phylink_config.dev =3D &dev->net->dev; + data->phylink_config.type =3D PHYLINK_NETDEV; + data->phylink_config.mac_capabilities =3D MAC_SYM_PAUSE | MAC_ASYM_PAUSE = | MAC_100; + if (data->is_ax88772d) + data->phylink_config.mac_capabilities |=3D MAC_10; + else if (data->chip_version < AX_VERSION_AX88279) + data->phylink_config.mac_capabilities |=3D MAC_10 | MAC_1000; + else + data->phylink_config.mac_capabilities |=3D MAC_1000 | MAC_2500FD; + + __set_bit(PHY_INTERFACE_MODE_INTERNAL, + data->phylink_config.supported_interfaces); + phy_if_mode =3D PHY_INTERFACE_MODE_INTERNAL; + + phylink =3D phylink_create(&data->phylink_config, dev->net->dev.fwnode, + phy_if_mode, &ax88179a_phylink_mac_ops); + if (IS_ERR(phylink)) + return PTR_ERR(phylink); + + data->phylink =3D phylink; + return 0; +} + +static int ax88179a_init_mdio(struct usbnet *dev) +{ + struct ax88179_data *data =3D dev->driver_priv; + int ret; + + data->mdio =3D mdiobus_alloc(); + if (!data->mdio) + return -ENOMEM; + + data->mdio->priv =3D dev; + data->mdio->read =3D ax88179_mdiobus_read; + data->mdio->write =3D ax88179_mdiobus_write; + data->mdio->read_c45 =3D ax88179_mdiobus_read_c45; + data->mdio->write_c45 =3D ax88179_mdiobus_write_c45; + data->mdio->name =3D "AX88179A MDIO Bus"; + data->mdio->phy_mask =3D ~(1 << AX88179_PHY_ID); + /* mii bus name is usb-- */ + snprintf(data->mdio->id, MII_BUS_ID_SIZE, "usb-%03d:%03d", + dev->udev->bus->busnum, dev->udev->devnum); + + netdev_err(dev->net, "Registering MDIO bus\n"); + + ret =3D mdiobus_register(data->mdio); + if (ret) { + netdev_err(dev->net, "Could not register MDIO bus (err %d)\n", ret); + mdiobus_free(data->mdio); + data->mdio =3D NULL; + } + + return ret; +} + +static int ax88179a_bind(struct usbnet *dev, struct usb_interface *intf) +{ + struct usb_device *udev =3D interface_to_usbdev(intf); + struct ax88179_data *ax179_data; + int ret; + u8 reg8; + + /* Check if vendor configuration */ + if (udev->actconfig->desc.bConfigurationValue !=3D 1) { + netdev_info(dev->net, "Switching to vendor mode\n"); + usb_driver_set_configuration(udev, 1); + return -ENODEV; + } + + ret =3D usbnet_get_endpoints(dev, intf); + if (ret < 0) + return ret; + + ax179_data =3D kzalloc_obj(*ax179_data); + if (!ax179_data) + return -ENOMEM; + + dev->driver_priv =3D ax179_data; + + ret =3D ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_CHIP_STATUS, + 1, 1, &ax179_data->chip_version); + if (ret < 0) + goto err_nodev; + + ax179_data->chip_version =3D (ax179_data->chip_version & 0xf0) >> 4; + ax179_data->is_ax88772d =3D 0; + if (ax179_data->chip_version =3D=3D AX_VERSION_AX88179A) { + if (udev->descriptor.bcdDevice =3D=3D 0x300) + ax179_data->is_ax88772d =3D 1; + } + + for (int i =3D 0; i < 3; i++) { + ret =3D ax88179_read_cmd(dev, AX88179A_ACCESS_BL, (0xFD + i), + 1, 1, &ax179_data->fw_version[i]); + if (ret < 0) + ax179_data->fw_version[i] =3D 0xff; + } + netdev_info(dev->net, "AX88179A/279/772D Chip Version: %x, FW: %d.%d.%d.%= d\n", + ax179_data->chip_version, + ax179_data->fw_version[0], ax179_data->fw_version[1], + ax179_data->fw_version[2], ax179_data->fw_version[3]); + + /* The AX88279 requires both the AX_RX_CTL_IPE and AX_RX_CTL_DROPCRCERR + * bits set in AX_RX_CTL for creating correct RX-URBs. AX_RX_CTL_DROPCRCE= RR + * is anyway set for all chips, make sure AX_RX_CTL_IPE is set via ip_ali= gn. + * Also configure eeprom access parameters. + */ + if (ax179_data->chip_version =3D=3D AX_VERSION_AX88279) { + ax179_data->ip_align =3D 1; + ax179_data->eeprom_read_cmd =3D AX88179A_FLASH_READ; + ax179_data->eeprom_block =3D 256; + } else { + ax179_data->ip_align =3D 0; + ax179_data->eeprom_read_cmd =3D AX_ACCESS_EFUS; + ax179_data->eeprom_block =3D 20; + } + + dev->net->netdev_ops =3D &ax88179_netdev_ops; + dev->net->ethtool_ops =3D &ax88179_ethtool_ops; + dev->net->needed_headroom =3D 8; + dev->net->needed_tailroom =3D 8; + dev->net->min_mtu =3D ETH_MIN_MTU; + dev->hard_mtu =3D 9 * 1024; + dev->net->max_mtu =3D dev->hard_mtu - dev->net->hard_header_len; + + /* Initialize MII structure */ + dev->mii.dev =3D dev->net; + dev->mii.mdio_read =3D ax88179_mdio_read; + dev->mii.mdio_write =3D ax88179_mdio_write; + dev->mii.phy_id_mask =3D 0xff; + dev->mii.reg_num_mask =3D 0xff; + dev->mii.phy_id =3D AX88179_PHY_ID; + if (!ax179_data->is_ax88772d) + dev->mii.supports_gmii =3D 1; + + dev->net->features |=3D NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO | + NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_FILTER; + + dev->net->hw_features |=3D dev->net->features; + + dev->net->vlan_features =3D NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO; + + netif_set_tso_max_size(dev->net, 16384); + + /* Enable Transmission of Link Speed byte in interrupt URB */ + ax88179_write_cmd(dev, AX_FW_MODE, AX_FW_MODE_179A, 0, 0, NULL); + ax88179_write_cmd(dev, AX_RELOAD_EEPROM_EFUSE, 0, 0, 0, NULL); + + /* Read MAC address from DTB or ASIX chip */ + ax88179_get_mac_addr(dev); + memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); + + /* Power PHY for probing */ + reg8 =3D AX_PHY_POWER; + ax88179_write_cmd(dev, AX88179A_PHY_POWER, 0, 0, 1, ®8); + msleep(250); + + ret =3D ax88179a_init_mdio(dev); + if (ret) + goto err_nodev; + + ret =3D ax88179a_phylink_setup(dev); + if (ret) + goto phylink_err; + + ret =3D ax88179a_init_phy(dev); + if (ret) + goto initphy_err; + + return 0; + +initphy_err: + phylink_destroy(ax179_data->phylink); +phylink_err: + ax88179a_mdio_unregister(ax179_data); +err_nodev: + kfree(ax179_data); + ax179_data =3D NULL; + + return ret; } =20 static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf) @@ -1338,6 +2092,28 @@ static void ax88179_unbind(struct usbnet *dev, struc= t usb_interface *intf) kfree(ax179_data); } =20 +static void ax88179a_unbind(struct usbnet *dev, struct usb_interface *intf) +{ + struct ax88179_data *ax179_data =3D dev->driver_priv; + u16 tmp16; + u8 tmp8; + + /* Configure RX control register =3D> stop operation */ + tmp16 =3D AX_RX_CTL_STOP; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); + + rtnl_lock(); + phylink_disconnect_phy(ax179_data->phylink); + rtnl_unlock(); + phylink_destroy(ax179_data->phylink); + ax88179a_mdio_unregister(ax179_data); + + tmp8 =3D 0; + ax88179_write_cmd(dev, AX88179A_PHY_POWER, 0, 0, 1, &tmp8); + + kfree(ax179_data); +} + static void ax88179_rx_checksum(struct sk_buff *skb, u32 *pkt_hdr) { @@ -1354,6 +2130,21 @@ ax88179_rx_checksum(struct sk_buff *skb, u32 *pkt_hd= r) skb->ip_summed =3D CHECKSUM_UNNECESSARY; } =20 +static void ax88179a_rx_checksum(struct sk_buff *skb, u64 pkt_desc) +{ + u32 pkt_type; + + skb->ip_summed =3D CHECKSUM_NONE; + /* checksum error bit is set */ + if (pkt_desc & AX179A_RX_PD_L4_ERR || pkt_desc & AX179A_RX_PD_L3_ERR) + return; + + pkt_type =3D pkt_desc & AX179A_RX_PD_L4_TYPE_MASK; + /* It must be a TCP or UDP packet with a valid checksum */ + if (pkt_type =3D=3D AX179A_RX_PD_L4_TCP || pkt_type =3D=3D AX179A_RX_PD_L= 4_UDP) + skb->ip_summed =3D CHECKSUM_UNNECESSARY; +} + static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) { struct sk_buff *ax_skb; @@ -1472,6 +2263,121 @@ static int ax88179_rx_fixup(struct usbnet *dev, str= uct sk_buff *skb) return 0; } =20 +static int ax88179a_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + struct ax88179_data *ax179_data =3D dev->driver_priv; + struct sk_buff *ax_skb; + u32 hdr_off, pkt_end; + u64 *pkt_desc_ptr; + u16 vlan_tag; + u16 pkt_cnt; + u64 rx_hdr; + + /* SKB contents for AX179A-based chips: + * + * ... + * + * + * ... + * + * + * + * where: + * contains pkt_len data bytes and padding: + * 2 bytes of IP alignment (optional, depends on AX_RX_CTL_IPE flag) + * packet data received + * optional padding to 8-bytes boundary + * contains 8 bytes: + * pkt_len and fields AX_RXHDR_* + * contains 8 bytes: + * pkt_cnt and hdr_off (offset of ) + * + * pkt_cnt is number of entries in the per-packet metadata array. + */ + + if (!skb || skb->len < sizeof(rx_hdr)) + goto err; + + /* RX Descriptor Header */ + skb_trim(skb, skb->len - sizeof(rx_hdr)); + rx_hdr =3D le64_to_cpup((u64 *)skb_tail_pointer(skb)); + + /* Check these packets */ + hdr_off =3D (rx_hdr & AX179A_RX_DH_DESC_OFFSET_MASK) >> AX179A_RX_DH_DESC= _OFFSET_SHIFT; + pkt_cnt =3D rx_hdr & AX179A_RX_DH_PKT_CNT_MASK; + + /* Consistency check header position */ + if (hdr_off !=3D skb->len - (pkt_cnt * sizeof(rx_hdr))) + goto err; + + /* Make sure that the bounds of the metadata array are inside the SKB + * (and in front of the counter at the end). + */ + if (pkt_cnt * 8 + hdr_off > skb->len) + goto err; + + /* Packets must not overlap the metadata array */ + skb_trim(skb, hdr_off); + + if (!pkt_cnt) + goto err; + + /* Get the first RX packet descriptor */ + pkt_desc_ptr =3D (u64 *)(skb->data + hdr_off); + + pkt_end =3D 0; + while (pkt_cnt--) { + u64 pkt_desc =3D le64_to_cpup(pkt_desc_ptr); + u32 pkt_len_plus_padd; + u32 pkt_len; + + pkt_len =3D (u32)((pkt_desc & AX179A_RX_PD_LEN_MASK) >> AX179A_RX_PD_LEN= _SHIFT) + - (ax179_data->ip_align ? 2 : 0); + pkt_len_plus_padd =3D ((pkt_len + 7 + (ax179_data->ip_align ? 2 : 0)) & = 0x7FFF8); + + pkt_end +=3D pkt_len_plus_padd; + if (pkt_end > hdr_off || (pkt_cnt =3D=3D 0 && pkt_end !=3D hdr_off)) + goto err; + + if (pkt_desc & AX179A_RX_PD_DROP || !(pkt_desc & AX179A_RX_PD_RX_OK) || + pkt_len > (dev->hard_mtu + AX179A_RX_HW_PAD)) { + skb_pull(skb, pkt_len_plus_padd); + + /* Next RX Packet Descriptor */ + pkt_desc_ptr++; + continue; + } + + ax_skb =3D netdev_alloc_skb_ip_align(dev->net, pkt_len); + if (!ax_skb) + goto err; + + skb_put(ax_skb, pkt_len); + memcpy(ax_skb->data, skb->data + (ax179_data->ip_align ? AX179A_RX_HW_PA= D : 0), + pkt_len); + + if (ax179_data->rx_checksum) + ax88179a_rx_checksum(ax_skb, pkt_desc); + + if (pkt_desc & AX179A_RX_PD_VLAN) { + vlan_tag =3D pkt_desc >> AX179A_RX_PD_VLAN_SHIFT; + __vlan_hwaccel_put_tag(ax_skb, htons(ETH_P_8021Q), + vlan_tag & VLAN_VID_MASK); + } + + usbnet_skb_return(dev, ax_skb); + skb_pull(skb, pkt_len_plus_padd); + + /* Next RX Packet Header */ + pkt_desc_ptr++; + } + + return 1; + +err: + return 0; +} + static struct sk_buff * ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) { @@ -1505,6 +2411,59 @@ ax88179_tx_fixup(struct usbnet *dev, struct sk_buff = *skb, gfp_t flags) return skb; } =20 +static struct sk_buff * +ax88179a_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) +{ + u64 tx_desc =3D skb->len & AX179A_TX_DESC_LEN_MASK; + int frame_size =3D dev->maxpacket; + struct sk_buff *ax_skb; + u64 *tx_desc_ptr; + int padding_size; + int headroom; + int tailroom; + u16 tci =3D 0; + + /* TSO MSS */ + tx_desc |=3D ((u64)(skb_shinfo(skb)->gso_size & AX179A_TX_DESC_MSS_MASK))= << + AX179A_TX_DESC_MSS_SHIFT; + + headroom =3D (skb->len + sizeof(tx_desc)) % 8; + padding_size =3D headroom ? 8 - headroom : 0; + + if (((skb->len + sizeof(tx_desc) + padding_size) % frame_size) =3D=3D 0) { + padding_size +=3D 8; + tx_desc |=3D AX179A_TX_DESC_DROP_PADD; + } + + if ((dev->net->features & NETIF_F_HW_VLAN_CTAG_TX) && (vlan_get_tag(skb, = &tci) >=3D 0)) { + tx_desc |=3D AX179A_TX_DESC_VLAN; + tx_desc |=3D ((u64)tci & AX179A_TX_DESC_VLAN_MASK) << AX179A_TX_DESC_VLA= N_SHIFT; + } + + if (!dev->can_dma_sg && (dev->net->features & NETIF_F_SG) && skb_lineariz= e(skb)) + return NULL; + + headroom =3D skb_headroom(skb); + tailroom =3D skb_tailroom(skb); + + if (!(headroom >=3D sizeof(tx_desc) && tailroom >=3D padding_size)) { + ax_skb =3D skb_copy_expand(skb, sizeof(tx_desc), padding_size, flags); + dev_kfree_skb_any(skb); + skb =3D ax_skb; + if (!skb) + return NULL; + } + if (padding_size !=3D 0) + skb_put_zero(skb, padding_size); + /* Copy TX header */ + tx_desc_ptr =3D skb_push(skb, sizeof(tx_desc)); + *tx_desc_ptr =3D cpu_to_le64(tx_desc); + + usbnet_set_skb_tx_stats(skb, 1, 0); + + return skb; +} + static int ax88179_link_reset(struct usbnet *dev) { struct ax88179_data *ax179_data =3D dev->driver_priv; @@ -1582,70 +2541,127 @@ static int ax88179_link_reset(struct usbnet *dev) =20 static int ax88179_reset(struct usbnet *dev) { - u8 buf[5]; - u16 *tmp16; - u8 *tmp; struct ax88179_data *ax179_data =3D dev->driver_priv; struct ethtool_keee eee_data; + u16 *tmp16; + u8 buf[5]; + u8 *tmp; =20 tmp16 =3D (u16 *)buf; tmp =3D (u8 *)buf; =20 /* Power up ethernet PHY */ - *tmp16 =3D 0; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); + if (ax179_data->chip_version < AX_VERSION_AX88179A) { + *tmp16 =3D 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); + + *tmp16 =3D AX_PHYPWR_RSTCTL_IPRL; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); + msleep(500); =20 - *tmp16 =3D AX_PHYPWR_RSTCTL_IPRL; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); - msleep(500); + *tmp =3D AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); + msleep(200); + } else { + *tmp =3D AX_PHY_POWER; + ax88179_write_cmd(dev, AX88179A_PHY_POWER, 0, 0, 1, tmp); + msleep(250); + } =20 - *tmp =3D AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); - msleep(200); + if (ax179_data->chip_version =3D=3D AX_VERSION_AX88279) { + *tmp16 =3D ax88179_mdio_read(dev->net, dev->mii.phy_id, MII_ADVERTISE); + *tmp16 &=3D ~(ADVERTISE_10FULL | ADVERTISE_10HALF); + *tmp16 |=3D AX_ADVERTISE_2500; + ax88179_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, *tmp16); + } =20 /* Ethernet PHY Auto Detach*/ ax88179_auto_detach(dev); =20 + if (ax179_data->chip_version >=3D AX_VERSION_AX88179A) { + *tmp =3D AX_MAC_EFF_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_BULK_OUT_CTRL, 1, 1, = tmp); + + *tmp16 =3D 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16); + + *tmp =3D 0x04; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); + *tmp =3D 0x10; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, 1, 1, tmp); + + *tmp =3D 0; + if (dev->net->features & NETIF_F_HW_VLAN_CTAG_FILTER) + *tmp |=3D AX_VLAN_CONTROL_VFE; + if (dev->net->features & NETIF_F_HW_VLAN_CTAG_RX) + *tmp |=3D AX_VLAN_CONTROL_VSO; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, tm= p); + + *tmp =3D 0xff; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_BM_INT_MASK, 1, 1, tm= p); + + *tmp =3D 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_BM_RX_DMA_CTL, 1, 1, = tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_BM_TX_DMA_CTL, 1, 1, = tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_ARC_CTRL, 1, 1, tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_SWP_CTRL, 1, 1, tmp); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_MAC_TX_HDR_CKSUM, 1, 1, t= mp); + } + /* Read MAC address from DTB or asix chip */ ax88179_get_mac_addr(dev); memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); =20 /* RX bulk configuration */ - memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); - - dev->rx_urb_size =3D 1024 * 20; - - *tmp =3D 0x34; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, 1, 1, tmp); - - *tmp =3D 0x52; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); + if (ax179_data->chip_version < AX_VERSION_AX88179A) { + memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); + *tmp =3D 0x34; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); + + *tmp =3D 0x52; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, + 1, 1, tmp); + dev->rx_urb_size =3D 1024 * 20; + } else { + /* The Bulk-Register configuration for the AX88179A is done in + * ax88179a_link_reset(), once the link is up for a given link and USB-s= peed. + */ + if (ax179_data->is_ax88772d) + dev->rx_urb_size =3D 1024 * 24; + else + dev->rx_urb_size =3D 1024 * 48; + } =20 /* Enable checksum offload */ *tmp =3D AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp); + ax179_data->rx_checksum =3D 1; =20 *tmp =3D AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP | AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp); =20 /* Configure RX control register =3D> start operation */ - *tmp16 =3D AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | - AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16); - - *tmp =3D AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | - AX_MONITOR_MODE_RWMP; + ax179_data->rxctl =3D AX_RX_CTL_DROPCRCERR | AX_RX_CTL_START | + AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; + if (ax179_data->ip_align) + ax179_data->rxctl |=3D AX_RX_CTL_IPE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &ax179_data->rxctl= ); + + if (ax179_data->chip_version < AX_VERSION_AX88179A) + *tmp =3D AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | AX_MONITOR_M= ODE_RWMP; + else + *tmp =3D AX_MONITOR_MODE_RWMP; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp); =20 /* Configure default medium type =3D> giga */ *tmp16 =3D AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | - AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX | - AX_MEDIUM_GIGAMODE; - ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, - 2, 2, tmp16); + AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_FULL_DUPLEX; + if (!ax179_data->is_ax88772d) + *tmp16 |=3D AX_MEDIUM_GIGAMODE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, tmp16); =20 /* Check if WoL is supported */ ax179_data->wol_supported =3D 0; @@ -1653,7 +2669,11 @@ static int ax88179_reset(struct usbnet *dev) 1, 1, &tmp) > 0) ax179_data->wol_supported =3D WAKE_MAGIC | WAKE_PHY; =20 - ax88179_led_setting(dev); + /* For chips starting with AX88179A, LEDS are configured by the adapter + * firmware directly from EEPROM/EFUSE values + */ + if (ax179_data->chip_version < AX_VERSION_AX88179A) + ax88179_led_setting(dev); =20 ax179_data->eee_enabled =3D 0; ax179_data->eee_active =3D 0; @@ -1706,6 +2726,27 @@ static int ax88179_stop(struct usbnet *dev) return 0; } =20 +static int ax88179a_stop(struct usbnet *dev) +{ + struct ax88179_data *ax179_data =3D dev->driver_priv; + u16 reg16; + u8 reg8; + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, ®16); + reg16 &=3D ~AX_MEDIUM_RECEIVE_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, ®16= ); + + reg16 =3D 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, ®16); + + reg8 =3D 0; + ax88179_read_cmd(dev, AX88179A_PHY_POWER, 0, 0, 1, ®8); + + phylink_stop(ax179_data->phylink); + + return 0; +} + static const struct driver_info ax88179_info =3D { .description =3D "ASIX AX88179 USB 3.0 Gigabit Ethernet", .bind =3D ax88179_bind, @@ -1732,6 +2773,42 @@ static const struct driver_info ax88178a_info =3D { .tx_fixup =3D ax88179_tx_fixup, }; =20 +static const struct driver_info ax88179a_info =3D { + .description =3D "ASIX AX88179A USB 3.2 Gigabit Ethernet", + .bind =3D ax88179a_bind, + .unbind =3D ax88179a_unbind, + .status =3D ax88179_status, + .reset =3D ax88179_reset, + .stop =3D ax88179a_stop, + .flags =3D FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET | FLAG_AVOID_= UNLINK_URBS, + .rx_fixup =3D ax88179a_rx_fixup, + .tx_fixup =3D ax88179a_tx_fixup, +}; + +static const struct driver_info ax88772d_info =3D { + .description =3D "ASIX AX88772D/E USB 2.0 Fast Ethernet", + .bind =3D ax88179a_bind, + .unbind =3D ax88179a_unbind, + .status =3D ax88179_status, + .reset =3D ax88179_reset, + .stop =3D ax88179a_stop, + .flags =3D FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET | FLAG_AVOID_= UNLINK_URBS, + .rx_fixup =3D ax88179a_rx_fixup, + .tx_fixup =3D ax88179a_tx_fixup, +}; + +static const struct driver_info ax88279_info =3D { + .description =3D "ASIX AX88279 USB 3.2 2.5Gigabit Ethernet", + .bind =3D ax88179a_bind, + .unbind =3D ax88179a_unbind, + .status =3D ax88179_status, + .reset =3D ax88179_reset, + .stop =3D ax88179a_stop, + .flags =3D FLAG_ETHER | FLAG_FRAMING_AX | FLAG_MULTI_PACKET | FLAG_AVOID_= UNLINK_URBS, + .rx_fixup =3D ax88179a_rx_fixup, + .tx_fixup =3D ax88179a_tx_fixup, +}; + static const struct driver_info cypress_GX3_info =3D { .description =3D "Cypress GX3 SuperSpeed to Gigabit Ethernet Controller", .bind =3D ax88179_bind, @@ -1877,6 +2954,18 @@ static const struct driver_info at_umc2000sp_info = =3D { =20 static const struct usb_device_id products[] =3D { { + /* ASIX AX88179A/B USB 3.2 Gigabit Ethernet */ + USB_DEVICE_VER(0x0b95, 0x1790, 0x0200, 0x0200), + .driver_info =3D (unsigned long)&ax88179a_info, +}, { + /* ASIX AX88772D USB 2.0 100Mbit Ethernet */ + USB_DEVICE_VER(0x0b95, 0x1790, 0x0300, 0x0300), + .driver_info =3D (unsigned long)&ax88772d_info, +}, { + /* ASIX AX88279 USB 3.2 2.5GBit Ethernet */ + USB_DEVICE_VER(0x0b95, 0x1790, 0x0400, 0x0400), + .driver_info =3D (unsigned long)&ax88279_info, +}, { /* ASIX AX88179 10/100/1000 */ USB_DEVICE_AND_INTERFACE_INFO(0x0b95, 0x1790, 0xff, 0xff, 0), .driver_info =3D (unsigned long)&ax88179_info, --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 E61762F8EBE; Fri, 24 Jul 2026 07:36:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878619; cv=none; b=cwqVguSHC3qUW6CSJaDkF7ouRNyyznmeQU946dgfAcZsbuhs99iUXuQxPQJW0Hpra8dQlye7lkLamczgWv8MCFITRsPc0PMbFkM/dLDbyX+GZAXPYGGCqEKC3/w6FYntgxthBekTtnhmDZnyvPvABooLbhbNFzQeoVycKVI84fQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878619; c=relaxed/simple; bh=AtidLZUpoFKxJxk2VVd2ucqs05PUi9WU9odzh3+TvEs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HEtmUdgIzL/PFC214DT725k7YiR+AvbyJzLtr53BinNI+K5dNFz7JT+YG3LbxRSWQvs0kqoEkzS97ICUDrwSpUGwb/wm6TF5lkHv5X3ltJMShCx8j2GTCa7SWDgZnZC1MfP68w1bdvoiO7uy0InPk6SPTK/7xfaKhaoLMxxIrDc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=bXzLUYuC; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=0uGsrmGD; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="bXzLUYuC"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="0uGsrmGD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878616; bh=AtidLZUpoFKxJxk2VVd2ucqs05PUi9WU9odzh3+TvEs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bXzLUYuCTUd2orLtgLQY5juf+zSomRWlSnAWLFVm7oGkGbMFkPb9CDWbSizJYR5AG x2HtQokN9uO/nWbkqqdpMegrFdy1biamZr5lTd7hX53IbgK2Ql7TP9Ng0KAMBk6GVJ 7rQSAW60bg5EdA9WU+D190ebkwMiWsYeqKfTIBo/iz2SJNE99NlOR8BI1nYoiy2E6R C6xlZBR6s2stVfHWWHqMojFsIMRhc9tmh4YjzJwsoFQVDTQWd+ru4xE7txM72oRMG6 V92DvrHMEfrzK25THF/u1hY9hmejqQ+367MRlZN7aIz63T2BpqcbEPIruilbZ6Zcd0 uVfGuJ22pV0EA== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 29F7A49441; Fri, 24 Jul 2026 07:36:56 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878607; bh=AtidLZUpoFKxJxk2VVd2ucqs05PUi9WU9odzh3+TvEs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=0uGsrmGDxg3HO7Iqpi3fZZuIMbBs5ZmD4/sDXOoUNNAZTS3U7mJq/V4Yph2SOT/e1 ZbxBQpQDmbPgkg2MZpL9Zir8FSiqepGyZomm5CPHdrzYquT/e+x0aSpv3vFCGXj0Ng Eg3TOI3QZMsiGvlpXXMQawJQSt6Rz2i3ksv0uHgJZTEzrOlFFCxI4QT3s7kL9yA8kG vY1TTuJvAKIlhCF1aIKGSCawExvu/8AeZ+/ZWvJdpbg/t5Db5+0/SF2//Yj3OOlDv1 NEMnTvvwb1Mqx8MOFx9USnFpfqWBMnKgBNtZ6tDc/mxHDz8T5v2gL8p7PiKDQCQy2n G+N0+KVM7wS2w== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id 68D9F492AD; Fri, 24 Jul 2026 07:36:47 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:46 +0200 Subject: [PATCH net-next v3 03/13] ax88179_178a: Use MMD accessor functions for AX88179A 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: quoted-printable Message-Id: <20260724-ax88179a-v3-3-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 The AX88179A uses a much simpler Clause-45 MMD access interface, which are made available through ax_read_mmd() and ax_write_mmd(), which in turn call the chips' respective implementation. Make use of these functions for stract MMD read/write operations. Signed-off-by: Birger Koblitz Reviewed-by: Andrew Lunn --- drivers/net/usb/ax88179_178a.c | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index b90a75a11024c58192bdb4a9436636bc9312148c..b7837c7a89f9b5ee520ef1ae91b= bc7619d1a12bd 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -985,22 +985,19 @@ ax88179_ethtool_get_eee(struct usbnet *dev, struct et= htool_keee *data) int val; =20 /* Get Supported EEE */ - val =3D ax88179_phy_read_mmd_indirect(dev, MDIO_PCS_EEE_ABLE, - MDIO_MMD_PCS); + val =3D ax_read_mmd(dev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); if (val < 0) return val; mii_eee_cap1_mod_linkmode_t(data->supported, val); =20 /* Get advertisement EEE */ - val =3D ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_ADV, - MDIO_MMD_AN); + val =3D ax_read_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); if (val < 0) return val; mii_eee_cap1_mod_linkmode_t(data->advertised, val); =20 /* Get LP advertisement EEE */ - val =3D ax88179_phy_read_mmd_indirect(dev, MDIO_AN_EEE_LPABLE, - MDIO_MMD_AN); + val =3D ax_read_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); if (val < 0) return val; mii_eee_cap1_mod_linkmode_t(data->lp_advertised, val); @@ -1013,8 +1010,7 @@ ax88179_ethtool_set_eee(struct usbnet *dev, struct et= htool_keee *data) { u16 tmp16 =3D linkmode_to_mii_eee_cap1_t(data->advertised); =20 - return ax88179_phy_write_mmd_indirect(dev, MDIO_AN_EEE_ADV, - MDIO_MMD_AN, tmp16); + return ax_write_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tmp16); } =20 static int ax88179_chk_eee(struct usbnet *dev) @@ -1028,32 +1024,19 @@ static int ax88179_chk_eee(struct usbnet *dev) int eee_lp, eee_cap, eee_adv; u32 lp, cap, adv, supported =3D 0; =20 - eee_cap =3D ax88179_phy_read_mmd_indirect(dev, - MDIO_PCS_EEE_ABLE, - MDIO_MMD_PCS); - if (eee_cap < 0) { - priv->eee_active =3D 0; + eee_cap =3D ax_read_mmd(dev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); + if (eee_cap < 0) return false; - } =20 cap =3D mmd_eee_cap_to_ethtool_sup_t(eee_cap); - if (!cap) { - priv->eee_active =3D 0; - return false; - } - - eee_lp =3D ax88179_phy_read_mmd_indirect(dev, - MDIO_AN_EEE_LPABLE, - MDIO_MMD_AN); - if (eee_lp < 0) { - priv->eee_active =3D 0; + if (!cap) return false; - } =20 - eee_adv =3D ax88179_phy_read_mmd_indirect(dev, - MDIO_AN_EEE_ADV, - MDIO_MMD_AN); + eee_lp =3D ax_read_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE); + if (eee_lp < 0) + return true; =20 + eee_adv =3D ax_read_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); if (eee_adv < 0) { priv->eee_active =3D 0; return false; --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 A76063A6B6A; Fri, 24 Jul 2026 07:36:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878620; cv=none; b=llQwK1dKJjHg+6c//VKJS2J8cYmXOTI+eRusJPSe9qNiDpHlo9/UosRp8YlEoQRsiydU6oNsa15ltyRuNAh7bhA8FL08qvqO61gjNZ+5lyHC1CuTsNho7EsBFQQi1okw+IyVhE1WiHHHAmnOtP8S8FNOjxfi7JgDGwCAohbO8JE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878620; c=relaxed/simple; bh=yS8ryxRoVmRaiU+ueTVr4cmgbVovhgnOfgoWXRpaOBM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ddGZlAwMq9mdPrOao3kfnscvP5w9XGBQw3fljyIVRJk65Izg3WmmuYDB3v7icT7rN98Kr7gzfqlyjYjLphlQuNil64RrCL5K0TFL1Rm5eLH0YzU+Kt2Hmdrth64Fxb5px8fLkygL4Kxl/zj+4WKFKAFb10IwrGaFQCI8lKQxaSI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=XbaGcsDi; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=opIs15cI; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="XbaGcsDi"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="opIs15cI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878616; bh=yS8ryxRoVmRaiU+ueTVr4cmgbVovhgnOfgoWXRpaOBM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XbaGcsDiHrHfyZcM+kUUxuhKCUziECbD+PB1IkOgRlh9w+QkuTpW0HjVY+cfl2vCl assB9m441QcNZ7+3yg+pfMQjo6I8cltFqsPO/fkdN/4lFWL4XPhd4DEGbo5GO+YTZ+ YdwpofrVTiZxnSsnVnFZ2SghhS791GIlztPtNcNc0vl87kwJKKywGE/kpVO7clYq7u zMQobIjpGoIf/jMwTLesOHvdSGYM+QayyREOj1KQtRYeTnfkxSU6UWnVO1poexYzZI 810R9IPLHTFJtSBL/891KRaljO61p7E1QO/3v/ODNoOUNDHdyhbWhz4a8VLHmG2U/j ZDVj2LE4CGw0Q== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id DC73A49448; Fri, 24 Jul 2026 07:36:56 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878607; bh=yS8ryxRoVmRaiU+ueTVr4cmgbVovhgnOfgoWXRpaOBM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=opIs15cIZ0l2EI/6DapLrmJ/ZP6PF4NP5xYWWaifa8Qha3WvjlTLk21s+OQfMbA1x 9Whnbw7N73js9qRhJH2Rapt054oi8ZjGk6Db7n9808P7CxQCVUEEqNXpxpZ/MDTpiA Z57vmTVc9RuHEwJns+IJnj0/zOw9XmDLk8RjAaLoPxqjNKWMfVJF1y60lEy83rq+Mj snxktaB1zi+VFf530W/gdxaSyo40BcUbv/chdjoLuTGEN3Gx17g4YQloFnpWAKViQN CTsSM6XIzy+UJsVvB1AzncqFLACVpoGDWVO2uqn48vL+3NG2njFcEkDW1TKjDBuRP4 7Vq6RtP9PgpDg== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id AF4CA4932E; Fri, 24 Jul 2026 07:36:47 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:47 +0200 Subject: [PATCH net-next v3 04/13] ax88179_178a: Add EEE HW configuration support for AX88179A 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: quoted-printable Message-Id: <20260724-ax88179a-v3-4-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 The AX88179A uses a much simpler HW configuration for EEE via a single EEE configuration register. Add support for this register and replace the EEE enable/disable functions with a single EEE configuration function which enables/disables EEE in the hardware. Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 71 +++++++++++++++++++-------------------= ---- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index b7837c7a89f9b5ee520ef1ae91bbc7619d1a12bd..2e2f96a97b8398ece7d70cf349c= 7db973959629f 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -36,6 +36,7 @@ #define AX_RELOAD_EEPROM_EFUSE 0x06 #define AX88179A_WAKEUP_SETTING 0x07 #define AX_FW_MODE 0x08 +#define AX_GPHY_CTL 0x0F #define AX88179A_FLASH_READ 0x21 #define AX88179A_FLASH_WRITE 0x24 #define AX88179A_PHY_CLAUSE45 0x27 @@ -127,6 +128,9 @@ #define AX88179A_VLAN_ID_DATA1 0x2D =20 #define AX_RX_BULKIN_QCTRL 0x2e + +#define AX_GPHY_EEE_CTRL 0x01 + #define AX_CLK_SELECT 0x33 #define AX_CLK_SELECT_BCS 0x01 #define AX_CLK_SELECT_ACS 0x02 @@ -1061,46 +1065,35 @@ static int ax88179_chk_eee(struct usbnet *dev) return false; } =20 -static void ax88179_disable_eee(struct usbnet *dev) -{ - u16 tmp16; - - tmp16 =3D GMII_PHY_PGSEL_PAGE3; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_PHY_PAGE_SELECT, 2, &tmp16); - - tmp16 =3D 0x3246; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - MII_PHYADDR, 2, &tmp16); - - tmp16 =3D GMII_PHY_PGSEL_PAGE0; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_PHY_PAGE_SELECT, 2, &tmp16); -} - -static void ax88179_enable_eee(struct usbnet *dev) +static void ax88179_eee_config(struct usbnet *dev, bool enable) { + struct ax88179_data *priv =3D dev->driver_priv; u16 tmp16; =20 - tmp16 =3D GMII_PHY_PGSEL_PAGE3; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_PHY_PAGE_SELECT, 2, &tmp16); - - tmp16 =3D 0x3247; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - MII_PHYADDR, 2, &tmp16); - - tmp16 =3D GMII_PHY_PGSEL_PAGE5; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_PHY_PAGE_SELECT, 2, &tmp16); - - tmp16 =3D 0x0680; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - MII_BMSR, 2, &tmp16); + if (priv->chip_version < AX_VERSION_AX88179A) { + tmp16 =3D GMII_PHY_PGSEL_PAGE3; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_PHY_PAGE_SELECT, 2, &tmp16); + + tmp16 =3D enable ? 0x3247 : 0x3246; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + MII_PHYADDR, 2, &tmp16); + if (enable) { + tmp16 =3D GMII_PHY_PGSEL_PAGE5; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_PHY_PAGE_SELECT, 2, &tmp16); + + tmp16 =3D 0x0680; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + MII_BMSR, 2, &tmp16); + } =20 - tmp16 =3D GMII_PHY_PGSEL_PAGE0; - ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, - GMII_PHY_PAGE_SELECT, 2, &tmp16); + tmp16 =3D GMII_PHY_PGSEL_PAGE0; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_PHY_PAGE_SELECT, 2, &tmp16); + } else { + ax88179_write_cmd(dev, AX_GPHY_CTL, AX_GPHY_EEE_CTRL, enable, 0, NULL); + } } =20 static int ax88179_get_eee(struct net_device *net, struct ethtool_keee *ed= ata) @@ -1122,13 +1115,13 @@ static int ax88179_set_eee(struct net_device *net, = struct ethtool_keee *edata) =20 priv->eee_enabled =3D edata->eee_enabled; if (!priv->eee_enabled) { - ax88179_disable_eee(dev); + ax88179_eee_config(dev, false); } else { priv->eee_enabled =3D ax88179_chk_eee(dev); if (!priv->eee_enabled) return -EOPNOTSUPP; =20 - ax88179_enable_eee(dev); + ax88179_eee_config(dev, true); } =20 ret =3D ax88179_ethtool_set_eee(dev, edata); @@ -2661,7 +2654,7 @@ static int ax88179_reset(struct usbnet *dev) ax179_data->eee_enabled =3D 0; ax179_data->eee_active =3D 0; =20 - ax88179_disable_eee(dev); + ax88179_eee_config(dev, false); =20 ax88179_ethtool_get_eee(dev, &eee_data); linkmode_zero(eee_data.advertised); --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 46F613AA1A7; Fri, 24 Jul 2026 07:36:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878620; cv=none; b=spNjZr1us8+CKC1b7XsUAMPDvsiu/TgZsYgjKM7xtpRO0eTlJpLboHv9kc7hDdjqEPbNrCyypLeRNOanMLUNq6A+Pawm291vX2k2Bi9PG0qxtMVh2aWflBUrgsA2Zzm+2ZLiL8gg7CXpDzEC34HSUT5P6V1Z60/nExGMJJBfqgo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878620; c=relaxed/simple; bh=qCvPeS6GlFQC/4Rao6DwJajLeup5Mjt3RQtMo270ucA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZWpamI96WzKzRszAKWEg3QCJ8Iskkh/mmLBwM5C9y6T9yYQDz3u/kM2+ZBu1D4CJDHcQ5d4YFhK1HEU4FzrXphkiaB1wPBBt8gMbyzZBFHuJCI8rHskCgT1Wjuosjwm5bI77FROcfyqHQspRZyS00BuL3AOQZhNPzSQjG7z2g0I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=zHifDaGO; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=xXdvJ5fG; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="zHifDaGO"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="xXdvJ5fG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878617; bh=qCvPeS6GlFQC/4Rao6DwJajLeup5Mjt3RQtMo270ucA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=zHifDaGOWNUvoNgNMSjqILah5izYlZirjSvm0UIKwRpGaAAwycPS9JRgUEknWKNyN G5NV5lLbsOk4TdVCCLkppbYLgTupDpYPSYmLKi844vVpOJmFp2+mrgxS/chyhdbLsm HEC15NW2YNGgY3GQ8Dc3sqwOnvJcLg7hgktpw2iZ4Wh+q8tn8udRszJmGnKBko4vYc /Vbf/hzQYSUtKIFiaKxfK1tDE4KUtj60ru/CyT2H/dtqHLE+AMaddNNKzFpD405NMg jaUexQko5wpnIS76sh09LBeu9za0ltb8w2xn63CKrD4q5wMlhvhCPRyhOC3hCfjdZT KzvqZdlEe875w== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 7C1CA4946B; Fri, 24 Jul 2026 07:36:57 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878608; bh=qCvPeS6GlFQC/4Rao6DwJajLeup5Mjt3RQtMo270ucA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=xXdvJ5fGRy+VzXQQiZFIJCn9E6Kwu2zvVIps4I5hjLzsF15bVYTbrD9MTZbcziSQD XrDuLKr5VhnyxJVPBLrMXLG+Zwf3Ko4+Btzkrj8fC4ILou26sbPgrajj0WfsEJqdy8 3fDIDdz1nAW6gtF6NbtfX1h0QQ2FPnE+tQMjh1t09IPUGKoe2CCs1140UCIsmrzTdR fjVyyypeyrJfbuMFcsNupeymv4PX/XDHsc9DsZxIKUfhVqeJV0xkGytA2KSnHf4RBj UY4MG4PwroAj/tIIpfaZ3SD8g29xUFzeYlYFHpaI6tLExZOP7ZjNemgTJxoafs5aB6 TxHztirHeqlTw== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id 01B4D48EFC; Fri, 24 Jul 2026 07:36:47 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:48 +0200 Subject: [PATCH net-next v3 05/13] ax88179_178a: Use phylink in get/set_link_ksettings 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: quoted-printable Message-Id: <20260724-ax88179a-v3-5-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 The PHYs in the AX179A-based USB-Ethernet controllers can be configured via phylink. Use this for link configuration. Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 2e2f96a97b8398ece7d70cf349c7db973959629f..136d1d39bf78658758d35372d4a= 9486e21befd87 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -967,9 +967,15 @@ ax88179_set_eeprom(struct net_device *net, struct etht= ool_eeprom *eeprom, } =20 static int ax88179_get_link_ksettings(struct net_device *net, - struct ethtool_link_ksettings *cmd) + struct ethtool_link_ksettings *cmd) { struct usbnet *dev =3D netdev_priv(net); + struct ax88179_data *data; + + data =3D dev->driver_priv; + + if (data->phylink) + return phy_ethtool_get_link_ksettings(net, cmd); =20 mii_ethtool_get_link_ksettings(&dev->mii, cmd); =20 @@ -980,6 +986,13 @@ static int ax88179_set_link_ksettings(struct net_devic= e *net, const struct ethtool_link_ksettings *cmd) { struct usbnet *dev =3D netdev_priv(net); + struct ax88179_data *data; + + data =3D dev->driver_priv; + + if (data->phylink) + return phy_ethtool_set_link_ksettings(net, cmd); + return mii_ethtool_set_link_ksettings(&dev->mii, cmd); } =20 --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 58B013AFB1A; Fri, 24 Jul 2026 07:37:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878622; cv=none; b=NYtBagUDFPAAPTjF06kdu1Ki0DLYzgp2hd+4XsEyoISkdoucZl9rsMDBRCo5cJlTrLm0CFvnUfClni8Qmkfwh96OaBf0nczteqMqyRSl1MlCA/l6M5lbDKSpajq3bAZS9nLqUFLdxrnJ13CwqQtGKsSGaUmVYVS44iMjJmDLdEA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878622; c=relaxed/simple; bh=ab6Rr5GO91mjk8oKOpJcmX5aThprr1KeInjVzYkD4QE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WLpAlo6P8Z/aW5XqkCKQUyiCDc+/lQuFeu2S3rvHFWeLwKMYEE3at9F5ZmnU28+n+eaBv/K9L4YinA7Rqkml+MD2RAEuBHg5ArPGVR0gkxA5ABANM1CZb6qyOkxAamTUtrKhu5P88fChay3qI+iWW9O+QtZQDIOH3LVun/01PVU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=1D9DxFSM; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=EUgloJFN; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="1D9DxFSM"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="EUgloJFN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878618; bh=ab6Rr5GO91mjk8oKOpJcmX5aThprr1KeInjVzYkD4QE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=1D9DxFSMqQ0tfg1VGpr5U3yHHYorFGKh6SlByaZdAZ27EJ9LoGxM4TTu3X9GozlPe hcYPdpae90l0EnUyiIcORufjQUW015z3yRmCuEhSfE1raapzKR2YSVZDO1E9T1UdRN YTfjWjWS+xiQPjfYABHGqMw7h4LX4F076xFk2ij4Rlqo28af22LIxrwHKm+BxFQPi/ oUm3n2iv9a4VvbOJ6ROHrTJr82ZsOEukb7JympYEqddVkB8Q8w80euHhyM3J0CrTLO ske681338B2zGl5OJlbR/Ip8l1WSsYDW0oD/6Shg294VI4XFwJxVWFyfT3TJ+h80BR N/649OeiCv0Lg== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 378C449442; Fri, 24 Jul 2026 07:36:58 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878608; bh=ab6Rr5GO91mjk8oKOpJcmX5aThprr1KeInjVzYkD4QE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=EUgloJFNQey5aBWJDHySQSkVhKfUFbXygaC1sHIF4vpk9MWhAW2P7CXkGFot8L8nl 6tZ/KjoemHB00BGDWrrhRJWREH2VIs2R6BJ18ykZx9xKCi3WbEhXh25k0fUbNDbn5I SAff9Uzt0LtExvJpiV21bwFYKMeJb6DD2YooETtxW1KYjwy55Ek0T8DGVCARrU4uC+ NBROIkY9Dtv1kfCMzdrUQUEDzG2RbKT1+ir6PS52pKCWPwlGRv7oth/tyCb1cGe34P RpGaIa3XBaaQsuAH9sWLygUJvT0x6cTV0MFg8wzNRRYUyyXWKj8ju7epqL9Q3XahxR xQsA9zwnMwGuA== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id 476D5493E6; Fri, 24 Jul 2026 07:36:48 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:49 +0200 Subject: [PATCH net-next v3 06/13] ax88179_178a: EEE setup for AX88179A-based chips 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: quoted-printable Message-Id: <20260724-ax88179a-v3-6-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 Add EEE setup for AX88179A-based chips. For these chips we enable EEE by default. Adapt the ax88179_chk_eee() EEE status verification function to also support AX88179A-based chips in order to make sure the initial setup leads to a correctly identified EEE status. Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 60 +++++++++++++++++++++++++++++---------= ---- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 136d1d39bf78658758d35372d4a9486e21befd87..8ea16d1231037832e12f74e2c53= 04ee4b7a54389 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -999,7 +999,17 @@ static int ax88179_set_link_ksettings(struct net_devic= e *net, static int ax88179_ethtool_get_eee(struct usbnet *dev, struct ethtool_keee *data) { - int val; + struct ax88179_data *ax179_data =3D dev->driver_priv; + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) =3D {}; + int val, ret; + + if (ax179_data->phylink) { + ret =3D phylink_ethtool_get_eee(ax179_data->phylink, data); + /* AX88279 MAC does not support 2500Mbit EEE */ + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, mask); + linkmode_andnot(data->supported, data->supported, mask); + return ret; + } =20 /* Get Supported EEE */ val =3D ax_read_mmd(dev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); @@ -1025,9 +1035,14 @@ ax88179_ethtool_get_eee(struct usbnet *dev, struct e= thtool_keee *data) static int ax88179_ethtool_set_eee(struct usbnet *dev, struct ethtool_keee *data) { - u16 tmp16 =3D linkmode_to_mii_eee_cap1_t(data->advertised); + struct ax88179_data *priv =3D dev->driver_priv; + u16 tmp16; =20 - return ax_write_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tmp16); + if (priv->phylink) + return phylink_ethtool_set_eee(priv->phylink, data); + + tmp16 =3D linkmode_to_mii_eee_cap2_t(data->advertised); + return ax_write_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2, tmp16); } =20 static int ax88179_chk_eee(struct usbnet *dev) @@ -1037,6 +1052,7 @@ static int ax88179_chk_eee(struct usbnet *dev) =20 mii_ethtool_gset(&dev->mii, &ecmd); =20 + priv->eee_active =3D 0; if (ecmd.duplex & DUPLEX_FULL) { int eee_lp, eee_cap, eee_adv; u32 lp, cap, adv, supported =3D 0; @@ -1054,10 +1070,8 @@ static int ax88179_chk_eee(struct usbnet *dev) return true; =20 eee_adv =3D ax_read_mmd(dev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); - if (eee_adv < 0) { - priv->eee_active =3D 0; - return false; - } + if (eee_adv < 0) + return true; =20 adv =3D mmd_eee_adv_to_ethtool_adv_t(eee_adv); lp =3D mmd_eee_adv_to_ethtool_adv_t(eee_lp); @@ -1065,16 +1079,13 @@ static int ax88179_chk_eee(struct usbnet *dev) SUPPORTED_1000baseT_Full : SUPPORTED_100baseT_Full; =20 - if (!(lp & adv & supported)) { - priv->eee_active =3D 0; - return false; - } + if (!(lp & adv & supported)) + return true; =20 priv->eee_active =3D 1; return true; } =20 - priv->eee_active =3D 0; return false; } =20 @@ -2667,14 +2678,27 @@ static int ax88179_reset(struct usbnet *dev) ax179_data->eee_enabled =3D 0; ax179_data->eee_active =3D 0; =20 - ax88179_eee_config(dev, false); + if (ax179_data->chip_version < AX_VERSION_AX88179A) { + ax88179_eee_config(dev, false); =20 - ax88179_ethtool_get_eee(dev, &eee_data); - linkmode_zero(eee_data.advertised); - ax88179_ethtool_set_eee(dev, &eee_data); + ax88179_ethtool_get_eee(dev, &eee_data); + linkmode_zero(eee_data.advertised); + ax88179_ethtool_set_eee(dev, &eee_data); + } else { + ax88179_eee_config(dev, true); + ax88179_ethtool_get_eee(dev, &eee_data); + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, eee_data.advertis= ed); + if (ax179_data->chip_version >=3D AX_VERSION_AX88279) + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, eee_data.adverti= sed); + ax88179_ethtool_set_eee(dev, &eee_data); + } =20 - /* Restart autoneg */ - mii_nway_restart(&dev->mii); + if (ax179_data->phylink) { + phylink_start(ax179_data->phylink); + } else { + /* Restart autoneg */ + mii_nway_restart(&dev->mii); + } =20 usbnet_link_change(dev, 0, 0); =20 --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 596473B1EF2; Fri, 24 Jul 2026 07:37:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878623; cv=none; b=LoB6bbt2R/Kg3dZW97BW4JXppHuP3p3YYgoiMnGSHgg5pKkermcgoXjH8vFePXbrllSaQ3GnXmwHnnOEkOusH07pzvgsfv4WMUVZuf2KUdP/h0ZNYbuyH6w6VL8VkK4o7OhkOSKmnZC9uQs5NM0VefLJ3gA2qui70u2KjEeAtWE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878623; c=relaxed/simple; bh=A4PRVdY551Fqg4eiE/V12aNQ1S3c71xr0cmz0PhIFh4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Wa+MZ5lQumNZUuQUKZ3qmIhRS7P+eQ5CKWnAh36IX0JqKdoW1m9HpUjDuflPzolZepgZtmo78sBo+a9mEiVCxDE33pFJDt48x7sm9r1LhQDuMRxTx2CTH/c74CsAF5S6IJrzVyzyJKD2yWb8TCyoMo1r8lfxrKTTmwwIkzPPKHY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=qzStT0pF; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=rHot+6RZ; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="qzStT0pF"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="rHot+6RZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878618; bh=A4PRVdY551Fqg4eiE/V12aNQ1S3c71xr0cmz0PhIFh4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qzStT0pFFzaZGnTmnEyY6VHcMMxdGM4lfMsgC338YR9XVr+N7vU60MHxFFUrNejmt efu1Ndz13MPFHi6x7X+kvZWPs74le2Lvv0AWr3z3mxvYalvMgkD25iV2OZN/JaEHXA SDEMmyuwQXYHSI/QYo/azcz16IV2RsEoytanXJsWr0z1SmGYGO2dTiiW41UZCcPO6q McWY1YJJYC4Y8pKvMP1YI3UCLnIXXI4OZJWJj5K1mZDu9lhgZxF5ldX1PNA0mjdPgb bCG1zQ/K/8PRnGb+719aMlSOlCbSL87DPKZRqeEATOJAXVrRb4Yr/Bu5BzO+G0V/VC FNwN6brulPI7g== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id B4ABA493BB; Fri, 24 Jul 2026 07:36:58 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878608; bh=A4PRVdY551Fqg4eiE/V12aNQ1S3c71xr0cmz0PhIFh4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=rHot+6RZpixT82qp8IEvRbFh7QrDS8LPKp+OBwPBnI3t6Zah6u0hxMgLLowPlkXSq 8BDOzyiWNr+3BwsSOBByUKMB21r5QoOloZDsdp9uFcrf0PpoecfhCzn+7xH/qGLSoh Lbl8LeFzfLARQtGec/j8XbjeEfq5qnMmrypGSiQKpBktLI2eHwdG81vKXaee4c6doZ M7vO+mZpsssU8GG2YEk1TmU0n/7mpwTNfgW6PzIF91wkruMXV12o1P6hZ3CWK6CDcc y+gl7F7FKDRwEVzVWYzwqcXTvvnbs1i7HgLjWvW9j8xt2eLSdUXcXtRLrF/jJvr+sb 2NUQMo8vtcoIw== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id 8D7EA48F41; Fri, 24 Jul 2026 07:36:48 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:50 +0200 Subject: [PATCH net-next v3 07/13] ax88179_178a: Obtain speed and duplex from Interrupt URB 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: quoted-printable Message-Id: <20260724-ax88179a-v3-7-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 For newer AX179A/772D firmwares and the AX88279, the interrupt URB response also contains information on the Ethernet speed and duplex status. Read this in order to use it to configure the link. Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 8ea16d1231037832e12f74e2c5304ee4b7a54389..02c015847eea3dfbdfa73f3d59a= 7d5b0dd1bc339 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -496,6 +496,7 @@ static int ax88179_write_cmd(struct usbnet *dev, u8 cmd= , u16 value, u16 index, =20 static void ax88179_status(struct usbnet *dev, struct urb *urb) { + struct ax88179_data *data =3D dev->driver_priv; struct ax88179_int_data *event; u32 link; =20 @@ -506,6 +507,9 @@ static void ax88179_status(struct usbnet *dev, struct u= rb *urb) le32_to_cpus((void *)&event->intdata1); =20 link =3D (((__force u32)event->intdata1) & AX_INT_PPLS_LINK) >> 16; + data->speed =3D (((__force u32)event->intdata1) >> 8) & 0x7; + data->full_duplex =3D (((__force u32)event->intdata1) >> 12) & 0x1; + data->link =3D link; =20 if (netif_carrier_ok(dev->net) !=3D link) { usbnet_link_change(dev, link, 1); --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 423B53B19B6; Fri, 24 Jul 2026 07:37:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878622; cv=none; b=V79VbWlLkHQl0F+J9vzEtDZKYMIz/xuWgjv9NVRfPfR44nh/VSkMNgHEPb8dcQUxVT/avHFrQX1yP9gc29fCtHM5CMKzfx7HnXQwtDQ/9kb282ZgXABMcKWq1TX4vkkLhsYi/NUMlUqC/U/rqZ3Dd7h6mMWUuWIYw8YIDMFU0Fk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878622; c=relaxed/simple; bh=z0SDU9UqzCrc+NpLDY6Ok2tA8Jfx+0J76yanVklX/hs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=i3KLMWAJD0g8uvWzcrXolfNSiCOAdSOn80lJR7uWl99FioPdnKYydg3T7aTrHRp3qDANoJnkQueMhR+8a2p8bKItHz90wELVN7GF8CMV/Bw7cPXnZwY2xzM6q3hUafKKRCHK6ZANpcX+xwKWZGsFj0agWPViL0tNwMcz2RhKDgE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=yJ0cdHRr; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=Tgcstv0q; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="yJ0cdHRr"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="Tgcstv0q" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878619; bh=z0SDU9UqzCrc+NpLDY6Ok2tA8Jfx+0J76yanVklX/hs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=yJ0cdHRrMUAgzGki7/gfKH2QslPzQM8CWv9DRpW3UKI1Rj8hsWilZ+geyzRJJNMeE Y9jMkrpIHser/WGYrNQcqBEPw5vcnIrzeFtpuAIYn7PKHyxGw8vwupfDUwe5eeRRxg pt6KdmyPpnLLMFCYcmlaXf0hGvubQN1OP/NvTHKecDnJVG0M0VOYdcAdo8VZwka/MB 2tQYhH/iP3l2KUBZuLOvyeVBUybnsILJprs5jsLHILlWHCKVwnSJzAZJKjjpRC6sYS Ni48LwvDP+0kve7fIPsKFYXVSxEJ53UTYCOGyHGCcr8qlZMQkkanIr+QE2tbLvppT5 /WLP2kvgmWX8A== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 3643C493D2; Fri, 24 Jul 2026 07:36:59 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878609; bh=z0SDU9UqzCrc+NpLDY6Ok2tA8Jfx+0J76yanVklX/hs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Tgcstv0q6uE1OBXoEvgczn+SHKAncfk+OnXfIPcxkAp3vgM6FVCaa44/inha91BqE NIZX823ijm4MzAj5ePzFVcPZx0H0B5SwxEYjhI62qS89UG5AnSUYTczD2bTA5XRuB1 Ma0fL8w+EDIB1tQKTXWUhL2VkVCj5WOdOPU2QS/Bh8eu3T/962azlbcipJ2zyJ214Q h15P8rVzZ11C8AKbzjf3ARv4hUTYlPlAZgzGzlfW4+JbmP26gqgig84Sb3K/ThMrhJ JHrQ6ZgQJAlRL3dSkq083I7lpyeW/UGg9hru0GiVN0/VsAPQfWO0E/iG+au0AXoQcC XBQ/oR1073pjQ== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id D3F8749344; Fri, 24 Jul 2026 07:36:48 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:51 +0200 Subject: [PATCH net-next v3 08/13] ax88179_178a: Add support for ethtool pause parameter configuration 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: quoted-printable Message-Id: <20260724-ax88179a-v3-8-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 The AX179A-based chips support pause parameter configuration. Make it available through ethtool ops. Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 02c015847eea3dfbdfa73f3d59a7d5b0dd1bc339..cc9a3ef4fa03ac36f89f78d2909= a84d9b11d336c 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -314,9 +314,6 @@ struct ax88179_data { u8 link; u8 speed; u8 full_duplex; - bool pause_autoneg; - bool pause_tx; - bool pause_rx; u8 rx_checksum; u8 eeprom_read_cmd; u16 eeprom_block; @@ -1000,6 +997,29 @@ static int ax88179_set_link_ksettings(struct net_devi= ce *net, return mii_ethtool_set_link_ksettings(&dev->mii, cmd); } =20 +static void ax88179a_get_pauseparam(struct net_device *net, struct ethtool= _pauseparam *pause) +{ + struct usbnet *dev =3D netdev_priv(net); + struct ax88179_data *data; + + data =3D dev->driver_priv; + + phylink_ethtool_get_pauseparam(data->phylink, pause); +} + +static int ax88179a_set_pauseparam(struct net_device *net, struct ethtool_= pauseparam *pause) +{ + struct usbnet *dev =3D netdev_priv(net); + struct ax88179_data *data; + int ret; + + data =3D dev->driver_priv; + + ret =3D phylink_ethtool_set_pauseparam(data->phylink, pause); + + return ret; +} + static int ax88179_ethtool_get_eee(struct usbnet *dev, struct ethtool_keee *data) { @@ -1177,6 +1197,8 @@ static const struct ethtool_ops ax88179_ethtool_ops = =3D { .nway_reset =3D usbnet_nway_reset, .get_link_ksettings =3D ax88179_get_link_ksettings, .set_link_ksettings =3D ax88179_set_link_ksettings, + .get_pauseparam =3D ax88179a_get_pauseparam, + .set_pauseparam =3D ax88179a_set_pauseparam, .get_ts_info =3D ethtool_op_get_ts_info, }; =20 --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 BA5153ACA74; Fri, 24 Jul 2026 07:37:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878625; cv=none; b=iy1uM3WMf/QaZlWAANOep6eoFLPM8tMEmNX7BJQzEuC0XTETWk+9LUiULRb25m2VPtvIMUviWjJeWUDUTLPv6u4WxvmtwSlH/Lmhmh5eoS3QhEysEQf/tF1kbFpkCuDKDZhI9u8id2QB80EfRsyLaZWxC2fjzRnkoH7Ul6dN9x8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878625; c=relaxed/simple; bh=SJu3YoTrHaAOpYFmFiAizjE7y2zKCL5FZ7+EZ/ARztE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=n8CtF5WMSZrSWDShHYxf3+CHOUhxv+4rSB2zFZpJN9Ps1tsz7ana0bx0zgXZ6kHHpLrzg0q1KPkgXmETXaevHwYpxG6yMG7AqMbj+EPSR7xr+iYxzhPZ1OjSk1o21pU1tk2PxtdslZsi2o7xOJJ2suTekCY8JAPBQkNRVVSf22E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=s5mAHjmG; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=20i/B+Gm; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="s5mAHjmG"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="20i/B+Gm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878622; bh=SJu3YoTrHaAOpYFmFiAizjE7y2zKCL5FZ7+EZ/ARztE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=s5mAHjmGyRMgmnCEsXR/smopi2VQ1Mr6eX+z3EK4qpa8CMBAOgEZj3wr7qG5VsGBO Iidk3iuD80q9fjq0RAq62Be3kJeBE0ZB6k6sCwuzZrxHLL2wEzA5i71yWf4Y2LEXh+ Ox3Jz3+w3gZUaa0CANO1aLRNWvGfJYGD7SsKg8yy1774WFqzC6AJQ/GJ0wJdAZ9EFp U+iVsRnO5B1fi14bWjcCB8wm9U1fHzVaAGcRkmY6+LpU0xN45fbqgevrdEj0DOUniR nzxUJVhZf70KMczp0y36uH8l0TniZTeGS01qlHflCczm6RA8qSS/HMhcmVhsHnyfpq Jz5iMVSDHTAQQ== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 15C464932E; Fri, 24 Jul 2026 07:37:02 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878609; bh=SJu3YoTrHaAOpYFmFiAizjE7y2zKCL5FZ7+EZ/ARztE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=20i/B+GmbM2uZy9hHkOOoM1EBlz6RpsB7Rf4CpOHDVKCOqmFMpxwWAbfz3UdEztBv PTikcfH7Zowv93nqJn/CTawl/gL3cpmRF/mR9OKB4OiqMBWfoij3cb9SvjVBJ0FhlG xmECqyXrvbHuWi8qQk1ln2ETgA66JOdhmooPvdpJcjYxIQ5l74vxdapRXU6QOjMikc TqR+OAzIiOejM065WfOMa5+jXTlGW+5Xq6s+pt9aNkgqLWpi99GCClP4meFwm4PamO 22WTzrH5CG4BZsC/GfOLMWrPOzG/4AijTPmGLLmnLW1W286FjOuuSBKsxpgCYVn2bF vIucN4y1qQn/A== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id 260A049367; Fri, 24 Jul 2026 07:36:49 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:52 +0200 Subject: [PATCH net-next v3 09/13] ax88179_178a: Add VLAN offload support for AX88179A 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: quoted-printable Message-Id: <20260724-ax88179a-v3-9-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 The AX88179A-based chips support VLAN offload. Add configuration support in netdev_ops. Features supported are: NETIF_F_HW_VLAN_CTAG_TX, NETIF_F_HW_VLAN_CTAG_RX and NETIF_F_HW_VLAN_CTAG_FILTER. Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 87 ++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 87 insertions(+) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index cc9a3ef4fa03ac36f89f78d2909a84d9b11d336c..d8617dad5990f38d39b4569a634= 7e219856c6f2a 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1202,6 +1202,62 @@ static const struct ethtool_ops ax88179_ethtool_ops = =3D { .get_ts_info =3D ethtool_op_get_ts_info, }; =20 +static int ax179a_vlan_rx_kill_vid(struct net_device *net, __be16 proto, u= 16 vid) +{ + struct usbnet *dev =3D netdev_priv(net); + u8 vlan_ctrl; + u16 reg16; + u8 reg8; + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, ®= 8); + vlan_ctrl =3D reg8; + + /* Address */ + reg8 =3D (vid / 16); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_ADDRESS, 1, 1, &re= g8); + + /* Data */ + reg8 =3D vlan_ctrl | AX_VLAN_CONTROL_RD; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, &re= g8); + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0, 2, 2, ®16= ); + reg16 &=3D ~(1 << (vid % 16)); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0, 2, 2, ®1= 6); + + reg8 =3D vlan_ctrl | AX_VLAN_CONTROL_WE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, &re= g8); + + return 0; +} + +static int ax179a_vlan_rx_add_vid(struct net_device *net, __be16 proto, u1= 6 vid) +{ + struct usbnet *dev =3D netdev_priv(net); + u8 vlan_ctrl; + u16 reg16; + u8 reg8; + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, ®= 8); + vlan_ctrl =3D reg8; + + /* Address */ + reg8 =3D (vid / 16); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_ADDRESS, 1, 1, &re= g8); + + /* Data */ + reg8 =3D vlan_ctrl | AX_VLAN_CONTROL_RD; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, &re= g8); + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0, 2, 2, ®16= ); + reg16 |=3D (1 << (vid % 16)); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0, 2, 2, ®1= 6); + + reg8 =3D vlan_ctrl | AX_VLAN_CONTROL_WE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, &re= g8); + + return 0; +} + static void ax88179_set_multicast(struct net_device *net) { struct usbnet *dev =3D netdev_priv(net); @@ -1247,6 +1303,7 @@ ax88179_set_features(struct net_device *net, netdev_f= eatures_t features) { u8 tmp; struct usbnet *dev =3D netdev_priv(net); + struct ax88179_data *data =3D dev->driver_priv; netdev_features_t changed =3D net->features ^ features; =20 if (changed & NETIF_F_IP_CSUM) { @@ -1266,6 +1323,34 @@ ax88179_set_features(struct net_device *net, netdev_= features_t features) tmp ^=3D AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp); + data->rx_checksum =3D !!(features & NETIF_F_RXCSUM); + } + + if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, &tm= p); + tmp ^=3D AX_VLAN_CONTROL_VFE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, &t= mp); + if (features & NETIF_F_HW_VLAN_CTAG_FILTER) { + for (int i =3D 0; i < 256; i++) { + u16 tmp16 =3D 0; + /* Address */ + tmp =3D i; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_ADDRESS, + 1, 1, &tmp); + /* Data */ + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_DATA0, + 2, 2, &tmp16); + tmp =3D AX_VLAN_CONTROL_WE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, + 1, 1, &tmp); + } + } + } + + if (changed & NETIF_F_HW_VLAN_CTAG_RX) { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, &tm= p); + tmp ^=3D AX_VLAN_CONTROL_VSO; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL, 1, 1, &t= mp); } =20 return 0; @@ -1333,6 +1418,8 @@ static const struct net_device_ops ax88179_netdev_ops= =3D { .ndo_eth_ioctl =3D usbnet_mii_ioctl, .ndo_set_rx_mode =3D ax88179_set_multicast, .ndo_set_features =3D ax88179_set_features, + .ndo_vlan_rx_add_vid =3D ax179a_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid =3D ax179a_vlan_rx_kill_vid, }; =20 static int ax88179_check_eeprom(struct usbnet *dev) --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 970613B4E88; Fri, 24 Jul 2026 07:37:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878625; cv=none; b=Bp/dHpbFE/iLffGy9gmtooeJUkW/aQkNVg0v8FKhXsQ51Ojn+U7w/NkE0PhkqDCc1T/ZRHtR18JQeGllv4WdgP1pdRZ6u0RhG9xL2qA1mwuUT3BQiJpE4bHcKbXQWvI84U8sU14DDv+Bb+sTvb6GBRLSNlEvDMq/EWhLzUx0xAQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878625; c=relaxed/simple; bh=XLqTh+EKqLwqHVaL78vW5c6DtoEBej9pbGdKMEgmVq0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DU2TMlvOkS9b1AZhWXpjK4v7NQ0tfQF3W6hS1IzWnZ71Gvyr6V+pRf6J+7hbnth3wPt7+YkTvh1lhRDGegeODixBoPWMD+d9X5/Q3Tz9uOuhX6bl6TjpoGoRlm/PF/pa+0OEySMW+iFUpP9GfyLV7mzDSBwiu9NF3/bUs1hinc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=c+8uCjRj; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=21e2eGm8; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="c+8uCjRj"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="21e2eGm8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878621; bh=XLqTh+EKqLwqHVaL78vW5c6DtoEBej9pbGdKMEgmVq0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=c+8uCjRj01AN9MpwGyGuu6Y9mUdryrTb9Sd5XS9Hz1MwOKt6Zj/ZJtKR8mss51oAz L15P2Q5W7dbCp9IKmsOYjZOy6Q1HR5DxZIj20wUSjK9gL1tYgiMTZsXKR2gvX3nztf XAsRZNj83hjxJ87IUjCHWw4Kqsp/Jy2HwoRTwyNrRSN46R1fuU1xGmMgZ1J3fnij6F +lEYEJDQ2SjM8qGxJ4CXeuOrH8XADx+NOrRwp1lb32Z6Wd+oCqHAHTsUJItkgfdbfA L30lvBQ/51RwHYtzV7N61/evXKXIomlxGFRuo1kZVXFfnN9wK7g50xFSrlN8MzhkWl D/JmRrUYKycMA== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id B93F74946B; Fri, 24 Jul 2026 07:37:01 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878609; bh=XLqTh+EKqLwqHVaL78vW5c6DtoEBej9pbGdKMEgmVq0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=21e2eGm88z3Cea0BB/lmBWAuHtlCHIp9o9A4wlueqFglsoIirYLKQphUG0PSliF3s 8fkXqeEw2ZH/oDTQW+1vbEHvJ7xOMjcdzxawA1yC3CJMvraGHsptqHXY41l/+RFE3P u1cv1yGcMz1a1YFtqyhTQQZk+8zMKBXBSwEaaev0hsmY/zDI4UFZRAoM0iKLPvtvIC j7QDr4WN3SnEFYM5/AeM16yh9m2lqiAx7e/Uvz05jqwV7emxykmmegy0YQdbcxpmNI UvqRrvS/uhNZzNaPPlt0gJHC6B+EfBNRS7cppFE1bq1jbILTQyGrwWpDaCZrMyneSB HQbmCTGzYQYPg== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id 6BC54493BD; Fri, 24 Jul 2026 07:36:49 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:53 +0200 Subject: [PATCH net-next v3 10/13] ax88179_178a: Add ethtool get_drvinfo 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: quoted-printable Message-Id: <20260724-ax88179a-v3-10-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 Add ax88179_get_drvinfo() as implementation of get_drvinfo, in order to provide information about the device firmware. Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index d8617dad5990f38d39b4569a6347e219856c6f2a..ae07bd1cf5eb1b15a089b3f67d2= f89cf56c10f8f 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -827,6 +827,21 @@ static void ax88179_disconnect(struct usb_interface *i= ntf) usbnet_disconnect(intf); } =20 +static void ax88179_get_drvinfo(struct net_device *net, struct ethtool_drv= info *info) +{ + struct usbnet *dev =3D netdev_priv(net); + struct ax88179_data *priv =3D dev->driver_priv; + + /* Inherit standard device info */ + usbnet_get_drvinfo(net, info); + if (priv->chip_version < AX_VERSION_AX88179A) + return; + + snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d.%d", + priv->fw_version[0], priv->fw_version[1], + priv->fw_version[2], priv->fw_version[3]); +} + static void ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) { @@ -1184,6 +1199,7 @@ static int ax88179_set_eee(struct net_device *net, st= ruct ethtool_keee *edata) } =20 static const struct ethtool_ops ax88179_ethtool_ops =3D { + .get_drvinfo =3D ax88179_get_drvinfo, .get_link =3D ethtool_op_get_link, .get_msglevel =3D usbnet_get_msglevel, .set_msglevel =3D usbnet_set_msglevel, --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 D920E3AE71E; Fri, 24 Jul 2026 07:37:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878626; cv=none; b=b4RAll+KjVuF6u+d5PRoS3x2tB/NYWx+KCs0wGCViWr4FvzXStSRwkdcXI4uzThOJbzgA7kARx6J6fNnF1w7MfbmxSMO6gsbZXMpiJsmhAzz71RF/Ti5kgRrsN//CsgVD5bvf9yFdSK51YZRbDX4E+19WMySw3G0J+8L8uxKv1A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878626; c=relaxed/simple; bh=i7LmyMhtu4hXYIf0Axfzf2NNZgFwjVFEAkQQi6jrUkk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Z+xZctCkBJx+nwEWbWbKxyniTRGthCCAaejK5FQdXa9eMNOia/MYWVpx+h1GEB8GmoC555c8xVsb2ITBWnu44+89F8bIiXT41qsvXMti/P6hgtyb+icGXLqZC4cZzThws8BPCMsQOcGukUcfKN1cNakEikpksreAPRUu96RES8w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=XaCtmoEa; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=dQ7Ggtzc; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="XaCtmoEa"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="dQ7Ggtzc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878622; bh=i7LmyMhtu4hXYIf0Axfzf2NNZgFwjVFEAkQQi6jrUkk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=XaCtmoEaao7kQNGBnVAcWbcWYCaghgyHYYyAFNiKKydm4ZpvvKT3s+KjO5GG6oF0D T3VXEH4Lk5VVPkbDrMtEZWyqKap8A57iIbJktBnmHw2cJ2ZZFsTuE5fXTC3rIS7c27 PIHXb5aPxQExg9YYvuMYGTpbOWaB0QjTl41kBCACboDFcN/cD1C/behQ7eq+HNO2PP Dhhv27OMmKj32zwWL2YYVo3/yAJ9cMOQxpKvYvJHlvfVzMAEYFZqW4S0pIvDpRICJ3 x7sdR+TtFZoEly8K45p8UonwD7lNBXHLG4p+TEjuXD56FkCKT6w8mxt8B+gNvyEyqI dwI7FJ7PvVrLA== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 2F03649374; Fri, 24 Jul 2026 07:37:02 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878609; bh=i7LmyMhtu4hXYIf0Axfzf2NNZgFwjVFEAkQQi6jrUkk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dQ7GgtzcxudiToLVTpU3Ee13aPov3tczOEJXqNHpkFa5sKLJsUSiJCaQuzJ9GMO3M JulNyl47MstVMzARhXe+GtOhoY1eQ0NJC1CUi0WxcYQ35yrvkibsDHPQ52JhFCGP/B /4hev1Jm5n/PCQjObMkAV1i2eTiMgFHuNd7R8TOx5Lm56mPaDXWXEaLqnveZ3m4XJY WRD9REEnLw1Ugo1onPW9ppNVy80uAPo/yoQlTsxQNJbshTeu5F73MgY2pvma/S/fwU 0gktKDoHBfhD/PNogW6n4BxHHqQKES9hMbw2czI5ml3PwiKVxrZMmhd8dBc03plV6h QGCL9jh/wIgNw== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id B1AC04931C; Fri, 24 Jul 2026 07:36:49 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:54 +0200 Subject: [PATCH net-next v3 11/13] ax88179_178a: Add support for AX88179A/772D/279 EEPROM access 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: quoted-printable Message-Id: <20260724-ax88179a-v3-11-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 The AX88179A/772D devices have 32 efuses with 20 bytes each, which can be randomly programmed. The AX88279 has 16K FLASH. Provide ethtool read capability for these devices. However, no write access is provided. Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 74 +++++++++++++++++++++++++++++++++-----= ---- 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index ae07bd1cf5eb1b15a089b3f67d2f89cf56c10f8f..2b3393e7a3b2221b85bfb7c7b6b= 7ea6d92fc1deb 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -18,6 +18,8 @@ =20 #define AX88179_PHY_ID 0x03 #define AX_EEPROM_LEN 0x100 +#define AX88279_EEPROM_LEN 0x4000 +#define AX88179A_EEPROM_LEN (32 * 20) #define AX88179_EEPROM_MAGIC 0x17900b95 #define AX_MCAST_FLTSIZE 8 #define AX_MAX_MCAST 64 @@ -38,6 +40,8 @@ #define AX_FW_MODE 0x08 #define AX_GPHY_CTL 0x0F #define AX88179A_FLASH_READ 0x21 +#define AX88179A_FLASH_WEN 0x22 +#define AX88179A_FLASH_WDIS 0x23 #define AX88179A_FLASH_WRITE 0x24 #define AX88179A_PHY_CLAUSE45 0x27 #define AX88179A_FLASH_ERASE_SECTION 0x28 @@ -868,41 +872,74 @@ ax88179_set_wol(struct net_device *net, struct ethtoo= l_wolinfo *wolinfo) =20 static int ax88179_get_eeprom_len(struct net_device *net) { - return AX_EEPROM_LEN; + struct usbnet *dev =3D netdev_priv(net); + struct ax88179_data *ax179_data; + + ax179_data =3D dev->driver_priv; + + if (ax179_data->chip_version < AX_VERSION_AX88179A) + return AX_EEPROM_LEN; + else if (ax179_data->chip_version >=3D AX_VERSION_AX88279) + return AX88279_EEPROM_LEN; + else + return AX88179A_EEPROM_LEN; } =20 -static int -ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, - u8 *data) +static void +ax88179_eeprom_access_params(struct ax88179_data *ax179_data, int i, u16 *= value, u16 *idx) +{ + /* AX88179 has a word-addressable EEPROM + * AX88179A uses EFUSES with 20 bytes length + * AX88279 has an EEPROM addressable in 256 byte blocks + */ + if (ax179_data->chip_version < AX_VERSION_AX88179A) { + *value =3D i; + *idx =3D 1; + } else if (ax179_data->chip_version >=3D AX_VERSION_AX88279) { + *value =3D (i * ax179_data->eeprom_block) >> 16; + *idx =3D (i * ax179_data->eeprom_block) & 0xffff; + } else { + *value =3D i << 4; + *idx =3D 0; + } +} + +static int ax88179_get_eeprom(struct net_device *net, struct ethtool_eepro= m *eeprom, u8 *data) { struct usbnet *dev =3D netdev_priv(net); - u16 *eeprom_buff; - int first_word, last_word; - int i, ret; + struct ax88179_data *ax179_data; + int first, last, i, ret; + u8 *eeprom_buff; + + ax179_data =3D dev->driver_priv; =20 if (eeprom->len =3D=3D 0) return -EINVAL; =20 eeprom->magic =3D AX88179_EEPROM_MAGIC; =20 - first_word =3D eeprom->offset >> 1; - last_word =3D (eeprom->offset + eeprom->len - 1) >> 1; - eeprom_buff =3D kmalloc_array(last_word - first_word + 1, sizeof(u16), - GFP_KERNEL); + first =3D eeprom->offset / ax179_data->eeprom_block; + last =3D (eeprom->offset + eeprom->len - 1) / ax179_data->eeprom_block; + + eeprom_buff =3D kzalloc((last - first + 1) * ax179_data->eeprom_block, GF= P_KERNEL); if (!eeprom_buff) return -ENOMEM; =20 - /* ax88179/178A returns 2 bytes from eeprom on read */ - for (i =3D first_word; i <=3D last_word; i++) { - ret =3D __ax88179_read_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2, - &eeprom_buff[i - first_word]); + for (i =3D first; i <=3D last; i++) { + u16 value, idx; + + ax88179_eeprom_access_params(ax179_data, i, &value, &idx); + ret =3D __ax88179_read_cmd(dev, ax179_data->eeprom_read_cmd, + value, idx, ax179_data->eeprom_block, + eeprom_buff + (i - first) * ax179_data->eeprom_block); + if (ret < 0) { kfree(eeprom_buff); return -EIO; } } =20 - memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); + memcpy(data, eeprom_buff + eeprom->offset % ax179_data->eeprom_block, eep= rom->len); kfree(eeprom_buff); return 0; } @@ -912,12 +949,17 @@ ax88179_set_eeprom(struct net_device *net, struct eth= tool_eeprom *eeprom, u8 *data) { struct usbnet *dev =3D netdev_priv(net); + struct ax88179_data *ax179_data; u16 *eeprom_buff; int first_word; int last_word; int ret; int i; =20 + ax179_data =3D dev->driver_priv; + if (ax179_data->chip_version >=3D AX_VERSION_AX88179A) + return -EOPNOTSUPP; + netdev_dbg(net, "write EEPROM len %d, offset %d, magic 0x%x\n", eeprom->len, eeprom->offset, eeprom->magic); =20 --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 BA5D13B4EB3; Fri, 24 Jul 2026 07:37:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878625; cv=none; b=U/WNasM67xPrjsh6m+itZKMxxdMquQJQK0oSw/TA6SDziTQNbC4Z9a4be3sS3QGKGxQQcGKTp3ARyrhZtWQ60Dcr7GynbVSec8YHcPkN4sl3bfV/+MLhOZwDD1jutaG9THFKwmAf+xjN+OzEQETQMNT5k1SOWXBj4S2xp9F56UA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878625; c=relaxed/simple; bh=hs6vOWcxq7NhNoT6wlrBwY/rtSOqSM4YClhCh6PJk8M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OYxlZKIP47tUNcnfftpaD61mVBfsA+KCq2vS4Jx6QLEgavujqKq+E5IvBIw3HUb1spnAGpo2AegAW8zsY+CogglPn3yDMLgUWT6dUMqPCuIbHStn0WoUZlfnd67wqcetEyY0K/sWYTo7Qn/H1tHqy0p6MMWNI71v08C6+1prVbQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=E2ZBBECc; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=Xvogqmj1; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="E2ZBBECc"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="Xvogqmj1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878622; bh=hs6vOWcxq7NhNoT6wlrBwY/rtSOqSM4YClhCh6PJk8M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=E2ZBBECc17jpQyXjfW7AJ1jwdw8Z0K9PRIEANMA45QTVa10vZ912oHz44vT998i/2 xZPlE9q0zhBbzm2+k5ItJqw8eSJZoVEiFVE6hn6GQDMdj6/Yj05COlSBMnyi2PrafF rTJLbl9E0EdCtCKETk96Zm/Wz2xoIP05l5zC1mE5gkrz2hS4UVde7RHVjGkmNJdb3n Qa++/abipzRhMrC7IyXD964s99z1PQXQ69DAImNWufG7kzXd7/Mn2ACzN3LfqAngH5 D56w8PTtlf8GYbap+zhnz1mw1OYo5vzUXmez7PwFWoePBVMW2i9gdjnTufiBGnFC25 dzpG6t1b4otRA== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 1C37749367; Fri, 24 Jul 2026 07:37:02 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878610; bh=hs6vOWcxq7NhNoT6wlrBwY/rtSOqSM4YClhCh6PJk8M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Xvogqmj1L9EdzITzhlG5L1pKVbKCZ6IKmTi0nhwTWFp0F7nG7lKPK577k+GdAk8q1 lcgb5tCYfLy5a7vxEcJH++ST+Og642nHd+aavlYNDn8G67FlE6vEQ85h73S6HXIrHC E0s6rRhK/u1a+YYIeBob2Fpoe5HlS3flHV9B9c8R22YpmUmNjK4FxJxhGtc5Ob/FJS FlKxLcT088g1aV36nipBOLsS9+LvS6jzuDDXVMS3udiVJUO1HBKY25TcpUp2/ETtro Q/2q1qHOepgQoqJc6TT4+AZmj/fG4w4dTf5XkQRVScAe2MzJhOYn8pIup9Kf48MViM 0cpKyOVmqXXPg== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id 04547492F2; Fri, 24 Jul 2026 07:36:49 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:55 +0200 Subject: [PATCH net-next v3 12/13] ax88179_178a: Add AX179A/AX279 multicast configuration 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: quoted-printable Message-Id: <20260724-ax88179a-v3-12-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 Add support for conditionally setting the ip_alignement flag AX_RX_CTL_IPE in AX_RX_CTL and make sure that AX_RX_CTL_DROPCRCERR is also set to be consistent with the initial configuration in ax88179_reset() Signed-off-by: Birger Koblitz --- drivers/net/usb/ax88179_178a.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 2b3393e7a3b2221b85bfb7c7b6b7ea6d92fc1deb..1e63d40de84364559a01d1fc02a= 652fcb7fa57e9 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1319,10 +1319,14 @@ static int ax179a_vlan_rx_add_vid(struct net_device= *net, __be16 proto, u16 vid) static void ax88179_set_multicast(struct net_device *net) { struct usbnet *dev =3D netdev_priv(net); - struct ax88179_data *data =3D dev->driver_priv; u8 *m_filter =3D ((u8 *)dev->data); + struct ax88179_data *data; + + data =3D dev->driver_priv; =20 - data->rxctl =3D (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE); + data->rxctl =3D (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_DROPCRCERR); + if (data->ip_align) + data->rxctl |=3D AX_RX_CTL_IPE; =20 if (net->flags & IFF_PROMISC) { data->rxctl |=3D AX_RX_CTL_PRO; --=20 2.47.3 From nobody Fri Jul 24 21:53:35 2026 Received: from bkemail.birger-koblitz.de (bkemail.birger-koblitz.de [23.88.97.239]) (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 CC85D3AEB2C; Fri, 24 Jul 2026 07:37:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=23.88.97.239 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878626; cv=none; b=UiFHUSB99P18zFELaPgiD+epwljy9p081kTmX6YdjU+GKMwf/rD5S+lgi/oaSyMZZGKTFWCaaLi0Pui+D+1ux83tnfoYXM7sLHZDvjCzz97uvWf6T0rin/T9FBrErw3HVU2ayrW5CfkcEurTbDBbHqkPWNq35A214FTGthpRtL0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784878626; c=relaxed/simple; bh=9hXaUqAEnt4o0EVeojsZR48KTcFJGOU0N7L3b7+WX7g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=E+FCLoV29d3ODh7Etq7dKnPUZqkFW4b2nNT2574teCbiDU5HG+jHB/QUF12TgY2jQ8El16ZY5U7EbSQOKCUNUdPZEijJQhOcxkhELj+3g4i3n/XuI7euJUUZF0pZPZsIdqNYp79awgwCNZeiFRHvGWBFWOPKkHdveI85GGuwf8I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de; spf=pass smtp.mailfrom=birger-koblitz.de; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=y+gAcOAK; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b=M+nJ8psV; arc=none smtp.client-ip=23.88.97.239 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=birger-koblitz.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="y+gAcOAK"; dkim=pass (2048-bit key) header.d=birger-koblitz.de header.i=@birger-koblitz.de header.b="M+nJ8psV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878623; bh=9hXaUqAEnt4o0EVeojsZR48KTcFJGOU0N7L3b7+WX7g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=y+gAcOAK3r2P0RMJCMXiBkETn0QTQa0P+C9g8tBMvQkZDwof4NICtvFMaaz3LzaDZ peZryjhPxQHla8glbwCkRYt0NGVImBFtlKzDwiBRA3yu9XfIaYkl9EDJKWLVPXFxUn YuM/QQDCixaWlk+0vourtfvctK822iGf75FGxm3PU2fU6RWlRrq+tbVX8ingp707pt agkEdDOknbkbVE2AmGMxpPyELgKWWdMiG6qI8diIXu0dHTiCNOCDD+wLWNc0HbSny8 oPXtn0LY1LvT5DZTPXo55kT9FArDsNahPjKzpBw4XNERE2tpx3rnNuX2Ob5H9U97rl co+brK+YqYflw== Received: by bkemail.birger-koblitz.de (Postfix, from userid 109) id 35382492F2; Fri, 24 Jul 2026 07:37:03 +0000 (UTC) X-Spam-Level: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=birger-koblitz.de; s=default; t=1784878610; bh=9hXaUqAEnt4o0EVeojsZR48KTcFJGOU0N7L3b7+WX7g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=M+nJ8psV25oZYFzTpAZ7M/ayi+EPb1thElMbl6WCUUJjgBFrLHO+t6ynRluWWrXnR m3UMBrScTfUQHeMiQd+nlWjwk4BPQrfKp+c0e4G7DkfgDAEygg7jNcPmjnYfcg4Fdk F6cbVZOzclzSdhiTCApKezrt012JVS6Rj/nga1wh1zCloDiszl+FyjlJHIBcVcfWCC NjNg9ujJrWwl4LsG6W78cgy7OeGweK0b95qb5IhZKP9u4D5giHsEjA/D0Kl28DJEvR EAvx3Su3cXQ9XcwJWYqcW4zdat7Ar3cpNui7dKQv3gFv+MM6VeOmLKjFSWgcQvEJKo dmy41Eb7QlLWQ== Received: from DebianDesktop.lan (p200300c69f1c3c00ecd187824fbc6faf.dip0.t-ipconnect.de [IPv6:2003:c6:9f1c:3c00:ecd1:8782:4fbc:6faf]) by bkemail.birger-koblitz.de (Postfix) with ESMTPSA id 4A5CE49293; Fri, 24 Jul 2026 07:36:50 +0000 (UTC) From: Birger Koblitz Date: Fri, 24 Jul 2026 09:36:56 +0200 Subject: [PATCH net-next v3 13/13] ax88796b: Add support for AX88772D, AX88179A and AX88279 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: quoted-printable Message-Id: <20260724-ax88179a-v3-13-bdde4f905883@birger-koblitz.de> References: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> In-Reply-To: <20260724-ax88179a-v3-0-bdde4f905883@birger-koblitz.de> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , Andrew Lunn , Heiner Kallweit Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Birger Koblitz X-Mailer: b4 0.14.2 The AX88772D, AX88179A and AX88279 are 100MBit, 1GBit and respectively 2.5 GBit PHYs that are found in ASIX USB-Ethernet controllers of the same name. Signed-off-by: Birger Koblitz --- drivers/net/phy/ax88796b.c | 194 +++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 194 insertions(+) diff --git a/drivers/net/phy/ax88796b.c b/drivers/net/phy/ax88796b.c index f20ddf64914993f7097070d1f56c1103ec1e40e8..871771fea64c9624ff783690847= 36db83350c846 100644 --- a/drivers/net/phy/ax88796b.c +++ b/drivers/net/phy/ax88796b.c @@ -13,6 +13,19 @@ #define PHY_ID_ASIX_AX88772A 0x003b1861 #define PHY_ID_ASIX_AX88772C 0x003b1881 #define PHY_ID_ASIX_AX88796B 0x003b1841 +#define PHY_ID_ASIX_AX88772D 0x003b772d +#define PHY_ID_ASIX_AX88179A 0x003b179a +#define PHY_ID_ASIX_AX88279 0x003b2790 + +#define AX_ADVERTISE_2500 0x1000 + +/* MII Vendor registers */ +#define AX_CTRL_STATUS 0x1d +#define AX_CTRL_STATUS_SPEED_MASK 0x0c +#define AX_CTRL_STATUS_SPEED_10 0x0 +#define AX_CTRL_STATUS_SPEED_100 0x4 +#define AX_CTRL_STATUS_SPEED_1000 0x8 +#define AX_CTRL_STATUS_SPEED_2500 0xc =20 MODULE_DESCRIPTION("Asix PHY driver"); MODULE_AUTHOR("Michael Schmitz "); @@ -83,6 +96,137 @@ static int asix_ax88772a_read_status(struct phy_device = *phydev) return 0; } =20 +static int asix_ax88279_read_status(struct phy_device *phydev) +{ + int ret, val; + + ret =3D genphy_update_link(phydev); + if (ret) + return ret; + + phydev->master_slave_get =3D MASTER_SLAVE_CFG_UNSUPPORTED; + phydev->master_slave_state =3D MASTER_SLAVE_STATE_UNSUPPORTED; + phydev->speed =3D SPEED_UNKNOWN; + phydev->duplex =3D DUPLEX_UNKNOWN; + phydev->pause =3D 0; + phydev->asym_pause =3D 0; + phydev->rate_matching =3D RATE_MATCH_PAUSE; + + if (!phydev->link) + return 0; + + ret =3D genphy_read_master_slave(phydev); + if (ret < 0) + return ret; + + ret =3D genphy_read_lpa(phydev); + if (ret < 0) + return ret; + + val =3D phy_read(phydev, MII_ADVERTISE); + if (val < 0) + return val; + + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + phydev->advertising, val & AX_ADVERTISE_2500); + + /* Read actual speed from vendor register */ + val =3D phy_read(phydev, AX_CTRL_STATUS); + switch (val & AX_CTRL_STATUS_SPEED_MASK) { + case AX_CTRL_STATUS_SPEED_2500: + phydev->speed =3D SPEED_2500; + break; + case AX_CTRL_STATUS_SPEED_1000: + phydev->speed =3D SPEED_1000; + break; + case AX_CTRL_STATUS_SPEED_100: + phydev->speed =3D SPEED_100; + break; + case AX_CTRL_STATUS_SPEED_10: + phydev->speed =3D SPEED_10; + } + + /* MDIO_AN_10GBT_STAT_LP2_5G is broken, but we can deduce that + * the link-partner advertised 2500M if remotely AN succceded + * for link speed > 1000M and we locally have a link speed of + * 2500M + */ + val =3D phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); + if (val >=3D 0 && val & MDIO_AN_10GBT_STAT_REMOK) { + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + phydev->lp_advertising, + phydev->speed =3D=3D SPEED_2500); + } + /* Only supports full duplex */ + phydev->duplex =3D DUPLEX_FULL; + + return 0; +} + +static int asix_ax88279_config_aneg(struct phy_device *phydev) +{ + bool changed =3D false; + int ret; + u32 adv; + + if (phydev->autoneg =3D=3D AUTONEG_DISABLE) { + phydev_warn(phydev, "Disabling autoneg is not supported\n"); + return -EINVAL; + } + + adv =3D linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising); + + ret =3D phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, + MDIO_AN_10GBT_CTRL_ADV2_5G, adv); + if (ret < 0) + return ret; + if (ret > 0) + changed =3D true; + + return __genphy_config_aneg(phydev, changed); +} + +static int asix_ax88279_get_features(struct phy_device *phydev) +{ + int ret; + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) =3D {}; + + /* MDIO_DEVS1/2 empty, so set mmds_present bits to allow reading abilitie= s */ + phydev->c45_ids.mmds_present |=3D MDIO_DEVS_PMAPMD | MDIO_DEVS_AN; + + linkmode_set_bit_array(phy_basic_ports_array, ARRAY_SIZE(phy_basic_ports_= array), + phydev->supported); + + ret =3D genphy_c45_pma_read_abilities(phydev); + if (ret < 0) + return ret; + + /* AX88279 does not support reported 100baseT-half duplex mode */ + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask); + linkmode_andnot(phydev->supported, phydev->supported, mask); + + return 0; +} + +/* AX88179A-based PHYs cannot access MMD registers via MII_MMD_CTRL/MII_MM= D_DATA + * Make sure to use c45 access instead. + */ +static int asix_read_mmd(struct phy_device *phydev, int devnum, u16 reg) +{ + struct mii_bus *bus =3D phydev->mdio.bus; + int addr =3D phydev->mdio.addr; + + return __mdiobus_c45_read(bus, addr, devnum, reg); +} + +static int asix_write_mmd(struct phy_device *phydev, int devnum, u16 reg, = u16 val) +{ + struct mii_bus *bus =3D phydev->mdio.bus; + int addr =3D phydev->mdio.addr; + + return __mdiobus_c45_write(bus, addr, devnum, reg, val); +} + static void asix_ax88772a_link_change_notify(struct phy_device *phydev) { /* Reset PHY, otherwise MII_LPA will provide outdated information. @@ -94,6 +238,25 @@ static void asix_ax88772a_link_change_notify(struct phy= _device *phydev) } } =20 +static int asix_ax88772D_get_features(struct phy_device *phydev) +{ + int ret; + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) =3D {}; + + /* MDIO_DEVS1/2 empty, so set mmds_present bits to allow reading abilitie= s */ + phydev->c45_ids.mmds_present |=3D MDIO_DEVS_PMAPMD | MDIO_DEVS_AN; + + ret =3D genphy_read_abilities(phydev); + if (ret < 0) + return ret; + + /* AX88772D does not support reported 1000baseT mode */ + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, mask); + linkmode_andnot(phydev->supported, phydev->supported, mask); + + return 0; +} + static struct phy_driver asix_driver[] =3D { { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772A), @@ -111,6 +274,34 @@ static struct phy_driver asix_driver[] =3D { .suspend =3D genphy_suspend, .resume =3D genphy_resume, .soft_reset =3D asix_soft_reset, +}, { + PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772D), + .name =3D "Asix Electronics AX88772D", + .flags =3D PHY_IS_INTERNAL, + .get_features =3D asix_ax88772D_get_features, + .read_mmd =3D asix_read_mmd, + .write_mmd =3D asix_write_mmd, + .suspend =3D genphy_suspend, + .resume =3D genphy_resume, +}, { + PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88179A), + .name =3D "Asix Electronics AX88179A", + .flags =3D PHY_IS_INTERNAL, + .suspend =3D genphy_suspend, + .resume =3D genphy_resume, + .read_mmd =3D asix_read_mmd, + .write_mmd =3D asix_write_mmd, +}, { + PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88279), + .name =3D "Asix Electronics AX88279", + .flags =3D PHY_IS_INTERNAL, + .get_features =3D asix_ax88279_get_features, + .read_status =3D asix_ax88279_read_status, + .config_aneg =3D asix_ax88279_config_aneg, + .read_mmd =3D asix_read_mmd, + .write_mmd =3D asix_write_mmd, + .suspend =3D genphy_suspend, + .resume =3D genphy_resume, }, { PHY_ID_MATCH_MODEL(PHY_ID_ASIX_AX88796B), .name =3D "Asix Electronics AX88796B", @@ -124,6 +315,9 @@ static const struct mdio_device_id __maybe_unused asix_= tbl[] =3D { { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772A) }, { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772C) }, { PHY_ID_MATCH_MODEL(PHY_ID_ASIX_AX88796B) }, + { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88772D) }, + { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88179A) }, + { PHY_ID_MATCH_EXACT(PHY_ID_ASIX_AX88279) }, { } }; =20 --=20 2.47.3