iPXE
mii.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 #include <string.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <ipxe/mii.h>
31 
32 /** @file
33  *
34  * Media Independent Interface
35  *
36  */
37 
38 /**
39  * Restart autonegotiation
40  *
41  * @v mii MII device
42  * @ret rc Return status code
43  */
44 int mii_restart ( struct mii_device *mii ) {
45  int bmcr;
46  int rc;
47 
48  /* Read BMCR */
49  bmcr = mii_read ( mii, MII_BMCR );
50  if ( bmcr < 0 ) {
51  rc = bmcr;
52  DBGC ( mii, "MII %p could not read BMCR: %s\n",
53  mii, strerror ( rc ) );
54  return rc;
55  }
56 
57  /* Enable and restart autonegotiation */
58  bmcr |= ( BMCR_ANENABLE | BMCR_ANRESTART );
59  if ( ( rc = mii_write ( mii, MII_BMCR, bmcr ) ) != 0 ) {
60  DBGC ( mii, "MII %p could not write BMCR: %s\n",
61  mii, strerror ( rc ) );
62  return rc;
63  }
64 
65  DBGC ( mii, "MII %p restarted autonegotiation\n", mii );
66  return 0;
67 }
68 
69 /**
70  * Reset MII device
71  *
72  * @v mii MII device
73  * @ret rc Return status code
74  */
75 int mii_reset ( struct mii_device *mii ) {
76  unsigned int i;
77  int bmcr;
78  int rc;
79 
80  /* Power-up, enable autonegotiation and initiate reset */
81  if ( ( rc = mii_write ( mii, MII_BMCR,
82  ( BMCR_RESET | BMCR_ANENABLE ) ) ) != 0 ) {
83  DBGC ( mii, "MII %p could not write BMCR: %s\n",
84  mii, strerror ( rc ) );
85  return rc;
86  }
87 
88  /* Wait for reset to complete */
89  for ( i = 0 ; i < MII_RESET_MAX_WAIT_MS ; i++ ) {
90 
91  /* Check if reset has completed */
92  bmcr = mii_read ( mii, MII_BMCR );
93  if ( bmcr < 0 ) {
94  rc = bmcr;
95  DBGC ( mii, "MII %p could not read BMCR: %s\n",
96  mii, strerror ( rc ) );
97  return rc;
98  }
99 
100  /* If reset is not complete, delay 1ms and retry */
101  if ( bmcr & BMCR_RESET ) {
102  mdelay ( 1 );
103  continue;
104  }
105 
106  /* Force autonegotation on again, in case it was
107  * cleared by the reset.
108  */
109  if ( ( rc = mii_restart ( mii ) ) != 0 )
110  return rc;
111 
112  DBGC ( mii, "MII %p reset after %dms\n", mii, i );
113  return 0;
114  }
115 
116  DBGC ( mii, "MII %p timed out waiting for reset\n", mii );
117  return -ETIMEDOUT;
118 }
119 
120 /**
121  * Update link status via MII
122  *
123  * @v mii MII device
124  * @v netdev Network device
125  * @ret rc Return status code
126  */
127 int mii_check_link ( struct mii_device *mii, struct net_device *netdev ) {
128  int bmsr;
129  int link;
130  int rc;
131 
132  /* Read BMSR */
133  bmsr = mii_read ( mii, MII_BMSR );
134  if ( bmsr < 0 ) {
135  rc = bmsr;
136  return rc;
137  }
138 
139  /* Report link status */
140  link = ( bmsr & BMSR_LSTATUS );
141  DBGC ( mii, "MII %p link %s (BMSR %#04x)\n",
142  mii, ( link ? "up" : "down" ), bmsr );
143  if ( link ) {
145  } else {
147  }
148 
149  return 0;
150 }
151 
152 /**
153  * Find PHY address
154  *
155  * @v mii MII device
156  * @ret rc Return status code
157  */
158 int mii_find ( struct mii_device *mii ) {
159  unsigned int address;
160  int id;
161 
162  /* Try all possible PHY addresses */
163  for ( address = 0 ; address <= MII_MAX_PHY_ADDRESS ; address++ ) {
164  mii->address = address;
165  id = mii_read ( mii, MII_PHYSID1 );
166  if ( ( id > 0x0000 ) && ( id < 0xffff ) ) {
167  DBGC ( mii, "MII %p found PHY at address %d\n",
168  mii, address );
169  return 0;
170  }
171  }
172 
173  DBGC ( mii, "MII %p failed to find an address\n", mii );
174  return -ENOENT;
175 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct mii_phy mii
Error codes.
uint64_t address
Base address.
Definition: ena.h:24
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:515
FILE_SECBOOT(PERMITTED)
#define BMCR_ANRESTART
Definition: mii.h:47
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition: netdevice.c:231
int mii_restart(struct mii_device *mii)
Restart autonegotiation.
Definition: mii.c:44
#define MII_RESET_MAX_WAIT_MS
Maximum time to wait for a reset, in milliseconds.
Definition: mii.h:143
An MII device.
Definition: mii.h:50
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition: netdevice.h:789
static struct net_device * netdev
Definition: gdbudp.c:52
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:25
uint8_t id
Request identifier.
Definition: ena.h:12
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
#define BMSR_LSTATUS
Definition: mii.h:58
A network device.
Definition: netdevice.h:353
Media Independent Interface.
#define MII_BMCR
Definition: atl1e.h:871
int mii_reset(struct mii_device *mii)
Reset MII device.
Definition: mii.c:75
int mii_check_link(struct mii_device *mii, struct net_device *netdev)
Update link status via MII.
Definition: mii.c:127
int mii_find(struct mii_device *mii)
Find PHY address.
Definition: mii.c:158
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:79
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define BMCR_RESET
Definition: mii.h:53
#define MII_MAX_PHY_ADDRESS
Maximum PHY address.
Definition: mii.h:146
static int mii_read(int phy_id, int location)
Definition: epic100.c:500
#define BMCR_ANENABLE
Definition: mii.h:50
#define MII_BMSR
Definition: atl1e.h:872
#define MII_PHYSID1
Definition: atl1e.h:873
static int mii_write(struct mii_device *mii, unsigned int reg, unsigned int data)
Write to MII register.
Definition: mii.h:105
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:670
String functions.