Parcourir la 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 il y a 6 ans
Parent
révision
6804a8c89b

+ 7
- 7
src/drivers/net/mii.c Voir le fichier

@@ -37,10 +37,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
37 37
 /**
38 38
  * Restart autonegotiation
39 39
  *
40
- * @v mii		MII interface
40
+ * @v mii		MII device
41 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 44
 	int bmcr;
45 45
 	int rc;
46 46
 
@@ -66,12 +66,12 @@ int mii_restart ( struct mii_interface *mii ) {
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 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 75
 	unsigned int i;
76 76
 	int bmcr;
77 77
 	int rc;
@@ -119,11 +119,11 @@ int mii_reset ( struct mii_interface *mii ) {
119 119
 /**
120 120
  * Update link status via MII
121 121
  *
122
- * @v mii		MII interface
122
+ * @v mii		MII device
123 123
  * @v netdev		Network device
124 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 127
 	int bmsr;
128 128
 	int link;
129 129
 	int rc;

+ 15
- 8
src/drivers/net/realtek.c Voir le fichier

@@ -242,12 +242,15 @@ static int realtek_init_eeprom ( struct net_device *netdev ) {
242 242
 /**
243 243
  * Read from MII register
244 244
  *
245
- * @v mii		MII interface
245
+ * @v mdio		MII interface
246
+ * @v phy		PHY address
246 247
  * @v reg		Register address
247 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 254
 	unsigned int i;
252 255
 	uint32_t value;
253 256
 
@@ -279,14 +282,17 @@ static int realtek_mii_read ( struct mii_interface *mii, unsigned int reg ) {
279 282
 /**
280 283
  * Write to MII register
281 284
  *
282
- * @v mii		MII interface
285
+ * @v mdio		MII interface
286
+ * @v phy		PHY address
283 287
  * @v reg		Register address
284 288
  * @v data		Data to write
285 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 296
 	unsigned int i;
291 297
 
292 298
 	/* Fail if PHYAR register is not present */
@@ -1158,7 +1164,8 @@ static int realtek_probe ( struct pci_device *pci ) {
1158 1164
 	}
1159 1165
 
1160 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 1169
 	if ( ( rc = realtek_phy_reset ( rtl ) ) != 0 )
1163 1170
 		goto err_phy_reset;
1164 1171
 

+ 3
- 1
src/drivers/net/realtek.h Voir le fichier

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

+ 12
- 7
src/drivers/net/rhine.c Voir le fichier

@@ -49,12 +49,14 @@ FILE_LICENCE ( GPL2_OR_LATER );
49 49
 /**
50 50
  * Read from MII register
51 51
  *
52
- * @v mii		MII interface
52
+ * @v mdio		MII interface
53
+ * @v phy		PHY address
53 54
  * @v reg		Register address
54 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 60
 	unsigned int timeout = RHINE_TIMEOUT_US;
59 61
 	uint8_t cr;
60 62
 
@@ -80,14 +82,16 @@ static int rhine_mii_read ( struct mii_interface *mii, unsigned int reg ) {
80 82
 /**
81 83
  * Write to MII register
82 84
  *
83
- * @v mii		MII interface
85
+ * @v mdio		MII interface
86
+ * @v phy		PHY address
84 87
  * @v reg		Register address
85 88
  * @v data		Data to write
86 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 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 95
 	unsigned int timeout = RHINE_TIMEOUT_US;
92 96
 	uint8_t cr;
93 97
 
@@ -719,7 +723,8 @@ static int rhine_probe ( struct pci_device *pci ) {
719 723
 		netdev->hw_addr[i] = readb ( rhn->regs + RHINE_MAC + i );
720 724
 
721 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 728
 	if ( ( rc = mii_reset ( &rhn->mii ) ) != 0 ) {
724 729
 		DBGC ( rhn, "RHINE %p could not reset MII: %s\n",
725 730
 		       rhn, strerror ( rc ) );

+ 3
- 1
src/drivers/net/rhine.h Voir le fichier

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

+ 10
- 6
src/drivers/net/smscusb.c Voir le fichier

@@ -481,13 +481,15 @@ static int smscusb_mii_wait ( struct smscusb_device *smscusb ) {
481 481
 /**
482 482
  * Read from MII register
483 483
  *
484
- * @v mii		MII interface
484
+ * @v mdio		MII interface
485
+ * @v phy		PHY address
485 486
  * @v reg		Register address
486 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 491
 	struct smscusb_device *smscusb =
490
-		container_of ( mii, struct smscusb_device, mii );
492
+		container_of ( mdio, struct smscusb_device, mdio );
491 493
 	unsigned int base = smscusb->mii_base;
492 494
 	uint32_t mii_access;
493 495
 	uint32_t mii_data;
@@ -520,15 +522,17 @@ static int smscusb_mii_read ( struct mii_interface *mii, unsigned int reg ) {
520 522
 /**
521 523
  * Write to MII register
522 524
  *
523
- * @v mii		MII interface
525
+ * @v mdio		MII interface
526
+ * @v phy		PHY address
524 527
  * @v reg		Register address
525 528
  * @v data		Data to write
526 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 533
 			       unsigned int data ) {
530 534
 	struct smscusb_device *smscusb =
531
-		container_of ( mii, struct smscusb_device, mii );
535
+		container_of ( mdio, struct smscusb_device, mdio );
532 536
 	unsigned int base = smscusb->mii_base;
533 537
 	uint32_t mii_access;
534 538
 	uint32_t mii_data;

+ 5
- 2
src/drivers/net/smscusb.h Voir le fichier

@@ -151,7 +151,9 @@ struct smscusb_device {
151 151
 	/** USB network device */
152 152
 	struct usbnet_device usbnet;
153 153
 	/** MII interface */
154
-	struct mii_interface mii;
154
+	struct mii_interface mdio;
155
+	/** MII device */
156
+	struct mii_device mii;
155 157
 	/** MII register base */
156 158
 	uint16_t mii_base;
157 159
 	/** PHY interrupt source register */
@@ -275,7 +277,8 @@ static inline __attribute__ (( always_inline )) void
275 277
 smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base,
276 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 282
 	smscusb->mii_base = mii_base;
280 283
 	smscusb->phy_source = phy_source;
281 284
 }

+ 12
- 7
src/drivers/net/velocity.c Voir le fichier

@@ -100,13 +100,15 @@ static int velocity_autopoll_start ( struct velocity_nic *vlc ) {
100 100
 /**
101 101
  * Read from MII register
102 102
  *
103
- * @v mii		MII interface
103
+ * @v mdio		MII interface
104
+ * @v phy		PHY address
104 105
  * @v reg		Register address
105 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 110
 	struct velocity_nic *vlc =
109
-		container_of ( mii, struct velocity_nic, mii );
111
+		container_of ( mdio, struct velocity_nic, mdio );
110 112
 	int timeout = VELOCITY_TIMEOUT_US;
111 113
 	int result;
112 114
 
@@ -140,15 +142,17 @@ static int velocity_mii_read ( struct mii_interface *mii, unsigned int reg ) {
140 142
 /**
141 143
  * Write to MII register
142 144
  *
143
- * @v mii		MII interface
145
+ * @v mdio		MII interface
146
+ * @v phy		PHY address
144 147
  * @v reg		Register address
145 148
  * @v data		Data to write
146 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 153
 				unsigned int data) {
150 154
 	struct velocity_nic *vlc =
151
-		container_of ( mii, struct velocity_nic, mii );
155
+		container_of ( mdio, struct velocity_nic, mdio );
152 156
 	int timeout = VELOCITY_TIMEOUT_US;
153 157
 
154 158
 	DBGC2 ( vlc, "VELOCITY %p MII write reg %d data 0x%04x\n",
@@ -747,7 +751,8 @@ static int velocity_probe ( struct pci_device *pci ) {
747 751
 	netdev->hw_addr[5] = readb ( vlc->regs + VELOCITY_MAC5 );
748 752
 
749 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 756
 	if ( ( rc = mii_reset ( &vlc->mii ) ) != 0 ) {
752 757
 		DBGC ( vlc, "VELOCITY %p could not reset MII: %s\n",
753 758
 		       vlc, strerror ( rc ) );

+ 3
- 1
src/drivers/net/velocity.h Voir le fichier

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

+ 48
- 19
src/include/ipxe/mii.h Voir le fichier

@@ -19,21 +19,24 @@ struct mii_operations {
19 19
 	/**
20 20
 	 * Read from MII register
21 21
 	 *
22
-	 * @v mii		MII interface
22
+	 * @v mdio		MII interface
23
+	 * @v phy		PHY address
23 24
 	 * @v reg		Register address
24 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 30
 	 * Write to MII register
29 31
 	 *
30
-	 * @v mii		MII interface
32
+	 * @v mdio		MII interface
33
+	 * @v phy		PHY address
31 34
 	 * @v reg		Register address
32 35
 	 * @v data		Data to write
33 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 42
 /** An MII interface */
@@ -42,49 +45,75 @@ struct mii_interface {
42 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 57
  * Initialise MII interface
47 58
  *
48
- * @v mii		MII interface
59
+ * @v mdio		MII interface
49 60
  * @v op		MII interface operations
50 61
  */
51 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 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 85
  * @v reg		Register address
61 86
  * @ret data		Data read, or negative error
62 87
  */
63 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 96
  * Write to MII register
70 97
  *
71
- * @v mii		MII interface
98
+ * @v mii		MII device
72 99
  * @v reg		Register address
73 100
  * @v data		Data to write
74 101
  * @ret rc		Return status code
75 102
  */
76 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 111
  * Dump MII registers (for debugging)
83 112
  *
84
- * @v mii		MII interface
113
+ * @v mii		MII device
85 114
  */
86 115
 static inline void
87
-mii_dump ( struct mii_interface *mii ) {
116
+mii_dump ( struct mii_device *mii ) {
88 117
 	unsigned int i;
89 118
 	int data;
90 119
 
@@ -112,9 +141,9 @@ mii_dump ( struct mii_interface *mii ) {
112 141
 /** Maximum time to wait for a reset, in milliseconds */
113 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 147
 			    struct net_device *netdev );
119 148
 
120 149
 #endif /* _IPXE_MII_H */

Chargement…
Annuler
Enregistrer