svn commit: r304326 - head/sys/dev/usb/net

Bjoern A. Zeeb bzeeb-lists at lists.zabbadoz.net
Thu Aug 18 16:44:45 UTC 2016


On 18 Aug 2016, at 5:07, Pyun YongHyeon wrote:

> Author: yongari
> Date: Thu Aug 18 05:07:02 2016
> New Revision: 304326
> URL: https://svnweb.freebsd.org/changeset/base/304326
>
> Log:
>   Switch to TX header format rather than directly manipulating header
>   structures.  This simplifies mbuf copy operation to USB buffers as
>   well as improving readability.  The controller supports Microsoft
>   LSOv1(aka TSO) but this change set does not include the support due
>   to copying overhead to USB buffers and large amount of memory waste.
>
>   Remove useless ZLP padding which seems to come from Linux.  Required
>   bits the code tried to set was not copied into USB buffer so it had
>   no effect.  Unlike Linux, FreeBSD USB stack automatically generates
>   ZLP so no explicit padding is required in driver.[1]
>
>   Micro-optimize updating IFCOUNTER_OPACKETS counter by moving it out
>   of TX loop since updating counter is not cheap operation as it did
>   long time ago and we already know how many number of packets were
>   queued after exiting the loop.
>
>   While here, fix a checksum offloading bug which will happen when
>   upper stack computes checksum while H/W checksum offloading is
>   active.  The controller should be notified to not recompute the
>   checksum in this case.
>
>   Reviewed by:	kevlo (initial version), hselasky
>   Pointed out by:	hselasky [1]
>
> Modified:
>   head/sys/dev/usb/net/if_axge.c
>   head/sys/dev/usb/net/if_axgereg.h
>
> Modified: head/sys/dev/usb/net/if_axge.c
> ==============================================================================
> --- head/sys/dev/usb/net/if_axge.c	Thu Aug 18 04:25:17 2016	(r304325)
> +++ head/sys/dev/usb/net/if_axge.c	Thu Aug 18 05:07:02 2016	(r304326)
> @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
>  #include <sys/systm.h>
>  #include <sys/bus.h>
>  #include <sys/condvar.h>
> +#include <sys/endian.h>
>  #include <sys/kernel.h>
>  #include <sys/lock.h>
>  #include <sys/module.h>
> @@ -144,8 +145,8 @@ static const struct usb_config axge_conf
>  		.type = UE_BULK,
>  		.endpoint = UE_ADDR_ANY,
>  		.direction = UE_DIR_OUT,
> -		.frames = 16,
> -		.bufsize = 16 * MCLBYTES,
> +		.frames = AXGE_N_FRAMES,
> +		.bufsize = AXGE_N_FRAMES * MCLBYTES,
>  		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
>  		.callback = axge_bulk_write_callback,
>  		.timeout = 10000,	/* 10 seconds */
> @@ -630,7 +631,7 @@ axge_bulk_write_callback(struct usb_xfer
>  	struct ifnet *ifp;
>  	struct usb_page_cache *pc;
>  	struct mbuf *m;
> -	uint32_t txhdr;
> +	struct axge_frame_txhdr txhdr;
>  	int nframes, pos;
>
>  	sc = usbd_xfer_softc(xfer);
> @@ -651,36 +652,25 @@ tr_setup:
>  			return;
>  		}
>
> -		for (nframes = 0; nframes < 16 &&
> +		for (nframes = 0; nframes < AXGE_N_FRAMES &&
>  		    !IFQ_DRV_IS_EMPTY(&ifp->if_snd); nframes++) {
>  			IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
>  			if (m == NULL)
>  				break;
>  			usbd_xfer_set_frame_offset(xfer, nframes * MCLBYTES,
> -				nframes);
> -			pos = 0;
> +			    nframes);
>  			pc = usbd_xfer_get_frame(xfer, nframes);
> -			txhdr = htole32(m->m_pkthdr.len);
> -			usbd_copy_in(pc, 0, &txhdr, sizeof(txhdr));
> -			txhdr = 0;
> -			txhdr = htole32(txhdr);
> -			usbd_copy_in(pc, 4, &txhdr, sizeof(txhdr));
> -			pos += 8;
> +			txhdr.mss = 0;
> +			txhdr.len = htole32(AXGE_TXBYTES(m->m_pkthdr.len));
> +			if ((ifp->if_capenable & IFCAP_TXCSUM) != 0 &&
> +			    (m->m_pkthdr.csum_flags & AXGE_CSUM_FEATURES) == 0)
> +				txhdr.len |= htole32(AXGE_CSUM_DISABLE);
> +
> +			pos = 0;
> +			usbd_copy_in(pc, pos, &txhdr, sizeof(txhdr));
> +			pos += sizeof(txhdr);
>  			usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len);
>  			pos += m->m_pkthdr.len;
> -			if ((pos % usbd_xfer_max_framelen(xfer)) == 0)
> -				txhdr |= 0x80008000;
> -
> -			/*
> -			 * XXX
> -			 * Update TX packet counter here. This is not
> -			 * correct way but it seems that there is no way
> -			 * to know how many packets are sent at the end
> -			 * of transfer because controller combines
> -			 * multiple writes into single one if there is
> -			 * room in TX buffer of controller.
> -			 */
> -			if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
>
>  			/*
>  			 * if there's a BPF listener, bounce a copy
> @@ -694,6 +684,16 @@ tr_setup:
>  			usbd_xfer_set_frame_len(xfer, nframes, pos);
>  		}
>  		if (nframes != 0) {
> +			/*
> +			 * XXX
> +			 * Update TX packet counter here. This is not
> +			 * correct way but it seems that there is no way
> +			 * to know how many packets are sent at the end
> +			 * of transfer because controller combines
> +			 * multiple writes into single one if there is
> +			 * room in TX buffer of controller.
> +			 */
> +			if_inc_counter(ifp, IFCOUNTER_OPACKETS, nframes);
>  			usbd_xfer_set_frames(xfer, nframes);
>  			usbd_transfer_submit(xfer);
>  			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
>
> Modified: head/sys/dev/usb/net/if_axgereg.h
> ==============================================================================
> --- head/sys/dev/usb/net/if_axgereg.h	Thu Aug 18 04:25:17 
> 2016	(r304325)
> +++ head/sys/dev/usb/net/if_axgereg.h	Thu Aug 18 05:07:02 
> 2016	(r304326)
> @@ -159,6 +159,26 @@ enum {
>  	AXGE_N_TRANSFER,
>  };
>
> +#define	AXGE_N_FRAMES	16
> +
> +struct axge_frame_txhdr {
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +	uint32_t		len;
> +#define	AXGE_TXLEN_MASK		0x0001FFFF
> +#define	AXGE_VLAN_INSERT	0x20000000
> +#define	AXGE_CSUM_DISABLE	0x80000000
> +	uint32_t		mss;
> +#define	AXGE_MSS_MASK		0x00003FFF
> +#define	AXGE_PADDING		0x80008000
> +#define	AXGE_VLAN_TAG_MASK	0xFFFF0000
> +#else
> +	uint32_t		mss;
> +	uint32_t		len;
> +#endif
> +} __packed;
> +
> +#define	AXGE_TXBYTES(x)		((x) & AXGE_TXLEN_MASK)


AXGE_TXLEN_MASK is only defined for LITTLE_ENDIAN and thus breaks builds 
on others.

AXGE_CSUM_DISABLE as well ..


> +
>  #define	AXGE_PHY_ADDR		3
>
>  struct axge_softc {
>


More information about the svn-src-head mailing list