1 /* $NetBSD: mii_bitbang.c,v 1.1 1999/11/17 17:47:59 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Common module for bit-bang'ing the MII. 42 */ 43 44 #include <sys/param.h> 45 #include <sys/device.h> 46 47 #include <dev/mii/mii.h> 48 #include <dev/mii/mii_bitbang.h> 49 50 void mii_bitbang_sync __P((struct device *, mii_bitbang_ops_t)); 51 void mii_bitbang_sendbits __P((struct device *, mii_bitbang_ops_t, 52 u_int32_t, int)); 53 54 #define WRITE(x) \ 55 do { \ 56 ops->mbo_write(sc, (x)); \ 57 delay(1); \ 58 } while (0) 59 60 #define READ ops->mbo_read(sc) 61 62 #define MDO ops->mbo_bits[MII_BIT_MDO] 63 #define MDI ops->mbo_bits[MII_BIT_MDI] 64 #define MDC ops->mbo_bits[MII_BIT_MDC] 65 #define MDIRPHY ops->mbo_bits[MII_BIT_DIR_HOST_PHY] 66 #define MDIRHOST ops->mbo_bits[MII_BIT_DIR_PHY_HOST] 67 68 /* 69 * mii_bitbang_sync: 70 * 71 * Synchronize the MII. 72 */ 73 void 74 mii_bitbang_sync(sc, ops) 75 struct device *sc; 76 mii_bitbang_ops_t ops; 77 { 78 int i, v; 79 80 v = MDIRPHY | MDO; 81 82 WRITE(v); 83 for (i = 0; i < 32; i++) { 84 WRITE(v | MDC); 85 WRITE(v); 86 } 87 } 88 89 /* 90 * mii_bitbang_sendbits: 91 * 92 * Send a series of bits to the MII. 93 */ 94 void 95 mii_bitbang_sendbits(sc, ops, data, nbits) 96 struct device *sc; 97 mii_bitbang_ops_t ops; 98 u_int32_t data; 99 int nbits; 100 { 101 int i, v; 102 103 v = MDIRPHY; 104 WRITE(v); 105 106 for (i = 1 << (nbits - 1); i != 0; i >>= 1) { 107 if (data & i) 108 v |= MDO; 109 else 110 v &= ~MDO; 111 WRITE(v); 112 WRITE(v | MDC); 113 WRITE(v); 114 } 115 } 116 117 /* 118 * mii_bitbang_readreg: 119 * 120 * Read a PHY register by bit-bang'ing the MII. 121 */ 122 int 123 mii_bitbang_readreg(sc, ops, phy, reg) 124 struct device *sc; 125 mii_bitbang_ops_t ops; 126 int phy, reg; 127 { 128 int val = 0, err = 0, i; 129 130 mii_bitbang_sync(sc, ops); 131 132 mii_bitbang_sendbits(sc, ops, MII_COMMAND_START, 2); 133 mii_bitbang_sendbits(sc, ops, MII_COMMAND_READ, 2); 134 mii_bitbang_sendbits(sc, ops, phy, 5); 135 mii_bitbang_sendbits(sc, ops, reg, 5); 136 137 /* Switch direction to PHY->host, without a clock transition. */ 138 WRITE(MDIRHOST); 139 140 /* Turnaround clock. */ 141 WRITE(MDIRHOST | MDC); 142 WRITE(MDIRHOST); 143 144 /* Check for error. */ 145 err = READ & MDI; 146 147 /* Idle clock. */ 148 WRITE(MDIRHOST | MDC); 149 WRITE(MDIRHOST); 150 151 for (i = 0; i < 16; i++) { 152 val <<= 1; 153 /* Read data prior to clock low-high transition. */ 154 if (err == 0 && (READ & MDI) != 0) 155 val |= 1; 156 157 WRITE(MDIRHOST | MDC); 158 WRITE(MDIRHOST); 159 } 160 161 /* Set direction to host->PHY, without a clock transition. */ 162 WRITE(MDIRPHY); 163 164 return (err ? 0 : val); 165 } 166 167 /* 168 * mii_bitbang_writereg: 169 * 170 * Write a PHY register by bit-bang'ing the MII. 171 */ 172 void 173 mii_bitbang_writereg(sc, ops, phy, reg, val) 174 struct device *sc; 175 mii_bitbang_ops_t ops; 176 int phy, reg, val; 177 { 178 179 mii_bitbang_sync(sc, ops); 180 181 mii_bitbang_sendbits(sc, ops, MII_COMMAND_START, 2); 182 mii_bitbang_sendbits(sc, ops, MII_COMMAND_WRITE, 2); 183 mii_bitbang_sendbits(sc, ops, phy, 5); 184 mii_bitbang_sendbits(sc, ops, reg, 5); 185 mii_bitbang_sendbits(sc, ops, MII_COMMAND_ACK, 2); 186 mii_bitbang_sendbits(sc, ops, val, 16); 187 188 WRITE(MDIRPHY); 189 } 190