Browse Source

[smscusb] Allow for alternative PHY register layouts

The LAN78xx PHY interrupt source and mask registers do not match those
used by the SMSC75xx and SMSC95xx.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 7 years ago
parent
commit
74f934a14e

+ 5
- 2
src/drivers/net/smsc75xx.c View File

350
 		goto err_set_filter;
350
 		goto err_set_filter;
351
 
351
 
352
 	/* Enable PHY interrupts and update link status */
352
 	/* Enable PHY interrupts and update link status */
353
-	if ( ( rc = smscusb_mii_open ( smscusb ) ) != 0 )
353
+	if ( ( rc = smscusb_mii_open ( smscusb, SMSC75XX_MII_PHY_INTR_MASK,
354
+				       ( SMSC75XX_PHY_INTR_ANEG_DONE |
355
+					 SMSC75XX_PHY_INTR_LINK_DOWN ) ) ) != 0)
354
 		goto err_mii_open;
356
 		goto err_mii_open;
355
 
357
 
356
 	return 0;
358
 	return 0;
497
 	smscusb = netdev->priv;
499
 	smscusb = netdev->priv;
498
 	memset ( smscusb, 0, sizeof ( *smscusb ) );
500
 	memset ( smscusb, 0, sizeof ( *smscusb ) );
499
 	smscusb_init ( smscusb, netdev, func, &smsc75xx_in_operations );
501
 	smscusb_init ( smscusb, netdev, func, &smsc75xx_in_operations );
500
-	smscusb_mii_init ( smscusb, SMSC75XX_MII_BASE );
502
+	smscusb_mii_init ( smscusb, SMSC75XX_MII_BASE,
503
+			   SMSC75XX_MII_PHY_INTR_SOURCE );
501
 	usb_refill_init ( &smscusb->usbnet.in, 0, SMSC75XX_IN_MTU,
504
 	usb_refill_init ( &smscusb->usbnet.in, 0, SMSC75XX_IN_MTU,
502
 			  SMSC75XX_IN_MAX_FILL );
505
 			  SMSC75XX_IN_MAX_FILL );
503
 	DBGC ( smscusb, "SMSC75XX %p on %s\n", smscusb, func->name );
506
 	DBGC ( smscusb, "SMSC75XX %p on %s\n", smscusb, func->name );

+ 12
- 0
src/drivers/net/smsc75xx.h View File

66
 /** MII register base */
66
 /** MII register base */
67
 #define SMSC75XX_MII_BASE 0x120
67
 #define SMSC75XX_MII_BASE 0x120
68
 
68
 
69
+/** PHY interrupt source MII register */
70
+#define SMSC75XX_MII_PHY_INTR_SOURCE 29
71
+
72
+/** PHY interrupt mask MII register */
73
+#define SMSC75XX_MII_PHY_INTR_MASK 30
74
+
75
+/** PHY interrupt: auto-negotiation complete */
76
+#define SMSC75XX_PHY_INTR_ANEG_DONE 0x0040
77
+
78
+/** PHY interrupt: link down */
79
+#define SMSC75XX_PHY_INTR_LINK_DOWN 0x0010
80
+
69
 /** MAC address perfect filter register base */
81
 /** MAC address perfect filter register base */
70
 #define SMSC75XX_ADDR_FILT_BASE 0x300
82
 #define SMSC75XX_ADDR_FILT_BASE 0x300
71
 
83
 

+ 5
- 2
src/drivers/net/smsc95xx.c View File

462
 		goto err_set_address;
462
 		goto err_set_address;
463
 
463
 
464
 	/* Enable PHY interrupts and update link status */
464
 	/* Enable PHY interrupts and update link status */
465
-	if ( ( rc = smscusb_mii_open ( smscusb ) ) != 0 )
465
+	if ( ( rc = smscusb_mii_open ( smscusb, SMSC95XX_MII_PHY_INTR_MASK,
466
+				       ( SMSC95XX_PHY_INTR_ANEG_DONE |
467
+					 SMSC95XX_PHY_INTR_LINK_DOWN ) ) ) != 0)
466
 		goto err_mii_open;
468
 		goto err_mii_open;
467
 
469
 
468
 	return 0;
470
 	return 0;
606
 	smscusb = netdev->priv;
608
 	smscusb = netdev->priv;
607
 	memset ( smscusb, 0, sizeof ( *smscusb ) );
609
 	memset ( smscusb, 0, sizeof ( *smscusb ) );
608
 	smscusb_init ( smscusb, netdev, func, &smsc95xx_in_operations );
610
 	smscusb_init ( smscusb, netdev, func, &smsc95xx_in_operations );
609
-	smscusb_mii_init ( smscusb, SMSC95XX_MII_BASE );
611
+	smscusb_mii_init ( smscusb, SMSC95XX_MII_BASE,
612
+			   SMSC95XX_MII_PHY_INTR_SOURCE );
610
 	usb_refill_init ( &smscusb->usbnet.in,
613
 	usb_refill_init ( &smscusb->usbnet.in,
611
 			  ( sizeof ( struct smsc95xx_tx_header ) -
614
 			  ( sizeof ( struct smsc95xx_tx_header ) -
612
 			    sizeof ( struct smsc95xx_rx_header ) ),
615
 			    sizeof ( struct smsc95xx_rx_header ) ),

+ 12
- 0
src/drivers/net/smsc95xx.h View File

65
 /** MII register base */
65
 /** MII register base */
66
 #define SMSC95XX_MII_BASE 0x0114
66
 #define SMSC95XX_MII_BASE 0x0114
67
 
67
 
68
+/** PHY interrupt source MII register */
69
+#define SMSC95XX_MII_PHY_INTR_SOURCE 29
70
+
71
+/** PHY interrupt mask MII register */
72
+#define SMSC95XX_MII_PHY_INTR_MASK 30
73
+
74
+/** PHY interrupt: auto-negotiation complete */
75
+#define SMSC95XX_PHY_INTR_ANEG_DONE 0x0040
76
+
77
+/** PHY interrupt: link down */
78
+#define SMSC95XX_PHY_INTR_LINK_DOWN 0x0010
79
+
68
 /** Receive packet header */
80
 /** Receive packet header */
69
 struct smsc95xx_rx_header {
81
 struct smsc95xx_rx_header {
70
 	/** Command word */
82
 	/** Command word */

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

578
 	int rc;
578
 	int rc;
579
 
579
 
580
 	/* Read PHY interrupt source */
580
 	/* Read PHY interrupt source */
581
-	intr = mii_read ( &smscusb->mii, SMSCUSB_MII_PHY_INTR_SOURCE );
581
+	intr = mii_read ( &smscusb->mii, smscusb->phy_source );
582
 	if ( intr < 0 ) {
582
 	if ( intr < 0 ) {
583
 		rc = intr;
583
 		rc = intr;
584
 		DBGC ( smscusb, "SMSCUSB %p could not get PHY interrupt "
584
 		DBGC ( smscusb, "SMSCUSB %p could not get PHY interrupt "
587
 	}
587
 	}
588
 
588
 
589
 	/* Acknowledge PHY interrupt */
589
 	/* Acknowledge PHY interrupt */
590
-	if ( ( rc = mii_write ( &smscusb->mii, SMSCUSB_MII_PHY_INTR_SOURCE,
590
+	if ( ( rc = mii_write ( &smscusb->mii, smscusb->phy_source,
591
 				intr ) ) != 0 ) {
591
 				intr ) ) != 0 ) {
592
 		DBGC ( smscusb, "SMSCUSB %p could not acknowledge PHY "
592
 		DBGC ( smscusb, "SMSCUSB %p could not acknowledge PHY "
593
 		       "interrupt: %s\n", smscusb, strerror ( rc ) );
593
 		       "interrupt: %s\n", smscusb, strerror ( rc ) );
610
  * Enable PHY interrupts and update link status
610
  * Enable PHY interrupts and update link status
611
  *
611
  *
612
  * @v smscusb		SMSC USB device
612
  * @v smscusb		SMSC USB device
613
+ * @v phy_mask		PHY interrupt mask register
614
+ * @v intrs		PHY interrupts to enable
613
  * @ret rc		Return status code
615
  * @ret rc		Return status code
614
  */
616
  */
615
-int smscusb_mii_open ( struct smscusb_device *smscusb ) {
617
+int smscusb_mii_open ( struct smscusb_device *smscusb,
618
+		       unsigned int phy_mask, unsigned int intrs ) {
616
 	int rc;
619
 	int rc;
617
 
620
 
618
 	/* Enable PHY interrupts */
621
 	/* Enable PHY interrupts */
619
-	if ( ( rc = mii_write ( &smscusb->mii, SMSCUSB_MII_PHY_INTR_MASK,
620
-				( SMSCUSB_PHY_INTR_ANEG_DONE |
621
-				  SMSCUSB_PHY_INTR_LINK_DOWN ) ) ) != 0 ) {
622
+	if ( ( rc = mii_write ( &smscusb->mii, phy_mask, intrs ) ) != 0 ) {
622
 		DBGC ( smscusb, "SMSCUSB %p could not set PHY interrupt "
623
 		DBGC ( smscusb, "SMSCUSB %p could not set PHY interrupt "
623
 		       "mask: %s\n", smscusb, strerror ( rc ) );
624
 		       "mask: %s\n", smscusb, strerror ( rc ) );
624
 		return rc;
625
 		return rc;

+ 8
- 14
src/drivers/net/smscusb.h View File

105
 #define SMSCUSB_MII_DATA_GET(mii_data) \
105
 #define SMSCUSB_MII_DATA_GET(mii_data) \
106
 	( ( (mii_data) >> 0 ) & 0xffff )		/**< Get data */
106
 	( ( (mii_data) >> 0 ) & 0xffff )		/**< Get data */
107
 
107
 
108
-/** PHY interrupt source MII register */
109
-#define SMSCUSB_MII_PHY_INTR_SOURCE 29
110
-
111
-/** PHY interrupt mask MII register */
112
-#define SMSCUSB_MII_PHY_INTR_MASK 30
113
-
114
-/** PHY interrupt: auto-negotiation complete */
115
-#define SMSCUSB_PHY_INTR_ANEG_DONE 0x0040
116
-
117
-/** PHY interrupt: link down */
118
-#define SMSCUSB_PHY_INTR_LINK_DOWN 0x0010
119
-
120
 /** Maximum time to wait for MII (in milliseconds) */
108
 /** Maximum time to wait for MII (in milliseconds) */
121
 #define SMSCUSB_MII_MAX_WAIT_MS 100
109
 #define SMSCUSB_MII_MAX_WAIT_MS 100
122
 
110
 
166
 	struct mii_interface mii;
154
 	struct mii_interface mii;
167
 	/** MII register base */
155
 	/** MII register base */
168
 	uint16_t mii_base;
156
 	uint16_t mii_base;
157
+	/** PHY interrupt source register */
158
+	uint16_t phy_source;
169
 	/** Interrupt status */
159
 	/** Interrupt status */
170
 	uint32_t int_sts;
160
 	uint32_t int_sts;
171
 };
161
 };
279
  *
269
  *
280
  * @v smscusb		SMSC USB device
270
  * @v smscusb		SMSC USB device
281
  * @v mii_base		MII register base
271
  * @v mii_base		MII register base
272
+ * @v phy_source	Interrupt source PHY register
282
  */
273
  */
283
 static inline __attribute__ (( always_inline )) void
274
 static inline __attribute__ (( always_inline )) void
284
-smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base ) {
275
+smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base,
276
+		   unsigned int phy_source ) {
285
 
277
 
286
 	mii_init ( &smscusb->mii, &smscusb_mii_operations );
278
 	mii_init ( &smscusb->mii, &smscusb_mii_operations );
287
 	smscusb->mii_base = mii_base;
279
 	smscusb->mii_base = mii_base;
280
+	smscusb->phy_source = phy_source;
288
 }
281
 }
289
 
282
 
290
 extern int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
283
 extern int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
292
 extern int smscusb_otp_fetch_mac ( struct smscusb_device *smscusb,
285
 extern int smscusb_otp_fetch_mac ( struct smscusb_device *smscusb,
293
 				   unsigned int otp_base );
286
 				   unsigned int otp_base );
294
 extern int smscusb_mii_check_link ( struct smscusb_device *smscusb );
287
 extern int smscusb_mii_check_link ( struct smscusb_device *smscusb );
295
-extern int smscusb_mii_open ( struct smscusb_device *smscusb );
288
+extern int smscusb_mii_open ( struct smscusb_device *smscusb,
289
+			      unsigned int phy_mask, unsigned int intrs );
296
 extern int smscusb_set_address ( struct smscusb_device *smscusb,
290
 extern int smscusb_set_address ( struct smscusb_device *smscusb,
297
 				 unsigned int addr_base );
291
 				 unsigned int addr_base );
298
 extern int smscusb_set_filter ( struct smscusb_device *smscusb,
292
 extern int smscusb_set_filter ( struct smscusb_device *smscusb,

Loading…
Cancel
Save