2005-08-31 20:53:10 +04:00
/*
* ASIX AX8817X based USB 2.0 Ethernet Devices
2006-07-29 18:12:50 +04:00
* Copyright ( C ) 2003 - 2006 David Hollis < dhollis @ davehollis . com >
2005-08-31 20:53:10 +04:00
* Copyright ( C ) 2005 Phil Chang < pchang23 @ sbcglobal . net >
2006-07-29 18:12:50 +04:00
* Copyright ( C ) 2006 James Painter < jamie . painter @ iname . com >
2005-08-31 20:53:10 +04:00
* Copyright ( c ) 2002 - 2003 TiVo Inc .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
2012-07-13 09:26:30 +04:00
# include "asix.h"
2006-07-29 18:12:50 +04:00
# define PHY_MODE_MARVELL 0x0000
# define MII_MARVELL_LED_CTRL 0x0018
# define MII_MARVELL_STATUS 0x001b
# define MII_MARVELL_CTRL 0x0014
# define MARVELL_LED_MANUAL 0x0019
# define MARVELL_STATUS_HWCFG 0x0004
# define MARVELL_CTRL_TXDELAY 0x0002
# define MARVELL_CTRL_RXDELAY 0x0080
2005-08-31 20:53:10 +04:00
2011-11-15 11:12:39 +04:00
# define PHY_MODE_RTL8211CL 0x000C
2011-10-04 13:55:17 +04:00
2005-08-31 20:53:10 +04:00
struct ax88172_int_data {
2007-12-22 20:42:36 +03:00
__le16 res1 ;
2005-08-31 20:53:10 +04:00
u8 link ;
2007-12-22 20:42:36 +03:00
__le16 res2 ;
2005-08-31 20:53:10 +04:00
u8 status ;
2007-12-22 20:42:36 +03:00
__le16 res3 ;
2010-06-02 22:10:09 +04:00
} __packed ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
static void asix_status ( struct usbnet * dev , struct urb * urb )
{
struct ax88172_int_data * event ;
int link ;
if ( urb - > actual_length < 8 )
return ;
event = urb - > transfer_buffer ;
link = event - > link & 0x01 ;
if ( netif_carrier_ok ( dev - > net ) ! = link ) {
if ( link ) {
netif_carrier_on ( dev - > net ) ;
usbnet_defer_kevent ( dev , EVENT_LINK_RESET ) ;
} else
netif_carrier_off ( dev - > net ) ;
2010-02-17 13:30:23 +03:00
netdev_dbg ( dev - > net , " Link Status is: %d \n " , link ) ;
2006-07-29 18:12:50 +04:00
}
}
2012-11-22 01:35:17 +04:00
static void asix_set_netdev_dev_addr ( struct usbnet * dev , u8 * addr )
{
if ( is_valid_ether_addr ( addr ) ) {
memcpy ( dev - > net - > dev_addr , addr , ETH_ALEN ) ;
} else {
netdev_info ( dev - > net , " invalid hw address, using random \n " ) ;
eth_hw_addr_random ( dev - > net ) ;
}
}
2006-07-29 18:12:50 +04:00
/* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */
static u32 asix_get_phyid ( struct usbnet * dev )
2005-08-31 20:53:10 +04:00
{
2006-07-29 18:12:50 +04:00
int phy_reg ;
u32 phy_id ;
2011-11-15 11:12:40 +04:00
int i ;
2005-08-31 20:53:10 +04:00
2011-11-15 11:12:40 +04:00
/* Poll for the rare case the FW or phy isn't ready yet. */
for ( i = 0 ; i < 100 ; i + + ) {
phy_reg = asix_mdio_read ( dev - > net , dev - > mii . phy_id , MII_PHYSID1 ) ;
if ( phy_reg ! = 0 & & phy_reg ! = 0xFFFF )
break ;
mdelay ( 1 ) ;
}
if ( phy_reg < = 0 | | phy_reg = = 0xFFFF )
2006-07-29 18:12:50 +04:00
return 0 ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
phy_id = ( phy_reg & 0xffff ) < < 16 ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
phy_reg = asix_mdio_read ( dev - > net , dev - > mii . phy_id , MII_PHYSID2 ) ;
if ( phy_reg < 0 )
return 0 ;
phy_id | = ( phy_reg & 0xffff ) ;
return phy_id ;
2005-08-31 20:53:10 +04:00
}
2006-07-29 18:12:50 +04:00
static u32 asix_get_link ( struct net_device * net )
{
struct usbnet * dev = netdev_priv ( net ) ;
return mii_link_ok ( & dev - > mii ) ;
}
static int asix_ioctl ( struct net_device * net , struct ifreq * rq , int cmd )
{
struct usbnet * dev = netdev_priv ( net ) ;
return generic_mii_ioctl ( & dev - > mii , if_mii ( rq ) , cmd , NULL ) ;
}
/* We need to override some ethtool_ops so we require our
own structure so we don ' t interfere with other usbnet
devices that may be connected at the same time . */
2009-09-02 12:03:33 +04:00
static const struct ethtool_ops ax88172_ethtool_ops = {
2006-07-29 18:12:50 +04:00
. get_drvinfo = asix_get_drvinfo ,
. get_link = asix_get_link ,
. get_msglevel = usbnet_get_msglevel ,
2005-08-31 20:53:10 +04:00
. set_msglevel = usbnet_set_msglevel ,
2006-03-29 05:15:42 +04:00
. get_wol = asix_get_wol ,
. set_wol = asix_set_wol ,
. get_eeprom_len = asix_get_eeprom_len ,
. get_eeprom = asix_get_eeprom ,
2012-07-19 04:23:07 +04:00
. set_eeprom = asix_set_eeprom ,
2006-10-09 02:08:01 +04:00
. get_settings = usbnet_get_settings ,
. set_settings = usbnet_set_settings ,
. nway_reset = usbnet_nway_reset ,
2005-08-31 20:53:10 +04:00
} ;
2006-07-29 18:12:50 +04:00
static void ax88172_set_multicast ( struct net_device * net )
2005-08-31 20:53:10 +04:00
{
struct usbnet * dev = netdev_priv ( net ) ;
2006-07-29 18:12:50 +04:00
struct asix_data * data = ( struct asix_data * ) & dev - > data ;
u8 rx_ctl = 0x8c ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
if ( net - > flags & IFF_PROMISC ) {
rx_ctl | = 0x01 ;
2009-12-03 10:58:21 +03:00
} else if ( net - > flags & IFF_ALLMULTI | |
2010-02-08 07:30:35 +03:00
netdev_mc_count ( net ) > AX_MAX_MCAST ) {
2006-07-29 18:12:50 +04:00
rx_ctl | = 0x02 ;
2010-02-08 07:30:35 +03:00
} else if ( netdev_mc_empty ( net ) ) {
2006-07-29 18:12:50 +04:00
/* just broadcast and directed */
} else {
/* We use the 20 byte dev->data
* for our 8 byte filter buffer
* to avoid allocating memory that
* is tricky to free later */
2010-04-02 01:22:57 +04:00
struct netdev_hw_addr * ha ;
2006-07-29 18:12:50 +04:00
u32 crc_bits ;
memset ( data - > multi_filter , 0 , AX_MCAST_FILTER_SIZE ) ;
/* Build the multicast hash filter. */
2010-04-02 01:22:57 +04:00
netdev_for_each_mc_addr ( ha , net ) {
crc_bits = ether_crc ( ETH_ALEN , ha - > addr ) > > 26 ;
2006-07-29 18:12:50 +04:00
data - > multi_filter [ crc_bits > > 3 ] | =
1 < < ( crc_bits & 7 ) ;
}
asix_write_cmd_async ( dev , AX_CMD_WRITE_MULTI_FILTER , 0 , 0 ,
AX_MCAST_FILTER_SIZE , data - > multi_filter ) ;
rx_ctl | = 0x10 ;
}
asix_write_cmd_async ( dev , AX_CMD_WRITE_RX_CTL , rx_ctl , 0 , 0 , NULL ) ;
}
static int ax88172_link_reset ( struct usbnet * dev )
{
u8 mode ;
2011-04-27 22:32:38 +04:00
struct ethtool_cmd ecmd = { . cmd = ETHTOOL_GSET } ;
2006-07-29 18:12:50 +04:00
mii_check_media ( & dev - > mii , 1 , 1 ) ;
mii_ethtool_gset ( & dev - > mii , & ecmd ) ;
mode = AX88172_MEDIUM_DEFAULT ;
if ( ecmd . duplex ! = DUPLEX_FULL )
mode | = ~ AX88172_MEDIUM_FD ;
2011-04-27 22:32:38 +04:00
netdev_dbg ( dev - > net , " ax88172_link_reset() speed: %u duplex: %d setting mode to 0x%04x \n " ,
ethtool_cmd_speed ( & ecmd ) , ecmd . duplex , mode ) ;
2006-07-29 18:12:50 +04:00
asix_write_medium_mode ( dev , mode ) ;
return 0 ;
2005-08-31 20:53:10 +04:00
}
2009-03-20 22:35:55 +03:00
static const struct net_device_ops ax88172_netdev_ops = {
. ndo_open = usbnet_open ,
. ndo_stop = usbnet_stop ,
. ndo_start_xmit = usbnet_start_xmit ,
. ndo_tx_timeout = usbnet_tx_timeout ,
. ndo_change_mtu = usbnet_change_mtu ,
. ndo_set_mac_address = eth_mac_addr ,
. ndo_validate_addr = eth_validate_addr ,
. ndo_do_ioctl = asix_ioctl ,
2011-08-16 10:29:01 +04:00
. ndo_set_rx_mode = ax88172_set_multicast ,
2009-03-20 22:35:55 +03:00
} ;
2006-03-29 05:15:42 +04:00
static int ax88172_bind ( struct usbnet * dev , struct usb_interface * intf )
2005-08-31 20:53:10 +04:00
{
int ret = 0 ;
2007-12-22 20:42:36 +03:00
u8 buf [ ETH_ALEN ] ;
2005-08-31 20:53:10 +04:00
int i ;
unsigned long gpio_bits = dev - > driver_info - > data ;
usbnet_get_endpoints ( dev , intf ) ;
/* Toggle the GPIOs in a manufacturer/model specific way */
for ( i = 2 ; i > = 0 ; i - - ) {
2011-10-04 13:55:18 +04:00
ret = asix_write_cmd ( dev , AX_CMD_WRITE_GPIOS ,
( gpio_bits > > ( i * 8 ) ) & 0xff , 0 , 0 , NULL ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
msleep ( 5 ) ;
}
2011-10-04 13:55:18 +04:00
ret = asix_write_rx_ctl ( dev , 0x80 ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
/* Get the MAC address */
2011-10-04 13:55:18 +04:00
ret = asix_read_cmd ( dev , AX88172_CMD_READ_NODE_ID , 0 , 0 , ETH_ALEN , buf ) ;
if ( ret < 0 ) {
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " read AX_CMD_READ_NODE_ID failed: %d \n " ,
ret ) ;
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
}
2012-11-22 01:35:17 +04:00
asix_set_netdev_dev_addr ( dev , buf ) ;
2005-08-31 20:53:10 +04:00
/* Initialize MII structure */
dev - > mii . dev = dev - > net ;
2006-03-29 05:15:42 +04:00
dev - > mii . mdio_read = asix_mdio_read ;
dev - > mii . mdio_write = asix_mdio_write ;
2005-08-31 20:53:10 +04:00
dev - > mii . phy_id_mask = 0x3f ;
dev - > mii . reg_num_mask = 0x1f ;
2006-07-29 18:12:50 +04:00
dev - > mii . phy_id = asix_get_phy_addr ( dev ) ;
2005-08-31 20:53:10 +04:00
2009-03-20 22:35:55 +03:00
dev - > net - > netdev_ops = & ax88172_netdev_ops ;
2006-03-29 05:15:42 +04:00
dev - > net - > ethtool_ops = & ax88172_ethtool_ops ;
2012-07-05 08:31:01 +04:00
dev - > net - > needed_headroom = 4 ; /* cf asix_tx_fixup() */
dev - > net - > needed_tailroom = 4 ; /* cf asix_tx_fixup() */
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
asix_mdio_write ( dev - > net , dev - > mii . phy_id , MII_BMCR , BMCR_RESET ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , MII_ADVERTISE ,
2005-08-31 20:53:10 +04:00
ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP ) ;
mii_nway_restart ( & dev - > mii ) ;
return 0 ;
2007-12-22 20:42:36 +03:00
out :
2005-08-31 20:53:10 +04:00
return ret ;
}
2009-09-02 12:03:33 +04:00
static const struct ethtool_ops ax88772_ethtool_ops = {
2006-03-29 05:15:42 +04:00
. get_drvinfo = asix_get_drvinfo ,
2006-07-29 18:12:50 +04:00
. get_link = asix_get_link ,
2005-08-31 20:53:10 +04:00
. get_msglevel = usbnet_get_msglevel ,
. set_msglevel = usbnet_set_msglevel ,
2006-03-29 05:15:42 +04:00
. get_wol = asix_get_wol ,
. set_wol = asix_set_wol ,
. get_eeprom_len = asix_get_eeprom_len ,
. get_eeprom = asix_get_eeprom ,
2012-07-19 04:23:07 +04:00
. set_eeprom = asix_set_eeprom ,
2006-10-09 02:08:01 +04:00
. get_settings = usbnet_get_settings ,
. set_settings = usbnet_set_settings ,
. nway_reset = usbnet_nway_reset ,
2005-08-31 20:53:10 +04:00
} ;
2006-07-29 18:12:50 +04:00
static int ax88772_link_reset ( struct usbnet * dev )
{
u16 mode ;
2011-04-27 22:32:38 +04:00
struct ethtool_cmd ecmd = { . cmd = ETHTOOL_GSET } ;
2006-07-29 18:12:50 +04:00
mii_check_media ( & dev - > mii , 1 , 1 ) ;
mii_ethtool_gset ( & dev - > mii , & ecmd ) ;
mode = AX88772_MEDIUM_DEFAULT ;
2011-04-27 22:32:38 +04:00
if ( ethtool_cmd_speed ( & ecmd ) ! = SPEED_100 )
2006-07-29 18:12:50 +04:00
mode & = ~ AX_MEDIUM_PS ;
if ( ecmd . duplex ! = DUPLEX_FULL )
mode & = ~ AX_MEDIUM_FD ;
2011-04-27 22:32:38 +04:00
netdev_dbg ( dev - > net , " ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x \n " ,
ethtool_cmd_speed ( & ecmd ) , ecmd . duplex , mode ) ;
2006-07-29 18:12:50 +04:00
asix_write_medium_mode ( dev , mode ) ;
return 0 ;
}
2011-10-04 13:55:16 +04:00
static int ax88772_reset ( struct usbnet * dev )
2005-08-31 20:53:10 +04:00
{
2012-01-10 10:40:17 +04:00
struct asix_data * data = ( struct asix_data * ) & dev - > data ;
2007-01-12 02:39:16 +03:00
int ret , embd_phy ;
2006-07-29 18:12:50 +04:00
u16 rx_ctl ;
2005-08-31 20:53:10 +04:00
2011-10-04 13:55:18 +04:00
ret = asix_write_gpio ( dev ,
AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN , 5 ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
2007-01-12 02:39:16 +03:00
embd_phy = ( ( asix_get_phy_addr ( dev ) & 0x1f ) = = 0x10 ? 1 : 0 ) ;
2011-10-04 13:55:16 +04:00
2011-10-04 13:55:18 +04:00
ret = asix_write_cmd ( dev , AX_CMD_SW_PHY_SELECT , embd_phy , 0 , 0 , NULL ) ;
if ( ret < 0 ) {
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " Select PHY #1 failed: %d \n " , ret ) ;
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
}
2011-10-04 13:55:18 +04:00
ret = asix_sw_reset ( dev , AX_SWRESET_IPPD | AX_SWRESET_PRL ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
msleep ( 150 ) ;
2011-10-04 13:55:18 +04:00
ret = asix_sw_reset ( dev , AX_SWRESET_CLEAR ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
msleep ( 150 ) ;
2011-10-04 13:55:16 +04:00
2007-01-12 02:39:16 +03:00
if ( embd_phy ) {
2011-10-04 13:55:18 +04:00
ret = asix_sw_reset ( dev , AX_SWRESET_IPRL ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2011-10-04 13:55:18 +04:00
} else {
ret = asix_sw_reset ( dev , AX_SWRESET_PRTE ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2007-01-12 02:39:16 +03:00
}
2005-08-31 20:53:10 +04:00
msleep ( 150 ) ;
2006-07-29 18:12:50 +04:00
rx_ctl = asix_read_rx_ctl ( dev ) ;
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " RX_CTL is 0x%04x after software reset \n " , rx_ctl ) ;
2011-10-04 13:55:18 +04:00
ret = asix_write_rx_ctl ( dev , 0x0000 ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
rx_ctl = asix_read_rx_ctl ( dev ) ;
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " RX_CTL is 0x%04x setting to 0x0000 \n " , rx_ctl ) ;
2006-07-29 18:12:50 +04:00
2011-10-04 13:55:18 +04:00
ret = asix_sw_reset ( dev , AX_SWRESET_PRL ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
msleep ( 150 ) ;
2006-03-29 05:15:42 +04:00
2011-10-04 13:55:18 +04:00
ret = asix_sw_reset ( dev , AX_SWRESET_IPRL | AX_SWRESET_PRL ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
2006-03-29 05:15:42 +04:00
msleep ( 150 ) ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
asix_mdio_write ( dev - > net , dev - > mii . phy_id , MII_BMCR , BMCR_RESET ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , MII_ADVERTISE ,
2005-08-31 20:53:10 +04:00
ADVERTISE_ALL | ADVERTISE_CSMA ) ;
mii_nway_restart ( & dev - > mii ) ;
2011-10-04 13:55:18 +04:00
ret = asix_write_medium_mode ( dev , AX88772_MEDIUM_DEFAULT ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
2011-10-04 13:55:18 +04:00
ret = asix_write_cmd ( dev , AX_CMD_WRITE_IPG0 ,
2005-08-31 20:53:10 +04:00
AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT ,
2011-10-04 13:55:18 +04:00
AX88772_IPG2_DEFAULT , 0 , NULL ) ;
if ( ret < 0 ) {
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " Write IPG,IPG1,IPG2 failed: %d \n " , ret ) ;
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
}
2012-01-10 10:40:17 +04:00
/* Rewrite MAC address */
memcpy ( data - > mac_addr , dev - > net - > dev_addr , ETH_ALEN ) ;
ret = asix_write_cmd ( dev , AX_CMD_WRITE_NODE_ID , 0 , 0 , ETH_ALEN ,
data - > mac_addr ) ;
if ( ret < 0 )
goto out ;
2005-08-31 20:53:10 +04:00
/* Set RX_CTL to default values with 2k buffer, and enable cactus */
2011-10-04 13:55:18 +04:00
ret = asix_write_rx_ctl ( dev , AX_DEFAULT_RX_CTL ) ;
if ( ret < 0 )
2007-12-22 20:42:36 +03:00
goto out ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
rx_ctl = asix_read_rx_ctl ( dev ) ;
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " RX_CTL is 0x%04x after all initializations \n " ,
rx_ctl ) ;
2006-07-29 18:12:50 +04:00
rx_ctl = asix_read_medium_status ( dev ) ;
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net ,
" Medium Status is 0x%04x after all initializations \n " ,
rx_ctl ) ;
2006-07-29 18:12:50 +04:00
2011-10-04 13:55:16 +04:00
return 0 ;
out :
return ret ;
}
static const struct net_device_ops ax88772_netdev_ops = {
. ndo_open = usbnet_open ,
. ndo_stop = usbnet_stop ,
. ndo_start_xmit = usbnet_start_xmit ,
. ndo_tx_timeout = usbnet_tx_timeout ,
. ndo_change_mtu = usbnet_change_mtu ,
. ndo_set_mac_address = asix_set_mac_address ,
. ndo_validate_addr = eth_validate_addr ,
. ndo_do_ioctl = asix_ioctl ,
. ndo_set_rx_mode = asix_set_multicast ,
} ;
static int ax88772_bind ( struct usbnet * dev , struct usb_interface * intf )
{
2011-11-15 11:12:41 +04:00
int ret , embd_phy ;
2011-10-04 13:55:16 +04:00
u8 buf [ ETH_ALEN ] ;
u32 phyid ;
usbnet_get_endpoints ( dev , intf ) ;
/* Get the MAC address */
2011-10-04 13:55:18 +04:00
ret = asix_read_cmd ( dev , AX_CMD_READ_NODE_ID , 0 , 0 , ETH_ALEN , buf ) ;
if ( ret < 0 ) {
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " Failed to read MAC address: %d \n " , ret ) ;
2011-10-04 13:55:18 +04:00
return ret ;
2011-10-04 13:55:16 +04:00
}
2012-11-22 01:35:17 +04:00
asix_set_netdev_dev_addr ( dev , buf ) ;
2011-10-04 13:55:16 +04:00
/* Initialize MII structure */
dev - > mii . dev = dev - > net ;
dev - > mii . mdio_read = asix_mdio_read ;
dev - > mii . mdio_write = asix_mdio_write ;
dev - > mii . phy_id_mask = 0x1f ;
dev - > mii . reg_num_mask = 0x1f ;
dev - > mii . phy_id = asix_get_phy_addr ( dev ) ;
dev - > net - > netdev_ops = & ax88772_netdev_ops ;
dev - > net - > ethtool_ops = & ax88772_ethtool_ops ;
2012-07-05 08:31:01 +04:00
dev - > net - > needed_headroom = 4 ; /* cf asix_tx_fixup() */
dev - > net - > needed_tailroom = 4 ; /* cf asix_tx_fixup() */
2011-10-04 13:55:16 +04:00
2011-11-15 11:12:41 +04:00
embd_phy = ( ( dev - > mii . phy_id & 0x1f ) = = 0x10 ? 1 : 0 ) ;
/* Reset the PHY to normal operation mode */
ret = asix_write_cmd ( dev , AX_CMD_SW_PHY_SELECT , embd_phy , 0 , 0 , NULL ) ;
if ( ret < 0 ) {
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " Select PHY #1 failed: %d \n " , ret ) ;
2011-11-15 11:12:41 +04:00
return ret ;
}
ret = asix_sw_reset ( dev , AX_SWRESET_IPPD | AX_SWRESET_PRL ) ;
2011-10-04 13:55:18 +04:00
if ( ret < 0 )
return ret ;
2011-10-04 13:55:16 +04:00
2011-11-15 11:12:41 +04:00
msleep ( 150 ) ;
ret = asix_sw_reset ( dev , AX_SWRESET_CLEAR ) ;
if ( ret < 0 )
return ret ;
msleep ( 150 ) ;
ret = asix_sw_reset ( dev , embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_PRTE ) ;
/* Read PHYID register *AFTER* the PHY was reset properly */
phyid = asix_get_phyid ( dev ) ;
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " PHYID=0x%08x \n " , phyid ) ;
2011-11-15 11:12:41 +04:00
2005-08-31 20:53:10 +04:00
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
if ( dev - > driver_info - > flags & FLAG_FRAMING_AX ) {
/* hard_mtu is still the default - the device does not support
jumbo eth frames */
dev - > rx_urb_size = 2048 ;
}
2011-10-04 13:55:18 +04:00
2005-08-31 20:53:10 +04:00
return 0 ;
}
2012-01-05 23:10:23 +04:00
static const struct ethtool_ops ax88178_ethtool_ops = {
2006-07-29 18:12:50 +04:00
. get_drvinfo = asix_get_drvinfo ,
. get_link = asix_get_link ,
. get_msglevel = usbnet_get_msglevel ,
. set_msglevel = usbnet_set_msglevel ,
. get_wol = asix_get_wol ,
. set_wol = asix_set_wol ,
. get_eeprom_len = asix_get_eeprom_len ,
. get_eeprom = asix_get_eeprom ,
2012-07-19 04:23:07 +04:00
. set_eeprom = asix_set_eeprom ,
2006-10-09 02:08:01 +04:00
. get_settings = usbnet_get_settings ,
. set_settings = usbnet_set_settings ,
. nway_reset = usbnet_nway_reset ,
2006-07-29 18:12:50 +04:00
} ;
static int marvell_phy_init ( struct usbnet * dev )
2005-08-31 20:53:10 +04:00
{
2006-07-29 18:12:50 +04:00
struct asix_data * data = ( struct asix_data * ) & dev - > data ;
u16 reg ;
2005-08-31 20:53:10 +04:00
2010-02-17 13:30:23 +03:00
netdev_dbg ( dev - > net , " marvell_phy_init() \n " ) ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
reg = asix_mdio_read ( dev - > net , dev - > mii . phy_id , MII_MARVELL_STATUS ) ;
2010-02-17 13:30:23 +03:00
netdev_dbg ( dev - > net , " MII_MARVELL_STATUS = 0x%04x \n " , reg ) ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
asix_mdio_write ( dev - > net , dev - > mii . phy_id , MII_MARVELL_CTRL ,
MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY ) ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
if ( data - > ledmode ) {
reg = asix_mdio_read ( dev - > net , dev - > mii . phy_id ,
MII_MARVELL_LED_CTRL ) ;
2010-02-17 13:30:23 +03:00
netdev_dbg ( dev - > net , " MII_MARVELL_LED_CTRL (1) = 0x%04x \n " , reg ) ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
reg & = 0xf8ff ;
reg | = ( 1 + 0x0100 ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id ,
MII_MARVELL_LED_CTRL , reg ) ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
reg = asix_mdio_read ( dev - > net , dev - > mii . phy_id ,
MII_MARVELL_LED_CTRL ) ;
2010-02-17 13:30:23 +03:00
netdev_dbg ( dev - > net , " MII_MARVELL_LED_CTRL (2) = 0x%04x \n " , reg ) ;
2006-07-29 18:12:50 +04:00
reg & = 0xfc0f ;
}
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
return 0 ;
}
2011-10-04 13:55:17 +04:00
static int rtl8211cl_phy_init ( struct usbnet * dev )
{
struct asix_data * data = ( struct asix_data * ) & dev - > data ;
netdev_dbg ( dev - > net , " rtl8211cl_phy_init() \n " ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , 0x1f , 0x0005 ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , 0x0c , 0 ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , 0x01 ,
asix_mdio_read ( dev - > net , dev - > mii . phy_id , 0x01 ) | 0x0080 ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , 0x1f , 0 ) ;
if ( data - > ledmode = = 12 ) {
asix_mdio_write ( dev - > net , dev - > mii . phy_id , 0x1f , 0x0002 ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , 0x1a , 0x00cb ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , 0x1f , 0 ) ;
}
return 0 ;
}
2006-07-29 18:12:50 +04:00
static int marvell_led_status ( struct usbnet * dev , u16 speed )
{
u16 reg = asix_mdio_read ( dev - > net , dev - > mii . phy_id , MARVELL_LED_MANUAL ) ;
2010-02-17 13:30:23 +03:00
netdev_dbg ( dev - > net , " marvell_led_status() read 0x%04x \n " , reg ) ;
2006-07-29 18:12:50 +04:00
/* Clear out the center LED bits - 0x03F0 */
reg & = 0xfc0f ;
switch ( speed ) {
case SPEED_1000 :
reg | = 0x03e0 ;
break ;
case SPEED_100 :
reg | = 0x03b0 ;
break ;
default :
reg | = 0x02f0 ;
2005-08-31 20:53:10 +04:00
}
2010-02-17 13:30:23 +03:00
netdev_dbg ( dev - > net , " marvell_led_status() writing 0x%04x \n " , reg ) ;
2006-07-29 18:12:50 +04:00
asix_mdio_write ( dev - > net , dev - > mii . phy_id , MARVELL_LED_MANUAL , reg ) ;
return 0 ;
}
2011-10-04 13:55:17 +04:00
static int ax88178_reset ( struct usbnet * dev )
{
struct asix_data * data = ( struct asix_data * ) & dev - > data ;
int ret ;
__le16 eeprom ;
u8 status ;
int gpio0 = 0 ;
2011-11-15 11:12:42 +04:00
u32 phyid ;
2011-10-04 13:55:17 +04:00
asix_read_cmd ( dev , AX_CMD_READ_GPIOS , 0 , 0 , 1 , & status ) ;
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " GPIO Status: 0x%04x \n " , status ) ;
2011-10-04 13:55:17 +04:00
asix_write_cmd ( dev , AX_CMD_WRITE_ENABLE , 0 , 0 , 0 , NULL ) ;
asix_read_cmd ( dev , AX_CMD_READ_EEPROM , 0x0017 , 0 , 2 , & eeprom ) ;
asix_write_cmd ( dev , AX_CMD_WRITE_DISABLE , 0 , 0 , 0 , NULL ) ;
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " EEPROM index 0x17 is 0x%04x \n " , eeprom ) ;
2011-10-04 13:55:17 +04:00
if ( eeprom = = cpu_to_le16 ( 0xffff ) ) {
data - > phymode = PHY_MODE_MARVELL ;
data - > ledmode = 0 ;
gpio0 = 1 ;
} else {
2011-11-15 11:12:42 +04:00
data - > phymode = le16_to_cpu ( eeprom ) & 0x7F ;
2011-10-04 13:55:17 +04:00
data - > ledmode = le16_to_cpu ( eeprom ) > > 8 ;
gpio0 = ( le16_to_cpu ( eeprom ) & 0x80 ) ? 0 : 1 ;
}
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " GPIO0: %d, PhyMode: %d \n " , gpio0 , data - > phymode ) ;
2011-10-04 13:55:17 +04:00
2011-11-15 11:12:42 +04:00
/* Power up external GigaPHY through AX88178 GPIO pin */
2011-10-04 13:55:17 +04:00
asix_write_gpio ( dev , AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN , 40 ) ;
if ( ( le16_to_cpu ( eeprom ) > > 8 ) ! = 1 ) {
asix_write_gpio ( dev , 0x003c , 30 ) ;
asix_write_gpio ( dev , 0x001c , 300 ) ;
asix_write_gpio ( dev , 0x003c , 30 ) ;
} else {
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " gpio phymode == 1 path \n " ) ;
2011-10-04 13:55:17 +04:00
asix_write_gpio ( dev , AX_GPIO_GPO1EN , 30 ) ;
asix_write_gpio ( dev , AX_GPIO_GPO1EN | AX_GPIO_GPO_1 , 30 ) ;
}
2011-11-15 11:12:42 +04:00
/* Read PHYID register *AFTER* powering up PHY */
phyid = asix_get_phyid ( dev ) ;
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " PHYID=0x%08x \n " , phyid ) ;
2011-11-15 11:12:42 +04:00
/* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */
asix_write_cmd ( dev , AX_CMD_SW_PHY_SELECT , 0 , 0 , 0 , NULL ) ;
2011-10-04 13:55:17 +04:00
asix_sw_reset ( dev , 0 ) ;
msleep ( 150 ) ;
asix_sw_reset ( dev , AX_SWRESET_PRL | AX_SWRESET_IPPD ) ;
msleep ( 150 ) ;
asix_write_rx_ctl ( dev , 0 ) ;
if ( data - > phymode = = PHY_MODE_MARVELL ) {
marvell_phy_init ( dev ) ;
msleep ( 60 ) ;
} else if ( data - > phymode = = PHY_MODE_RTL8211CL )
rtl8211cl_phy_init ( dev ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , MII_BMCR ,
BMCR_RESET | BMCR_ANENABLE ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , MII_ADVERTISE ,
ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP ) ;
asix_mdio_write ( dev - > net , dev - > mii . phy_id , MII_CTRL1000 ,
ADVERTISE_1000FULL ) ;
mii_nway_restart ( & dev - > mii ) ;
2011-10-04 13:55:18 +04:00
ret = asix_write_medium_mode ( dev , AX88178_MEDIUM_DEFAULT ) ;
if ( ret < 0 )
return ret ;
2011-10-04 13:55:17 +04:00
2012-01-10 10:40:23 +04:00
/* Rewrite MAC address */
memcpy ( data - > mac_addr , dev - > net - > dev_addr , ETH_ALEN ) ;
ret = asix_write_cmd ( dev , AX_CMD_WRITE_NODE_ID , 0 , 0 , ETH_ALEN ,
data - > mac_addr ) ;
if ( ret < 0 )
return ret ;
2011-10-04 13:55:18 +04:00
ret = asix_write_rx_ctl ( dev , AX_DEFAULT_RX_CTL ) ;
if ( ret < 0 )
return ret ;
2011-10-04 13:55:17 +04:00
return 0 ;
}
2006-07-29 18:12:50 +04:00
static int ax88178_link_reset ( struct usbnet * dev )
{
u16 mode ;
2011-04-27 22:32:38 +04:00
struct ethtool_cmd ecmd = { . cmd = ETHTOOL_GSET } ;
2006-07-29 18:12:50 +04:00
struct asix_data * data = ( struct asix_data * ) & dev - > data ;
2011-04-27 22:32:38 +04:00
u32 speed ;
2006-07-29 18:12:50 +04:00
2010-02-17 13:30:23 +03:00
netdev_dbg ( dev - > net , " ax88178_link_reset() \n " ) ;
2006-07-29 18:12:50 +04:00
mii_check_media ( & dev - > mii , 1 , 1 ) ;
mii_ethtool_gset ( & dev - > mii , & ecmd ) ;
mode = AX88178_MEDIUM_DEFAULT ;
2011-04-27 22:32:38 +04:00
speed = ethtool_cmd_speed ( & ecmd ) ;
2006-07-29 18:12:50 +04:00
2011-04-27 22:32:38 +04:00
if ( speed = = SPEED_1000 )
2008-11-20 12:48:46 +03:00
mode | = AX_MEDIUM_GM ;
2011-04-27 22:32:38 +04:00
else if ( speed = = SPEED_100 )
2006-07-29 18:12:50 +04:00
mode | = AX_MEDIUM_PS ;
else
mode & = ~ ( AX_MEDIUM_PS | AX_MEDIUM_GM ) ;
2008-11-20 12:48:46 +03:00
mode | = AX_MEDIUM_ENCK ;
2006-07-29 18:12:50 +04:00
if ( ecmd . duplex = = DUPLEX_FULL )
mode | = AX_MEDIUM_FD ;
else
mode & = ~ AX_MEDIUM_FD ;
2011-04-27 22:32:38 +04:00
netdev_dbg ( dev - > net , " ax88178_link_reset() speed: %u duplex: %d setting mode to 0x%04x \n " ,
speed , ecmd . duplex , mode ) ;
2006-07-29 18:12:50 +04:00
asix_write_medium_mode ( dev , mode ) ;
if ( data - > phymode = = PHY_MODE_MARVELL & & data - > ledmode )
2011-04-27 22:32:38 +04:00
marvell_led_status ( dev , speed ) ;
2006-07-29 18:12:50 +04:00
return 0 ;
}
static void ax88178_set_mfb ( struct usbnet * dev )
{
u16 mfb = AX_RX_CTL_MFB_16384 ;
u16 rxctl ;
u16 medium ;
int old_rx_urb_size = dev - > rx_urb_size ;
if ( dev - > hard_mtu < 2048 ) {
dev - > rx_urb_size = 2048 ;
mfb = AX_RX_CTL_MFB_2048 ;
} else if ( dev - > hard_mtu < 4096 ) {
dev - > rx_urb_size = 4096 ;
mfb = AX_RX_CTL_MFB_4096 ;
} else if ( dev - > hard_mtu < 8192 ) {
dev - > rx_urb_size = 8192 ;
mfb = AX_RX_CTL_MFB_8192 ;
} else if ( dev - > hard_mtu < 16384 ) {
dev - > rx_urb_size = 16384 ;
mfb = AX_RX_CTL_MFB_16384 ;
2005-08-31 20:53:10 +04:00
}
2006-07-29 18:12:50 +04:00
rxctl = asix_read_rx_ctl ( dev ) ;
asix_write_rx_ctl ( dev , ( rxctl & ~ AX_RX_CTL_MFB_16384 ) | mfb ) ;
medium = asix_read_medium_status ( dev ) ;
if ( dev - > net - > mtu > 1500 )
medium | = AX_MEDIUM_JFE ;
else
medium & = ~ AX_MEDIUM_JFE ;
asix_write_medium_mode ( dev , medium ) ;
if ( dev - > rx_urb_size > old_rx_urb_size )
usbnet_unlink_rx_urbs ( dev ) ;
2005-08-31 20:53:10 +04:00
}
2006-07-29 18:12:50 +04:00
static int ax88178_change_mtu ( struct net_device * net , int new_mtu )
2005-08-31 20:53:10 +04:00
{
2006-07-29 18:12:50 +04:00
struct usbnet * dev = netdev_priv ( net ) ;
int ll_mtu = new_mtu + net - > hard_header_len + 4 ;
2005-08-31 20:53:10 +04:00
2010-02-17 13:30:23 +03:00
netdev_dbg ( dev - > net , " ax88178_change_mtu() new_mtu=%d \n " , new_mtu ) ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
if ( new_mtu < = 0 | | ll_mtu > 16384 )
return - EINVAL ;
if ( ( ll_mtu % dev - > maxpacket ) = = 0 )
return - EDOM ;
net - > mtu = new_mtu ;
dev - > hard_mtu = net - > mtu + net - > hard_header_len ;
ax88178_set_mfb ( dev ) ;
return 0 ;
}
2009-03-20 22:35:55 +03:00
static const struct net_device_ops ax88178_netdev_ops = {
. ndo_open = usbnet_open ,
. ndo_stop = usbnet_stop ,
. ndo_start_xmit = usbnet_start_xmit ,
. ndo_tx_timeout = usbnet_tx_timeout ,
2010-03-09 15:24:38 +03:00
. ndo_set_mac_address = asix_set_mac_address ,
2009-03-20 22:35:55 +03:00
. ndo_validate_addr = eth_validate_addr ,
2011-08-16 10:29:01 +04:00
. ndo_set_rx_mode = asix_set_multicast ,
2009-03-20 22:35:55 +03:00
. ndo_do_ioctl = asix_ioctl ,
. ndo_change_mtu = ax88178_change_mtu ,
} ;
2006-07-29 18:12:50 +04:00
static int ax88178_bind ( struct usbnet * dev , struct usb_interface * intf )
{
int ret ;
2007-12-22 20:42:36 +03:00
u8 buf [ ETH_ALEN ] ;
2006-07-29 18:12:50 +04:00
usbnet_get_endpoints ( dev , intf ) ;
/* Get the MAC address */
2011-10-04 13:55:18 +04:00
ret = asix_read_cmd ( dev , AX_CMD_READ_NODE_ID , 0 , 0 , ETH_ALEN , buf ) ;
if ( ret < 0 ) {
2012-09-19 13:46:14 +04:00
netdev_dbg ( dev - > net , " Failed to read MAC address: %d \n " , ret ) ;
2011-10-04 13:55:18 +04:00
return ret ;
2005-08-31 20:53:10 +04:00
}
2012-11-22 01:35:17 +04:00
asix_set_netdev_dev_addr ( dev , buf ) ;
2005-08-31 20:53:10 +04:00
2006-07-29 18:12:50 +04:00
/* Initialize MII structure */
dev - > mii . dev = dev - > net ;
dev - > mii . mdio_read = asix_mdio_read ;
dev - > mii . mdio_write = asix_mdio_write ;
dev - > mii . phy_id_mask = 0x1f ;
dev - > mii . reg_num_mask = 0xff ;
dev - > mii . supports_gmii = 1 ;
dev - > mii . phy_id = asix_get_phy_addr ( dev ) ;
2009-03-20 22:35:55 +03:00
dev - > net - > netdev_ops = & ax88178_netdev_ops ;
2006-07-29 18:12:50 +04:00
dev - > net - > ethtool_ops = & ax88178_ethtool_ops ;
2005-08-31 20:53:10 +04:00
2011-11-15 11:12:42 +04:00
/* Blink LEDS so users know driver saw dongle */
asix_sw_reset ( dev , 0 ) ;
msleep ( 150 ) ;
2005-08-31 20:53:10 +04:00
2011-11-15 11:12:42 +04:00
asix_sw_reset ( dev , AX_SWRESET_PRL | AX_SWRESET_IPPD ) ;
msleep ( 150 ) ;
2006-07-29 18:12:50 +04:00
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
if ( dev - > driver_info - > flags & FLAG_FRAMING_AX ) {
/* hard_mtu is still the default - the device does not support
jumbo eth frames */
dev - > rx_urb_size = 2048 ;
}
2011-10-04 13:55:18 +04:00
return 0 ;
2005-08-31 20:53:10 +04:00
}
static const struct driver_info ax8817x_info = {
. description = " ASIX AX8817x USB 2.0 Ethernet " ,
2006-03-29 05:15:42 +04:00
. bind = ax88172_bind ,
. status = asix_status ,
2005-08-31 20:53:10 +04:00
. link_reset = ax88172_link_reset ,
. reset = ax88172_link_reset ,
2009-11-04 18:29:52 +03:00
. flags = FLAG_ETHER | FLAG_LINK_INTR ,
2005-08-31 20:53:10 +04:00
. data = 0x00130103 ,
} ;
static const struct driver_info dlink_dub_e100_info = {
. description = " DLink DUB-E100 USB Ethernet " ,
2006-03-29 05:15:42 +04:00
. bind = ax88172_bind ,
. status = asix_status ,
2005-08-31 20:53:10 +04:00
. link_reset = ax88172_link_reset ,
. reset = ax88172_link_reset ,
2009-11-04 18:29:52 +03:00
. flags = FLAG_ETHER | FLAG_LINK_INTR ,
2005-08-31 20:53:10 +04:00
. data = 0x009f9d9f ,
} ;
static const struct driver_info netgear_fa120_info = {
. description = " Netgear FA-120 USB Ethernet " ,
2006-03-29 05:15:42 +04:00
. bind = ax88172_bind ,
. status = asix_status ,
2005-08-31 20:53:10 +04:00
. link_reset = ax88172_link_reset ,
. reset = ax88172_link_reset ,
2009-11-04 18:29:52 +03:00
. flags = FLAG_ETHER | FLAG_LINK_INTR ,
2005-08-31 20:53:10 +04:00
. data = 0x00130103 ,
} ;
static const struct driver_info hawking_uf200_info = {
. description = " Hawking UF200 USB Ethernet " ,
2006-03-29 05:15:42 +04:00
. bind = ax88172_bind ,
. status = asix_status ,
2005-08-31 20:53:10 +04:00
. link_reset = ax88172_link_reset ,
. reset = ax88172_link_reset ,
2009-11-04 18:29:52 +03:00
. flags = FLAG_ETHER | FLAG_LINK_INTR ,
2005-08-31 20:53:10 +04:00
. data = 0x001f1d1f ,
} ;
static const struct driver_info ax88772_info = {
. description = " ASIX AX88772 USB 2.0 Ethernet " ,
. bind = ax88772_bind ,
2006-03-29 05:15:42 +04:00
. status = asix_status ,
2005-08-31 20:53:10 +04:00
. link_reset = ax88772_link_reset ,
2011-10-04 13:55:16 +04:00
. reset = ax88772_reset ,
2012-03-15 00:18:32 +04:00
. flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET ,
2006-07-29 18:12:50 +04:00
. rx_fixup = asix_rx_fixup ,
. tx_fixup = asix_tx_fixup ,
} ;
static const struct driver_info ax88178_info = {
. description = " ASIX AX88178 USB 2.0 Ethernet " ,
. bind = ax88178_bind ,
. status = asix_status ,
. link_reset = ax88178_link_reset ,
2011-10-04 13:55:17 +04:00
. reset = ax88178_reset ,
2009-11-04 18:29:52 +03:00
. flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR ,
2006-07-29 18:12:50 +04:00
. rx_fixup = asix_rx_fixup ,
. tx_fixup = asix_tx_fixup ,
2005-08-31 20:53:10 +04:00
} ;
2012-07-13 09:26:31 +04:00
extern const struct driver_info ax88172a_info ;
2005-08-31 20:53:10 +04:00
static const struct usb_device_id products [ ] = {
{
// Linksys USB200M
USB_DEVICE ( 0x077b , 0x2226 ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
} , {
// Netgear FA120
USB_DEVICE ( 0x0846 , 0x1040 ) ,
. driver_info = ( unsigned long ) & netgear_fa120_info ,
} , {
// DLink DUB-E100
USB_DEVICE ( 0x2001 , 0x1a00 ) ,
. driver_info = ( unsigned long ) & dlink_dub_e100_info ,
} , {
// Intellinet, ST Lab USB Ethernet
USB_DEVICE ( 0x0b95 , 0x1720 ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
} , {
// Hawking UF200, TrendNet TU2-ET100
USB_DEVICE ( 0x07b8 , 0x420a ) ,
. driver_info = ( unsigned long ) & hawking_uf200_info ,
} , {
2007-02-20 16:02:24 +03:00
// Billionton Systems, USB2AR
USB_DEVICE ( 0x08dd , 0x90ff ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
2005-08-31 20:53:10 +04:00
} , {
// ATEN UC210T
USB_DEVICE ( 0x0557 , 0x2009 ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
} , {
// Buffalo LUA-U2-KTX
USB_DEVICE ( 0x0411 , 0x003d ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
2008-05-07 07:42:35 +04:00
} , {
// Buffalo LUA-U2-GT 10/100/1000
USB_DEVICE ( 0x0411 , 0x006e ) ,
. driver_info = ( unsigned long ) & ax88178_info ,
2005-08-31 20:53:10 +04:00
} , {
// Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
USB_DEVICE ( 0x6189 , 0x182d ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
2012-03-09 02:44:03 +04:00
} , {
// Sitecom LN-031 "USB 2.0 10/100/1000 Ethernet adapter"
USB_DEVICE ( 0x0df6 , 0x0056 ) ,
. driver_info = ( unsigned long ) & ax88178_info ,
2005-08-31 20:53:10 +04:00
} , {
// corega FEther USB2-TX
USB_DEVICE ( 0x07aa , 0x0017 ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
} , {
// Surecom EP-1427X-2
USB_DEVICE ( 0x1189 , 0x0893 ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
} , {
// goodway corp usb gwusb2e
USB_DEVICE ( 0x1631 , 0x6200 ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
2007-02-20 16:02:24 +03:00
} , {
// JVC MP-PRX1 Port Replicator
USB_DEVICE ( 0x04f1 , 0x3008 ) ,
. driver_info = ( unsigned long ) & ax8817x_info ,
2012-09-28 23:58:44 +04:00
} , {
// Lenovo U2L100P 10/100
USB_DEVICE ( 0x17ef , 0x7203 ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2011-07-20 09:57:04 +04:00
} , {
// ASIX AX88772B 10/100
USB_DEVICE ( 0x0b95 , 0x772b ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2005-08-31 20:53:10 +04:00
} , {
// ASIX AX88772 10/100
2007-02-20 16:02:24 +03:00
USB_DEVICE ( 0x0b95 , 0x7720 ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2006-05-18 12:13:17 +04:00
} , {
// ASIX AX88178 10/100/1000
USB_DEVICE ( 0x0b95 , 0x1780 ) ,
2006-07-29 18:12:50 +04:00
. driver_info = ( unsigned long ) & ax88178_info ,
2010-12-15 15:16:30 +03:00
} , {
// Logitec LAN-GTJ/U2A
USB_DEVICE ( 0x0789 , 0x0160 ) ,
. driver_info = ( unsigned long ) & ax88178_info ,
2005-12-19 21:58:38 +03:00
} , {
// Linksys USB200M Rev 2
USB_DEVICE ( 0x13b1 , 0x0018 ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2006-01-05 22:39:49 +03:00
} , {
// 0Q0 cable ethernet
USB_DEVICE ( 0x1557 , 0x7720 ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2006-07-29 18:12:50 +04:00
} , {
// DLink DUB-E100 H/W Ver B1
USB_DEVICE ( 0x07d1 , 0x3c05 ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2006-09-21 16:09:29 +04:00
} , {
// DLink DUB-E100 H/W Ver B1 Alternate
USB_DEVICE ( 0x2001 , 0x3c05 ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2012-09-18 01:50:57 +04:00
} , {
// DLink DUB-E100 H/W Ver C1
USB_DEVICE ( 0x2001 , 0x1a02 ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2006-07-29 18:12:50 +04:00
} , {
// Linksys USB1000
USB_DEVICE ( 0x1737 , 0x0039 ) ,
. driver_info = ( unsigned long ) & ax88178_info ,
2007-01-26 16:57:38 +03:00
} , {
// IO-DATA ETG-US2
USB_DEVICE ( 0x04bb , 0x0930 ) ,
. driver_info = ( unsigned long ) & ax88178_info ,
2007-05-23 15:33:17 +04:00
} , {
// Belkin F5D5055
USB_DEVICE ( 0x050d , 0x5055 ) ,
. driver_info = ( unsigned long ) & ax88178_info ,
2008-05-15 04:04:13 +04:00
} , {
// Apple USB Ethernet Adapter
USB_DEVICE ( 0x05ac , 0x1402 ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2008-11-11 21:02:53 +03:00
} , {
// Cables-to-Go USB Ethernet Adapter
USB_DEVICE ( 0x0b95 , 0x772a ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2009-02-25 10:52:24 +03:00
} , {
// ABOCOM for pci
USB_DEVICE ( 0x14ea , 0xab11 ) ,
. driver_info = ( unsigned long ) & ax88178_info ,
} , {
// ASIX 88772a
USB_DEVICE ( 0x0db0 , 0xa877 ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2011-12-16 14:49:22 +04:00
} , {
// Asus USB Ethernet Adapter
USB_DEVICE ( 0x0b95 , 0x7e2b ) ,
. driver_info = ( unsigned long ) & ax88772_info ,
2012-07-13 09:26:31 +04:00
} , {
/* ASIX 88172a demo board */
USB_DEVICE ( 0x0b95 , 0x172a ) ,
. driver_info = ( unsigned long ) & ax88172a_info ,
2005-08-31 20:53:10 +04:00
} ,
{ } , // END
} ;
MODULE_DEVICE_TABLE ( usb , products ) ;
static struct usb_driver asix_driver = {
2011-10-04 13:55:18 +04:00
. name = DRIVER_NAME ,
2005-08-31 20:53:10 +04:00
. id_table = products ,
. probe = usbnet_probe ,
. suspend = usbnet_suspend ,
. resume = usbnet_resume ,
. disconnect = usbnet_disconnect ,
2007-08-03 15:52:19 +04:00
. supports_autosuspend = 1 ,
2012-04-23 21:08:51 +04:00
. disable_hub_initiated_lpm = 1 ,
2005-08-31 20:53:10 +04:00
} ;
2011-11-18 21:44:20 +04:00
module_usb_driver ( asix_driver ) ;
2005-08-31 20:53:10 +04:00
MODULE_AUTHOR ( " David Hollis " ) ;
2011-10-04 13:55:16 +04:00
MODULE_VERSION ( DRIVER_VERSION ) ;
2005-08-31 20:53:10 +04:00
MODULE_DESCRIPTION ( " ASIX AX8817X based USB 2.0 Ethernet Devices " ) ;
MODULE_LICENSE ( " GPL " ) ;