// SPDX-License-Identifier: GPL-2.0+
/*
* Marvell 10G 88x3310 PHY driver
*
* Based upon the ID registers, this PHY appears to be a mixture of IPs
* from two different companies.
*
* There appears to be several different data paths through the PHY which
* are automatically managed by the PHY. The following has been determined
* via observation and experimentation for a setup using single-lane Serdes:
*
* SGMII PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for <= 1G)
* 10GBASE-KR PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for 10G)
* 10GBASE-KR PHYXS -- BASE-R PCS -- Fiber
*
* With XAUI, observation shows:
*
* XAUI PHYXS -- <appropriate PCS as above>
*
* and no switching of the host interface mode occurs.
*
* If both the fiber and copper ports are connected, the first to gain
* link takes priority and the other port is completely locked out.
*/
#include <linux/bitfield.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/hwmon.h>
#include <linux/marvell_phy.h>
#include <linux/phy.h>
#include <linux/sfp.h>
#include <linux/netdevice.h>
#define MV_PHY_ALASKA_NBT_QUIRK_MASK 0xfffffffe
#define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
#define MV_VERSION(a,b,c,d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
enum {
MV_PMA_FW_VER0 = 0xc011,
MV_PMA_FW_VER1 = 0xc012,
MV_PMA_21X0_PORT_CTRL = 0xc04a,
MV_PMA_21X0_PORT_CTRL_SWRST = BIT(15),
MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK = 0x7,
MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII = 0x0,
MV_PMA_2180_PORT_CTRL_MACTYPE_DXGMII = 0x1,
MV_PMA_2180_PORT_CTRL_MACTYPE_QXGMII = 0x2,
MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER = 0x4,
MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN = 0x5,
MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
MV_PMA_BOOT = 0xc050,
MV_PMA_BOOT_FATAL = BIT(0),
MV_PCS_BASE_T = 0x0000,
MV_PCS_BASE_R = 0x1000,
MV_PCS_1000BASEX = 0x2000,
MV_PCS_CSCR1 = 0x8000,
MV_PCS_CSCR1_ED_MASK =