Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
zmii.c
Go to the documentation of this file.
1 /*
2  * drivers/net/ethernet/ibm/emac/zmii.c
3  *
4  * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
5  *
6  * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
8  *
9  * Based on the arch/ppc version of the driver:
10  *
11  * Copyright (c) 2004, 2005 Zultys Technologies.
12  * Eugene Surovegin <[email protected]> or <[email protected]>
13  *
14  * Based on original work by
15  * Armin Kuster <[email protected]>
16  * Copyright 2001 MontaVista Softare Inc.
17  *
18  * This program is free software; you can redistribute it and/or modify it
19  * under the terms of the GNU General Public License as published by the
20  * Free Software Foundation; either version 2 of the License, or (at your
21  * option) any later version.
22  *
23  */
24 #include <linux/slab.h>
25 #include <linux/kernel.h>
26 #include <linux/ethtool.h>
27 #include <asm/io.h>
28 
29 #include "emac.h"
30 #include "core.h"
31 
32 /* ZMIIx_FER */
33 #define ZMII_FER_MDI(idx) (0x80000000 >> ((idx) * 4))
34 #define ZMII_FER_MDI_ALL (ZMII_FER_MDI(0) | ZMII_FER_MDI(1) | \
35  ZMII_FER_MDI(2) | ZMII_FER_MDI(3))
36 
37 #define ZMII_FER_SMII(idx) (0x40000000 >> ((idx) * 4))
38 #define ZMII_FER_RMII(idx) (0x20000000 >> ((idx) * 4))
39 #define ZMII_FER_MII(idx) (0x10000000 >> ((idx) * 4))
40 
41 /* ZMIIx_SSR */
42 #define ZMII_SSR_SCI(idx) (0x40000000 >> ((idx) * 4))
43 #define ZMII_SSR_FSS(idx) (0x20000000 >> ((idx) * 4))
44 #define ZMII_SSR_SP(idx) (0x10000000 >> ((idx) * 4))
45 
46 /* ZMII only supports MII, RMII and SMII
47  * we also support autodetection for backward compatibility
48  */
49 static inline int zmii_valid_mode(int mode)
50 {
51  return mode == PHY_MODE_MII ||
52  mode == PHY_MODE_RMII ||
53  mode == PHY_MODE_SMII ||
54  mode == PHY_MODE_NA;
55 }
56 
57 static inline const char *zmii_mode_name(int mode)
58 {
59  switch (mode) {
60  case PHY_MODE_MII:
61  return "MII";
62  case PHY_MODE_RMII:
63  return "RMII";
64  case PHY_MODE_SMII:
65  return "SMII";
66  default:
67  BUG();
68  }
69 }
70 
71 static inline u32 zmii_mode_mask(int mode, int input)
72 {
73  switch (mode) {
74  case PHY_MODE_MII:
75  return ZMII_FER_MII(input);
76  case PHY_MODE_RMII:
77  return ZMII_FER_RMII(input);
78  case PHY_MODE_SMII:
79  return ZMII_FER_SMII(input);
80  default:
81  return 0;
82  }
83 }
84 
85 int __devinit zmii_attach(struct platform_device *ofdev, int input, int *mode)
86 {
87  struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
88  struct zmii_regs __iomem *p = dev->base;
89 
90  ZMII_DBG(dev, "init(%d, %d)" NL, input, *mode);
91 
92  if (!zmii_valid_mode(*mode)) {
93  /* Probably an EMAC connected to RGMII,
94  * but it still may need ZMII for MDIO so
95  * we don't fail here.
96  */
97  dev->users++;
98  return 0;
99  }
100 
101  mutex_lock(&dev->lock);
102 
103  /* Autodetect ZMII mode if not specified.
104  * This is only for backward compatibility with the old driver.
105  * Please, always specify PHY mode in your board port to avoid
106  * any surprises.
107  */
108  if (dev->mode == PHY_MODE_NA) {
109  if (*mode == PHY_MODE_NA) {
110  u32 r = dev->fer_save;
111 
112  ZMII_DBG(dev, "autodetecting mode, FER = 0x%08x" NL, r);
113 
114  if (r & (ZMII_FER_MII(0) | ZMII_FER_MII(1)))
115  dev->mode = PHY_MODE_MII;
116  else if (r & (ZMII_FER_RMII(0) | ZMII_FER_RMII(1)))
117  dev->mode = PHY_MODE_RMII;
118  else
119  dev->mode = PHY_MODE_SMII;
120  } else
121  dev->mode = *mode;
122 
123  printk(KERN_NOTICE "%s: bridge in %s mode\n",
124  ofdev->dev.of_node->full_name,
125  zmii_mode_name(dev->mode));
126  } else {
127  /* All inputs must use the same mode */
128  if (*mode != PHY_MODE_NA && *mode != dev->mode) {
130  "%s: invalid mode %d specified for input %d\n",
131  ofdev->dev.of_node->full_name, *mode, input);
132  mutex_unlock(&dev->lock);
133  return -EINVAL;
134  }
135  }
136 
137  /* Report back correct PHY mode,
138  * it may be used during PHY initialization.
139  */
140  *mode = dev->mode;
141 
142  /* Enable this input */
143  out_be32(&p->fer, in_be32(&p->fer) | zmii_mode_mask(dev->mode, input));
144  ++dev->users;
145 
146  mutex_unlock(&dev->lock);
147 
148  return 0;
149 }
150 
151 void zmii_get_mdio(struct platform_device *ofdev, int input)
152 {
153  struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
154  u32 fer;
155 
156  ZMII_DBG2(dev, "get_mdio(%d)" NL, input);
157 
158  mutex_lock(&dev->lock);
159 
160  fer = in_be32(&dev->base->fer) & ~ZMII_FER_MDI_ALL;
161  out_be32(&dev->base->fer, fer | ZMII_FER_MDI(input));
162 }
163 
164 void zmii_put_mdio(struct platform_device *ofdev, int input)
165 {
166  struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
167 
168  ZMII_DBG2(dev, "put_mdio(%d)" NL, input);
169  mutex_unlock(&dev->lock);
170 }
171 
172 
173 void zmii_set_speed(struct platform_device *ofdev, int input, int speed)
174 {
175  struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
176  u32 ssr;
177 
178  mutex_lock(&dev->lock);
179 
180  ssr = in_be32(&dev->base->ssr);
181 
182  ZMII_DBG(dev, "speed(%d, %d)" NL, input, speed);
183 
184  if (speed == SPEED_100)
185  ssr |= ZMII_SSR_SP(input);
186  else
187  ssr &= ~ZMII_SSR_SP(input);
188 
189  out_be32(&dev->base->ssr, ssr);
190 
191  mutex_unlock(&dev->lock);
192 }
193 
194 void zmii_detach(struct platform_device *ofdev, int input)
195 {
196  struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
197 
198  BUG_ON(!dev || dev->users == 0);
199 
200  mutex_lock(&dev->lock);
201 
202  ZMII_DBG(dev, "detach(%d)" NL, input);
203 
204  /* Disable this input */
205  out_be32(&dev->base->fer,
206  in_be32(&dev->base->fer) & ~zmii_mode_mask(dev->mode, input));
207 
208  --dev->users;
209 
210  mutex_unlock(&dev->lock);
211 }
212 
214 {
215  return sizeof(struct emac_ethtool_regs_subhdr) +
216  sizeof(struct zmii_regs);
217 }
218 
219 void *zmii_dump_regs(struct platform_device *ofdev, void *buf)
220 {
221  struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
222  struct emac_ethtool_regs_subhdr *hdr = buf;
223  struct zmii_regs *regs = (struct zmii_regs *)(hdr + 1);
224 
225  hdr->version = 0;
226  hdr->index = 0; /* for now, are there chips with more than one
227  * zmii ? if yes, then we'll add a cell_index
228  * like we do for emac
229  */
230  memcpy_fromio(regs, dev->base, sizeof(struct zmii_regs));
231  return regs + 1;
232 }
233 
234 static int __devinit zmii_probe(struct platform_device *ofdev)
235 {
236  struct device_node *np = ofdev->dev.of_node;
237  struct zmii_instance *dev;
238  struct resource regs;
239  int rc;
240 
241  rc = -ENOMEM;
242  dev = kzalloc(sizeof(struct zmii_instance), GFP_KERNEL);
243  if (dev == NULL)
244  goto err_gone;
245 
246  mutex_init(&dev->lock);
247  dev->ofdev = ofdev;
248  dev->mode = PHY_MODE_NA;
249 
250  rc = -ENXIO;
251  if (of_address_to_resource(np, 0, &regs)) {
252  printk(KERN_ERR "%s: Can't get registers address\n",
253  np->full_name);
254  goto err_free;
255  }
256 
257  rc = -ENOMEM;
258  dev->base = (struct zmii_regs __iomem *)ioremap(regs.start,
259  sizeof(struct zmii_regs));
260  if (dev->base == NULL) {
261  printk(KERN_ERR "%s: Can't map device registers!\n",
262  np->full_name);
263  goto err_free;
264  }
265 
266  /* We may need FER value for autodetection later */
267  dev->fer_save = in_be32(&dev->base->fer);
268 
269  /* Disable all inputs by default */
270  out_be32(&dev->base->fer, 0);
271 
273  "ZMII %s initialized\n", ofdev->dev.of_node->full_name);
274  wmb();
275  dev_set_drvdata(&ofdev->dev, dev);
276 
277  return 0;
278 
279  err_free:
280  kfree(dev);
281  err_gone:
282  return rc;
283 }
284 
285 static int __devexit zmii_remove(struct platform_device *ofdev)
286 {
287  struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
288 
289  dev_set_drvdata(&ofdev->dev, NULL);
290 
291  WARN_ON(dev->users != 0);
292 
293  iounmap(dev->base);
294  kfree(dev);
295 
296  return 0;
297 }
298 
299 static struct of_device_id zmii_match[] =
300 {
301  {
302  .compatible = "ibm,zmii",
303  },
304  /* For backward compat with old DT */
305  {
306  .type = "emac-zmii",
307  },
308  {},
309 };
310 
311 static struct platform_driver zmii_driver = {
312  .driver = {
313  .name = "emac-zmii",
314  .owner = THIS_MODULE,
315  .of_match_table = zmii_match,
316  },
317  .probe = zmii_probe,
318  .remove = zmii_remove,
319 };
320 
321 int __init zmii_init(void)
322 {
323  return platform_driver_register(&zmii_driver);
324 }
325 
326 void zmii_exit(void)
327 {
328  platform_driver_unregister(&zmii_driver);
329 }