1 #ifndef _IPXE_MII_H
2 #define _IPXE_MII_H
3
4 /** @file
5 *
6 * Media Independent Interface
7 *
8 */
9
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
12 #include <mii.h>
13 #include <ipxe/netdevice.h>
14
15 struct mii_interface;
16
17 /** MII interface operations */
18 struct mii_operations {
19 /**
20 * Read from MII register
21 *
22 * @v mdio MII interface
23 * @v phy PHY address
24 * @v reg Register address
25 * @ret data Data read, or negative error
26 */
27 int ( * read ) ( struct mii_interface *mdio, unsigned int phy,
28 unsigned int reg );
29 /**
30 * Write to MII register
31 *
32 * @v mdio MII interface
33 * @v phy PHY address
34 * @v reg Register address
35 * @v data Data to write
36 * @ret rc Return status code
37 */
38 int ( * write ) ( struct mii_interface *mdio, unsigned int phy,
39 unsigned int reg, unsigned int data );
40 };
41
42 /** An MII interface */
43 struct mii_interface {
44 /** Interface operations */
45 struct mii_operations *op;
46 };
47
48 /** An MII device */
49 struct mii_device {
50 /** MII interface */
51 struct mii_interface *mdio;
52 /** PHY address */
53 unsigned int address;
54 };
55
56 /**
57 * Initialise MII interface
58 *
59 * @v mdio MII interface
60 * @v op MII interface operations
61 */
62 static inline __attribute__ (( always_inline )) void
mdio_init(struct mii_interface * mdio,struct mii_operations * op)63 mdio_init ( struct mii_interface *mdio, struct mii_operations *op ) {
64 mdio->op = op;
65 }
66
67 /**
68 * Initialise MII device
69 *
70 * @v mii MII device
71 * @v mdio MII interface
72 * @v address PHY address
73 */
74 static inline __attribute__ (( always_inline )) void
mii_init(struct mii_device * mii,struct mii_interface * mdio,unsigned int address)75 mii_init ( struct mii_device *mii, struct mii_interface *mdio,
76 unsigned int address ) {
77 mii->mdio = mdio;
78 mii->address = address;
79 }
80
81 /**
82 * Read from MII register
83 *
84 * @v mii MII device
85 * @v reg Register address
86 * @ret data Data read, or negative error
87 */
88 static inline __attribute__ (( always_inline )) int
mii_read(struct mii_device * mii,unsigned int reg)89 mii_read ( struct mii_device *mii, unsigned int reg ) {
90 struct mii_interface *mdio = mii->mdio;
91
92 return mdio->op->read ( mdio, mii->address, reg );
93 }
94
95 /**
96 * Write to MII register
97 *
98 * @v mii MII device
99 * @v reg Register address
100 * @v data Data to write
101 * @ret rc Return status code
102 */
103 static inline __attribute__ (( always_inline )) int
mii_write(struct mii_device * mii,unsigned int reg,unsigned int data)104 mii_write ( struct mii_device *mii, unsigned int reg, unsigned int data ) {
105 struct mii_interface *mdio = mii->mdio;
106
107 return mdio->op->write ( mdio, mii->address, reg, data );
108 }
109
110 /**
111 * Dump MII registers (for debugging)
112 *
113 * @v mii MII device
114 */
115 static inline void
mii_dump(struct mii_device * mii)116 mii_dump ( struct mii_device *mii ) {
117 unsigned int i;
118 int data;
119
120 /* Do nothing unless debug output is enabled */
121 if ( ! DBG_LOG )
122 return;
123
124 /* Dump basic MII register set */
125 for ( i = 0 ; i < 16 ; i++ ) {
126 if ( ( i % 8 ) == 0 ) {
127 DBGC ( mii, "MII %p registers %02x-%02x:",
128 mii, i, ( i + 7 ) );
129 }
130 data = mii_read ( mii, i );
131 if ( data >= 0 ) {
132 DBGC ( mii, " %04x", data );
133 } else {
134 DBGC ( mii, " XXXX" );
135 }
136 if ( ( i % 8 ) == 7 )
137 DBGC ( mii, "\n" );
138 }
139 }
140
141 /** Maximum time to wait for a reset, in milliseconds */
142 #define MII_RESET_MAX_WAIT_MS 500
143
144 /** Maximum PHY address */
145 #define MII_MAX_PHY_ADDRESS 31
146
147 extern int mii_restart ( struct mii_device *mii );
148 extern int mii_reset ( struct mii_device *mii );
149 extern int mii_check_link ( struct mii_device *mii,
150 struct net_device *netdev );
151 extern int mii_find ( struct mii_device *mii );
152
153 #endif /* _IPXE_MII_H */
154