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