tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: axen
On Tue, Aug 8, 2023 at 3:55 PM Robert Swindells <rjs%fdy2.co.uk@localhost> wrote:
> Nick Hudson <nick.hudson%gmx.co.uk@localhost> wrote:
> >On 04/08/2023 18:52, Robert Swindells wrote:
> >>
> >> Has anyone used axen(4) recently?
> >>
> >> I needed to make some changes to get it to work for a USB-C Ethernet
> >> adapter but would like to know if the driver in the tree works for any
> >> older devices.
I've noticed axen driver doesn't work correctly, it drops many ping
replies, extremely slow on NFS, and invalid hdr messages, etc.
I made some patches, too. [1]
Comparing with FreeBSD AX88179 driver axge, I assume axen needed to
to change RX_BULKIN_QCTRL params depending on usb bus speed and
ethernet link speed, as TX part works.
This works on super-speed, but not on high-speed.
I don't understand how QCTRL params effect, but manage to work it
by mofifying QCTRL parameters and RX buffer size. [2]
I'm not sure why axen gets upset when buf size exceeds cetain value.
MIIF_DOPAUSE flag works well. It improves transfer rate incredibly.
(Why most of usb ethernet drivers don't set this flag?)
However, flow control is not enabled when ifconfig it up. I have to do
ifconfig axen media utp
ifconfig axen media auto
to enable flowcontrol,rxpause,txpause.
BTW AXEN_BUFSZ_LS should be AXEN_BUFSZ_FS, as AX88179 doesn't
look supporting low-speed.
Its wSpeedsSupported reports only FS, HS, SS speed.
> >
> > thunderx# dmesg | egrep "(NetBSD 10|axen)"
> > [ 1.000000] NetBSD 10.99.4 (GENERIC64) #138: Thu Apr 27 18:33:42 BST
> > 2023
> > [ 4.320147] axen0 at uhub6 port 3
> > [ 4.320147] axen0: ASIX Elec. Corp. (0x0b95) AX88179 (0x1790), rev
> > 3.00/1.00, addr 4
> > [ 4.819877] axen0: AX88179
> > [ 4.819877] rgephy0 at axen0 phy 3: RTL8211E 1000BASE-T media interface
> > [ 4.889879] axen0: Ethernet address 00:13:3b:79:92:71
> > thunderx#
>
> What kind of USB port is that connected to?
>
> The driver currently defaults to the smallest buffer size if the device
> is on a speed 5 (USB_SPEED_SUPER_PLUS) port.
>
> The diffs that I'm using are attached, can try moving the check in #if 0
> to after the check for 'pkt_len == 0'.
When AXEN_RXCTL_IPE (RCR_IPE in FreeBSD) is set, the frame that
doesn't have double 0xee is broken. So driver should check them.
> It doesn't work for me at all without the change to the length argument
> to usbnet_enqueue().
original axen_uno_rx_loop looks good to me.
With patch, I got `discarding oversize frame (len=1518)'
message too when `ping -s1472 dest.'
>
>
> Index: if_axen.c
> ===================================================================
> RCS file: /cvsroot/src/sys/dev/usb/if_axen.c,v
> retrieving revision 1.94
> diff -u -r1.94 if_axen.c
> --- if_axen.c 20 Aug 2022 14:08:59 -0000 1.94
> +++ if_axen.c 7 Aug 2023 20:58:37 -0000
> @@ -614,6 +614,7 @@
>
> /* decide on what our bufsize will be */
> switch (dev->ud_speed) {
> + case USB_SPEED_SUPER_PLUS:
> case USB_SPEED_SUPER:
> un->un_rx_bufsz = AXEN_BUFSZ_SS * 1024;
> break;
> @@ -759,6 +760,9 @@
> hdr_offset = (uint16_t)(rx_hdr >> 16);
> pkt_count = (uint16_t)(rx_hdr & 0xffff);
>
> + if (pkt_count == 0)
> + return;
> +
> /* sanity check */
> if (hdr_offset > total_len) {
> aprint_error_dev(un->un_dev,
> @@ -790,15 +794,20 @@
> rnd_add_uint32(usbnet_rndsrc(un), pkt_count);
>
> do {
> +#if 0
> if ((buf[0] != 0xee) || (buf[1] != 0xee)) {
> aprint_error_dev(un->un_dev,
> "invalid buffer(pkt#%d), continue\n", pkt_count);
> if_statadd(ifp, if_ierrors, pkt_count);
> return;
> }
> -
> +#endif
> pkt_hdr = le32toh(*hdr_p);
> pkt_len = (pkt_hdr >> 16) & 0x1fff;
> +
> + if (pkt_len == 0)
> + goto nextpkt;
> +
> DPRINTFN(10,
> ("%s: rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n",
> device_xname(un->un_dev), pkt_count, pkt_hdr, pkt_len));
> @@ -813,7 +822,7 @@
> goto nextpkt;
> }
>
> - usbnet_enqueue(un, buf + ETHER_ALIGN, pkt_len - 6,
> + usbnet_enqueue(un, buf + ETHER_ALIGN, pkt_len - 2,
> axen_csum_flags_rx(ifp, pkt_hdr), 0, 0);
Cheers,
--
[1]
--- sys/dev/usb/if_axen.c 2022-08-20 23:30:49.194557768 +0000
+++ sys/dev/usb/if_axen.c 2023-11-04 21:56:52.018478467 +0000
@@ -67,6 +67,13 @@ static const struct axen_type axen_devs[
#define axen_lookup(v, p) ((const struct axen_type *)usb_lookup(axen_devs, v, p))
+static struct axen_qctrl axen_bulk_size[] = {
+ { 7, 0x4f, 0x00, 0x12, 0xff },
+ { 7, 0x20, 0x03, 0x16, 0xff },
+ { 7, 0xae, 0x07, 0x18, 0xff },
+ { 7, 0xcc, 0x4c, 0x18, 0x08 }
+};
+
static int axen_match(device_t, cfdata_t, void *);
static void axen_attach(device_t, device_t, void *);
@@ -176,6 +183,7 @@ axen_uno_mii_statchg(struct ifnet *ifp)
struct usbnet * const un = ifp->if_softc;
struct mii_data * const mii = usbnet_mii(un);
int err;
+ size_t qctrl;
uint16_t val;
uint16_t wval;
@@ -201,25 +209,57 @@ axen_uno_mii_statchg(struct ifnet *ifp)
if (!usbnet_havelink(un))
return;
+ uint8_t link_status;
+ err = axen_cmd(un, AXEN_CMD_MAC_READ, 1, AXEN_USB_UPLINK, &link_status);
+ if (err)
+ return;
+ DPRINTF(("%s: link status: 0x%x\n", device_xname(un->un_dev),
+ link_status));
+
val = 0;
- if ((mii->mii_media_active & IFM_FDX) != 0)
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
val |= AXEN_MEDIUM_FDX;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
+ val |= AXEN_MEDIUM_TXFLOW_CTRL_EN;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
+ val |= AXEN_MEDIUM_RXFLOW_CTRL_EN;
+ }
+ val |= AXEN_MEDIUM_RECV_EN;
- val |= AXEN_MEDIUM_RXFLOW_CTRL_EN | AXEN_MEDIUM_TXFLOW_CTRL_EN |
- AXEN_MEDIUM_RECV_EN;
switch (IFM_SUBTYPE(mii->mii_media_active)) {
case IFM_1000_T:
val |= AXEN_MEDIUM_GIGA | AXEN_MEDIUM_EN_125MHZ;
+ if (link_status & AXEN_USB_SS)
+ qctrl = 0;
+ else if (link_status & AXEN_USB_HS)
+ qctrl = 1;
+ else
+ qctrl = 3;
break;
case IFM_100_TX:
val |= AXEN_MEDIUM_PS;
+ if (link_status & (AXEN_USB_SS | AXEN_USB_HS))
+ qctrl = 2;
+ else
+ qctrl = 3;
break;
case IFM_10_T:
- /* doesn't need to be handled */
+ case 0x02: /* cable not connected */
+ qctrl = 3;
+ break;
+ default:
+ device_printf(un->un_dev, "unknown uplink bus: 0x%02x\n",
+ link_status);
+ qctrl = 3;
break;
}
- DPRINTF(("%s: val=%#x\n", __func__, val));
+ DPRINTF(("%s: val=%#x qctrl=%zu usb=%#x media_active=%#x\n", __func__,
+ val, qctrl, link_status, mii->mii_media_active));
+ err = axen_cmd(un, AXEN_CMD_MAC_SET_RXSR, 5, AXEN_RX_BULKIN_QCTRL,
+ &axen_bulk_size[qctrl]);
+ if (err)
+ device_printf(un->un_dev, "set bulkin qctrl failed\n");
wval = htole16(val);
err = axen_cmd(un, AXEN_CMD_MAC_WRITE2, 2, AXEN_MEDIUM_STATUS, &wval);
if (err)
@@ -614,14 +654,16 @@ axen_attach(device_t parent, device_t se
/* decide on what our bufsize will be */
switch (dev->ud_speed) {
- case USB_SPEED_SUPER:
- un->un_rx_bufsz = AXEN_BUFSZ_SS * 1024;
+ case USB_SPEED_FULL:
+ un->un_rx_bufsz = AXEN_BUFSZ_LS * 1024;
break;
case USB_SPEED_HIGH:
un->un_rx_bufsz = AXEN_BUFSZ_HS * 1024;
break;
+ case USB_SPEED_SUPER:
+ case USB_SPEED_SUPER_PLUS:
default:
- un->un_rx_bufsz = AXEN_BUFSZ_LS * 1024;
+ un->un_rx_bufsz = AXEN_BUFSZ_SS * 1024;
break;
}
un->un_tx_bufsz = IP_MAXPACKET + ETHER_HDR_LEN + ETHER_CRC_LEN +
@@ -683,6 +725,7 @@ axen_attach(device_t parent, device_t se
IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_TCPv6_Tx |
IFCAP_CSUM_UDPv6_Rx | IFCAP_CSUM_UDPv6_Tx;
+ unm.un_mii_flags = MIIF_DOPAUSE;
usbnet_attach_ifp(un, IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST,
0, &unm);
}
[2]
--- sys/dev/usb/if_axen.c 2023-11-04 21:56:52.018478467 +0000
+++ sys/dev/usb/if_axen.c 2023-11-04 21:58:21.351252690 +0000
@@ -69,9 +69,9 @@ static const struct axen_type axen_devs[
static struct axen_qctrl axen_bulk_size[] = {
{ 7, 0x4f, 0x00, 0x12, 0xff },
- { 7, 0x20, 0x03, 0x16, 0xff },
- { 7, 0xae, 0x07, 0x18, 0xff },
- { 7, 0xcc, 0x4c, 0x18, 0x08 }
+ { 7, 0xae, 0x00, 0x16, 0xff },
+ { 7, 0xae, 0x00, 0x18, 0xff },
+ { 7, 0xcc, 0x0c, 0x18, 0x08 }
};
static int axen_match(device_t, cfdata_t, void *);
@@ -655,19 +655,21 @@ axen_attach(device_t parent, device_t se
/* decide on what our bufsize will be */
switch (dev->ud_speed) {
case USB_SPEED_FULL:
- un->un_rx_bufsz = AXEN_BUFSZ_LS * 1024;
+ un->un_rx_bufsz = /*AXEN_BUFSZ_LS*/ 20 * 1024;
break;
case USB_SPEED_HIGH:
- un->un_rx_bufsz = AXEN_BUFSZ_HS * 1024;
+ un->un_rx_bufsz = /*AXEN_BUFSZ_HS*/ 20 * 1024;
break;
case USB_SPEED_SUPER:
case USB_SPEED_SUPER_PLUS:
default:
- un->un_rx_bufsz = AXEN_BUFSZ_SS * 1024;
+ un->un_rx_bufsz = /*AXEN_BUFSZ_SS*/ 64 * 1024;
break;
}
un->un_tx_bufsz = IP_MAXPACKET + ETHER_HDR_LEN + ETHER_CRC_LEN +
ETHER_VLAN_ENCAP_LEN + sizeof(struct axen_sframe_hdr);
+ aprint_normal_dev(un->un_dev, "speed %u rx_bufsz %#x tx_bufsz %#x\n",
+ dev->ud_speed, un->un_rx_bufsz, un->un_tx_bufsz);
/* Find endpoints. */
id = usbd_get_interface_descriptor(un->un_iface);
Home |
Main Index |
Thread Index |
Old Index