source: rtems/cpukit/libnetworking/rtems/rtems_mii_ioctl_kern.c @ b3f8c9e1

4.104.11
Last change on this file since b3f8c9e1 was b3f8c9e1, checked in by Ralf Corsepius <ralf.corsepius@…>, on Dec 22, 2008 at 7:47:28 AM

Include <errno.h> (POSIX,C99) instead of <sys/errno.h> (BSD'ism).

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/* $Id$ */
2
3/* Simple (default) implementation for SIOCGIFMEDIA/SIOCSIFMEDIA
4 * to be used by ethernet drivers [from their ioctl].
5 *
6 * KERNEL PART (support for drivers)
7 *
8 * NOTE: This much simpler than the BSD ifmedia API
9 */
10
11/*
12 * Authorship
13 * ----------
14 * This software was created by
15 *     Till Straumann <strauman@slac.stanford.edu>, 2005,
16 *         Stanford Linear Accelerator Center, Stanford University.
17 *
18 * Acknowledgement of sponsorship
19 * ------------------------------
20 * This software was produced by
21 *     the Stanford Linear Accelerator Center, Stanford University,
22 *         under Contract DE-AC03-76SFO0515 with the Department of Energy.
23 *
24 * Government disclaimer of liability
25 * ----------------------------------
26 * Neither the United States nor the United States Department of Energy,
27 * nor any of their employees, makes any warranty, express or implied, or
28 * assumes any legal liability or responsibility for the accuracy,
29 * completeness, or usefulness of any data, apparatus, product, or process
30 * disclosed, or represents that its use would not infringe privately owned
31 * rights.
32 *
33 * Stanford disclaimer of liability
34 * --------------------------------
35 * Stanford University makes no representations or warranties, express or
36 * implied, nor assumes any liability for the use of this software.
37 *
38 * Stanford disclaimer of copyright
39 * --------------------------------
40 * Stanford University, owner of the copyright, hereby disclaims its
41 * copyright and all other rights in this software.  Hence, anyone may
42 * freely use it for any purpose without restriction. 
43 *
44 * Maintenance of notices
45 * ----------------------
46 * In the interest of clarity regarding the origin and status of this
47 * SLAC software, this and all the preceding Stanford University notices
48 * are to remain affixed to any copy or derivative of this software made
49 * or distributed by the recipient and are to be affixed to any copy of
50 * software made or distributed by the recipient that contains a copy or
51 * derivative of this software.
52 *
53 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
54 */ 
55
56/* include first to avoid 'malloc' clash with rtems_bsdnet_malloc() hack */
57
58#include <rtems.h>
59#include <rtems/rtems_bsdnet.h>
60#include <sys/mbuf.h>
61#include <sys/socket.h>
62#include <sys/sockio.h>
63#include <net/ethernet.h>
64#include <net/if.h>
65
66#ifndef __KERNEL__
67#define __KERNEL__
68#endif
69
70#include <rtems/rtems_mii_ioctl.h>
71
72#include <errno.h>
73
74
75#define DEBUG
76
77
78#ifndef MII_1000TCR
79#define MII_1000TCR MII_100T2CR
80#endif
81
82#ifndef MII_1000TSR
83#define MII_1000TSR MII_100T2SR
84#endif
85
86int
87rtems_mii_ioctl (struct rtems_mdio_info *info, void *uarg, int cmd,
88                 int *media)
89{
90  uint32_t bmcr, bmsr, aner, bmcr2 = 0, bmsr2 = 0, anar, lpar;
91  int phy = IFM_INST (*media);
92  unsigned tmp;
93  int subtype = 0, options = 0;
94
95  switch (cmd) {
96  default:
97    return EINVAL;
98
99#ifdef DEBUG
100  case 0:
101#endif
102  case SIOCGIFMEDIA:
103    if (info->mdio_r (phy, uarg, MII_BMCR, &bmcr))
104      return EINVAL;
105    if (info->mdio_r (phy, uarg, MII_BMSR, &bmsr))
106      return EINVAL;
107    if (info->mdio_r (phy, uarg, MII_ANER, &aner))
108      return EINVAL;
109    if (info->has_gmii) {
110      if (info->mdio_r (phy, uarg, MII_1000TCR, &bmcr2))
111        return EINVAL;
112      if (info->mdio_r (phy, uarg, MII_1000TSR, &bmsr2))
113        return EINVAL;
114    }
115
116    /* link status */
117    if (BMSR_LINK & bmsr)
118      options |= IFM_LINK_OK;
119
120    /* do we have autonegotiation disabled ? */
121    if (!(BMCR_AUTOEN & bmcr)) {
122      options |= IFM_ANEG_DIS;
123
124      /* duplex is enforced */
125      options |= BMCR_FDX & bmcr ? IFM_FDX : IFM_HDX;
126
127      /* determine speed */
128      switch (BMCR_SPEED (bmcr)) {
129      case BMCR_S10:
130        subtype = IFM_10_T;
131        break;
132      case BMCR_S100:
133        subtype = IFM_100_TX;
134        break;
135      case BMCR_S1000:
136        subtype = IFM_1000_T;
137        break;
138      default:
139        return ENOTSUP;         /* ?? */
140      }
141    } else if (!(BMSR_LINK & bmsr) || !(BMSR_ACOMP & bmsr)) {
142      subtype = IFM_NONE;
143    } else {
144      /* everything ok on our side */
145
146          if ( ! (ANER_LPAN & aner) ) {
147                /* Link partner doesn't autonegotiate --> our settings are the
148                 * result of 'parallel detect' (in particular: duplex status is HALF
149                 * according to the standard!).
150                 * Let them know that something's fishy...
151                 */
152                options |= IFM_ANEG_DIS;
153          }
154
155      tmp = ((bmcr2 << 2) & bmsr2) & (GTSR_LP_1000THDX | GTSR_LP_1000TFDX);
156      if (tmp) {
157        if (GTSR_LP_1000TFDX & tmp)
158          options |= IFM_FDX;
159        subtype = IFM_1000_T;
160      } else {
161        if (info->mdio_r (phy, uarg, MII_ANAR, &anar))
162          return EINVAL;
163        if (info->mdio_r (phy, uarg, MII_ANLPAR, &lpar))
164          return EINVAL;
165        if (ANLPAR_ACK & lpar) {
166          /* this is a negotiated link; otherwise we merely detect the partner's ability */
167        }
168        tmp = anar & lpar;
169        if (ANLPAR_TX_FD & tmp) {
170          options |= IFM_FDX;
171          subtype = IFM_100_TX;
172        } else if (ANLPAR_T4 & tmp) {
173          subtype = IFM_100_T4;
174        } else if (ANLPAR_TX & tmp) {
175          subtype = IFM_100_TX;
176        } else if (ANLPAR_10_FD & tmp) {
177          options |= IFM_FDX;
178          subtype = IFM_10_T;
179        } else {
180          subtype = IFM_10_T;
181        }
182      }
183    }
184
185    *media = IFM_MAKEWORD (IFM_ETHER, subtype, options, phy);
186
187    break;
188
189#ifdef DEBUG
190  case 1:
191#endif
192  case SIOCSIFMEDIA:
193    if (IFM_ETHER != IFM_TYPE (*media))
194      return EINVAL;
195
196    if (info->mdio_r (phy, uarg, MII_BMSR, &bmsr))
197      return EINVAL;
198
199    tmp = (IFM_FDX & *media);
200
201    switch (IFM_SUBTYPE (*media)) {
202    default:
203      return ENOTSUP;
204
205    case IFM_AUTO:
206      bmcr = BMCR_AUTOEN | BMCR_STARTNEG;
207      tmp = 0;
208      break;
209
210    case IFM_1000_T:
211      if (!info->has_gmii)
212        return ENOTSUP;
213
214      if (info->mdio_r (phy, uarg, MII_EXTSR, &bmsr2))
215        return EINVAL;
216
217      if (!(bmsr2 & (tmp ? EXTSR_1000TFDX : EXTSR_1000THDX)))
218        return EOPNOTSUPP;
219      bmcr = BMCR_S1000;
220      break;
221
222    case IFM_100_TX:
223      if (!(bmsr & (tmp ? BMSR_100TXFDX : BMSR_100TXHDX)))
224        return EOPNOTSUPP;
225      bmcr = BMCR_S100;
226      break;
227
228    case IFM_10_T:
229      if (!(bmsr & (tmp ? BMSR_10TFDX : BMSR_10THDX)))
230        return EOPNOTSUPP;
231      bmcr = BMCR_S10;
232      break;
233    }
234
235    if (tmp)
236      bmcr |= BMCR_FDX;
237
238    if (info->mdio_w (phy, uarg, MII_BMCR, bmcr))
239      return EINVAL;
240
241    /* TODO: should we adapt advertised capabilites ? */
242
243    break;
244  }
245
246  return 0;
247}
Note: See TracBrowser for help on using the repository browser.