Subject: Re: kern/32900: Full-size packets get truncated by 4 bytes when using vlan(4).
To: None <pavel@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,>
From: Pavel Cahyna <pavel.cahyna@st.mff.cuni.cz>
List: netbsd-bugs
Date: 04/08/2006 20:50:02
The following reply was made to PR kern/32900; it has been noted by GNATS.

From: Pavel Cahyna <pavel.cahyna@st.mff.cuni.cz>
To: gnats-bugs@netbsd.org
Cc: ndehne@gmail.com
Subject: Re: kern/32900: Full-size packets get truncated by 4 bytes when using vlan(4).
Date: Sat, 8 Apr 2006 22:49:07 +0200

 Please try the following patch.
 
 Index: if_sip.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/pci/if_sip.c,v
 retrieving revision 1.105
 diff -u -r1.105 if_sip.c
 --- if_sip.c	27 Mar 2006 18:45:03 -0000	1.105
 +++ if_sip.c	8 Apr 2006 20:47:53 -0000
 @@ -309,6 +309,16 @@
  	struct sip_txsq sc_txfreeq;	/* free Tx descsofts */
  	struct sip_txsq sc_txdirtyq;	/* dirty Tx descsofts */
  
 +	/* values of interface state at last init */
 +	struct {
 +		/* if_capenable */
 +		uint64_t	ic;
 +		/* ec_capenable */
 +		int		ec;
 +		/* VLAN_ATTACHED */
 +		int		is_vlan;
 +	}	sc_prev;
 +		
  	short	sc_if_flags;
  
  	int	sc_rxptr;		/* next ready Rx descriptor/descsoft */
 @@ -1017,6 +1027,9 @@
  	 */
  	if_attach(ifp);
  	ether_ifattach(ifp, enaddr);
 +	sc->sc_prev.ec = sc->sc_ethercom.ec_capenable;
 +	sc->sc_prev.is_vlan = VLAN_ATTACHED(&(sc)->sc_ethercom);
 +	sc->sc_prev.ic = ifp->if_capenable;
  #if NRND > 0
  	rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
  	    RND_TYPE_NET, 0);
 @@ -1561,11 +1574,19 @@
  		 * filter when setting promiscuous or debug mode.  Otherwise
  		 * fall through to ether_ioctl, which will reset the chip.
  		 */
 +
 +#define COMPARE_EC(sc) (((sc)->sc_prev.ec == (sc)->sc_ethercom.ec_capenable) \
 +			&& ((sc)->sc_prev.is_vlan ==			     \
 +			    VLAN_ATTACHED(&(sc)->sc_ethercom) ))
 +
 +#define COMPARE_IC(sc, ifp) ((sc)->sc_prev.ic == (ifp)->if_capenable)
 +
  #define RESETIGN (IFF_CANTCHANGE|IFF_DEBUG)
  		if (((ifp->if_flags & (IFF_UP|IFF_RUNNING))
  		    == (IFF_UP|IFF_RUNNING))
  		    && ((ifp->if_flags & (~RESETIGN))
 -		    == (sc->sc_if_flags & (~RESETIGN)))) {
 +		    == (sc->sc_if_flags & (~RESETIGN)))
 +		    && COMPARE_EC(sc) && COMPARE_IC(sc, ifp)) {
  			/* Set up the receive filter. */
  			(*sc->sc_model->sip_variant->sipv_set_filter)(sc);
  			error = 0;
 @@ -2560,6 +2581,9 @@
  	ifp->if_flags |= IFF_RUNNING;
  	ifp->if_flags &= ~IFF_OACTIVE;
  	sc->sc_if_flags = ifp->if_flags;
 +	sc->sc_prev.ec = sc->sc_ethercom.ec_capenable;
 +	sc->sc_prev.is_vlan = VLAN_ATTACHED(&(sc)->sc_ethercom);
 +	sc->sc_prev.ic = ifp->if_capenable;
  
   out:
  	if (error)