[PATCH] libata: improve driver initialization and deinitialization
[linux-2.6/kvm.git] / drivers / net / fs_enet / mii-bitbang.c
blob48f9cf83ab6f4e857aa0fbf30daa47f8ace08898
1 /*
2 * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
4 * Copyright (c) 2003 Intracom S.A.
5 * by Pantelis Antoniou <panto@intracom.gr>
6 *
7 * 2005 (c) MontaVista Software, Inc.
8 * Vitaly Bordug <vbordug@ru.mvista.com>
10 * This file is licensed under the terms of the GNU General Public License
11 * version 2. This program is licensed "as is" without any warranty of any
12 * kind, whether express or implied.
16 #include <linux/module.h>
17 #include <linux/types.h>
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/string.h>
21 #include <linux/ptrace.h>
22 #include <linux/errno.h>
23 #include <linux/ioport.h>
24 #include <linux/slab.h>
25 #include <linux/interrupt.h>
26 #include <linux/pci.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/netdevice.h>
30 #include <linux/etherdevice.h>
31 #include <linux/skbuff.h>
32 #include <linux/spinlock.h>
33 #include <linux/mii.h>
34 #include <linux/ethtool.h>
35 #include <linux/bitops.h>
37 #include <asm/pgtable.h>
38 #include <asm/irq.h>
39 #include <asm/uaccess.h>
41 #include "fs_enet.h"
43 #ifdef CONFIG_8xx
44 static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit)
46 immap_t *im = (immap_t *)fs_enet_immap;
47 void *dir, *dat, *ppar;
48 int adv;
49 u8 msk;
51 switch (port) {
52 case fsiop_porta:
53 dir = &im->im_ioport.iop_padir;
54 dat = &im->im_ioport.iop_padat;
55 ppar = &im->im_ioport.iop_papar;
56 break;
58 case fsiop_portb:
59 dir = &im->im_cpm.cp_pbdir;
60 dat = &im->im_cpm.cp_pbdat;
61 ppar = &im->im_cpm.cp_pbpar;
62 break;
64 case fsiop_portc:
65 dir = &im->im_ioport.iop_pcdir;
66 dat = &im->im_ioport.iop_pcdat;
67 ppar = &im->im_ioport.iop_pcpar;
68 break;
70 case fsiop_portd:
71 dir = &im->im_ioport.iop_pddir;
72 dat = &im->im_ioport.iop_pddat;
73 ppar = &im->im_ioport.iop_pdpar;
74 break;
76 case fsiop_porte:
77 dir = &im->im_cpm.cp_pedir;
78 dat = &im->im_cpm.cp_pedat;
79 ppar = &im->im_cpm.cp_pepar;
80 break;
82 default:
83 printk(KERN_ERR DRV_MODULE_NAME
84 "Illegal port value %d!\n", port);
85 return -EINVAL;
88 adv = bit >> 3;
89 dir = (char *)dir + adv;
90 dat = (char *)dat + adv;
91 ppar = (char *)ppar + adv;
93 msk = 1 << (7 - (bit & 7));
94 if ((in_8(ppar) & msk) != 0) {
95 printk(KERN_ERR DRV_MODULE_NAME
96 "pin %d on port %d is not general purpose!\n", bit, port);
97 return -EINVAL;
100 *dirp = dir;
101 *datp = dat;
102 *mskp = msk;
104 return 0;
106 #endif
108 #ifdef CONFIG_8260
109 static int bitbang_prep_bit(u8 **dirp, u8 **datp, u8 *mskp, int port, int bit)
111 iop_cpm2_t *io = &((cpm2_map_t *)fs_enet_immap)->im_ioport;
112 void *dir, *dat, *ppar;
113 int adv;
114 u8 msk;
116 switch (port) {
117 case fsiop_porta:
118 dir = &io->iop_pdira;
119 dat = &io->iop_pdata;
120 ppar = &io->iop_ppara;
121 break;
123 case fsiop_portb:
124 dir = &io->iop_pdirb;
125 dat = &io->iop_pdatb;
126 ppar = &io->iop_pparb;
127 break;
129 case fsiop_portc:
130 dir = &io->iop_pdirc;
131 dat = &io->iop_pdatc;
132 ppar = &io->iop_pparc;
133 break;
135 case fsiop_portd:
136 dir = &io->iop_pdird;
137 dat = &io->iop_pdatd;
138 ppar = &io->iop_ppard;
139 break;
141 default:
142 printk(KERN_ERR DRV_MODULE_NAME
143 "Illegal port value %d!\n", port);
144 return -EINVAL;
147 adv = bit >> 3;
148 dir = (char *)dir + adv;
149 dat = (char *)dat + adv;
150 ppar = (char *)ppar + adv;
152 msk = 1 << (7 - (bit & 7));
153 if ((in_8(ppar) & msk) != 0) {
154 printk(KERN_ERR DRV_MODULE_NAME
155 "pin %d on port %d is not general purpose!\n", bit, port);
156 return -EINVAL;
159 *dirp = dir;
160 *datp = dat;
161 *mskp = msk;
163 return 0;
165 #endif
167 static inline void bb_set(u8 *p, u8 m)
169 out_8(p, in_8(p) | m);
172 static inline void bb_clr(u8 *p, u8 m)
174 out_8(p, in_8(p) & ~m);
177 static inline int bb_read(u8 *p, u8 m)
179 return (in_8(p) & m) != 0;
182 static inline void mdio_active(struct fs_enet_mii_bus *bus)
184 bb_set(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk);
187 static inline void mdio_tristate(struct fs_enet_mii_bus *bus)
189 bb_clr(bus->bitbang.mdio_dir, bus->bitbang.mdio_msk);
192 static inline int mdio_read(struct fs_enet_mii_bus *bus)
194 return bb_read(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
197 static inline void mdio(struct fs_enet_mii_bus *bus, int what)
199 if (what)
200 bb_set(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
201 else
202 bb_clr(bus->bitbang.mdio_dat, bus->bitbang.mdio_msk);
205 static inline void mdc(struct fs_enet_mii_bus *bus, int what)
207 if (what)
208 bb_set(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk);
209 else
210 bb_clr(bus->bitbang.mdc_dat, bus->bitbang.mdc_msk);
213 static inline void mii_delay(struct fs_enet_mii_bus *bus)
215 udelay(bus->bus_info->i.bitbang.delay);
218 /* Utility to send the preamble, address, and register (common to read and write). */
219 static void bitbang_pre(struct fs_enet_mii_bus *bus, int read, u8 addr, u8 reg)
221 int j;
224 * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
225 * The IEEE spec says this is a PHY optional requirement. The AMD
226 * 79C874 requires one after power up and one after a MII communications
227 * error. This means that we are doing more preambles than we need,
228 * but it is safer and will be much more robust.
231 mdio_active(bus);
232 mdio(bus, 1);
233 for (j = 0; j < 32; j++) {
234 mdc(bus, 0);
235 mii_delay(bus);
236 mdc(bus, 1);
237 mii_delay(bus);
240 /* send the start bit (01) and the read opcode (10) or write (10) */
241 mdc(bus, 0);
242 mdio(bus, 0);
243 mii_delay(bus);
244 mdc(bus, 1);
245 mii_delay(bus);
246 mdc(bus, 0);
247 mdio(bus, 1);
248 mii_delay(bus);
249 mdc(bus, 1);
250 mii_delay(bus);
251 mdc(bus, 0);
252 mdio(bus, read);
253 mii_delay(bus);
254 mdc(bus, 1);
255 mii_delay(bus);
256 mdc(bus, 0);
257 mdio(bus, !read);
258 mii_delay(bus);
259 mdc(bus, 1);
260 mii_delay(bus);
262 /* send the PHY address */
263 for (j = 0; j < 5; j++) {
264 mdc(bus, 0);
265 mdio(bus, (addr & 0x10) != 0);
266 mii_delay(bus);
267 mdc(bus, 1);
268 mii_delay(bus);
269 addr <<= 1;
272 /* send the register address */
273 for (j = 0; j < 5; j++) {
274 mdc(bus, 0);
275 mdio(bus, (reg & 0x10) != 0);
276 mii_delay(bus);
277 mdc(bus, 1);
278 mii_delay(bus);
279 reg <<= 1;
283 static int mii_read(struct fs_enet_mii_bus *bus, int phy_id, int location)
285 u16 rdreg;
286 int ret, j;
287 u8 addr = phy_id & 0xff;
288 u8 reg = location & 0xff;
290 bitbang_pre(bus, 1, addr, reg);
292 /* tri-state our MDIO I/O pin so we can read */
293 mdc(bus, 0);
294 mdio_tristate(bus);
295 mii_delay(bus);
296 mdc(bus, 1);
297 mii_delay(bus);
299 /* check the turnaround bit: the PHY should be driving it to zero */
300 if (mdio_read(bus) != 0) {
301 /* PHY didn't drive TA low */
302 for (j = 0; j < 32; j++) {
303 mdc(bus, 0);
304 mii_delay(bus);
305 mdc(bus, 1);
306 mii_delay(bus);
308 ret = -1;
309 goto out;
312 mdc(bus, 0);
313 mii_delay(bus);
315 /* read 16 bits of register data, MSB first */
316 rdreg = 0;
317 for (j = 0; j < 16; j++) {
318 mdc(bus, 1);
319 mii_delay(bus);
320 rdreg <<= 1;
321 rdreg |= mdio_read(bus);
322 mdc(bus, 0);
323 mii_delay(bus);
326 mdc(bus, 1);
327 mii_delay(bus);
328 mdc(bus, 0);
329 mii_delay(bus);
330 mdc(bus, 1);
331 mii_delay(bus);
333 ret = rdreg;
334 out:
335 return ret;
338 static void mii_write(struct fs_enet_mii_bus *bus, int phy_id, int location, int val)
340 int j;
341 u8 addr = phy_id & 0xff;
342 u8 reg = location & 0xff;
343 u16 value = val & 0xffff;
345 bitbang_pre(bus, 0, addr, reg);
347 /* send the turnaround (10) */
348 mdc(bus, 0);
349 mdio(bus, 1);
350 mii_delay(bus);
351 mdc(bus, 1);
352 mii_delay(bus);
353 mdc(bus, 0);
354 mdio(bus, 0);
355 mii_delay(bus);
356 mdc(bus, 1);
357 mii_delay(bus);
359 /* write 16 bits of register data, MSB first */
360 for (j = 0; j < 16; j++) {
361 mdc(bus, 0);
362 mdio(bus, (value & 0x8000) != 0);
363 mii_delay(bus);
364 mdc(bus, 1);
365 mii_delay(bus);
366 value <<= 1;
370 * Tri-state the MDIO line.
372 mdio_tristate(bus);
373 mdc(bus, 0);
374 mii_delay(bus);
375 mdc(bus, 1);
376 mii_delay(bus);
379 int fs_mii_bitbang_init(struct fs_enet_mii_bus *bus)
381 const struct fs_mii_bus_info *bi = bus->bus_info;
382 int r;
384 r = bitbang_prep_bit(&bus->bitbang.mdio_dir,
385 &bus->bitbang.mdio_dat,
386 &bus->bitbang.mdio_msk,
387 bi->i.bitbang.mdio_port,
388 bi->i.bitbang.mdio_bit);
389 if (r != 0)
390 return r;
392 r = bitbang_prep_bit(&bus->bitbang.mdc_dir,
393 &bus->bitbang.mdc_dat,
394 &bus->bitbang.mdc_msk,
395 bi->i.bitbang.mdc_port,
396 bi->i.bitbang.mdc_bit);
397 if (r != 0)
398 return r;
400 bus->mii_read = mii_read;
401 bus->mii_write = mii_write;
403 return 0;