Skip to content

Commit

Permalink
[smscusb] Allow for alternative PHY register layouts
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mcb30 committed Jul 10, 2017
1 parent 340f033 commit 74f934a
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 24 deletions.
7 changes: 5 additions & 2 deletions src/drivers/net/smsc75xx.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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 );
Expand Down
12 changes: 12 additions & 0 deletions src/drivers/net/smsc75xx.h
Expand Up @@ -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

Expand Down
7 changes: 5 additions & 2 deletions src/drivers/net/smsc95xx.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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 ) ),
Expand Down
12 changes: 12 additions & 0 deletions src/drivers/net/smsc95xx.h
Expand Up @@ -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 */
Expand Down
13 changes: 7 additions & 6 deletions src/drivers/net/smscusb.c
Expand Up @@ -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 "
Expand All @@ -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 ) );
Expand All @@ -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;
Expand Down
22 changes: 8 additions & 14 deletions src/drivers/net/smscusb.h
Expand Up @@ -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

Expand Down Expand Up @@ -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;
};
Expand Down Expand Up @@ -279,20 +269,24 @@ 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,
unsigned int e2p_base );
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,
Expand Down

0 comments on commit 74f934a

Please sign in to comment.