summaryrefslogtreecommitdiffstats
path: root/src/drivers
diff options
context:
space:
mode:
authorMichael Brown2017-07-10 13:38:39 +0200
committerMichael Brown2017-07-10 13:41:23 +0200
commit74f934a14e8d0bead8086433596745e7c2b67990 (patch)
tree2ca329bea266f5aa5507ca1a80c5a90ee5d7a6a4 /src/drivers
parent[smscusb] Move non-inline register access functions to smscusb.c (diff)
downloadipxe-74f934a14e8d0bead8086433596745e7c2b67990.tar.gz
ipxe-74f934a14e8d0bead8086433596745e7c2b67990.tar.xz
ipxe-74f934a14e8d0bead8086433596745e7c2b67990.zip
[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>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/net/smsc75xx.c7
-rw-r--r--src/drivers/net/smsc75xx.h12
-rw-r--r--src/drivers/net/smsc95xx.c7
-rw-r--r--src/drivers/net/smsc95xx.h12
-rw-r--r--src/drivers/net/smscusb.c13
-rw-r--r--src/drivers/net/smscusb.h22
6 files changed, 49 insertions, 24 deletions
diff --git a/src/drivers/net/smsc75xx.c b/src/drivers/net/smsc75xx.c
index c04dc1a7..0da255c2 100644
--- a/src/drivers/net/smsc75xx.c
+++ b/src/drivers/net/smsc75xx.c
@@ -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 );
diff --git a/src/drivers/net/smsc75xx.h b/src/drivers/net/smsc75xx.h
index 0a330fd9..f8bcefb7 100644
--- a/src/drivers/net/smsc75xx.h
+++ b/src/drivers/net/smsc75xx.h
@@ -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
diff --git a/src/drivers/net/smsc95xx.c b/src/drivers/net/smsc95xx.c
index e56cf5b4..9b09657d 100644
--- a/src/drivers/net/smsc95xx.c
+++ b/src/drivers/net/smsc95xx.c
@@ -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 ) ),
diff --git a/src/drivers/net/smsc95xx.h b/src/drivers/net/smsc95xx.h
index b0ecf6ee..0cdf3824 100644
--- a/src/drivers/net/smsc95xx.h
+++ b/src/drivers/net/smsc95xx.h
@@ -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 */
diff --git a/src/drivers/net/smscusb.c b/src/drivers/net/smscusb.c
index 19a679c4..60390ce3 100644
--- a/src/drivers/net/smscusb.c
+++ b/src/drivers/net/smscusb.c
@@ -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;
diff --git a/src/drivers/net/smscusb.h b/src/drivers/net/smscusb.h
index d7216d9a..5e4440ea 100644
--- a/src/drivers/net/smscusb.h
+++ b/src/drivers/net/smscusb.h
@@ -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,