// SPDX-License-Identifier: GPL-2.0+
/*
* drivers/net/phy/micrel.c
*
* Driver for Micrel PHYs
*
* Author: David J. Choi
*
* Copyright (c) 2010-2013 Micrel, Inc.
* Copyright (c) 2014 Johan Hovold <johan@kernel.org>
*
* Support : Micrel Phys:
* Giga phys: ksz9021, ksz9031, ksz9131
* 100/10 Phys : ksz8001, ksz8721, ksz8737, ksz8041
* ksz8021, ksz8031, ksz8051,
* ksz8081, ksz8091,
* ksz8061,
* Switch : ksz8873, ksz886x
* ksz9477
*/
#include <linux/bitfield.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/micrel_phy.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/delay.h>
/* Operation Mode Strap Override */
#define MII_KSZPHY_OMSO 0x16
#define KSZPHY_OMSO_FACTORY_TEST BIT(15)
#define KSZPHY_OMSO_B_CAST_OFF BIT(9)
#define KSZPHY_OMSO_NAND_TREE_ON BIT(5)
#define KSZPHY_OMSO_RMII_OVERRIDE BIT(1)
#define KSZPHY_OMSO_MII_OVERRIDE BIT(0)
/* general Interrupt control/status reg in vendor specific block. */
#define MII_KSZPHY_INTCS 0x1B
#define KSZPHY_INTCS_JABBER BIT(15)
#define KSZPHY_INTCS_RECEIVE_ERR BIT(14)
#define KSZPHY_INTCS_PAGE_RECEIVE BIT(13)
#define KSZPHY_INTCS_PARELLEL BIT(12)
#define KSZPHY_INTCS_LINK_PARTNER_ACK BIT(11)
#define KSZPHY_INTCS_LINK_DOWN BIT(10)
#define KSZPHY_INTCS_REMOTE_FAULT BIT(9)
#define KSZPHY_INTCS_LINK_UP BIT(8)
#define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\
KSZPHY_INTCS_LINK_DOWN)
/* PHY Control 1 */
#define MII_KSZPHY_CTRL_1 0x1e
/* PHY Control 2 / PHY Control (if no PHY Control 1) */
#define MII_KSZPHY_CTRL_2 0x1f
#define MII_KSZPHY_CTRL MII_KSZPHY_CTRL_2
/* bitmap of PHY register to set interrupt mode */
#define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9)
#define KSZPHY_RMII_REF_CLK_SEL BIT(7)
/* Write/read to/from extended registers */
#define MII_KSZPHY_EXTREG 0x0b
#define KSZPHY_EXTREG_WRITE 0x8000
#define MII_KSZPHY_EXTREG_WRITE 0x0c
#define MII_KSZPHY_EXTREG_READ 0x0d
/* Extended registers */
#define MII_KSZPHY_CLK_CONTROL_PAD_SKEW 0x104
#define MII_KSZPHY_RX_DATA_PAD_SKEW 0x105
#define MII_KSZPHY_TX_DATA_PAD_SKEW 0x106
#define PS_TO_REG 200
struct kszphy_hw_stat {
const char *string;
u8 reg;
u8 bits;
};
static struct kszphy_hw_stat kszphy_hw_stats[] = {
{ "phy_receive_errors", 21, 16},
{ "phy_idle_errors", 10, 8 },
};
struct kszphy_type {
u32 led_mode_reg;
u16 interrupt_level_mask;
bool has_broadcast_disable;
bool has_nand_tree_disable;
bool has_rmii_ref_clk_sel;
};
struct kszphy_priv {
const struct kszphy_type *type;
int led_mode;
bool rmii_ref_clk_sel;
bool rmii_ref_clk_sel_val;
u64 stats[ARRAY_SIZE(kszphy_hw_stats)];
};
static const