Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / mii.c
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
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <string.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <ipxe/mii.h>
26
27 /** @file
28  *
29  * Media Independent Interface
30  *
31  */
32
33 /**
34  * Restart autonegotiation
35  *
36  * @v mii               MII interface
37  * @ret rc              Return status code
38  */
39 int mii_restart ( struct mii_interface *mii ) {
40         int bmcr;
41         int rc;
42
43         /* Read BMCR */
44         bmcr = mii_read ( mii, MII_BMCR );
45         if ( bmcr < 0 ) {
46                 rc = bmcr;
47                 DBGC ( mii, "MII %p could not read BMCR: %s\n",
48                        mii, strerror ( rc ) );
49                 return rc;
50         }
51
52         /* Enable and restart autonegotiation */
53         bmcr |= ( BMCR_ANENABLE | BMCR_ANRESTART );
54         if ( ( rc = mii_write ( mii, MII_BMCR, bmcr ) ) != 0 ) {
55                 DBGC ( mii, "MII %p could not write BMCR: %s\n",
56                        mii, strerror ( rc ) );
57                 return rc;
58         }
59
60         DBGC ( mii, "MII %p restarted autonegotiation\n", mii );
61         return 0;
62 }
63
64 /**
65  * Reset MII interface
66  *
67  * @v mii               MII interface
68  * @ret rc              Return status code
69  */
70 int mii_reset ( struct mii_interface *mii ) {
71         unsigned int i;
72         int bmcr;
73         int rc;
74
75         /* Power-up, enable autonegotiation and initiate reset */
76         if ( ( rc = mii_write ( mii, MII_BMCR,
77                                 ( BMCR_RESET | BMCR_ANENABLE ) ) ) != 0 ) {
78                 DBGC ( mii, "MII %p could not write BMCR: %s\n",
79                        mii, strerror ( rc ) );
80                 return rc;
81         }
82
83         /* Wait for reset to complete */
84         for ( i = 0 ; i < MII_RESET_MAX_WAIT_MS ; i++ ) {
85
86                 /* Check if reset has completed */
87                 bmcr = mii_read ( mii, MII_BMCR );
88                 if ( bmcr < 0 ) {
89                         rc = bmcr;
90                         DBGC ( mii, "MII %p could not read BMCR: %s\n",
91                                mii, strerror ( rc ) );
92                         return rc;
93                 }
94
95                 /* If reset is not complete, delay 1ms and retry */
96                 if ( bmcr & BMCR_RESET ) {
97                         mdelay ( 1 );
98                         continue;
99                 }
100
101                 /* Force autonegotation on again, in case it was
102                  * cleared by the reset.
103                  */
104                 if ( ( rc = mii_restart ( mii ) ) != 0 )
105                         return rc;
106
107                 DBGC ( mii, "MII %p reset after %dms\n", mii, i );
108                 return 0;
109         }
110
111         DBGC ( mii, "MII %p timed out waiting for reset\n", mii );
112         return -ETIMEDOUT;
113 }