mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-29 16:18:09 -04:00
Add a driver for ADIN1140. The device is a 10BASE-T1S MAC-PHY (integrated in the same package) that connects to a CPU over an SPI bus, and implements the Open Alliance TC6 protocol for control and frame transfers. As such, this driver relies on oa_tc6 for the communication with the device. The device has an alternative name (AD3306), so the driver can be probed using one of the two compatible strings. For control transactions, ADIN1140 only implements the protected mode. The driver has a custom implementation for the mii_bus access methods as a workaround for hardware issues: 1. The OA TC6 standard defines the direct and indirect access modes for MDIO transactions. The ADIN1140 incorrectly advertises indirect mode only (supported capabilities register - 0x2, bit 9), while actually implementing just the direct mode. We cannot rely on the CAP register to choose an access method (which oa_tc6 does by default, even though it only implements the direct mode), so the driver has to use its own. 2. The ADIN1140 cannot access the C22 register space of the internal PHY, while the PHY is busy receiving frames. If that happens, the CONFIG0 and CONFIG2 registers of the MAC will get corrupted and the data transfer will stop. Those two registers configure settings for the transfer protocol between the MAC and host, so the value for some of their subfields shouldn't be changed while the netdev is up. Since we know the PHY is internal, the MAC driver can implement a custom mii_bus, which can intercept C22 accesses. Most of the registers mapped in the 0x0 - 0x3 range (the only ones the PHY offers) are read only, and their value can be read from somewhere else (e.g the PHYID 1 & 2 have the same value as 0x1 in the MAC memory map). For the fields that are R/W (loopback and AN/reset) in the control register, the PHY driver already implements the set_loopback() and config_aneg() functions. The C22 write function of the driver is a no-op and is used to protect against the ioctl MDIO access path. C45 accesses do not cause this issue, so we can properly implement them. Signed-off-by: Ciprian Regus <ciprian.regus@analog.com> Link: https://patch.msgid.link/20260708-adin1140-driver-v5-13-4aca7b51a58b@analog.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>