Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Generic bitbanged MDIO library

Previously, bitbanged MDIO was only supported in individual
hardware-specific drivers. This code factors out the higher level
protocol implementation, reducing the hardware-specific portion to
functions setting direction, data, and clock.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

authored by

Scott Wood and committed by
David S. Miller
e2ec4581 976de6a8

+239
+9
drivers/net/phy/Kconfig
··· 90 90 This control will have specified number allocated for each fixed 91 91 PHY type enabled. 92 92 93 + config MDIO_BITBANG 94 + tristate "Support for bitbanged MDIO buses" 95 + help 96 + This module implements the MDIO bus protocol in software, 97 + for use by low level drivers that export the ability to 98 + drive the relevant pins. 99 + 100 + If in doubt, say N. 101 + 93 102 endif # PHYLIB
+1
drivers/net/phy/Makefile
··· 13 13 obj-$(CONFIG_BROADCOM_PHY) += broadcom.o 14 14 obj-$(CONFIG_ICPLUS_PHY) += icplus.o 15 15 obj-$(CONFIG_FIXED_PHY) += fixed.o 16 + obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
+187
drivers/net/phy/mdio-bitbang.c
··· 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/slab.h> 23 + #include <linux/types.h> 24 + #include <linux/delay.h> 25 + 26 + #define MDIO_READ 1 27 + #define MDIO_WRITE 0 28 + 29 + #define MDIO_SETUP_TIME 10 30 + #define MDIO_HOLD_TIME 10 31 + 32 + /* Minimum MDC period is 400 ns, plus some margin for error. MDIO_DELAY 33 + * is done twice per period. 34 + */ 35 + #define MDIO_DELAY 250 36 + 37 + /* The PHY may take up to 300 ns to produce data, plus some margin 38 + * for error. 39 + */ 40 + #define MDIO_READ_DELAY 350 41 + 42 + /* MDIO must already be configured as output. */ 43 + static void mdiobb_send_bit(struct mdiobb_ctrl *ctrl, int val) 44 + { 45 + const struct mdiobb_ops *ops = ctrl->ops; 46 + 47 + ops->set_mdio_data(ctrl, val); 48 + ndelay(MDIO_DELAY); 49 + ops->set_mdc(ctrl, 1); 50 + ndelay(MDIO_DELAY); 51 + ops->set_mdc(ctrl, 0); 52 + } 53 + 54 + /* MDIO must already be configured as input. */ 55 + static int mdiobb_get_bit(struct mdiobb_ctrl *ctrl) 56 + { 57 + const struct mdiobb_ops *ops = ctrl->ops; 58 + 59 + ndelay(MDIO_DELAY); 60 + ops->set_mdc(ctrl, 1); 61 + ndelay(MDIO_READ_DELAY); 62 + ops->set_mdc(ctrl, 0); 63 + 64 + return ops->get_mdio_data(ctrl); 65 + } 66 + 67 + /* MDIO must already be configured as output. */ 68 + static void mdiobb_send_num(struct mdiobb_ctrl *ctrl, u16 val, int bits) 69 + { 70 + int i; 71 + 72 + for (i = bits - 1; i >= 0; i--) 73 + mdiobb_send_bit(ctrl, (val >> i) & 1); 74 + } 75 + 76 + /* MDIO must already be configured as input. */ 77 + static u16 mdiobb_get_num(struct mdiobb_ctrl *ctrl, int bits) 78 + { 79 + int i; 80 + u16 ret = 0; 81 + 82 + for (i = bits - 1; i >= 0; i--) { 83 + ret <<= 1; 84 + ret |= mdiobb_get_bit(ctrl); 85 + } 86 + 87 + return ret; 88 + } 89 + 90 + /* Utility to send the preamble, address, and 91 + * register (common to read and write). 92 + */ 93 + static void mdiobb_cmd(struct mdiobb_ctrl *ctrl, int read, u8 phy, u8 reg) 94 + { 95 + const struct mdiobb_ops *ops = ctrl->ops; 96 + int i; 97 + 98 + ops->set_mdio_dir(ctrl, 1); 99 + 100 + /* 101 + * Send a 32 bit preamble ('1's) with an extra '1' bit for good 102 + * measure. The IEEE spec says this is a PHY optional 103 + * requirement. The AMD 79C874 requires one after power up and 104 + * one after a MII communications error. This means that we are 105 + * doing more preambles than we need, but it is safer and will be 106 + * much more robust. 107 + */ 108 + 109 + for (i = 0; i < 32; i++) 110 + mdiobb_send_bit(ctrl, 1); 111 + 112 + /* send the start bit (01) and the read opcode (10) or write (10) */ 113 + mdiobb_send_bit(ctrl, 0); 114 + mdiobb_send_bit(ctrl, 1); 115 + mdiobb_send_bit(ctrl, read); 116 + mdiobb_send_bit(ctrl, !read); 117 + 118 + mdiobb_send_num(ctrl, phy, 5); 119 + mdiobb_send_num(ctrl, reg, 5); 120 + } 121 + 122 + 123 + static int mdiobb_read(struct mii_bus *bus, int phy, int reg) 124 + { 125 + struct mdiobb_ctrl *ctrl = bus->priv; 126 + int ret, i; 127 + 128 + mdiobb_cmd(ctrl, MDIO_READ, phy, reg); 129 + ctrl->ops->set_mdio_dir(ctrl, 0); 130 + 131 + /* check the turnaround bit: the PHY should be driving it to zero */ 132 + if (mdiobb_get_bit(ctrl) != 0) { 133 + /* PHY didn't drive TA low -- flush any bits it 134 + * may be trying to send. 135 + */ 136 + for (i = 0; i < 32; i++) 137 + mdiobb_get_bit(ctrl); 138 + 139 + return 0xffff; 140 + } 141 + 142 + ret = mdiobb_get_num(ctrl, 16); 143 + mdiobb_get_bit(ctrl); 144 + return ret; 145 + } 146 + 147 + static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val) 148 + { 149 + struct mdiobb_ctrl *ctrl = bus->priv; 150 + 151 + mdiobb_cmd(ctrl, MDIO_WRITE, phy, reg); 152 + 153 + /* send the turnaround (10) */ 154 + mdiobb_send_bit(ctrl, 1); 155 + mdiobb_send_bit(ctrl, 0); 156 + 157 + mdiobb_send_num(ctrl, val, 16); 158 + 159 + ctrl->ops->set_mdio_dir(ctrl, 0); 160 + mdiobb_get_bit(ctrl); 161 + return 0; 162 + } 163 + 164 + struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl) 165 + { 166 + struct mii_bus *bus; 167 + 168 + bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); 169 + if (!bus) 170 + return NULL; 171 + 172 + __module_get(ctrl->ops->owner); 173 + 174 + bus->read = mdiobb_read; 175 + bus->write = mdiobb_write; 176 + bus->priv = ctrl; 177 + 178 + return bus; 179 + } 180 + 181 + void free_mdio_bitbang(struct mii_bus *bus) 182 + { 183 + struct mdiobb_ctrl *ctrl = bus->priv; 184 + 185 + module_put(ctrl->ops->owner); 186 + kfree(bus); 187 + }
+42
include/linux/mdio-bitbang.h
··· 1 + #ifndef __LINUX_MDIO_BITBANG_H 2 + #define __LINUX_MDIO_BITBANG_H 3 + 4 + #include <linux/phy.h> 5 + #include <linux/module.h> 6 + 7 + struct mdiobb_ctrl; 8 + 9 + struct mdiobb_ops { 10 + struct module *owner; 11 + 12 + /* Set the Management Data Clock high if level is one, 13 + * low if level is zero. 14 + */ 15 + void (*set_mdc)(struct mdiobb_ctrl *ctrl, int level); 16 + 17 + /* Configure the Management Data I/O pin as an input if 18 + * "output" is zero, or an output if "output" is one. 19 + */ 20 + void (*set_mdio_dir)(struct mdiobb_ctrl *ctrl, int output); 21 + 22 + /* Set the Management Data I/O pin high if value is one, 23 + * low if "value" is zero. This may only be called 24 + * when the MDIO pin is configured as an output. 25 + */ 26 + void (*set_mdio_data)(struct mdiobb_ctrl *ctrl, int value); 27 + 28 + /* Retrieve the state Management Data I/O pin. */ 29 + int (*get_mdio_data)(struct mdiobb_ctrl *ctrl); 30 + }; 31 + 32 + struct mdiobb_ctrl { 33 + const struct mdiobb_ops *ops; 34 + }; 35 + 36 + /* The returned bus is not yet registered with the phy layer. */ 37 + struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl); 38 + 39 + /* The bus must already have been unregistered. */ 40 + void free_mdio_bitbang(struct mii_bus *bus); 41 + 42 + #endif