linux/drivers/net/mdio/mdio-bitbang.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Bitbanged MDIO support.
   4 *
   5 * Author: Scott Wood <scottwood@freescale.com>
   6 * Copyright (c) 2007 Freescale Semiconductor
   7 *
   8 * Based on CPM2 MDIO code which is:
   9 *
  10 * Copyright (c) 2003 Intracom S.A.
  11 *  by Pantelis Antoniou <panto@intracom.gr>
  12 *
  13 * 2005 (c) MontaVista Software, Inc.
  14 * Vitaly Bordug <vbordug@ru.mvista.com>
  15 */
  16
  17#include <linux/delay.h>
  18#include <linux/mdio-bitbang.h>
  19#include <linux/module.h>
  20#include <linux/types.h>
  21
  22#define MDIO_READ 2
  23#define MDIO_WRITE 1
  24
  25#define MDIO_C45 (1<<15)
  26#define MDIO_C45_ADDR (MDIO_C45 | 0)
  27#define MDIO_C45_READ (MDIO_C45 | 3)
  28#define MDIO_C45_WRITE (MDIO_C45 | 1)
  29
  30#define MDIO_SETUP_TIME 10
  31#define MDIO_HOLD_TIME 10
  32
  33/* Minimum MDC period is 400 ns, plus some margin for error.  MDIO_DELAY
  34 * is done twice per period.
  35 */
  36#define MDIO_DELAY 250
  37
  38/* The PHY may take up to 300 ns to produce data, plus some margin
  39 * for error.
  40 */
  41#define MDIO_READ_DELAY 350
  42
  43/* MDIO must already be configured as output. */
  44static void mdiobb_send_bit(struct mdiobb_ctrl *ctrl, int val)
  45{
  46        const struct mdiobb_ops *ops = ctrl->ops;
  47
  48        ops->set_mdio_data(ctrl, val);
  49        ndelay(MDIO_DELAY);
  50        ops->set_mdc(ctrl, 1);
  51        ndelay(MDIO_DELAY);
  52        ops->set_mdc(ctrl, 0);
  53}
  54
  55/* MDIO must already be configured as input. */
  56static int mdiobb_get_bit(struct mdiobb_ctrl *ctrl)
  57{
  58        const struct mdiobb_ops *ops = ctrl->ops;
  59
  60        ndelay(MDIO_DELAY);
  61        ops->set_mdc(ctrl, 1);
  62        ndelay(MDIO_READ_DELAY);
  63        ops->set_mdc(ctrl, 0);
  64
  65        return ops->get_mdio_data(ctrl);
  66}
  67
  68/* MDIO must already be configured as output. */
  69static void mdiobb_send_num(struct mdiobb_ctrl *ctrl, u16 val, int bits)
  70{
  71        int i;
  72
  73        for (i = bits - 1; i >= 0; i--)
  74                mdiobb_send_bit(ctrl, (val >> i) & 1);
  75}
  76
  77/* MDIO must already be configured as input. */
  78static u16 mdiobb_get_num(struct mdiobb_ctrl *ctrl, int bits)
  79{
  80        int i;
  81        u16 ret = 0;
  82
  83        for (i = bits - 1; i >= 0; i--) {
  84                ret <<= 1;
  85                ret |= mdiobb_get_bit(ctrl);
  86        }
  87
  88        return ret;
  89}
  90
  91/* Utility to send the preamble, address, and
  92 * register (common to read and write).
  93 */
  94static void mdiobb_cmd(struct mdiobb_ctrl *ctrl, int op, u8 phy, u8 reg)
  95{
  96        const struct mdiobb_ops *ops = ctrl->ops;
  97        int i;
  98
  99        ops->set_mdio_dir(ctrl, 1);
 100
 101        /*
 102         * Send a 32 bit preamble ('1's) with an extra '1' bit for good
 103         * measure.  The IEEE spec says this is a PHY optional
 104         * requirement.  The AMD 79C874 requires one after power up and
 105         * one after a MII communications error.  This means that we are
 106         * doing more preambles than we need, but it is safer and will be
 107         * much more robust.
 108         */
 109
 110        for (i = 0; i < 32; i++)
 111                mdiobb_send_bit(ctrl, 1);
 112
 113        /* send the start bit (01) and the read opcode (10) or write (01).
 114           Clause 45 operation uses 00 for the start and 11, 10 for
 115           read/write */
 116        mdiobb_send_bit(ctrl, 0);
 117        if (op & MDIO_C45)
 118                mdiobb_send_bit(ctrl, 0);
 119        else
 120                mdiobb_send_bit(ctrl, 1);
 121        mdiobb_send_bit(ctrl, (op >> 1) & 1);
 122        mdiobb_send_bit(ctrl, (op >> 0) & 1);
 123
 124        mdiobb_send_num(ctrl, phy, 5);
 125        mdiobb_send_num(ctrl, reg, 5);
 126}
 127
 128/* In clause 45 mode all commands are prefixed by MDIO_ADDR to specify the
 129   lower 16 bits of the 21 bit address. This transfer is done identically to a
 130   MDIO_WRITE except for a different code. To enable clause 45 mode or
 131   MII_ADDR_C45 into the address. Theoretically clause 45 and normal devices
 132   can exist on the same bus. Normal devices should ignore the MDIO_ADDR
 133   phase. */
 134static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr)
 135{
 136        unsigned int dev_addr = (addr >> 16) & 0x1F;
 137        unsigned int reg = addr & 0xFFFF;
 138        mdiobb_cmd(ctrl, MDIO_C45_ADDR, phy, dev_addr);
 139
 140        /* send the turnaround (10) */
 141        mdiobb_send_bit(ctrl, 1);
 142        mdiobb_send_bit(ctrl, 0);
 143
 144        mdiobb_send_num(ctrl, reg, 16);
 145
 146        ctrl->ops->set_mdio_dir(ctrl, 0);
 147        mdiobb_get_bit(ctrl);
 148
 149        return dev_addr;
 150}
 151
 152int mdiobb_read(struct mii_bus *bus, int phy, int reg)
 153{
 154        struct mdiobb_ctrl *ctrl = bus->priv;
 155        int ret, i;
 156
 157        if (reg & MII_ADDR_C45) {
 158                reg = mdiobb_cmd_addr(ctrl, phy, reg);
 159                mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
 160        } else
 161                mdiobb_cmd(ctrl, ctrl->op_c22_read, phy, reg);
 162
 163        ctrl->ops->set_mdio_dir(ctrl, 0);
 164
 165        /* check the turnaround bit: the PHY should be driving it to zero, if this
 166         * PHY is listed in phy_ignore_ta_mask as having broken TA, skip that
 167         */
 168        if (mdiobb_get_bit(ctrl) != 0 &&
 169            !(bus->phy_ignore_ta_mask & (1 << phy))) {
 170                /* PHY didn't drive TA low -- flush any bits it
 171                 * may be trying to send.
 172                 */
 173                for (i = 0; i < 32; i++)
 174                        mdiobb_get_bit(ctrl);
 175
 176                return 0xffff;
 177        }
 178
 179        ret = mdiobb_get_num(ctrl, 16);
 180        mdiobb_get_bit(ctrl);
 181        return ret;
 182}
 183EXPORT_SYMBOL(mdiobb_read);
 184
 185int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
 186{
 187        struct mdiobb_ctrl *ctrl = bus->priv;
 188
 189        if (reg & MII_ADDR_C45) {
 190                reg = mdiobb_cmd_addr(ctrl, phy, reg);
 191                mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
 192        } else
 193                mdiobb_cmd(ctrl, ctrl->op_c22_write, phy, reg);
 194
 195        /* send the turnaround (10) */
 196        mdiobb_send_bit(ctrl, 1);
 197        mdiobb_send_bit(ctrl, 0);
 198
 199        mdiobb_send_num(ctrl, val, 16);
 200
 201        ctrl->ops->set_mdio_dir(ctrl, 0);
 202        mdiobb_get_bit(ctrl);
 203        return 0;
 204}
 205EXPORT_SYMBOL(mdiobb_write);
 206
 207struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl)
 208{
 209        struct mii_bus *bus;
 210
 211        bus = mdiobus_alloc();
 212        if (!bus)
 213                return NULL;
 214
 215        __module_get(ctrl->ops->owner);
 216
 217        bus->read = mdiobb_read;
 218        bus->write = mdiobb_write;
 219        bus->priv = ctrl;
 220        if (!ctrl->override_op_c22) {
 221                ctrl->op_c22_read = MDIO_READ;
 222                ctrl->op_c22_write = MDIO_WRITE;
 223        }
 224
 225        return bus;
 226}
 227EXPORT_SYMBOL(alloc_mdio_bitbang);
 228
 229void free_mdio_bitbang(struct mii_bus *bus)
 230{
 231        struct mdiobb_ctrl *ctrl = bus->priv;
 232
 233        module_put(ctrl->ops->owner);
 234        mdiobus_free(bus);
 235}
 236EXPORT_SYMBOL(free_mdio_bitbang);
 237
 238MODULE_LICENSE("GPL v2");
 239