iPXE
Functions | Variables
smsc75xx.c File Reference

SMSC LAN75xx USB Ethernet driver. More...

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/ethernet.h>
#include <ipxe/usb.h>
#include <ipxe/usbnet.h>
#include <ipxe/profile.h>
#include "smsc75xx.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int smsc75xx_dump_statistics (struct smscusb_device *smscusb)
 Dump statistics (for debugging)
static int smsc75xx_reset (struct smscusb_device *smscusb)
 Reset device.
static void smsc75xx_in_complete (struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
 Complete bulk IN transfer.
static int smsc75xx_out_transmit (struct smscusb_device *smscusb, struct io_buffer *iobuf)
 Transmit packet.
static int smsc75xx_open (struct net_device *netdev)
 Open network device.
static void smsc75xx_close (struct net_device *netdev)
 Close network device.
int smsc75xx_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
void smsc75xx_poll (struct net_device *netdev)
 Poll for completed and received packets.
static int smsc75xx_probe (struct usb_function *func, struct usb_configuration_descriptor *config)
 Probe device.
static void smsc75xx_remove (struct usb_function *func)
 Remove device.

Variables

static struct profiler
smsc75xx_in_profiler 
__profiler
 Bulk IN completion profiler.
struct
usb_endpoint_driver_operations 
smsc75xx_in_operations
 Bulk IN endpoint operations.
static struct net_device_operations smsc75xx_operations
 SMSC75xx network device operations.
static struct usb_device_id smsc75xx_ids []
 SMSC75xx device IDs.
struct usb_driver smsc75xx_driver __usb_driver
 SMSC LAN75xx driver.

Detailed Description

SMSC LAN75xx USB Ethernet driver.

Definition in file smsc75xx.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
int smsc75xx_dump_statistics ( struct smscusb_device smscusb)

Dump statistics (for debugging)

Parameters:
smscusbSMSC USB device
Return values:
rcReturn status code

Definition at line 63 of file smsc75xx.c.

References smsc75xx_rx_error_statistics::alignment, smsc75xx_byte_statistics::broadcast, smsc75xx_frame_statistics::broadcast, smsc75xx_rx_statistics::byte, smsc75xx_tx_statistics::byte, smsc75xx_tx_error_statistics::carrier, smsc75xx_tx_error_statistics::count, DBG_LOG, DBGC, smsc75xx_tx_error_statistics::deferral, smsc75xx_rx_error_statistics::dropped, smsc75xx_rx_statistics::err, smsc75xx_tx_statistics::err, smsc75xx_tx_error_statistics::excessive, smsc75xx_rx_error_statistics::fcs, smsc75xx_tx_error_statistics::fcs, smsc75xx_rx_error_statistics::fragment, smsc75xx_rx_statistics::frame, smsc75xx_tx_statistics::frame, smsc75xx_rx_error_statistics::jabber, smsc75xx_tx_error_statistics::late, le32_to_cpu, smsc75xx_byte_statistics::multicast, smsc75xx_frame_statistics::multicast, smsc75xx_tx_error_statistics::multiple, smsc75xx_rx_error_statistics::oversize, smsc75xx_frame_statistics::pause, rc, smsc75xx_statistics::rx, smsc75xx_tx_error_statistics::single, smscusb_get_statistics(), strerror(), smsc75xx_statistics::tx, smsc75xx_rx_error_statistics::undersize, smsc75xx_byte_statistics::unicast, and smsc75xx_frame_statistics::unicast.

Referenced by lan78xx_close(), and smsc75xx_close().

                                                                {
        struct smsc75xx_statistics stats;
        int rc;

        /* Do nothing unless debugging is enabled */
        if ( ! DBG_LOG )
                return 0;

        /* Get statistics */
        if ( ( rc = smscusb_get_statistics ( smscusb, 0, &stats,
                                             sizeof ( stats ) ) ) != 0 ) {
                DBGC ( smscusb, "SMSC75XX %p could not get statistics: "
                       "%s\n", smscusb, strerror ( rc ) );
                return rc;
        }

        /* Dump statistics */
        DBGC ( smscusb, "SMSC75XX %p RXE fcs %d aln %d frg %d jab %d und %d "
               "ovr %d drp %d\n", smscusb, le32_to_cpu ( stats.rx.err.fcs ),
               le32_to_cpu ( stats.rx.err.alignment ),
               le32_to_cpu ( stats.rx.err.fragment ),
               le32_to_cpu ( stats.rx.err.jabber ),
               le32_to_cpu ( stats.rx.err.undersize ),
               le32_to_cpu ( stats.rx.err.oversize ),
               le32_to_cpu ( stats.rx.err.dropped ) );
        DBGC ( smscusb, "SMSC75XX %p RXB ucast %d bcast %d mcast %d\n",
               smscusb, le32_to_cpu ( stats.rx.byte.unicast ),
               le32_to_cpu ( stats.rx.byte.broadcast ),
               le32_to_cpu ( stats.rx.byte.multicast ) );
        DBGC ( smscusb, "SMSC75XX %p RXF ucast %d bcast %d mcast %d pause "
               "%d\n", smscusb, le32_to_cpu ( stats.rx.frame.unicast ),
               le32_to_cpu ( stats.rx.frame.broadcast ),
               le32_to_cpu ( stats.rx.frame.multicast ),
               le32_to_cpu ( stats.rx.frame.pause ) );
        DBGC ( smscusb, "SMSC75XX %p TXE fcs %d def %d car %d cnt %d sgl %d "
               "mul %d exc %d lat %d\n", smscusb,
               le32_to_cpu ( stats.tx.err.fcs ),
               le32_to_cpu ( stats.tx.err.deferral ),
               le32_to_cpu ( stats.tx.err.carrier ),
               le32_to_cpu ( stats.tx.err.count ),
               le32_to_cpu ( stats.tx.err.single ),
               le32_to_cpu ( stats.tx.err.multiple ),
               le32_to_cpu ( stats.tx.err.excessive ),
               le32_to_cpu ( stats.tx.err.late ) );
        DBGC ( smscusb, "SMSC75XX %p TXB ucast %d bcast %d mcast %d\n",
               smscusb, le32_to_cpu ( stats.tx.byte.unicast ),
               le32_to_cpu ( stats.tx.byte.broadcast ),
               le32_to_cpu ( stats.tx.byte.multicast ) );
        DBGC ( smscusb, "SMSC75XX %p TXF ucast %d bcast %d mcast %d pause "
               "%d\n", smscusb, le32_to_cpu ( stats.tx.frame.unicast ),
               le32_to_cpu ( stats.tx.frame.broadcast ),
               le32_to_cpu ( stats.tx.frame.multicast ),
               le32_to_cpu ( stats.tx.frame.pause ) );

        return 0;
}
static int smsc75xx_reset ( struct smscusb_device smscusb) [static]

Reset device.

Parameters:
smscusbSMSC USB device
Return values:
rcReturn status code

Definition at line 133 of file smsc75xx.c.

References DBGC, ETIMEDOUT, mdelay(), rc, SMSC75XX_HW_CFG, SMSC75XX_HW_CFG_LRST, SMSC75XX_RESET_MAX_WAIT_MS, smscusb_readl(), and smscusb_writel().

Referenced by smsc75xx_close(), smsc75xx_open(), and smsc75xx_probe().

                                                             {
        uint32_t hw_cfg;
        unsigned int i;
        int rc;

        /* Reset device */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_HW_CFG,
                                     SMSC75XX_HW_CFG_LRST ) ) != 0 )
                return rc;

        /* Wait for reset to complete */
        for ( i = 0 ; i < SMSC75XX_RESET_MAX_WAIT_MS ; i++ ) {

                /* Check if reset has completed */
                if ( ( rc = smscusb_readl ( smscusb, SMSC75XX_HW_CFG,
                                            &hw_cfg ) ) != 0 )
                        return rc;
                if ( ! ( hw_cfg & SMSC75XX_HW_CFG_LRST ) )
                        return 0;

                /* Delay */
                mdelay ( 1 );
        }

        DBGC ( smscusb, "SMSC75XX %p timed out waiting for reset\n",
               smscusb );
        return -ETIMEDOUT;
}
static void smsc75xx_in_complete ( struct usb_endpoint ep,
struct io_buffer iobuf,
int  rc 
) [static]

Complete bulk IN transfer.

Parameters:
epUSB endpoint
iobufI/O buffer
rcCompletion status code

Definition at line 176 of file smsc75xx.c.

References smsc75xx_rx_header::command, container_of, cpu_to_le32, io_buffer::data, DBGC, DBGC_HDA, EINVAL, EIO, free_iob(), header, usbnet_device::in, iob_disown, iob_len(), iob_pull, le32_to_cpu, netdev, smscusb_device::netdev, netdev_rx(), netdev_rx_err(), usb_endpoint::open, profile_start(), profile_stop(), SMSC75XX_RX_RED, strerror(), and smscusb_device::usbnet.

                                                                     {
        struct smscusb_device *smscusb =
                container_of ( ep, struct smscusb_device, usbnet.in );
        struct net_device *netdev = smscusb->netdev;
        struct smsc75xx_rx_header *header;

        /* Profile completions */
        profile_start ( &smsc75xx_in_profiler );

        /* Ignore packets cancelled when the endpoint closes */
        if ( ! ep->open ) {
                free_iob ( iobuf );
                return;
        }

        /* Record USB errors against the network device */
        if ( rc != 0 ) {
                DBGC ( smscusb, "SMSC75XX %p bulk IN failed: %s\n",
                       smscusb, strerror ( rc ) );
                goto err;
        }

        /* Sanity check */
        if ( iob_len ( iobuf ) < ( sizeof ( *header ) ) ) {
                DBGC ( smscusb, "SMSC75XX %p underlength bulk IN\n",
                       smscusb );
                DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
                rc = -EINVAL;
                goto err;
        }

        /* Strip header */
        header = iobuf->data;
        iob_pull ( iobuf, sizeof ( *header ) );

        /* Check for errors */
        if ( header->command & cpu_to_le32 ( SMSC75XX_RX_RED ) ) {
                DBGC ( smscusb, "SMSC75XX %p receive error (%08x):\n",
                       smscusb, le32_to_cpu ( header->command ) );
                DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
                rc = -EIO;
                goto err;
        }

        /* Hand off to network stack */
        netdev_rx ( netdev, iob_disown ( iobuf ) );

        profile_stop ( &smsc75xx_in_profiler );
        return;

 err:
        /* Hand off to network stack */
        netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
}
static int smsc75xx_out_transmit ( struct smscusb_device smscusb,
struct io_buffer iobuf 
) [static]

Transmit packet.

Parameters:
smscusbSMSC USB device
iobufI/O buffer
Return values:
rcReturn status code

Definition at line 244 of file smsc75xx.c.

References smsc75xx_tx_header::command, cpu_to_le32, header, iob_ensure_headroom(), iob_len(), iob_push, len, smsc75xx_tx_header::mss, usbnet_device::out, profile_start(), profile_stop(), rc, SMSC75XX_TX_FCS, smsc75xx_tx_header::tag, usb_stream(), and smscusb_device::usbnet.

Referenced by smsc75xx_transmit().

                                                             {
        struct smsc75xx_tx_header *header;
        size_t len = iob_len ( iobuf );
        int rc;

        /* Profile transmissions */
        profile_start ( &smsc75xx_out_profiler );

        /* Prepend header */
        if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *header ) ) ) != 0 )
                return rc;
        header = iob_push ( iobuf, sizeof ( *header ) );
        header->command = cpu_to_le32 ( SMSC75XX_TX_FCS | len );
        header->tag = 0;
        header->mss = 0;

        /* Enqueue I/O buffer */
        if ( ( rc = usb_stream ( &smscusb->usbnet.out, iobuf, 0 ) ) != 0 )
                return rc;

        profile_stop ( &smsc75xx_out_profiler );
        return 0;
}
static int smsc75xx_open ( struct net_device netdev) [static]

Open network device.

Parameters:
netdevNetwork device
Return values:
rcReturn status code

Definition at line 282 of file smsc75xx.c.

References DBGC, smscusb_device::int_sts, net_device::priv, rc, SMSC75XX_ADDR_FILT_BASE, SMSC75XX_BULK_IN_DLY, SMSC75XX_BULK_IN_DLY_SET, SMSC75XX_FCT_RX_CTL, SMSC75XX_FCT_RX_CTL_BAD, SMSC75XX_FCT_RX_CTL_EN, SMSC75XX_FCT_TX_CTL, SMSC75XX_FCT_TX_CTL_EN, SMSC75XX_HW_CFG, SMSC75XX_HW_CFG_BIR, SMSC75XX_INT_EP_CTL, SMSC75XX_INT_EP_CTL_PHY_EN, SMSC75XX_INT_EP_CTL_RDFO_EN, SMSC75XX_MAC_RX, SMSC75XX_MAC_RX_EN, SMSC75XX_MAC_RX_FCS, SMSC75XX_MAC_RX_MAX_SIZE_DEFAULT, SMSC75XX_MAC_TX, SMSC75XX_MAC_TX_EN, SMSC75XX_MII_PHY_INTR_MASK, SMSC75XX_PHY_INTR_ANEG_DONE, SMSC75XX_PHY_INTR_LINK_DOWN, smsc75xx_reset(), SMSC75XX_RFE_CTL, SMSC75XX_RFE_CTL_AB, SMSC75XX_RFE_CTL_AM, SMSC75XX_RFE_CTL_AU, SMSC75XX_RX_ADDR_BASE, smscusb_mii_open(), smscusb_set_address(), smscusb_set_filter(), smscusb_writel(), strerror(), smscusb_device::usbnet, usbnet_close(), and usbnet_open().

                                                       {
        struct smscusb_device *smscusb = netdev->priv;
        int rc;

        /* Clear stored interrupt status */
        smscusb->int_sts = 0;

        /* Configure bulk IN empty response */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_HW_CFG,
                                     SMSC75XX_HW_CFG_BIR ) ) != 0 )
                goto err_hw_cfg;

        /* Open USB network device */
        if ( ( rc = usbnet_open ( &smscusb->usbnet ) ) != 0 ) {
                DBGC ( smscusb, "SMSC75XX %p could not open: %s\n",
                       smscusb, strerror ( rc ) );
                goto err_open;
        }

        /* Configure interrupt endpoint */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_INT_EP_CTL,
                                     ( SMSC75XX_INT_EP_CTL_RDFO_EN |
                                       SMSC75XX_INT_EP_CTL_PHY_EN ) ) ) != 0 )
                goto err_int_ep_ctl;

        /* Configure bulk IN delay */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_BULK_IN_DLY,
                                     SMSC75XX_BULK_IN_DLY_SET ( 0 ) ) ) != 0 )
                goto err_bulk_in_dly;

        /* Configure receive filters */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_RFE_CTL,
                                     ( SMSC75XX_RFE_CTL_AB |
                                       SMSC75XX_RFE_CTL_AM |
                                       SMSC75XX_RFE_CTL_AU ) ) ) != 0 )
                goto err_rfe_ctl;

        /* Configure receive FIFO */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_FCT_RX_CTL,
                                     ( SMSC75XX_FCT_RX_CTL_EN |
                                       SMSC75XX_FCT_RX_CTL_BAD ) ) ) != 0 )
                goto err_fct_rx_ctl;

        /* Configure transmit FIFO */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_FCT_TX_CTL,
                                     SMSC75XX_FCT_TX_CTL_EN ) ) != 0 )
                goto err_fct_tx_ctl;

        /* Configure receive datapath */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_MAC_RX,
                                     ( SMSC75XX_MAC_RX_MAX_SIZE_DEFAULT |
                                       SMSC75XX_MAC_RX_FCS |
                                       SMSC75XX_MAC_RX_EN ) ) ) != 0 )
                goto err_mac_rx;

        /* Configure transmit datapath */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_MAC_TX,
                                     SMSC75XX_MAC_TX_EN ) ) != 0 )
                goto err_mac_tx;

        /* Set MAC address */
        if ( ( rc = smscusb_set_address ( smscusb,
                                          SMSC75XX_RX_ADDR_BASE ) ) != 0 )
                goto err_set_address;

        /* Set MAC address perfect filter */
        if ( ( rc = smscusb_set_filter ( smscusb,
                                         SMSC75XX_ADDR_FILT_BASE ) ) != 0 )
                goto err_set_filter;

        /* Enable PHY interrupts and update link status */
        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;

 err_mii_open:
 err_set_filter:
 err_set_address:
 err_mac_tx:
 err_mac_rx:
 err_fct_tx_ctl:
 err_fct_rx_ctl:
 err_rfe_ctl:
 err_bulk_in_dly:
 err_int_ep_ctl:
        usbnet_close ( &smscusb->usbnet );
 err_open:
 err_hw_cfg:
        smsc75xx_reset ( smscusb );
        return rc;
}
static void smsc75xx_close ( struct net_device netdev) [static]

Close network device.

Parameters:
netdevNetwork device

Definition at line 382 of file smsc75xx.c.

References DBG_LOG, net_device::priv, smsc75xx_dump_statistics(), smsc75xx_reset(), smscusb_device::usbnet, and usbnet_close().

                                                         {
        struct smscusb_device *smscusb = netdev->priv;

        /* Close USB network device */
        usbnet_close ( &smscusb->usbnet );

        /* Dump statistics (for debugging) */
        if ( DBG_LOG )
                smsc75xx_dump_statistics ( smscusb );

        /* Reset device */
        smsc75xx_reset ( smscusb );
}
int smsc75xx_transmit ( struct net_device netdev,
struct io_buffer iobuf 
)

Transmit packet.

Parameters:
netdevNetwork device
iobufI/O buffer
Return values:
rcReturn status code

Definition at line 403 of file smsc75xx.c.

References net_device::priv, rc, and smsc75xx_out_transmit().

                                                                             {
        struct smscusb_device *smscusb = netdev->priv;
        int rc;

        /* Transmit packet */
        if ( ( rc = smsc75xx_out_transmit ( smscusb, iobuf ) ) != 0 )
                return rc;

        return 0;
}
void smsc75xx_poll ( struct net_device netdev)

Poll for completed and received packets.

Parameters:
netdevNetwork device

Definition at line 419 of file smsc75xx.c.

References smscusb_device::bus, DBGC, DBGC2, ENOBUFS, ENOTTY, smscusb_device::int_sts, netdev_rx_err(), NULL, net_device::priv, rc, SMSC75XX_INT_STS, SMSC75XX_INT_STS_PHY_INT, SMSC75XX_INT_STS_RDFO_INT, smscusb_mii_check_link(), smscusb_writel(), usb_poll(), smscusb_device::usbnet, and usbnet_refill().

                                                 {
        struct smscusb_device *smscusb = netdev->priv;
        uint32_t int_sts;
        int rc;

        /* Poll USB bus */
        usb_poll ( smscusb->bus );

        /* Refill endpoints */
        if ( ( rc = usbnet_refill ( &smscusb->usbnet ) ) != 0 )
                netdev_rx_err ( netdev, NULL, rc );

        /* Do nothing more unless there are interrupts to handle */
        int_sts = smscusb->int_sts;
        if ( ! int_sts )
                return;

        /* Check link status if applicable */
        if ( int_sts & SMSC75XX_INT_STS_PHY_INT ) {
                smscusb_mii_check_link ( smscusb );
                int_sts &= ~SMSC75XX_INT_STS_PHY_INT;
        }

        /* Record RX FIFO overflow if applicable */
        if ( int_sts & SMSC75XX_INT_STS_RDFO_INT ) {
                DBGC2 ( smscusb, "SMSC75XX %p RX FIFO overflowed\n", smscusb );
                netdev_rx_err ( netdev, NULL, -ENOBUFS );
                int_sts &= ~SMSC75XX_INT_STS_RDFO_INT;
        }

        /* Check for unexpected interrupts */
        if ( int_sts ) {
                DBGC ( smscusb, "SMSC75XX %p unexpected interrupt %#08x\n",
                       smscusb, int_sts );
                netdev_rx_err ( netdev, NULL, -ENOTTY );
        }

        /* Clear interrupts */
        if ( ( rc = smscusb_writel ( smscusb, SMSC75XX_INT_STS,
                                     smscusb->int_sts ) ) != 0 )
                netdev_rx_err ( netdev, NULL, rc );
        smscusb->int_sts = 0;
}
static int smsc75xx_probe ( struct usb_function func,
struct usb_configuration_descriptor config 
) [static]

Probe device.

Parameters:
funcUSB function
configConfiguration descriptor
Return values:
rcReturn status code

Definition at line 485 of file smsc75xx.c.

References alloc_etherdev(), DBGC, net_device::dev, usb_function::dev, ENOMEM, usbnet_device::in, memset(), usb_function::name, netdev, netdev_init(), netdev_nullify(), netdev_put(), net_device::priv, rc, register_netdev(), SMSC75XX_E2P_BASE, SMSC75XX_IN_MAX_FILL, SMSC75XX_IN_MTU, SMSC75XX_MII_BASE, SMSC75XX_MII_PHY_INTR_SOURCE, smsc75xx_reset(), smscusb_eeprom_fetch_mac(), smscusb_init(), smscusb_mii_init(), strerror(), unregister_netdev(), usb_func_set_drvdata(), usb_refill_init(), smscusb_device::usbnet, and usbnet_describe().

                                                                          {
        struct net_device *netdev;
        struct smscusb_device *smscusb;
        int rc;

        /* Allocate and initialise structure */
        netdev = alloc_etherdev ( sizeof ( *smscusb ) );
        if ( ! netdev ) {
                rc = -ENOMEM;
                goto err_alloc;
        }
        netdev_init ( netdev, &smsc75xx_operations );
        netdev->dev = &func->dev;
        smscusb = netdev->priv;
        memset ( smscusb, 0, sizeof ( *smscusb ) );
        smscusb_init ( smscusb, netdev, func, &smsc75xx_in_operations );
        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 );

        /* Describe USB network device */
        if ( ( rc = usbnet_describe ( &smscusb->usbnet, config ) ) != 0 ) {
                DBGC ( smscusb, "SMSC75XX %p could not describe: %s\n",
                       smscusb, strerror ( rc ) );
                goto err_describe;
        }

        /* Reset device */
        if ( ( rc = smsc75xx_reset ( smscusb ) ) != 0 )
                goto err_reset;

        /* Read MAC address */
        if ( ( rc = smscusb_eeprom_fetch_mac ( smscusb,
                                               SMSC75XX_E2P_BASE ) ) != 0 )
                goto err_fetch_mac;

        /* Register network device */
        if ( ( rc = register_netdev ( netdev ) ) != 0 )
                goto err_register;

        usb_func_set_drvdata ( func, netdev );
        return 0;

        unregister_netdev ( netdev );
 err_register:
 err_fetch_mac:
 err_reset:
 err_describe:
        netdev_nullify ( netdev );
        netdev_put ( netdev );
 err_alloc:
        return rc;
}
static void smsc75xx_remove ( struct usb_function func) [static]

Remove device.

Parameters:
funcUSB function

Definition at line 547 of file smsc75xx.c.

References netdev, netdev_nullify(), netdev_put(), unregister_netdev(), and usb_func_get_drvdata().

                                                          {
        struct net_device *netdev = usb_func_get_drvdata ( func );

        unregister_netdev ( netdev );
        netdev_nullify ( netdev );
        netdev_put ( netdev );
}

Variable Documentation

struct profiler smsc75xx_out_profiler __profiler [static]
Initial value:
        { .name = "smsc75xx.in" }

Bulk IN completion profiler.

Bulk OUT profiler.

Definition at line 43 of file smsc75xx.c.

Initial value:
 {
        .complete = smsc75xx_in_complete,
}

Bulk IN endpoint operations.

Definition at line 233 of file smsc75xx.c.

Referenced by lan78xx_probe().

Initial value:
 {
        .open           = smsc75xx_open,
        .close          = smsc75xx_close,
        .transmit       = smsc75xx_transmit,
        .poll           = smsc75xx_poll,
}

SMSC75xx network device operations.

Definition at line 464 of file smsc75xx.c.

struct usb_device_id smsc75xx_ids[] [static]
Initial value:
 {
        {
                .name = "smsc7500",
                .vendor = 0x0424,
                .product = 0x7500,
        },
        {
                .name = "smsc7505",
                .vendor = 0x0424,
                .product = 0x7505,
        },
}

SMSC75xx device IDs.

Definition at line 556 of file smsc75xx.c.

struct usb_driver smsc75xx_driver __usb_driver
Initial value:
 {
        .ids = smsc75xx_ids,
        .id_count = ( sizeof ( smsc75xx_ids ) / sizeof ( smsc75xx_ids[0] ) ),
        .class = USB_CLASS_ID ( 0xff, 0x00, 0xff ),
        .score = USB_SCORE_NORMAL,
        .probe = smsc75xx_probe,
        .remove = smsc75xx_remove,
}

SMSC LAN75xx driver.

Definition at line 570 of file smsc75xx.c.