uboot/drivers/net/phy/micrel_ksz8xxx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Micrel PHY drivers
   4 *
   5 * Copyright 2010-2011 Freescale Semiconductor, Inc.
   6 * author Andy Fleming
   7 * (C) 2012 NetModule AG, David Andrey, added KSZ9031
   8 */
   9#include <common.h>
  10#include <dm.h>
  11#include <errno.h>
  12#include <fdtdec.h>
  13#include <micrel.h>
  14#include <phy.h>
  15
  16static struct phy_driver KSZ804_driver = {
  17        .name = "Micrel KSZ804",
  18        .uid = 0x221510,
  19        .mask = 0xfffff0,
  20        .features = PHY_BASIC_FEATURES,
  21        .config = &genphy_config,
  22        .startup = &genphy_startup,
  23        .shutdown = &genphy_shutdown,
  24};
  25
  26#define MII_KSZPHY_OMSO         0x16
  27#define KSZPHY_OMSO_FACTORY_TEST BIT(15)
  28#define KSZPHY_OMSO_B_CAST_OFF  (1 << 9)
  29
  30static int ksz_genconfig_bcastoff(struct phy_device *phydev)
  31{
  32        int ret;
  33
  34        ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO);
  35        if (ret < 0)
  36                return ret;
  37
  38        ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO,
  39                        ret | KSZPHY_OMSO_B_CAST_OFF);
  40        if (ret < 0)
  41                return ret;
  42
  43        return genphy_config(phydev);
  44}
  45
  46static struct phy_driver KSZ8031_driver = {
  47        .name = "Micrel KSZ8021/KSZ8031",
  48        .uid = 0x221550,
  49        .mask = 0xfffff0,
  50        .features = PHY_BASIC_FEATURES,
  51        .config = &ksz_genconfig_bcastoff,
  52        .startup = &genphy_startup,
  53        .shutdown = &genphy_shutdown,
  54};
  55
  56/**
  57 * KSZ8051
  58 */
  59#define MII_KSZ8051_PHY_OMSO                    0x16
  60#define MII_KSZ8051_PHY_OMSO_NAND_TREE_ON       (1 << 5)
  61
  62static int ksz8051_config(struct phy_device *phydev)
  63{
  64        unsigned val;
  65
  66        /* Disable NAND-tree */
  67        val = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO);
  68        val &= ~MII_KSZ8051_PHY_OMSO_NAND_TREE_ON;
  69        phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO, val);
  70
  71        return genphy_config(phydev);
  72}
  73
  74static struct phy_driver KSZ8051_driver = {
  75        .name = "Micrel KSZ8051",
  76        .uid = 0x221550,
  77        .mask = 0xfffff0,
  78        .features = PHY_BASIC_FEATURES,
  79        .config = &ksz8051_config,
  80        .startup = &genphy_startup,
  81        .shutdown = &genphy_shutdown,
  82};
  83
  84static int ksz8081_config(struct phy_device *phydev)
  85{
  86        int ret;
  87
  88        ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO);
  89        if (ret < 0)
  90                return ret;
  91
  92        ret &= ~KSZPHY_OMSO_FACTORY_TEST;
  93
  94        ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO,
  95                        ret | KSZPHY_OMSO_B_CAST_OFF);
  96        if (ret < 0)
  97                return ret;
  98
  99        return genphy_config(phydev);
 100}
 101
 102static struct phy_driver KSZ8081_driver = {
 103        .name = "Micrel KSZ8081",
 104        .uid = 0x221560,
 105        .mask = 0xfffff0,
 106        .features = PHY_BASIC_FEATURES,
 107        .config = &ksz8081_config,
 108        .startup = &genphy_startup,
 109        .shutdown = &genphy_shutdown,
 110};
 111
 112/**
 113 * KSZ8895
 114 */
 115
 116static unsigned short smireg_to_phy(unsigned short reg)
 117{
 118        return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5);
 119}
 120
 121static unsigned short smireg_to_reg(unsigned short reg)
 122{
 123        return reg & 0x1F;
 124}
 125
 126static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val)
 127{
 128        phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE,
 129                                                smireg_to_reg(smireg), val);
 130}
 131
 132#if 0
 133static int ksz8895_read_smireg(struct phy_device *phydev, int smireg)
 134{
 135        return phydev->bus->read(phydev->bus, smireg_to_phy(smireg),
 136                                        MDIO_DEVAD_NONE, smireg_to_reg(smireg));
 137}
 138#endif
 139
 140int ksz8895_config(struct phy_device *phydev)
 141{
 142        /* we are connected directly to the switch without
 143         * dedicated PHY. SCONF1 == 001 */
 144        phydev->link = 1;
 145        phydev->duplex = DUPLEX_FULL;
 146        phydev->speed = SPEED_100;
 147
 148        /* Force the switch to start */
 149        ksz8895_write_smireg(phydev, 1, 1);
 150
 151        return 0;
 152}
 153
 154static int ksz8895_startup(struct phy_device *phydev)
 155{
 156        return 0;
 157}
 158
 159static struct phy_driver ksz8895_driver = {
 160        .name = "Micrel KSZ8895/KSZ8864",
 161        .uid  = 0x221450,
 162        .mask = 0xffffe1,
 163        .features = PHY_BASIC_FEATURES,
 164        .config   = &ksz8895_config,
 165        .startup  = &ksz8895_startup,
 166        .shutdown = &genphy_shutdown,
 167};
 168
 169/* Micrel used the exact same model number for the KSZ9021,
 170 * so the revision number is used to distinguish them.
 171 */
 172static struct phy_driver KS8721_driver = {
 173        .name = "Micrel KS8721BL",
 174        .uid = 0x221618,
 175        .mask = 0xfffffc,
 176        .features = PHY_BASIC_FEATURES,
 177        .config = &genphy_config,
 178        .startup = &genphy_startup,
 179        .shutdown = &genphy_shutdown,
 180};
 181
 182int ksz886x_config(struct phy_device *phydev)
 183{
 184        /* we are connected directly to the switch without
 185         * dedicated PHY. */
 186        phydev->link = 1;
 187        phydev->duplex = DUPLEX_FULL;
 188        phydev->speed = SPEED_100;
 189        return 0;
 190}
 191
 192static int ksz886x_startup(struct phy_device *phydev)
 193{
 194        return 0;
 195}
 196
 197static struct phy_driver ksz886x_driver = {
 198        .name = "Micrel KSZ886x Switch",
 199        .uid  = 0x00221430,
 200        .mask = 0xfffff0,
 201        .features = PHY_BASIC_FEATURES,
 202        .config = &ksz886x_config,
 203        .startup = &ksz886x_startup,
 204        .shutdown = &genphy_shutdown,
 205};
 206
 207int phy_micrel_ksz8xxx_init(void)
 208{
 209        phy_register(&KSZ804_driver);
 210        phy_register(&KSZ8031_driver);
 211        phy_register(&KSZ8051_driver);
 212        phy_register(&KSZ8081_driver);
 213        phy_register(&KS8721_driver);
 214        phy_register(&ksz8895_driver);
 215        phy_register(&ksz886x_driver);
 216        return 0;
 217}
 218