source: rtems/cpukit/libnetworking/rtems/rtems_mii_ioctl_kern.c @ 643b820

Last change on this file since 643b820 was 643b820, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 6, 2017 at 9:11:49 AM

Include missing <sys/param.h>

Some kernel-space header expect that <sys/param.h> is present.

Update #2833.

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