Browse Source

[mii] Separate concepts of MII interface and MII device

We currently have no generic concept of a PHY address, since all
existing implementations simply hardcode the PHY address within the
MII access methods.

A bit-bashing MII interface will need to be provided with an explicit
PHY address in order to generate the correct waveform.  Allow for this
by separating out the concept of a MII device (i.e. a specific PHY
address attached to a particular MII interface).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
6804a8c89b

+ 7
- 7
src/drivers/net/mii.c View File

37
 /**
37
 /**
38
  * Restart autonegotiation
38
  * Restart autonegotiation
39
  *
39
  *
40
- * @v mii		MII interface
40
+ * @v mii		MII device
41
  * @ret rc		Return status code
41
  * @ret rc		Return status code
42
  */
42
  */
43
-int mii_restart ( struct mii_interface *mii ) {
43
+int mii_restart ( struct mii_device *mii ) {
44
 	int bmcr;
44
 	int bmcr;
45
 	int rc;
45
 	int rc;
46
 
46
 
66
 }
66
 }
67
 
67
 
68
 /**
68
 /**
69
- * Reset MII interface
69
+ * Reset MII device
70
  *
70
  *
71
- * @v mii		MII interface
71
+ * @v mii		MII device
72
  * @ret rc		Return status code
72
  * @ret rc		Return status code
73
  */
73
  */
74
-int mii_reset ( struct mii_interface *mii ) {
74
+int mii_reset ( struct mii_device *mii ) {
75
 	unsigned int i;
75
 	unsigned int i;
76
 	int bmcr;
76
 	int bmcr;
77
 	int rc;
77
 	int rc;
119
 /**
119
 /**
120
  * Update link status via MII
120
  * Update link status via MII
121
  *
121
  *
122
- * @v mii		MII interface
122
+ * @v mii		MII device
123
  * @v netdev		Network device
123
  * @v netdev		Network device
124
  * @ret rc		Return status code
124
  * @ret rc		Return status code
125
  */
125
  */
126
-int mii_check_link ( struct mii_interface *mii, struct net_device *netdev ) {
126
+int mii_check_link ( struct mii_device *mii, struct net_device *netdev ) {
127
 	int bmsr;
127
 	int bmsr;
128
 	int link;
128
 	int link;
129
 	int rc;
129
 	int rc;

+ 15
- 8
src/drivers/net/realtek.c View File

242
 /**
242
 /**
243
  * Read from MII register
243
  * Read from MII register
244
  *
244
  *
245
- * @v mii		MII interface
245
+ * @v mdio		MII interface
246
+ * @v phy		PHY address
246
  * @v reg		Register address
247
  * @v reg		Register address
247
  * @ret value		Data read, or negative error
248
  * @ret value		Data read, or negative error
248
  */
249
  */
249
-static int realtek_mii_read ( struct mii_interface *mii, unsigned int reg ) {
250
-	struct realtek_nic *rtl = container_of ( mii, struct realtek_nic, mii );
250
+static int realtek_mii_read ( struct mii_interface *mdio,
251
+			      unsigned int phy __unused, unsigned int reg ) {
252
+	struct realtek_nic *rtl =
253
+		container_of ( mdio, struct realtek_nic, mdio );
251
 	unsigned int i;
254
 	unsigned int i;
252
 	uint32_t value;
255
 	uint32_t value;
253
 
256
 
279
 /**
282
 /**
280
  * Write to MII register
283
  * Write to MII register
281
  *
284
  *
282
- * @v mii		MII interface
285
+ * @v mdio		MII interface
286
+ * @v phy		PHY address
283
  * @v reg		Register address
287
  * @v reg		Register address
284
  * @v data		Data to write
288
  * @v data		Data to write
285
  * @ret rc		Return status code
289
  * @ret rc		Return status code
286
  */
290
  */
287
-static int realtek_mii_write ( struct mii_interface *mii, unsigned int reg,
288
-			       unsigned int data) {
289
-	struct realtek_nic *rtl = container_of ( mii, struct realtek_nic, mii );
291
+static int realtek_mii_write ( struct mii_interface *mdio,
292
+			       unsigned int phy __unused, unsigned int reg,
293
+			       unsigned int data ) {
294
+	struct realtek_nic *rtl =
295
+		container_of ( mdio, struct realtek_nic, mdio );
290
 	unsigned int i;
296
 	unsigned int i;
291
 
297
 
292
 	/* Fail if PHYAR register is not present */
298
 	/* Fail if PHYAR register is not present */
1158
 	}
1164
 	}
1159
 
1165
 
1160
 	/* Initialise and reset MII interface */
1166
 	/* Initialise and reset MII interface */
1161
-	mii_init ( &rtl->mii, &realtek_mii_operations );
1167
+	mdio_init ( &rtl->mdio, &realtek_mii_operations );
1168
+	mii_init ( &rtl->mii, &rtl->mdio, 0 );
1162
 	if ( ( rc = realtek_phy_reset ( rtl ) ) != 0 )
1169
 	if ( ( rc = realtek_phy_reset ( rtl ) ) != 0 )
1163
 		goto err_phy_reset;
1170
 		goto err_phy_reset;
1164
 
1171
 

+ 3
- 1
src/drivers/net/realtek.h View File

283
 	/** Non-volatile options */
283
 	/** Non-volatile options */
284
 	struct nvo_block nvo;
284
 	struct nvo_block nvo;
285
 	/** MII interface */
285
 	/** MII interface */
286
-	struct mii_interface mii;
286
+	struct mii_interface mdio;
287
+	/** MII device */
288
+	struct mii_device mii;
287
 
289
 
288
 	/** Legacy datapath mode */
290
 	/** Legacy datapath mode */
289
 	int legacy;
291
 	int legacy;

+ 12
- 7
src/drivers/net/rhine.c View File

49
 /**
49
 /**
50
  * Read from MII register
50
  * Read from MII register
51
  *
51
  *
52
- * @v mii		MII interface
52
+ * @v mdio		MII interface
53
+ * @v phy		PHY address
53
  * @v reg		Register address
54
  * @v reg		Register address
54
  * @ret value		Data read, or negative error
55
  * @ret value		Data read, or negative error
55
  */
56
  */
56
-static int rhine_mii_read ( struct mii_interface *mii, unsigned int reg ) {
57
-	struct rhine_nic *rhn = container_of ( mii, struct rhine_nic, mii );
57
+static int rhine_mii_read ( struct mii_interface *mdio,
58
+			    unsigned int phy __unused, unsigned int reg ) {
59
+	struct rhine_nic *rhn = container_of ( mdio, struct rhine_nic, mdio );
58
 	unsigned int timeout = RHINE_TIMEOUT_US;
60
 	unsigned int timeout = RHINE_TIMEOUT_US;
59
 	uint8_t cr;
61
 	uint8_t cr;
60
 
62
 
80
 /**
82
 /**
81
  * Write to MII register
83
  * Write to MII register
82
  *
84
  *
83
- * @v mii		MII interface
85
+ * @v mdio		MII interface
86
+ * @v phy		PHY address
84
  * @v reg		Register address
87
  * @v reg		Register address
85
  * @v data		Data to write
88
  * @v data		Data to write
86
  * @ret rc		Return status code
89
  * @ret rc		Return status code
87
  */
90
  */
88
-static int rhine_mii_write ( struct mii_interface *mii, unsigned int reg,
91
+static int rhine_mii_write ( struct mii_interface *mdio,
92
+			     unsigned int phy __unused, unsigned int reg,
89
                              unsigned int data ) {
93
                              unsigned int data ) {
90
-	struct rhine_nic *rhn = container_of ( mii, struct rhine_nic, mii );
94
+	struct rhine_nic *rhn = container_of ( mdio, struct rhine_nic, mdio );
91
 	unsigned int timeout = RHINE_TIMEOUT_US;
95
 	unsigned int timeout = RHINE_TIMEOUT_US;
92
 	uint8_t cr;
96
 	uint8_t cr;
93
 
97
 
719
 		netdev->hw_addr[i] = readb ( rhn->regs + RHINE_MAC + i );
723
 		netdev->hw_addr[i] = readb ( rhn->regs + RHINE_MAC + i );
720
 
724
 
721
 	/* Initialise and reset MII interface */
725
 	/* Initialise and reset MII interface */
722
-	mii_init ( &rhn->mii, &rhine_mii_operations );
726
+	mdio_init ( &rhn->mdio, &rhine_mii_operations );
727
+	mii_init ( &rhn->mii, &rhn->mdio, 0 );
723
 	if ( ( rc = mii_reset ( &rhn->mii ) ) != 0 ) {
728
 	if ( ( rc = mii_reset ( &rhn->mii ) ) != 0 ) {
724
 		DBGC ( rhn, "RHINE %p could not reset MII: %s\n",
729
 		DBGC ( rhn, "RHINE %p could not reset MII: %s\n",
725
 		       rhn, strerror ( rc ) );
730
 		       rhn, strerror ( rc ) );

+ 3
- 1
src/drivers/net/rhine.h View File

237
 	uint8_t cr1;
237
 	uint8_t cr1;
238
 
238
 
239
 	/** MII interface */
239
 	/** MII interface */
240
-	struct mii_interface mii;
240
+	struct mii_interface mdio;
241
+	/** MII device */
242
+	struct mii_device mii;
241
 
243
 
242
 	/** Transmit descriptor ring */
244
 	/** Transmit descriptor ring */
243
 	struct rhine_ring tx;
245
 	struct rhine_ring tx;

+ 10
- 6
src/drivers/net/smscusb.c View File

481
 /**
481
 /**
482
  * Read from MII register
482
  * Read from MII register
483
  *
483
  *
484
- * @v mii		MII interface
484
+ * @v mdio		MII interface
485
+ * @v phy		PHY address
485
  * @v reg		Register address
486
  * @v reg		Register address
486
  * @ret value		Data read, or negative error
487
  * @ret value		Data read, or negative error
487
  */
488
  */
488
-static int smscusb_mii_read ( struct mii_interface *mii, unsigned int reg ) {
489
+static int smscusb_mii_read ( struct mii_interface *mdio,
490
+			      unsigned int phy __unused, unsigned int reg ) {
489
 	struct smscusb_device *smscusb =
491
 	struct smscusb_device *smscusb =
490
-		container_of ( mii, struct smscusb_device, mii );
492
+		container_of ( mdio, struct smscusb_device, mdio );
491
 	unsigned int base = smscusb->mii_base;
493
 	unsigned int base = smscusb->mii_base;
492
 	uint32_t mii_access;
494
 	uint32_t mii_access;
493
 	uint32_t mii_data;
495
 	uint32_t mii_data;
520
 /**
522
 /**
521
  * Write to MII register
523
  * Write to MII register
522
  *
524
  *
523
- * @v mii		MII interface
525
+ * @v mdio		MII interface
526
+ * @v phy		PHY address
524
  * @v reg		Register address
527
  * @v reg		Register address
525
  * @v data		Data to write
528
  * @v data		Data to write
526
  * @ret rc		Return status code
529
  * @ret rc		Return status code
527
  */
530
  */
528
-static int smscusb_mii_write ( struct mii_interface *mii, unsigned int reg,
531
+static int smscusb_mii_write ( struct mii_interface *mdio,
532
+			       unsigned int phy __unused, unsigned int reg,
529
 			       unsigned int data ) {
533
 			       unsigned int data ) {
530
 	struct smscusb_device *smscusb =
534
 	struct smscusb_device *smscusb =
531
-		container_of ( mii, struct smscusb_device, mii );
535
+		container_of ( mdio, struct smscusb_device, mdio );
532
 	unsigned int base = smscusb->mii_base;
536
 	unsigned int base = smscusb->mii_base;
533
 	uint32_t mii_access;
537
 	uint32_t mii_access;
534
 	uint32_t mii_data;
538
 	uint32_t mii_data;

+ 5
- 2
src/drivers/net/smscusb.h View File

151
 	/** USB network device */
151
 	/** USB network device */
152
 	struct usbnet_device usbnet;
152
 	struct usbnet_device usbnet;
153
 	/** MII interface */
153
 	/** MII interface */
154
-	struct mii_interface mii;
154
+	struct mii_interface mdio;
155
+	/** MII device */
156
+	struct mii_device mii;
155
 	/** MII register base */
157
 	/** MII register base */
156
 	uint16_t mii_base;
158
 	uint16_t mii_base;
157
 	/** PHY interrupt source register */
159
 	/** PHY interrupt source register */
275
 smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base,
277
 smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base,
276
 		   unsigned int phy_source ) {
278
 		   unsigned int phy_source ) {
277
 
279
 
278
-	mii_init ( &smscusb->mii, &smscusb_mii_operations );
280
+	mdio_init ( &smscusb->mdio, &smscusb_mii_operations );
281
+	mii_init ( &smscusb->mii, &smscusb->mdio, 0 );
279
 	smscusb->mii_base = mii_base;
282
 	smscusb->mii_base = mii_base;
280
 	smscusb->phy_source = phy_source;
283
 	smscusb->phy_source = phy_source;
281
 }
284
 }

+ 12
- 7
src/drivers/net/velocity.c View File

100
 /**
100
 /**
101
  * Read from MII register
101
  * Read from MII register
102
  *
102
  *
103
- * @v mii		MII interface
103
+ * @v mdio		MII interface
104
+ * @v phy		PHY address
104
  * @v reg		Register address
105
  * @v reg		Register address
105
  * @ret value		Data read, or negative error
106
  * @ret value		Data read, or negative error
106
  */
107
  */
107
-static int velocity_mii_read ( struct mii_interface *mii, unsigned int reg ) {
108
+static int velocity_mii_read ( struct mii_interface *mdio,
109
+			       unsigned int phy __unused, unsigned int reg ) {
108
 	struct velocity_nic *vlc =
110
 	struct velocity_nic *vlc =
109
-		container_of ( mii, struct velocity_nic, mii );
111
+		container_of ( mdio, struct velocity_nic, mdio );
110
 	int timeout = VELOCITY_TIMEOUT_US;
112
 	int timeout = VELOCITY_TIMEOUT_US;
111
 	int result;
113
 	int result;
112
 
114
 
140
 /**
142
 /**
141
  * Write to MII register
143
  * Write to MII register
142
  *
144
  *
143
- * @v mii		MII interface
145
+ * @v mdio		MII interface
146
+ * @v phy		PHY address
144
  * @v reg		Register address
147
  * @v reg		Register address
145
  * @v data		Data to write
148
  * @v data		Data to write
146
  * @ret rc		Return status code
149
  * @ret rc		Return status code
147
  */
150
  */
148
-static int velocity_mii_write ( struct mii_interface *mii, unsigned int reg,
151
+static int velocity_mii_write ( struct mii_interface *mdio,
152
+				unsigned int phy __unused, unsigned int reg,
149
 				unsigned int data) {
153
 				unsigned int data) {
150
 	struct velocity_nic *vlc =
154
 	struct velocity_nic *vlc =
151
-		container_of ( mii, struct velocity_nic, mii );
155
+		container_of ( mdio, struct velocity_nic, mdio );
152
 	int timeout = VELOCITY_TIMEOUT_US;
156
 	int timeout = VELOCITY_TIMEOUT_US;
153
 
157
 
154
 	DBGC2 ( vlc, "VELOCITY %p MII write reg %d data 0x%04x\n",
158
 	DBGC2 ( vlc, "VELOCITY %p MII write reg %d data 0x%04x\n",
747
 	netdev->hw_addr[5] = readb ( vlc->regs + VELOCITY_MAC5 );
751
 	netdev->hw_addr[5] = readb ( vlc->regs + VELOCITY_MAC5 );
748
 
752
 
749
 	/* Initialise and reset MII interface */
753
 	/* Initialise and reset MII interface */
750
-	mii_init ( &vlc->mii, &velocity_mii_operations );
754
+	mdio_init ( &vlc->mdio, &velocity_mii_operations );
755
+	mii_init ( &vlc->mii, &vlc->mdio, 0 );
751
 	if ( ( rc = mii_reset ( &vlc->mii ) ) != 0 ) {
756
 	if ( ( rc = mii_reset ( &vlc->mii ) ) != 0 ) {
752
 		DBGC ( vlc, "VELOCITY %p could not reset MII: %s\n",
757
 		DBGC ( vlc, "VELOCITY %p could not reset MII: %s\n",
753
 		       vlc, strerror ( rc ) );
758
 		       vlc, strerror ( rc ) );

+ 3
- 1
src/drivers/net/velocity.h View File

326
 	/** Registers */
326
 	/** Registers */
327
 	void *regs;
327
 	void *regs;
328
 	/** MII interface */
328
 	/** MII interface */
329
-	struct mii_interface mii;
329
+	struct mii_interface mdio;
330
+	/** MII device */
331
+	struct mii_device mii;
330
 	/** Netdev */
332
 	/** Netdev */
331
 	struct net_device *netdev;
333
 	struct net_device *netdev;
332
 
334
 

+ 48
- 19
src/include/ipxe/mii.h View File

19
 	/**
19
 	/**
20
 	 * Read from MII register
20
 	 * Read from MII register
21
 	 *
21
 	 *
22
-	 * @v mii		MII interface
22
+	 * @v mdio		MII interface
23
+	 * @v phy		PHY address
23
 	 * @v reg		Register address
24
 	 * @v reg		Register address
24
 	 * @ret data		Data read, or negative error
25
 	 * @ret data		Data read, or negative error
25
 	 */
26
 	 */
26
-	int ( * read ) ( struct mii_interface *mii, unsigned int reg );
27
+	int ( * read ) ( struct mii_interface *mdio, unsigned int phy,
28
+			 unsigned int reg );
27
 	/**
29
 	/**
28
 	 * Write to MII register
30
 	 * Write to MII register
29
 	 *
31
 	 *
30
-	 * @v mii		MII interface
32
+	 * @v mdio		MII interface
33
+	 * @v phy		PHY address
31
 	 * @v reg		Register address
34
 	 * @v reg		Register address
32
 	 * @v data		Data to write
35
 	 * @v data		Data to write
33
 	 * @ret rc		Return status code
36
 	 * @ret rc		Return status code
34
 	 */
37
 	 */
35
-	int ( * write ) ( struct mii_interface *mii, unsigned int reg,
36
-			  unsigned int data );
38
+	int ( * write ) ( struct mii_interface *mdio, unsigned int phy,
39
+			  unsigned int reg, unsigned int data );
37
 };
40
 };
38
 
41
 
39
 /** An MII interface */
42
 /** An MII interface */
42
 	struct mii_operations *op;
45
 	struct mii_operations *op;
43
 };
46
 };
44
 
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
+
45
 /**
56
 /**
46
  * Initialise MII interface
57
  * Initialise MII interface
47
  *
58
  *
48
- * @v mii		MII interface
59
+ * @v mdio		MII interface
49
  * @v op		MII interface operations
60
  * @v op		MII interface operations
50
  */
61
  */
51
 static inline __attribute__ (( always_inline )) void
62
 static inline __attribute__ (( always_inline )) void
52
-mii_init ( struct mii_interface *mii, struct mii_operations *op ) {
53
-	mii->op = op;
63
+mdio_init ( struct mii_interface *mdio, struct mii_operations *op ) {
64
+	mdio->op = op;
54
 }
65
 }
55
 
66
 
56
 /**
67
 /**
57
- * Read from MII register
68
+ * Initialise MII device
58
  *
69
  *
70
+ * @v mii		MII device
59
  * @v mii		MII interface
71
  * @v mii		MII interface
72
+ * @v address		PHY address
73
+ */
74
+static inline __attribute__ (( always_inline )) void
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
60
  * @v reg		Register address
85
  * @v reg		Register address
61
  * @ret data		Data read, or negative error
86
  * @ret data		Data read, or negative error
62
  */
87
  */
63
 static inline __attribute__ (( always_inline )) int
88
 static inline __attribute__ (( always_inline )) int
64
-mii_read ( struct mii_interface *mii, unsigned int reg ) {
65
-	return mii->op->read ( mii, 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 );
66
 }
93
 }
67
 
94
 
68
 /**
95
 /**
69
  * Write to MII register
96
  * Write to MII register
70
  *
97
  *
71
- * @v mii		MII interface
98
+ * @v mii		MII device
72
  * @v reg		Register address
99
  * @v reg		Register address
73
  * @v data		Data to write
100
  * @v data		Data to write
74
  * @ret rc		Return status code
101
  * @ret rc		Return status code
75
  */
102
  */
76
 static inline __attribute__ (( always_inline )) int
103
 static inline __attribute__ (( always_inline )) int
77
-mii_write ( struct mii_interface *mii, unsigned int reg, unsigned int data ) {
78
-	return mii->op->write ( mii, reg, 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 );
79
 }
108
 }
80
 
109
 
81
 /**
110
 /**
82
  * Dump MII registers (for debugging)
111
  * Dump MII registers (for debugging)
83
  *
112
  *
84
- * @v mii		MII interface
113
+ * @v mii		MII device
85
  */
114
  */
86
 static inline void
115
 static inline void
87
-mii_dump ( struct mii_interface *mii ) {
116
+mii_dump ( struct mii_device *mii ) {
88
 	unsigned int i;
117
 	unsigned int i;
89
 	int data;
118
 	int data;
90
 
119
 
112
 /** Maximum time to wait for a reset, in milliseconds */
141
 /** Maximum time to wait for a reset, in milliseconds */
113
 #define MII_RESET_MAX_WAIT_MS 500
142
 #define MII_RESET_MAX_WAIT_MS 500
114
 
143
 
115
-extern int mii_restart ( struct mii_interface *mii );
116
-extern int mii_reset ( struct mii_interface *mii );
117
-extern int mii_check_link ( struct mii_interface *mii,
144
+extern int mii_restart ( struct mii_device *mii );
145
+extern int mii_reset ( struct mii_device *mii );
146
+extern int mii_check_link ( struct mii_device *mii,
118
 			    struct net_device *netdev );
147
 			    struct net_device *netdev );
119
 
148
 
120
 #endif /* _IPXE_MII_H */
149
 #endif /* _IPXE_MII_H */

Loading…
Cancel
Save