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 6 years ago
parent
commit
74f934a14e

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

@@ -350,7 +350,9 @@ static int smsc75xx_open ( struct net_device *netdev ) {
350 350
 		goto err_set_filter;
351 351
 
352 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 356
 		goto err_mii_open;
355 357
 
356 358
 	return 0;
@@ -497,7 +499,8 @@ static int smsc75xx_probe ( struct usb_function *func,
497 499
 	smscusb = netdev->priv;
498 500
 	memset ( smscusb, 0, sizeof ( *smscusb ) );
499 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 504
 	usb_refill_init ( &smscusb->usbnet.in, 0, SMSC75XX_IN_MTU,
502 505
 			  SMSC75XX_IN_MAX_FILL );
503 506
 	DBGC ( smscusb, "SMSC75XX %p on %s\n", smscusb, func->name );

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

@@ -66,6 +66,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
66 66
 /** MII register base */
67 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 81
 /** MAC address perfect filter register base */
70 82
 #define SMSC75XX_ADDR_FILT_BASE 0x300
71 83
 

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

@@ -462,7 +462,9 @@ static int smsc95xx_open ( struct net_device *netdev ) {
462 462
 		goto err_set_address;
463 463
 
464 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 468
 		goto err_mii_open;
467 469
 
468 470
 	return 0;
@@ -606,7 +608,8 @@ static int smsc95xx_probe ( struct usb_function *func,
606 608
 	smscusb = netdev->priv;
607 609
 	memset ( smscusb, 0, sizeof ( *smscusb ) );
608 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 613
 	usb_refill_init ( &smscusb->usbnet.in,
611 614
 			  ( sizeof ( struct smsc95xx_tx_header ) -
612 615
 			    sizeof ( struct smsc95xx_rx_header ) ),

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

@@ -65,6 +65,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
65 65
 /** MII register base */
66 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 80
 /** Receive packet header */
69 81
 struct smsc95xx_rx_header {
70 82
 	/** Command word */

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

@@ -578,7 +578,7 @@ int smscusb_mii_check_link ( struct smscusb_device *smscusb ) {
578 578
 	int rc;
579 579
 
580 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 582
 	if ( intr < 0 ) {
583 583
 		rc = intr;
584 584
 		DBGC ( smscusb, "SMSCUSB %p could not get PHY interrupt "
@@ -587,7 +587,7 @@ int smscusb_mii_check_link ( struct smscusb_device *smscusb ) {
587 587
 	}
588 588
 
589 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 591
 				intr ) ) != 0 ) {
592 592
 		DBGC ( smscusb, "SMSCUSB %p could not acknowledge PHY "
593 593
 		       "interrupt: %s\n", smscusb, strerror ( rc ) );
@@ -610,15 +610,16 @@ int smscusb_mii_check_link ( struct smscusb_device *smscusb ) {
610 610
  * Enable PHY interrupts and update link status
611 611
  *
612 612
  * @v smscusb		SMSC USB device
613
+ * @v phy_mask		PHY interrupt mask register
614
+ * @v intrs		PHY interrupts to enable
613 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 619
 	int rc;
617 620
 
618 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 623
 		DBGC ( smscusb, "SMSCUSB %p could not set PHY interrupt "
623 624
 		       "mask: %s\n", smscusb, strerror ( rc ) );
624 625
 		return rc;

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

@@ -105,18 +105,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
105 105
 #define SMSCUSB_MII_DATA_GET(mii_data) \
106 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 108
 /** Maximum time to wait for MII (in milliseconds) */
121 109
 #define SMSCUSB_MII_MAX_WAIT_MS 100
122 110
 
@@ -166,6 +154,8 @@ struct smscusb_device {
166 154
 	struct mii_interface mii;
167 155
 	/** MII register base */
168 156
 	uint16_t mii_base;
157
+	/** PHY interrupt source register */
158
+	uint16_t phy_source;
169 159
 	/** Interrupt status */
170 160
 	uint32_t int_sts;
171 161
 };
@@ -279,12 +269,15 @@ smscusb_init ( struct smscusb_device *smscusb, struct net_device *netdev,
279 269
  *
280 270
  * @v smscusb		SMSC USB device
281 271
  * @v mii_base		MII register base
272
+ * @v phy_source	Interrupt source PHY register
282 273
  */
283 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 278
 	mii_init ( &smscusb->mii, &smscusb_mii_operations );
287 279
 	smscusb->mii_base = mii_base;
280
+	smscusb->phy_source = phy_source;
288 281
 }
289 282
 
290 283
 extern int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
@@ -292,7 +285,8 @@ extern int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
292 285
 extern int smscusb_otp_fetch_mac ( struct smscusb_device *smscusb,
293 286
 				   unsigned int otp_base );
294 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 290
 extern int smscusb_set_address ( struct smscusb_device *smscusb,
297 291
 				 unsigned int addr_base );
298 292
 extern int smscusb_set_filter ( struct smscusb_device *smscusb,

Loading…
Cancel
Save