]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[smscusb] Allow for alternative PHY register layouts
authorMichael Brown <mcb30@ipxe.org>
Mon, 10 Jul 2017 11:38:39 +0000 (12:38 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 10 Jul 2017 11:41:23 +0000 (12:41 +0100)
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>
src/drivers/net/smsc75xx.c
src/drivers/net/smsc75xx.h
src/drivers/net/smsc95xx.c
src/drivers/net/smsc95xx.h
src/drivers/net/smscusb.c
src/drivers/net/smscusb.h

index c04dc1a7ffdff25439773d3ce487b6f51d91a9f3..0da255c209801ea39e69e173e8897f40d33ca58b 100644 (file)
@@ -350,7 +350,9 @@ static int smsc75xx_open ( struct net_device *netdev ) {
                goto err_set_filter;
 
        /* Enable PHY interrupts and update link status */
-       if ( ( rc = smscusb_mii_open ( smscusb ) ) != 0 )
+       if ( ( rc = smscusb_mii_open ( smscusb, SMSC75XX_MII_PHY_INTR_MASK,
+                                      ( SMSC75XX_PHY_INTR_ANEG_DONE |
+                                        SMSC75XX_PHY_INTR_LINK_DOWN ) ) ) != 0)
                goto err_mii_open;
 
        return 0;
@@ -497,7 +499,8 @@ static int smsc75xx_probe ( struct usb_function *func,
        smscusb = netdev->priv;
        memset ( smscusb, 0, sizeof ( *smscusb ) );
        smscusb_init ( smscusb, netdev, func, &smsc75xx_in_operations );
-       smscusb_mii_init ( smscusb, SMSC75XX_MII_BASE );
+       smscusb_mii_init ( smscusb, SMSC75XX_MII_BASE,
+                          SMSC75XX_MII_PHY_INTR_SOURCE );
        usb_refill_init ( &smscusb->usbnet.in, 0, SMSC75XX_IN_MTU,
                          SMSC75XX_IN_MAX_FILL );
        DBGC ( smscusb, "SMSC75XX %p on %s\n", smscusb, func->name );
index 0a330fd9ffa7d823ebb2d8ade487403271d54d96..f8bcefb785ae6df5d6cc9a7e27f568105f992ba2 100644 (file)
@@ -66,6 +66,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** MII register base */
 #define SMSC75XX_MII_BASE 0x120
 
+/** PHY interrupt source MII register */
+#define SMSC75XX_MII_PHY_INTR_SOURCE 29
+
+/** PHY interrupt mask MII register */
+#define SMSC75XX_MII_PHY_INTR_MASK 30
+
+/** PHY interrupt: auto-negotiation complete */
+#define SMSC75XX_PHY_INTR_ANEG_DONE 0x0040
+
+/** PHY interrupt: link down */
+#define SMSC75XX_PHY_INTR_LINK_DOWN 0x0010
+
 /** MAC address perfect filter register base */
 #define SMSC75XX_ADDR_FILT_BASE 0x300
 
index e56cf5b45ad2a06617a600d08b2208826344335b..9b09657db3aca8e78ccb8c819e34a7bb38a898d6 100644 (file)
@@ -462,7 +462,9 @@ static int smsc95xx_open ( struct net_device *netdev ) {
                goto err_set_address;
 
        /* Enable PHY interrupts and update link status */
-       if ( ( rc = smscusb_mii_open ( smscusb ) ) != 0 )
+       if ( ( rc = smscusb_mii_open ( smscusb, SMSC95XX_MII_PHY_INTR_MASK,
+                                      ( SMSC95XX_PHY_INTR_ANEG_DONE |
+                                        SMSC95XX_PHY_INTR_LINK_DOWN ) ) ) != 0)
                goto err_mii_open;
 
        return 0;
@@ -606,7 +608,8 @@ static int smsc95xx_probe ( struct usb_function *func,
        smscusb = netdev->priv;
        memset ( smscusb, 0, sizeof ( *smscusb ) );
        smscusb_init ( smscusb, netdev, func, &smsc95xx_in_operations );
-       smscusb_mii_init ( smscusb, SMSC95XX_MII_BASE );
+       smscusb_mii_init ( smscusb, SMSC95XX_MII_BASE,
+                          SMSC95XX_MII_PHY_INTR_SOURCE );
        usb_refill_init ( &smscusb->usbnet.in,
                          ( sizeof ( struct smsc95xx_tx_header ) -
                            sizeof ( struct smsc95xx_rx_header ) ),
index b0ecf6ee2dc09bf1c562190aa7353be9371053c5..0cdf3824806cf0f2b68dca6eabddd75612cd5b6e 100644 (file)
@@ -65,6 +65,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** MII register base */
 #define SMSC95XX_MII_BASE 0x0114
 
+/** PHY interrupt source MII register */
+#define SMSC95XX_MII_PHY_INTR_SOURCE 29
+
+/** PHY interrupt mask MII register */
+#define SMSC95XX_MII_PHY_INTR_MASK 30
+
+/** PHY interrupt: auto-negotiation complete */
+#define SMSC95XX_PHY_INTR_ANEG_DONE 0x0040
+
+/** PHY interrupt: link down */
+#define SMSC95XX_PHY_INTR_LINK_DOWN 0x0010
+
 /** Receive packet header */
 struct smsc95xx_rx_header {
        /** Command word */
index 19a679c462c0e73c2a094211150698d6773d610a..60390ce31c564e0f4e3f7d529e2a6b293e9c96f0 100644 (file)
@@ -578,7 +578,7 @@ int smscusb_mii_check_link ( struct smscusb_device *smscusb ) {
        int rc;
 
        /* Read PHY interrupt source */
-       intr = mii_read ( &smscusb->mii, SMSCUSB_MII_PHY_INTR_SOURCE );
+       intr = mii_read ( &smscusb->mii, smscusb->phy_source );
        if ( intr < 0 ) {
                rc = intr;
                DBGC ( smscusb, "SMSCUSB %p could not get PHY interrupt "
@@ -587,7 +587,7 @@ int smscusb_mii_check_link ( struct smscusb_device *smscusb ) {
        }
 
        /* Acknowledge PHY interrupt */
-       if ( ( rc = mii_write ( &smscusb->mii, SMSCUSB_MII_PHY_INTR_SOURCE,
+       if ( ( rc = mii_write ( &smscusb->mii, smscusb->phy_source,
                                intr ) ) != 0 ) {
                DBGC ( smscusb, "SMSCUSB %p could not acknowledge PHY "
                       "interrupt: %s\n", smscusb, strerror ( rc ) );
@@ -610,15 +610,16 @@ int smscusb_mii_check_link ( struct smscusb_device *smscusb ) {
  * Enable PHY interrupts and update link status
  *
  * @v smscusb          SMSC USB device
+ * @v phy_mask         PHY interrupt mask register
+ * @v intrs            PHY interrupts to enable
  * @ret rc             Return status code
  */
-int smscusb_mii_open ( struct smscusb_device *smscusb ) {
+int smscusb_mii_open ( struct smscusb_device *smscusb,
+                      unsigned int phy_mask, unsigned int intrs ) {
        int rc;
 
        /* Enable PHY interrupts */
-       if ( ( rc = mii_write ( &smscusb->mii, SMSCUSB_MII_PHY_INTR_MASK,
-                               ( SMSCUSB_PHY_INTR_ANEG_DONE |
-                                 SMSCUSB_PHY_INTR_LINK_DOWN ) ) ) != 0 ) {
+       if ( ( rc = mii_write ( &smscusb->mii, phy_mask, intrs ) ) != 0 ) {
                DBGC ( smscusb, "SMSCUSB %p could not set PHY interrupt "
                       "mask: %s\n", smscusb, strerror ( rc ) );
                return rc;
index d7216d9a8db0d31da9a57dc579b234b555e8a9d3..5e4440ea60fa28963a9baa53a0b6db815ecea41c 100644 (file)
@@ -105,18 +105,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define SMSCUSB_MII_DATA_GET(mii_data) \
        ( ( (mii_data) >> 0 ) & 0xffff )                /**< Get data */
 
-/** PHY interrupt source MII register */
-#define SMSCUSB_MII_PHY_INTR_SOURCE 29
-
-/** PHY interrupt mask MII register */
-#define SMSCUSB_MII_PHY_INTR_MASK 30
-
-/** PHY interrupt: auto-negotiation complete */
-#define SMSCUSB_PHY_INTR_ANEG_DONE 0x0040
-
-/** PHY interrupt: link down */
-#define SMSCUSB_PHY_INTR_LINK_DOWN 0x0010
-
 /** Maximum time to wait for MII (in milliseconds) */
 #define SMSCUSB_MII_MAX_WAIT_MS 100
 
@@ -166,6 +154,8 @@ struct smscusb_device {
        struct mii_interface mii;
        /** MII register base */
        uint16_t mii_base;
+       /** PHY interrupt source register */
+       uint16_t phy_source;
        /** Interrupt status */
        uint32_t int_sts;
 };
@@ -279,12 +269,15 @@ smscusb_init ( struct smscusb_device *smscusb, struct net_device *netdev,
  *
  * @v smscusb          SMSC USB device
  * @v mii_base         MII register base
+ * @v phy_source       Interrupt source PHY register
  */
 static inline __attribute__ (( always_inline )) void
-smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base ) {
+smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base,
+                  unsigned int phy_source ) {
 
        mii_init ( &smscusb->mii, &smscusb_mii_operations );
        smscusb->mii_base = mii_base;
+       smscusb->phy_source = phy_source;
 }
 
 extern int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
@@ -292,7 +285,8 @@ extern int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
 extern int smscusb_otp_fetch_mac ( struct smscusb_device *smscusb,
                                   unsigned int otp_base );
 extern int smscusb_mii_check_link ( struct smscusb_device *smscusb );
-extern int smscusb_mii_open ( struct smscusb_device *smscusb );
+extern int smscusb_mii_open ( struct smscusb_device *smscusb,
+                             unsigned int phy_mask, unsigned int intrs );
 extern int smscusb_set_address ( struct smscusb_device *smscusb,
                                 unsigned int addr_base );
 extern int smscusb_set_filter ( struct smscusb_device *smscusb,