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