Example #1
0
static int smsc95xx_bind(struct usbnet *dev)
{
	struct smsc95xx_priv *pdata = NULL;
	int ret;

	printf(SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");

	ret = usbnet_get_endpoints(dev);
	if (ret < 0) {
		netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret);
		return ret;
	}

	dev->data[0] = (unsigned long)malloc(sizeof(struct smsc95xx_priv));

	pdata = (struct smsc95xx_priv *)(dev->data[0]);
	if (!pdata) {
		netdev_warn(dev->net, "Unable to allocate struct smsc95xx_priv\n");
		return -ENOMEM;
	}

	pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE;
	pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;

	/* Init all registers */
	ret = smsc95xx_reset(dev);

	dev->edev.get_ethaddr = smsc95xx_get_ethaddr;
	dev->edev.set_ethaddr = smsc95xx_set_ethaddr;
	mdiobus_register(&dev->miibus);

	return 0;
}
Example #2
0
/**
 * Close network device
 *
 * @v netdev		Network device
 */
static void smsc95xx_close ( struct net_device *netdev ) {
	struct smsc95xx_device *smsc95xx = netdev->priv;

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

	/* Dump statistics (for debugging) */
	smsc95xx_dump_statistics ( smsc95xx );

	/* Reset device */
	smsc95xx_reset ( smsc95xx );
}
Example #3
0
/**
 * Open network device
 *
 * @v netdev		Network device
 * @ret rc		Return status code
 */
static int smsc95xx_open ( struct net_device *netdev ) {
	struct smsc95xx_device *smsc95xx = netdev->priv;
	union smsc95xx_mac mac;
	int rc;

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

	/* Copy MAC address */
	memset ( &mac, 0, sizeof ( mac ) );
	memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );

	/* Configure bulk IN empty response */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_HW_CFG,
				      SMSC95XX_HW_CFG_BIR ) ) != 0 )
		goto err_hw_cfg;

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

	/* Configure interrupt endpoint */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_INT_EP_CTL,
				      ( SMSC95XX_INT_EP_CTL_RXDF_EN |
					SMSC95XX_INT_EP_CTL_PHY_EN ) ) ) != 0 )
		goto err_int_ep_ctl;

	/* Configure bulk IN delay */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_BULK_IN_DLY,
				      SMSC95XX_BULK_IN_DLY_SET ( 0 ) ) ) != 0 )
		goto err_bulk_in_dly;

	/* Configure MAC */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_MAC_CR,
				      ( SMSC95XX_MAC_CR_RXALL |
					SMSC95XX_MAC_CR_FDPX |
					SMSC95XX_MAC_CR_MCPAS |
					SMSC95XX_MAC_CR_PRMS |
					SMSC95XX_MAC_CR_PASSBAD |
					SMSC95XX_MAC_CR_TXEN |
					SMSC95XX_MAC_CR_RXEN ) ) ) != 0 )
		goto err_mac_cr;

	/* Configure transmit datapath */
	if ( ( rc = smsc95xx_writel ( smsc95xx, SMSC95XX_TX_CFG,
				      SMSC95XX_TX_CFG_ON ) ) != 0 )
		goto err_tx_cfg;

	/* Write MAC address high register */
	if ( ( rc = smsc95xx_raw_writel ( smsc95xx, SMSC95XX_ADDRH,
					  mac.addr.h ) ) != 0 )
		goto err_addrh;

	/* Write MAC address low register */
	if ( ( rc = smsc95xx_raw_writel ( smsc95xx, SMSC95XX_ADDRL,
					  mac.addr.l ) ) != 0 )
		goto err_addrl;

	/* Enable PHY interrupts */
	if ( ( rc = mii_write ( &smsc95xx->mii, SMSC95XX_MII_PHY_INTR_MASK,
				( SMSC95XX_PHY_INTR_ANEG_DONE |
				  SMSC95XX_PHY_INTR_LINK_DOWN ) ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not set PHY interrupt "
		       "mask: %s\n", smsc95xx, strerror ( rc ) );
		goto err_phy_intr_mask;
	}

	/* Update link status */
	smsc95xx_check_link ( smsc95xx );

	return 0;

 err_phy_intr_mask:
 err_addrl:
 err_addrh:
 err_tx_cfg:
 err_mac_cr:
 err_bulk_in_dly:
 err_int_ep_ctl:
	usbnet_close ( &smsc95xx->usbnet );
 err_open:
 err_hw_cfg:
	smsc95xx_reset ( smsc95xx );
	return rc;
}
Example #4
0
/**
 * Probe device
 *
 * @v func		USB function
 * @v config		Configuration descriptor
 * @ret rc		Return status code
 */
static int smsc95xx_probe ( struct usb_function *func,
			    struct usb_configuration_descriptor *config ) {
	struct usb_device *usb = func->usb;
	struct net_device *netdev;
	struct smsc95xx_device *smsc95xx;
	int rc;

	/* Allocate and initialise structure */
	netdev = alloc_etherdev ( sizeof ( *smsc95xx ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc;
	}
	netdev_init ( netdev, &smsc95xx_operations );
	netdev->dev = &func->dev;
	smsc95xx = netdev->priv;
	memset ( smsc95xx, 0, sizeof ( *smsc95xx ) );
	smsc95xx->usb = usb;
	smsc95xx->bus = usb->port->hub->bus;
	smsc95xx->netdev = netdev;
	usbnet_init ( &smsc95xx->usbnet, func, &smsc95xx_intr_operations,
		      &smsc95xx_in_operations, &smsc95xx_out_operations );
	usb_refill_init ( &smsc95xx->usbnet.intr, 0, 0,
			  SMSC95XX_INTR_MAX_FILL );
	usb_refill_init ( &smsc95xx->usbnet.in,
			  ( sizeof ( struct smsc95xx_tx_header ) -
			    sizeof ( struct smsc95xx_rx_header ) ),
			  SMSC95XX_IN_MTU, SMSC95XX_IN_MAX_FILL );
	mii_init ( &smsc95xx->mii, &smsc95xx_mii_operations );
	DBGC ( smsc95xx, "SMSC95XX %p on %s\n", smsc95xx, func->name );

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

	/* Reset device */
	if ( ( rc = smsc95xx_reset ( smsc95xx ) ) != 0 )
		goto err_reset;

	/* Read MAC address */
	if ( ( rc = smsc95xx_fetch_mac ( smsc95xx, netdev->hw_addr ) ) != 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;
}