* Re: Getting the correct asix AX88178 usb gige driver in mainline?
[not found] ` <20110705153519.GA6198@kroah.com>
@ 2011-07-06 17:25 ` Marc MERLIN
2011-07-06 20:09 ` Arnd Bergmann
2011-07-06 21:08 ` Marc MERLIN
0 siblings, 2 replies; 6+ messages in thread
From: Marc MERLIN @ 2011-07-06 17:25 UTC (permalink / raw)
To: netdev; +Cc: greg
Howdy netdev folks,
On Tue, Jul 05, 2011 at 08:35:19AM -0700, Greg KH wrote:
> I looked at this and it seems they took a very old version of the driver
> (from 2003) and somehow changed it to work for this device. I can't
> really tell what they changed unless I were to dig through the original
> version.
>
> I suggest you post your original message to the
> mailing list. The network developers there should be able to help you
> out as I can't at the moment due to real-work and travel.
Here are the details. If somehow their driver could be integrated in
mainline by putting the relevant bits in the current driver, that would be
fantastic :)
(obviously it would have been better if they had done that themselves to
start with, no idea why they didn't).
----------------------------------------------------------------------------
I just bought a USB gige ethernet adapter from 'winstars' called 'delphi g
usb 2.0 gigabit lan'.
Linux 2.6.39.1 says:
usb 8-1: Product: AX88178
usb 8-1: Manufacturer: ASIX Elec. Corp.
usb 8-1: SerialNumber: 000002
asix 8-1:1.0: eth1: register 'asix' at usb-0000:00:1d.7-1, ASIX AX88178 USB 2.0 Ethernet, 00:0e:c6:88:7c:ae
usbcore: registered new interface driver asix
but that driver brings up an eth1 that cannot send data.
Google showed me the vendor website with a working linux driver:
http://www.asix.com.tw/FrootAttach/driver/AX88772_772A_178_LINUX2.6.9_REV122.zip
Their driver which compiled out of tree easily and said:
ASIX USB Ethernet Adapter:v4.1.0 19:16:59 Jun 28 2011
<6> http://www.asix.com.tw
eth%d: status ep1in, 8 bytes period 11
eth1: register 'asix' at usb-0000:00:1d.7-1, ASIX AX88178 USB 2.0 Ethernet, 00:0e:c6:88:7c:ae
usbcore: registered new interface driver asix
eth1: rxqlen 0 --> 5
eth1: ax88178 - Link status is: 0
eth1: kevent 4 scheduled
eth1: ax88178 - Link status is: 1
eth1: no IPv6 routers present
It worked fine with dhcp (which the stock driver sure didn't).
Is there someone who can see if that driver can be merged in mainline to
replace the non working one?
For comparison, the mainline one also outputted a traceback. The full relevant logs are below:
usb 8-1: new high speed USB device number 8 using ehci_hcd
usb 8-1: New USB device found, idVendor=0b95, idProduct=1780
usb 8-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 8-1: Product: AX88178
usb 8-1: Manufacturer: ASIX Elec. Corp.
usb 8-1: SerialNumber: 000002
asix 8-1:1.0: eth1: register 'asix' at usb-0000:00:1d.7-1, ASIX AX88178 USB 2.0 Ethernet, 00:0e:c6:88:7c:ae
usbcore: registered new interface driver asix
asix 8-1:1.0: eth1: link down
ADDRCONF(NETDEV_UP): eth1: link is not ready
ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
asix 8-1:1.0: eth1: link up, 1000Mbps, full-duplex, lpa 0xC5E1
eth1: no IPv6 routers present
gandalfthegrey:~# ifconfig eth1 192.168.205.10
gandalfthegrey:~# ping 192.168.205.254
PING 192.168.205.254 (192.168.205.254) 56(84) bytes of data.
>From 192.168.205.10 icmp_seq=3 Destination Host Unreachable
>From 192.168.205.10 icmp_seq=4 Destination Host Unreachable
(tcpdump showed some traffic though)
Later, I found this in dmesg:
------------[ cut here ]------------
WARNING: at net/sched/sch_generic.c:256 dev_watchdog+0x113/0x1a9()
Hardware name: 4063FM6
NETDEV WATCHDOG: eth1 (asix): transmit queue 0 timed out
Modules linked in: asix usbnet nfs fscache usb_storage usb_libusual uas xt_tcpudp xt_state nls_iso8859_1 nls_cp437 vfat fat vboxnetadp vboxnetflt vboxdrv fuse nfsd lockd nfs_acl auth_rpcgss sunrpc autofs4 acpi_cpufreq mperf cpufreq_conservative cpufreq_powersave ipt_REJECT cpufreq_stats cpufreq_userspace cpufreq_ondemand freq_table ipt_MASQUERADE ipt_LOG iptable_mangle iptable_filter rfcomm bnep binfmt_misc fbcon tileblit font bitblit fbcon_rotate fbcon_cw fbcon_ud fbcon_ccw softcursor iptable_nat nf_nat nf_conntrack_ipv4 i915 drm_kms_helper nf_conntrack drm fb fbdev nf_defrag_ipv4 i2c_algo_bit cfbcopyarea cfbimgblt cfbfillrect ip_tables x_tables ipv6 btusb bluetooth snd_hda_codec_conexant msr snd_hda_intel coretemp snd_hda_codec snd_hwdep snd_pcm_oss input_polldev snd_mixer_oss thinkpad_a
cpi snd_pcm snd_seq_dummy snd_seq_oss snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq uvcvideo videodev media pcmcia arc4 snd_timer snd_seq_device r852 sm_common nand nand_ids yenta_socket pcmcia_rsrc iwlagn mac80211 nand_bch pcmcia_core rtc_cmos snd ppdev ehci_hcd bch sdhci_pci sdhci nand_ecc mtd mmc_core parport_pc r592 rtc_core uhci_hcd memstick cfg80211 snd_page_alloc rfkill e1000e soundcore processor battery rtc_lib usbcore psmouse lp ac nvram tpm_tis serio_raw sr_mod cdrom wmi evdev sg parport raid10 raid456 async_raid6_recov async_pq raid6_pq async_xor xor async_memcpy async_tx multipath sha256_generic dm_crypt dm_mod aes_i586 aes_generic ecb cbc intel_agp intel_gtt video agpgart backlight thermal thermal_sys hwmon button
Pid: 0, comm: swapper Not tainted 2.6.39.1-core2-volpreempt-noide-hm64-20110620 #2
Call Trace:
[<c0133599>] warn_slowpath_common+0x60/0x75
[<c0133612>] warn_slowpath_fmt+0x26/0x2a
[<c03c8a35>] dev_watchdog+0x113/0x1a9
[<c012dd94>] ? try_to_wake_up+0x321/0x32c
[<c024f023>] ? jbd2_journal_force_commit_nested+0x6e/0x6e
[<c03c8922>] ? __netdev_watchdog_up+0x52/0x52
[<c013c8c1>] run_timer_softirq+0x139/0x1b5
[<c01380c1>] __do_softirq+0x7a/0x110
[<c0138047>] ? __local_bh_enable+0x6c/0x6c
<IRQ> [<c0137f7a>] ? irq_exit+0x3d/0x8b
[<c01039f1>] ? do_IRQ+0x7b/0x91
[<c0443bb0>] ? common_interrupt+0x30/0x38
[<c014007b>] ? get_signal_to_deliver+0x18d/0x32a
[<f8b82fc9>] ? acpi_idle_enter_simple+0x136/0x16a [processor]
[<c03a1a6f>] ? cpuidle_idle_call+0x6f/0xa0
[<c0101b91>] ? cpu_idle+0x8b/0xa6
[<c042a560>] ? rest_init+0x58/0x5a
[<c06257d6>] ? start_kernel+0x313/0x318
[<c06250a8>] ? i386_start_kernel+0xa8/0xb0
---[ end trace 0c6c364f0d69b5d1 ]---
device eth1 entered promiscuous mode
device eth1 left promiscuous mode
usbcore: deregistering interface driver asix
asix 8-1:1.0: eth1: unregister 'asix' usb-0000:00:1d.7-1, ASIX AX88178 USB 2.0 Ethernet
Thanks,
Marc
--
"A mouse is a device used to point at the xterm you want to type in" - A.S.R.
Microsoft is to operating systems ....
.... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Getting the correct asix AX88178 usb gige driver in mainline?
2011-07-06 17:25 ` Getting the correct asix AX88178 usb gige driver in mainline? Marc MERLIN
@ 2011-07-06 20:09 ` Arnd Bergmann
[not found] ` <20110706201751.GG22090@merlins.org>
2011-07-06 21:08 ` Marc MERLIN
1 sibling, 1 reply; 6+ messages in thread
From: Arnd Bergmann @ 2011-07-06 20:09 UTC (permalink / raw)
To: Marc MERLIN; +Cc: netdev, greg
On Wednesday 06 July 2011 19:25:38 Marc MERLIN wrote:
> Howdy netdev folks,
>
> On Tue, Jul 05, 2011 at 08:35:19AM -0700, Greg KH wrote:
> > I looked at this and it seems they took a very old version of the driver
> > (from 2003) and somehow changed it to work for this device. I can't
> > really tell what they changed unless I were to dig through the original
> > version.
> >
> > I suggest you post your original message to the
> > mailing list. The network developers there should be able to help you
> > out as I can't at the moment due to real-work and travel.
>
> Here are the details. If somehow their driver could be integrated in
> mainline by putting the relevant bits in the current driver, that would be
> fantastic :)
> (obviously it would have been better if they had done that themselves to
> start with, no idea why they didn't).
>
Hi Marc,
I've taken a look at the driver you linked to and compared it to the
version that was closest at the time.
This is similar to the patch they must have had at some point. I would guess
that the answer is somewhere in there. It's quite different to the much
cleaner patch 933a27d39e "USB: asix - Add AX88178 support and many other
changes", which was merged later with a similar intention.
Arnd
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 4cbb408..3c1d0ee 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -739,11 +739,15 @@ static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, i
static int ax88172_link_reset(struct usbnet *dev)
{
u16 lpa;
+ u16 adv;
+ u16 res;
u8 mode;
mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN;
lpa = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_LPA);
- if (lpa & LPA_DUPLEX)
+ adv = ax8817x_mdio_read(dev->net, dev->mii.phy_id, MII_ADVERTISE);
+ res = mii_nway_result(lpa|adv);
+ if (res & LPA_DUPLEX)
mode |= AX_MEDIUM_FULL_DUPLEX;
ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL);
@@ -816,7 +820,7 @@ static int ax8817x_get_eeprom(struct net_device *net,
eeprom->offset + i, 0, 2, &ebuf[i]) < 0)
return -EINVAL;
}
- return 0;
+ return i * 2;
}
static void ax8817x_get_drvinfo (struct net_device *net,
@@ -960,6 +964,29 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
goto out2;
msleep(5);
+
+ /* Initialize MII structure */
+ dev->mii.dev = dev->net;
+ dev->mii.mdio_read = ax8817x_mdio_read;
+ dev->mii.mdio_write = ax8817x_mdio_write;
+ dev->mii.phy_id_mask = 0xff;
+ dev->mii.reg_num_mask = 0xff;
+
+ /* Get the PHY id */
+ if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
+ dbg("Error reading PHY ID: %02x", ret);
+ goto out2;
+ } else if (ret < 2) {
+ /* this should always return 2 bytes */
+ dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
+ ret);
+ ret = -EIO;
+ goto out2;
+ }
+ dev->mii.phy_id = *((u8 *)buf + 1);
+
+ if (dev->mii.phy_id == 0x10)
+ {
if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0x0001, 0, 0, buf)) < 0) {
dbg("Select PHY #1 failed: %d", ret);
goto out2;
@@ -984,6 +1011,21 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
dbg("Failed to set Internal/External PHY reset control: %d", ret);
goto out2;
}
+ }
+ else
+ {
+ if ((ret =
+ ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0x0000, 0, 0, buf)) < 0) {
+ dbg("Select PHY #1 failed: %d", ret);
+ goto out2;
+ }
+
+ if ((ret =
+ ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD | AX_SWRESET_PRL, 0, 0, buf)) < 0) {
+ dbg("Failed to power down internal PHY: %d", ret);
+ goto out2;
+ }
+ }
msleep(150);
if ((ret =
@@ -1006,6 +1048,8 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
goto out2;
}
+ if (dev->mii.phy_id == 0x10)
+ {
if (((ret =
ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, 0x0010, 2, 2, buf)) < 0)
|| (*((u16 *)buf) != 0x003b)) {
@@ -1013,26 +1057,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
goto out2;
}
- /* Initialize MII structure */
- dev->mii.dev = dev->net;
- dev->mii.mdio_read = ax8817x_mdio_read;
- dev->mii.mdio_write = ax8817x_mdio_write;
- dev->mii.phy_id_mask = 0xff;
- dev->mii.reg_num_mask = 0xff;
-
- /* Get the PHY id */
- if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
- dbg("Error reading PHY ID: %02x", ret);
- goto out2;
- } else if (ret < 2) {
- /* this should always return 2 bytes */
- dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x",
- ret);
- ret = -EIO;
- goto out2;
- }
- dev->mii.phy_id = *((u8 *)buf + 1);
-
if ((ret =
ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL, 0, 0, buf)) < 0) {
dbg("Set external PHY reset pin level: %d", ret);
@@ -1045,14 +1069,14 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
goto out2;
}
msleep(150);
-
+ }
dev->net->set_multicast_list = ax8817x_set_multicast;
dev->net->ethtool_ops = &ax88772_ethtool_ops;
ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
ax8817x_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
- ADVERTISE_ALL | ADVERTISE_CSMA);
+ ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
mii_nway_restart(&dev->mii);
if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) {
@@ -1060,7 +1084,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
goto out2;
}
- if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT,AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, AX88772_IPG0_DEFAULT | (AX88772_IPG1_DEFAULT << 8), AX88772_IPG2_DEFAULT, 0, buf)) < 0) {
dbg("Write IPG,IPG1,IPG2 failed: %d", ret);
goto out2;
}
@@ -1088,6 +1112,663 @@ out1:
return ret;
}
+static int mediacheck(struct usbnet *dev)
+{
+ int ret,fullduplex;
+ u16 phylinkstatus1, phylinkstatus2, data16, tempshort = 0;
+ struct ax8817x_data *ax17xdataptr = (struct ax8817x_data *)&dev->data;
+ struct ax88178_data *ax178dataptr = (struct ax88178_data *)ax17xdataptr->ax178dataptr;
+
+
+ if ((ret =ax8817x_read_cmd(dev,AX_CMD_READ_MII_REG,dev->mii.phy_id,
+ GMII_PHY_ANLPAR, REG_LENGTH, &data16)) < 0) {
+ dbg("error on reading MII register 5 failed: %02x", ret);
+ return ret; //
+ }
+ phylinkstatus1 = le16_to_cpu(data16);
+
+ if ((ret =ax8817x_read_cmd(dev,AX_CMD_READ_MII_REG,dev->mii.phy_id, GMII_PHY_1000BT_STATUS,
+ REG_LENGTH, &data16)) < 0) {
+ dbg("error on reading MII register 0x0a failed: %02x", ret);
+ return ret; //
+ }
+ phylinkstatus2 = le16_to_cpu(data16);
+
+ if(ax178dataptr->PhyMode == PHY_MODE_MARVELL){ //1st generation Marvel PHY
+ if(ax178dataptr->LedMode == 1){
+ if ((ret = ax8817x_read_cmd(dev,AX_CMD_READ_MII_REG,dev->mii.phy_id, MARVELL_MANUAL_LED,
+ REG_LENGTH, &data16)) < 0) {
+ dbg("error on reading MII register 0x19 failed: %02x", ret);
+ return ret; //
+ }
+ tempshort = le16_to_cpu(data16);
+ tempshort &=0xfc0f;
+ }
+ }
+
+ fullduplex=1;
+ if(phylinkstatus2 & (GMII_1000_AUX_STATUS_FD_CAPABLE|GMII_1000_AUX_STATUS_HD_CAPABLE)){ /* 1000BT full duplex */
+ ax178dataptr->MediaLink =
+ MEDIUM_GIGA_MODE|MEDIUM_FULL_DUPLEX_MODE|MEDIUM_ENABLE_125MHZ|MEDIUM_ENABLE_RECEIVE;
+ if(ax178dataptr->PhyMode == PHY_MODE_MARVELL){
+ if(ax178dataptr->LedMode == 1){
+ tempshort|=0x3e0;
+ }
+ }
+ }else if(phylinkstatus1 & GMII_ANLPAR_100TXFD){ /* 100BT full duplex */
+ ax178dataptr->MediaLink=MEDIUM_FULL_DUPLEX_MODE|MEDIUM_ENABLE_RECEIVE|MEDIUM_MII_100M_MODE;
+ if(ax178dataptr->PhyMode == PHY_MODE_MARVELL){
+ if(ax178dataptr->LedMode == 1){
+ tempshort|=0x3b0;
+ }
+ }
+ }else if(phylinkstatus1 & GMII_ANLPAR_100TX){ /* 100BT half duplex */
+ ax178dataptr->MediaLink=(MEDIUM_ENABLE_RECEIVE|MEDIUM_MII_100M_MODE);
+ fullduplex=0;
+ if(ax178dataptr->PhyMode == PHY_MODE_MARVELL){
+ if(ax178dataptr->LedMode == 1){
+ tempshort|=0x3b0;
+ }
+ }
+ }else if(phylinkstatus1 & GMII_ANLPAR_10TFD){ /* 10 full duplex */
+ ax178dataptr->MediaLink = (MEDIUM_FULL_DUPLEX_MODE|MEDIUM_ENABLE_RECEIVE);
+ if(ax178dataptr->PhyMode == PHY_MODE_MARVELL){
+ if(ax178dataptr->LedMode == 1){
+ tempshort|=0x02f0;
+ }
+ }
+ }else{
+ /* 10 half duplex*/
+ ax178dataptr->MediaLink = MEDIUM_ENABLE_RECEIVE;
+ fullduplex=0;
+ if(ax178dataptr->PhyMode == PHY_MODE_MARVELL){
+ if(ax178dataptr->LedMode == 1){
+ tempshort|=0x02f0;
+ }
+ }
+ }
+
+ if(ax178dataptr->PhyMode == PHY_MODE_MARVELL){
+ if(ax178dataptr->LedMode == 1){
+ data16 = le16_to_cpu(tempshort);
+ if ( (ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, (u8)dev->mii.phy_id,
+ MARVELL_MANUAL_LED, REG_LENGTH, &data16)) < 0){
+ dbg("error on writing MII register 0x19 failed: %02x", ret);
+ return ret;
+ }
+ }
+ }
+ ax178dataptr->MediaLink |= 0x0004;
+ if(ax178dataptr->UseRgmii != 0)
+ ax178dataptr->MediaLink |= 0x0008;
+ if(fullduplex){
+ ax178dataptr->MediaLink |= 0x0020; //ebable tx flow control as default;
+ ax178dataptr->MediaLink |= 0x0010; //ebable rx flow control as default;
+ }
+
+ return 0;
+}
+
+static int marevell_init(struct usbnet *dev)
+{
+ struct ax8817x_data *ax17xdataptr = (struct ax8817x_data *)&dev->data;
+ struct ax88178_data *ax178dataptr = (struct ax88178_data *)ax17xdataptr->ax178dataptr;
+ u16 tmp,phyreg,PhyPatch,data16;
+ int ret;
+ void *buf;
+ u8 PhyID = (u8)ax178dataptr->PhyID;
+
+ buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if(!buf)
+ return -ENOMEM;
+
+ if(ax178dataptr->UseGpio0)
+ {
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,AXGPIOS_GPO0EN |AXGPIOS_RSE,0, 0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(25);
+ tmp = AXGPIOS_GPO2 | AXGPIOS_GPO2EN | AXGPIOS_GPO0EN;
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, tmp, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(25);
+ tmp = AXGPIOS_GPO2EN | AXGPIOS_GPO0EN;
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, tmp, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(245);
+ tmp = AXGPIOS_GPO2 | AXGPIOS_GPO2EN | AXGPIOS_GPO0EN;
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, tmp, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+
+ }
+ else /* !UseGpio0 */
+ {
+ tmp = AXGPIOS_GPO1|AXGPIOS_GPO1EN | AXGPIOS_RSE;
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, tmp, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ if(ax178dataptr->LedMode != 1) //our new demo board
+ {
+ msleep(25);
+ tmp = AXGPIOS_GPO1|AXGPIOS_GPO1EN | AXGPIOS_GPO2EN | AXGPIOS_GPO2;
+ if ((ret =ax8817x_write_cmd(dev,AX_CMD_WRITE_GPIOS,tmp,0,0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(25);
+ tmp = AXGPIOS_GPO2EN | AXGPIOS_GPO1|AXGPIOS_GPO1EN;
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, tmp, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(245);
+ tmp = AXGPIOS_GPO1|AXGPIOS_GPO1EN|AXGPIOS_GPO2|AXGPIOS_GPO2EN;
+ if ((ret = ax8817x_write_cmd(dev,AX_CMD_WRITE_GPIOS,tmp,0,0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ }
+ else if(ax178dataptr->LedMode == 1) //bufflo old card
+ {
+ msleep(350);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, AXGPIOS_GPO1EN, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(350);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, AXGPIOS_GPO1|AXGPIOS_GPO1EN, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ }
+ }
+
+
+ if((ret = ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, PhyID, PHY_MARVELL_STATUS, REG_LENGTH, &data16)) < 0){
+ dbg("read register reg 27 failed: %d", ret);
+ return ret;
+ } //read phy register
+
+ phyreg = le16_to_cpu(data16);
+ if(!(phyreg & MARVELL_STATUS_HWCFG)){
+ ax178dataptr->UseRgmii=1;
+ PhyPatch = MARVELL_CTRL_RXDELAY | MARVELL_CTRL_TXDELAY;
+ data16 = cpu_to_le16(PhyPatch);
+ if((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, PHY_MARVELL_CTRL, REG_LENGTH, &data16)) < 0)
+ return ret;
+ ax178dataptr->MediaLink |= MEDIUM_ENABLE_125MHZ;
+ }
+
+ if(ax178dataptr->LedMode == 1){
+ if((ret = ax8817x_read_cmd(dev,AX_CMD_READ_MII_REG, PhyID, MARVELL_LED_CTRL, REG_LENGTH, &data16))< 0)
+ return ret;
+ phyreg = le16_to_cpu(data16);
+ phyreg &= 0xf8ff;
+ phyreg |= (1+0x100);
+
+ data16 = le16_to_cpu(phyreg);
+ if((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, MARVELL_LED_CTRL, REG_LENGTH,&data16))< 0)
+ return ret;
+ if((ret = ax8817x_read_cmd(dev,AX_CMD_READ_MII_REG, PhyID, MARVELL_LED_CTRL, REG_LENGTH, &data16))< 0)
+ return ret;
+ phyreg = le16_to_cpu(data16);
+ phyreg &=0xfc0f;
+ } else if(ax178dataptr->LedMode == 2){
+
+ if((ret = ax8817x_read_cmd(dev,AX_CMD_READ_MII_REG, PhyID, MARVELL_LED_CTRL, REG_LENGTH, &data16))< 0)
+ return ret;
+
+ phyreg = le16_to_cpu(data16);
+ phyreg &= 0xf886;
+ phyreg |= (1+0x10+0x300);
+ data16 = cpu_to_le16(phyreg);
+ if((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, MARVELL_LED_CTRL, REG_LENGTH,&data16))< 0)
+ return ret;
+
+ }else if(ax178dataptr->LedMode == 5){
+ if((ret = ax8817x_read_cmd(dev,AX_CMD_READ_MII_REG, PhyID, MARVELL_LED_CTRL, REG_LENGTH, &data16))< 0)
+ return ret;
+ phyreg = le16_to_cpu(data16);
+ phyreg &= 0xf8be;
+ phyreg |= (1+0x40+0x300);
+ data16 = cpu_to_le16(phyreg);
+ if((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, MARVELL_LED_CTRL, REG_LENGTH,&data16))< 0)
+ return ret;
+ }
+
+ ax178dataptr->phyreg = phyreg;
+ return 0;
+}
+
+static int cicada_init(struct usbnet *dev)
+{
+
+ struct ax8817x_data *ax17xdataptr = (struct ax8817x_data *)&dev->data;
+ struct ax88178_data *ax178dataptr = (struct ax88178_data *)ax17xdataptr->ax178dataptr;
+ u16 tmp, phyreg, i, data16;
+ int ret;
+ void *buf;
+ u8 PhyID = (u8)ax178dataptr->PhyID;
+
+ buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if(!buf)
+ return -ENOMEM;
+
+ if(ax178dataptr->UseGpio0)
+ {
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,AXGPIOS_GPO0 | AXGPIOS_GPO0EN | AXGPIOS_RSE,0, 0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ }
+ else
+ {
+ tmp = AXGPIOS_GPO1|AXGPIOS_GPO1EN | AXGPIOS_RSE;
+ if ((ret =ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,tmp,0,0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ if(ax178dataptr->LedMode!= 1) //our new demo board
+ {
+ msleep(25);
+ tmp = AXGPIOS_GPO1|AXGPIOS_GPO1EN | AXGPIOS_GPO2EN | AXGPIOS_GPO2;
+ if ((ret =ax8817x_write_cmd(dev,AX_CMD_WRITE_GPIOS,tmp,0,0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(25);
+ tmp = AXGPIOS_GPO2EN | AXGPIOS_GPO1|AXGPIOS_GPO1EN;
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, tmp, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(245);
+ tmp = AXGPIOS_GPO1|AXGPIOS_GPO1EN|AXGPIOS_GPO2|AXGPIOS_GPO2EN;
+ if ((ret = ax8817x_write_cmd(dev,AX_CMD_WRITE_GPIOS,tmp,0,0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ }
+ else if(ax178dataptr->LedMode==1) //bufflo old card
+ {
+ msleep(350);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, AXGPIOS_GPO1EN, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(350);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, AXGPIOS_GPO1|AXGPIOS_GPO1EN, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ }
+ }
+
+ if(ax178dataptr->PhyMode == PHY_MODE_CICADA_FAMILY){ //CICADA 1st version phy
+ ax178dataptr->UseRgmii=1;
+ ax178dataptr->MediaLink |= MEDIUM_ENABLE_125MHZ;// MEDIUM_ENABLE_125MHZ;
+
+ for (i = 0; i < sizeof(CICADA_FAMILY_HWINIT)/sizeof(CICADA_FAMILY_HWINIT[0]); i++) {
+ data16 = cpu_to_le16(CICADA_FAMILY_HWINIT[i].value);
+ ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, CICADA_FAMILY_HWINIT[i].offset, REG_LENGTH, &data16);
+ if(ret < 0) return ret;
+ }
+ }
+ else if(ax178dataptr->PhyMode == PHY_MODE_CICADA_V2){
+ ax178dataptr->UseRgmii=1;
+ ax178dataptr->MediaLink |= MEDIUM_ENABLE_125MHZ;
+
+ for (i = 0; i < ( sizeof(CICADA_V2_HWINIT)/sizeof(CICADA_V2_HWINIT[0]) ); i++) {
+ data16 = cpu_to_le16(CICADA_V2_HWINIT[i].value);
+ ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, CICADA_V2_HWINIT[i].offset, REG_LENGTH, &data16);
+ if(ret < 0) return ret;
+ }
+ }
+ else if(ax178dataptr->PhyMode == PHY_MODE_CICADA_V2_ASIX){
+ ax178dataptr->UseRgmii=1;
+ ax178dataptr->MediaLink |= MEDIUM_ENABLE_125MHZ;
+
+ for (i = 0; i < ( sizeof(CICADA_V2_ASIX_HWINIT)/sizeof(CICADA_V2_ASIX_HWINIT[0]) ); i++) {
+ data16 = cpu_to_le16(CICADA_V2_ASIX_HWINIT[i].value);
+ ret=ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, CICADA_V2_ASIX_HWINIT[i].offset, REG_LENGTH, &data16);
+ if(ret < 0) return ret;
+ }
+ }
+
+ if(ax178dataptr->PhyMode == PHY_MODE_CICADA_FAMILY){
+ if(ax178dataptr->LedMode == 3){
+ if((ret = ax8817x_read_cmd(dev,AX_CMD_READ_MII_REG, PhyID, 27, 2, &data16))< 0)
+ return ret;
+ phyreg = le16_to_cpu(data16);
+ phyreg &= 0xfcff;
+ phyreg |= 0x0100;
+ data16 = cpu_to_le16(phyreg);
+ if((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, 27,2,&data16))< 0)
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int agere_init(struct usbnet *dev)
+{
+ struct ax8817x_data *ax17xdataptr = (struct ax8817x_data *)&dev->data;
+ struct ax88178_data *ax178dataptr = (struct ax88178_data *)ax17xdataptr->ax178dataptr;
+ u16 tmp, phyreg, i;
+ int ret;
+ void *buf;
+ u8 PhyID = (u8)ax178dataptr->PhyID;
+
+ buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if(!buf)
+ return -ENOMEM;
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,AXGPIOS_GPO1|AXGPIOS_GPO1EN | AXGPIOS_RSE,0,0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(25);
+ if ((ret=ax8817x_write_cmd(dev,AX_CMD_WRITE_GPIOS,AXGPIOS_GPO1|AXGPIOS_GPO1EN
+ | AXGPIOS_GPO2EN | AXGPIOS_GPO2,0,0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(25);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, AXGPIOS_GPO2EN | AXGPIOS_GPO1
+ | AXGPIOS_GPO1EN, 0, 0, buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+ msleep(245);
+ if ((ret=ax8817x_write_cmd(dev,AX_CMD_WRITE_GPIOS,AXGPIOS_GPO1|AXGPIOS_GPO1EN|AXGPIOS_GPO2
+ | AXGPIOS_GPO2EN,0,0,buf)) < 0){
+ dbg("write GPIO failed: %d", ret);
+ return ret;
+ }
+
+ ax178dataptr->UseRgmii=1;
+ ax178dataptr->MediaLink |= MEDIUM_ENABLE_125MHZ;
+
+ phyreg = cpu_to_le16(BMCR_RESET);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, MII_BMCR, REG_LENGTH, &phyreg)) < 0) {
+ dbg("Failed to write MII reg - MII_BMCR: %02x", ret);
+ return ret;
+ } //software reset
+
+ while (1)
+ {
+ phyreg = cpu_to_le16(0x1001);
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, 21, REG_LENGTH, &phyreg);
+ msleep(10);
+ ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, PhyID, 21, REG_LENGTH, &phyreg);
+ tmp = le16_to_cpu(phyreg);
+ if ((tmp & 0xf00f) == 0x1001)
+ break;
+ msleep(10);
+ }
+
+ if (ax178dataptr->LedMode == 4)
+ {
+ phyreg = cpu_to_le16(0x7417);
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, 28, 2, &phyreg);
+ }
+ else if (ax178dataptr->LedMode == 9)
+ {
+ phyreg = cpu_to_le16(0x7a10);
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, 28, 2, &phyreg);
+ }
+ else if (ax178dataptr->LedMode == 10)
+ {
+ phyreg = cpu_to_le16(0x7a13);
+ ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, PhyID, 28, 2, &phyreg);
+ }
+
+ for (i = 0; i < ( sizeof(AGERE_FAMILY_HWINIT)/sizeof(AGERE_FAMILY_HWINIT[0]) ); i++) {
+ phyreg = cpu_to_le16(AGERE_FAMILY_HWINIT[i].value);
+ ret=ax8817x_write_cmd(dev,AX_CMD_WRITE_MII_REG,PhyID,AGERE_FAMILY_HWINIT[i].offset,REG_LENGTH,&phyreg);
+ if(ret < 0) return ret;
+ }
+
+ return 0;
+}
+
+static int phy_init(struct usbnet *dev)
+{
+ struct ax8817x_data *ax17xdataptr = (struct ax8817x_data *)&dev->data;
+ struct ax88178_data *ax178dataptr = (struct ax88178_data *)ax17xdataptr->ax178dataptr;
+ int ret;
+ u16 tmp, data16, phyanar, phyauxctrl, phyctrl, phyreg = 0;
+ void *buf;
+
+ buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if(!buf)
+ return -ENOMEM;
+
+ if(ax178dataptr->PhyMode == PHY_MODE_MARVELL) {
+ if((ret = marevell_init(dev)) < 0) return ret;
+ }else if(ax178dataptr->PhyMode == PHY_MODE_CICADA_FAMILY) {
+ if((ret = cicada_init(dev)) < 0) return ret;
+ }else if(ax178dataptr->PhyMode == PHY_MODE_CICADA_V1) {
+ if((ret = cicada_init(dev)) < 0) return ret;
+ }else if(ax178dataptr->PhyMode == PHY_MODE_CICADA_V2_ASIX) {
+ if((ret = cicada_init(dev)) < 0) return ret;
+ }else if(ax178dataptr->PhyMode == PHY_MODE_AGERE_FAMILY) {
+ if((ret = agere_init(dev)) < 0) return ret;
+ }
+
+ if(ax178dataptr->PhyMode != PHY_MODE_AGERE_FAMILY)
+ {
+ /* reset phy */
+ data16 = cpu_to_le16(BMCR_RESET);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, dev->mii.phy_id,
+ MII_BMCR, REG_LENGTH, (void *)(&data16))) < 0) {
+ dbg("Failed to write MII reg - MII_BMCR: %02x", ret);
+ return ret;
+ }
+ }
+
+ if ((ret = ax8817x_read_cmd(dev,AX_CMD_READ_MII_REG, dev->mii.phy_id , MII_BMCR,
+ REG_LENGTH, &data16)) < 0) {
+ dbg("error on read MII reg - MII_BMCR: %02x", ret);
+ return ret; //could be 0x0000
+ }
+
+ phyctrl = le16_to_cpu(data16);
+ tmp=phyctrl;
+ phyctrl &=~(BMCR_PDOWN|BMCR_ISOLATE);
+ if(phyctrl != tmp){
+ data16 = cpu_to_le16(phyctrl);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, dev->mii.phy_id, MII_BMCR,
+ REG_LENGTH, &data16)) < 0) {
+ dbg("Failed to write MII reg - MII_BMCR: %02x", ret);
+ return ret;
+ }
+
+ }
+
+ phyctrl&= ~BMCR_ISOLATE;
+ phyanar=1+(0x0400|ADVERTISE_100FULL|ADVERTISE_100HALF|ADVERTISE_10FULL|ADVERTISE_10HALF);
+ phyauxctrl=0x0200; //1000M and full duplex
+
+ data16 = cpu_to_le16(phyanar);
+ if((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,dev->mii.phy_id,
+ GMII_PHY_ANAR,REG_LENGTH,&data16))< 0) return ret;
+
+ data16 = cpu_to_le16(phyauxctrl);
+ if((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,dev->mii.phy_id,
+ GMII_PHY_1000BT_CONTROL,REG_LENGTH,&data16))< 0) return ret;
+
+ phyctrl |= (BMCR_ANENABLE|BMCR_ANRESTART);
+ data16 = cpu_to_le16(phyctrl);
+ if((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,dev->mii.phy_id,
+ GMII_PHY_CONTROL,REG_LENGTH,&data16))< 0) return ret;
+
+ if(ax178dataptr->PhyMode == PHY_MODE_MARVELL){
+ if(ax178dataptr->LedMode==1) {
+ phyreg |= 0x3f0;
+ data16 = cpu_to_le16(phyreg);
+ if((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,dev->mii.phy_id,
+ 25,REG_LENGTH,&phyreg))< 0) return ret;
+ }
+ }
+
+ msleep(3000);
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0,
+ (AX88772_IPG0_DEFAULT | (AX88772_IPG1_DEFAULT << 8)),
+ 0x000e, 0, buf)) < 0) {
+ dbg("write IPG IPG1 IPG2 reg failed: %d", ret);
+ return ret;
+ }
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, buf)) < 0) {
+ dbg("disable PHY access failed: %d", ret);
+ return ret;
+ }
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL,
+ (AX_RX_CTL_MFB | AX_RX_CTL_START | AX_RX_CTL_AB),
+ 0, 0, buf)) < 0) {
+ dbg("write RX ctrl reg failed: %d", ret);
+ return ret;
+ }
+
+ return 0;
+
+}
+
+static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int ret;
+ void *buf;
+ u16 EepromData,PhyID, temp16;
+ struct ax8817x_data *ax17xdataptr = (struct ax8817x_data *)&dev->data;
+ struct ax88178_data *ax178dataptr;
+
+ get_endpoints(dev,intf);
+
+ buf = kmalloc(6, GFP_KERNEL);
+ if(!buf) {
+ dbg ("Cannot allocate memory for buffer");
+ return -ENOMEM;
+ }
+
+ /* allocate 178 data */
+ if (!(ax178dataptr = kmalloc (sizeof(struct ax88178_data), GFP_KERNEL))) {
+ dbg ("Cannot allocate memory for AX88178 data");
+ return -ENOMEM;
+ }
+ memset (ax178dataptr, 0, sizeof(struct ax88178_data));
+ ax17xdataptr->ax178dataptr = ax178dataptr;
+ /* end of allocate 178 data */
+
+ if ((ret = ax8817x_write_cmd(dev, 0x22, 0x0000, 0, 0, buf)) < 0) {
+ dbg("write S/W reset failed: %d", ret);
+ return ret;
+ }
+ msleep(150);
+
+ if ((ret = ax8817x_write_cmd(dev, 0x20, 0x0048, 0, 0, buf)) < 0) {
+ dbg("write S/W reset failed: %d", ret);
+ return ret;
+ }
+ msleep(150);
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0000, 0, 0, buf)) < 0) {
+ dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
+ return ret; //stop rcv
+ }
+
+ msleep(150);
+
+ /* Get the MAC address */
+ memset(buf, 0, ETH_ALEN);
+ if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)) < 0) {
+ dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
+ return ret;
+ }
+ memcpy(dev->net->dev_addr, buf, ETH_ALEN);
+ /* End of get MAC address */
+
+
+ /* Get the EEPROM data*/
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_EEPROM_EN, 0, 0, 0, buf)) < 0) {
+ dbg("enable SROM reading failed: %d", ret);
+ return ret; // ???
+ }
+
+ if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM,
+ 0x0017, 0, 2, (void *)(&EepromData))) < 0) {
+ dbg("read SROM address 17h failed: %d", ret);
+ return ret;
+ }
+
+ ax178dataptr->EepromData = le16_to_cpu(EepromData);
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_EEPROM_DIS, 0, 0, 0, buf)) < 0) {
+ dbg("disable SROM reading failed: %d", ret);
+ return ret; // ???
+ }
+ /* End of get EEPROM data */
+
+ /* Get PHY id */
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, buf)) < 0) {
+ dbg("enable PHY reg. access capability: %d", ret);
+ return ret; //enable Phy register access capability
+ }
+
+ if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, REG_LENGTH, &temp16)) < 0) {
+ dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);
+ return ret;
+ } else if (ret < 2) {
+ /* this should always return 2 bytes */
+ dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", ret);
+ return -EIO;
+ }
+
+ PhyID = le16_to_cpu(temp16);
+ PhyID = (PhyID >> 8) & PHY_ID_MASK;
+ ax178dataptr->PhyID = PhyID;
+ /* End of get PHY id */
+
+ /* Initialize MII structure */
+ dev->mii.dev = dev->net;
+ dev->mii.mdio_read = ax8817x_mdio_read;
+ dev->mii.mdio_write = ax8817x_mdio_write;
+ dev->mii.phy_id_mask = 0x3f;
+ dev->mii.reg_num_mask = 0x1f;
+ dev->mii.phy_id = (u8)ax178dataptr->PhyID;
+
+ if (ax178dataptr->EepromData == 0xffff)
+ {
+ ax178dataptr->PhyMode = PHY_MODE_MARVELL;
+ ax178dataptr->LedMode = 0;
+ ax178dataptr->UseGpio0 = 1; //True
+ }
+ else
+ {
+ ax178dataptr->PhyMode = (u8)(ax178dataptr->EepromData & EEPROMMASK);
+ ax178dataptr->LedMode = (u8)(ax178dataptr->EepromData>>8);
+ if(ax178dataptr->EepromData & 0x80) {
+ ax178dataptr->UseGpio0=0; //MARVEL se and other
+ }
+ else {
+ ax178dataptr->UseGpio0=1; //cameo
+ }
+ }
+
+ if ((ret = phy_init(dev)) < 0) return ret;
+
+ return 0;
+}
+
static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
u32 *header;
@@ -1199,6 +1880,70 @@ static int ax88772_link_reset(struct usbnet *dev)
return 0;
}
+static int set_media(struct usbnet *dev)
+{
+ int ret;
+ void *buf;
+ struct ax8817x_data *ax17xdataptr = (struct ax8817x_data *)&dev->data;
+ struct ax88178_data *ax178dataptr = (struct ax88178_data *)ax17xdataptr->ax178dataptr;
+
+ buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+ if(!buf)
+ return -ENOMEM;
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0x0000, 0, 0, buf)) < 0) {
+ dbg("enable PHY reg. access capability: %d", ret);
+ return ret; //enable Phy register access capability
+ }
+
+ mediacheck(dev);
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE,
+ ax178dataptr->MediaLink, 0, 0, buf)) < 0) {
+ dbg("write mode medium reg failed: %d", ret);
+ return ret;
+ }
+
+ if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, buf)) < 0) {
+ dbg("disable PHY access failed: %d", ret);
+ return ret;
+ }
+
+ dev->net->set_multicast_list = ax8817x_set_multicast;
+ dev->net->ethtool_ops = &ax8817x_ethtool_ops;
+ return 0;
+}
+
+static int ax88178_link_reset(struct usbnet *dev)
+{
+ int ret;
+
+ if ((ret = set_media(dev)) < 0) return ret;
+ return 0;
+}
+
+static const struct driver_info ax88178_info = {
+ .description = "ASIX AX88178 USB 2.0 Ethernet",
+ .bind = ax88178_bind,
+ .status = ax8817x_status,
+ .link_reset = ax88178_link_reset,
+ .flags = FLAG_ETHER|FLAG_FRAMING_AX,
+ .rx_fixup = ax88772_rx_fixup,
+ .tx_fixup = ax88772_tx_fixup,
+ .data = 0x00130103, //useless here
+};
+
+static const struct driver_info belkin178_info = {
+ .description = "Belkin Gigabit USB 2.0 Network Adapter",
+ .bind = ax88178_bind,
+ .status = ax8817x_status,
+ .link_reset = ax88178_link_reset,
+ .flags = FLAG_ETHER|FLAG_FRAMING_AX,
+ .rx_fixup = ax88772_rx_fixup,
+ .tx_fixup = ax88772_tx_fixup,
+ .data = 0x00130103, //useless here
+};
+
static const struct driver_info ax8817x_info = {
.description = "ASIX AX8817x USB 2.0 Ethernet",
.bind = ax8817x_bind,
@@ -1251,6 +1996,18 @@ static const struct driver_info ax88772_info = {
.data = 0x00130103,
};
+static const struct driver_info dlink_dub_e100b_info = {
+ .description = "D-Link DUB-E100 USB 2.0 Fast Ethernet Adapter",
+ .bind = ax88772_bind,
+ .status = ax8817x_status,
+ .link_reset = ax88772_link_reset,
+ .reset = ax88772_link_reset,
+ .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+ .rx_fixup = ax88772_rx_fixup,
+ .tx_fixup = ax88772_tx_fixup,
+ .data = 0x00130103,
+};
+
#endif /* CONFIG_USB_AX8817X */
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: Getting the correct asix AX88178 usb gige driver in mainline?
2011-07-06 17:25 ` Getting the correct asix AX88178 usb gige driver in mainline? Marc MERLIN
2011-07-06 20:09 ` Arnd Bergmann
@ 2011-07-06 21:08 ` Marc MERLIN
2011-07-07 12:55 ` Arnd Bergmann
1 sibling, 1 reply; 6+ messages in thread
From: Marc MERLIN @ 2011-07-06 21:08 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: netdev, greg
On Wed, Jul 06, 2011 at 10:09:05PM +0200, Arnd Bergmann wrote:
> > Here are the details. If somehow their driver could be integrated in
> > mainline by putting the relevant bits in the current driver, that would be
> > fantastic :)
> > (obviously it would have been better if they had done that themselves to
> > start with, no idea why they didn't).
> >
>
> Hi Marc,
>
> I've taken a look at the driver you linked to and compared it to the
> version that was closest at the time.
>
> This is similar to the patch they must have had at some point. I would guess
> that the answer is somewhere in there. It's quite different to the much
> cleaner patch 933a27d39e "USB: asix - Add AX88178 support and many other
> changes", which was merged later with a similar intention.
(...)
> The patch I mentioned was merged back in 2006, for 2.6.19. Either that
> patch was never complete and is missing support for your hardware, or
> it broke since then. You should probably try an old kernel to see if it's
> actually a regression.
Thanks for the details Arnd, I'll see if I can boot 2.6.19 on that laptop
and report back.
Marc
--
"A mouse is a device used to point at the xterm you want to type in" - A.S.R.
Microsoft is to operating systems ....
.... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Getting the correct asix AX88178 usb gige driver in mainline?
2011-07-06 21:08 ` Marc MERLIN
@ 2011-07-07 12:55 ` Arnd Bergmann
2011-07-07 17:23 ` Marc MERLIN
0 siblings, 1 reply; 6+ messages in thread
From: Arnd Bergmann @ 2011-07-07 12:55 UTC (permalink / raw)
To: Marc MERLIN; +Cc: netdev, greg
On Wednesday 06 July 2011, Marc MERLIN wrote:
> > The patch I mentioned was merged back in 2006, for 2.6.19. Either that
> > patch was never complete and is missing support for your hardware, or
> > it broke since then. You should probably try an old kernel to see if it's
> > actually a regression.
>
> Thanks for the details Arnd, I'll see if I can boot 2.6.19 on that laptop
> and report back.
I would perhaps try something less ancient first, 2.6.27-longterm would be
a good candidate. If it was working at some point but broken later, chances
are that it wasn't broken until a few years ago, rather than shortly after
it was merged.
Arnd
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Getting the correct asix AX88178 usb gige driver in mainline?
2011-07-07 12:55 ` Arnd Bergmann
@ 2011-07-07 17:23 ` Marc MERLIN
2011-07-07 17:43 ` Arnd Bergmann
0 siblings, 1 reply; 6+ messages in thread
From: Marc MERLIN @ 2011-07-07 17:23 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: netdev, greg
On Thu, Jul 07, 2011 at 02:55:36PM +0200, Arnd Bergmann wrote:
> On Wednesday 06 July 2011, Marc MERLIN wrote:
> > > The patch I mentioned was merged back in 2006, for 2.6.19. Either that
> > > patch was never complete and is missing support for your hardware, or
> > > it broke since then. You should probably try an old kernel to see if it's
> > > actually a regression.
> >
> > Thanks for the details Arnd, I'll see if I can boot 2.6.19 on that laptop
> > and report back.
>
> I would perhaps try something less ancient first, 2.6.27-longterm would be
> a good candidate. If it was working at some point but broken later, chances
> are that it wasn't broken until a few years ago, rather than shortly after
> it was merged.
So, it was problematic to build and boot old kernels for that system, but I
tried my USB adapter in older systems with older kernels.
2.6.20 and 2.6.22.1 both were able to bring the interface up and DHCP.
2.6.24.3 was NOT able to.
Neither was 2.6.34.1.
Mind you, those were not exactly the same kernels with the compile options
on the same machine, but those were the tests I was reasonably able to do
for now.
Linux polgara.svh.merlins.org 2.6.20-16-generic #2 SMP Thu Jun 7 20:19:32 UTC 2007 i686 GNU/Linux
usb 1-5: new high speed USB device using ehci_hcd and address 3
usb 1-5: configuration #1 chosen from 1 choice
eth0: register 'asix' at usb-0000:00:1a.7-5, ASIX AX88178 USB 2.0 Ethernet, 00:0e:c6:88:7c:ae
usbcore: registered new interface driver asix
eth2: link down
ADDRCONF(NETDEV_UP): eth2: link is not ready
ADDRCONF(NETDEV_CHANGE): eth2: link becomes ready
eth2: link up, 1000Mbps, full-duplex, lpa 0xC5E1
eth2: no IPv6 routers present
eth1: no IPv6 routers present
-> OK
2.6.22.1-libata-tj-20070803-p4smp-preempt-1khz-marc4
eth0: register 'asix' at usb-0000:00:1a.7-5, ASIX AX88178 USB 2.0 Ethernet, 00:0e:c6:88:7c:ae
usbcore: registered new interface driver asix
eth2: link down
ADDRCONF(NETDEV_UP): eth2: link is not ready
ADDRCONF(NETDEV_CHANGE): eth2: link becomes ready
eth2: link up, 1000Mbps, full-duplex, lpa 0xC5E1
eth2: no IPv6 routers present
eth1: no IPv6 routers present
-> OK
2.6.24.3-slub-k8up-preempt-noticks-marc1 (different machine)
usb 1-4: new high speed USB device using ehci_hcd and address 4
usb 1-4: configuration #1 chosen from 1 choice
eth1: register 'asix' at usb-0000:00:02.2-4, ASIX AX88178 USB 2.0 Ethernet, 00:0e:c6:88:7c:ae
usbcore: registered new interface driver asix
udev: renamed network interface eth1 to eth3
eth3: link up, 1000Mbps, full-duplex, lpa 0xCDE1
eth3: link up, 1000Mbps, full-duplex, lpa 0xCDE1
eth3: no IPv6 routers present
-> NOT OK
Linux polgara.svh.merlins.org 2.6.34.1-core2smp-1khznohz-preempt-notcks-noide-hm64-20100724 #2 SMP Sat Jul 24 16:02:09 PDT 2010 i686 GNU/Linux
usb 1-5: new high speed USB device using ehci_hcd and address 4
usb 1-5: New USB device found, idVendor=0b95, idProduct=1780
usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-5: Product: AX88178
usb 1-5: Manufacturer: ASIX Elec. Corp.
usb 1-5: SerialNumber: 000002
asix 1-5:1.0: eth1: register 'asix' at usb-0000:00:1a.7-5, ASIX AX88178 USB
2.0 Ethernet, 00:0e:c6:88:7c:ae
usbcore: registered new interface driver asix
eth1: link down
ADDRCONF(NETDEV_UP): eth1: link is not ready
ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
eth1: link up, 1000Mbps, full-duplex, lpa 0xC5E1
eth1: no IPv6 routers present
-> NOT OK
Marc
--
"A mouse is a device used to point at the xterm you want to type in" - A.S.R.
Microsoft is to operating systems ....
.... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Getting the correct asix AX88178 usb gige driver in mainline?
2011-07-07 17:23 ` Marc MERLIN
@ 2011-07-07 17:43 ` Arnd Bergmann
0 siblings, 0 replies; 6+ messages in thread
From: Arnd Bergmann @ 2011-07-07 17:43 UTC (permalink / raw)
To: Marc MERLIN; +Cc: netdev, greg
On Thursday 07 July 2011 19:23:50 Marc MERLIN wrote:
> On Thu, Jul 07, 2011 at 02:55:36PM +0200, Arnd Bergmann wrote:
> > On Wednesday 06 July 2011, Marc MERLIN wrote:
> > > > The patch I mentioned was merged back in 2006, for 2.6.19. Either that
> > > > patch was never complete and is missing support for your hardware, or
> > > > it broke since then. You should probably try an old kernel to see if it's
> > > > actually a regression.
> > >
> > > Thanks for the details Arnd, I'll see if I can boot 2.6.19 on that laptop
> > > and report back.
> >
> > I would perhaps try something less ancient first, 2.6.27-longterm would be
> > a good candidate. If it was working at some point but broken later, chances
> > are that it wasn't broken until a few years ago, rather than shortly after
> > it was merged.
>
> So, it was problematic to build and boot old kernels for that system, but I
> tried my USB adapter in older systems with older kernels.
>
> 2.6.20 and 2.6.22.1 both were able to bring the interface up and DHCP.
> 2.6.24.3 was NOT able to.
> Neither was 2.6.34.1.
Not a lot has changed int hat driver between 2.6.22 and 2.6.24, so you could
try
git diff v2.6.22..v2.6.24 drivers/net/usb/asix.c | patch -Rp1
on the latest version and see if that helps. There are some rejects, but
those all look harmless.
Arnd
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-07-07 17:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <E1Qes7I-0004Rx-88@myth-lvr.svh.merlins.org>
[not found] ` <20110629033025.GA32153@merlins.org>
[not found] ` <20110629042345.GB18344@kroah.com>
[not found] ` <20110703031309.GL3224@merlins.org>
[not found] ` <20110705153519.GA6198@kroah.com>
2011-07-06 17:25 ` Getting the correct asix AX88178 usb gige driver in mainline? Marc MERLIN
2011-07-06 20:09 ` Arnd Bergmann
[not found] ` <20110706201751.GG22090@merlins.org>
2011-07-06 21:08 ` Marc MERLIN
2011-07-07 12:55 ` Arnd Bergmann
2011-07-07 17:23 ` Marc MERLIN
2011-07-07 17:43 ` Arnd Bergmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).