linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* gianfar.c: Unwanted VLAN tagging on TX frames
@ 2009-08-24 16:10 Torsten Fleischer
  2009-08-24 23:32 ` Andy Fleming
  0 siblings, 1 reply; 3+ messages in thread
From: Torsten Fleischer @ 2009-08-24 16:10 UTC (permalink / raw)
  To: linuxppc-dev

Hello everyone,

I have the Freescale's MPC8313erdb eval board and run the latest stable linux
kernel version (linux-2.6.30.5).

After creating a VLAN device (e.g. eth0.2) a VLAN tag is also inserted into 
frames that don't relate to a VLAN device. This is the case for frames that 
are directly sent through a standard ethernet interface (e.g. eth0).

When creating a VLAN device the gianfar driver enables the  hardware supported 
VLAN tagging on TX frames. This is done by setting the VLINS bit of the TCTRL 
register inside the function gianfar_vlan_rx_register().
The problem is that every outgoing frame will be tagged.  For frames from an 
interface like eth0 the VLN bit of the FCB isn't set. Therefore the eTSEC uses 
the content of the Default VLAN control word register (DFVLAN) to tag the 
frame. As long as this register will not be modified after a reset of the 
controller the outgoing frames will be tagged with VID = 0 (priority tagged 
frames). 

The following patch solves this problem.

diff -uprN linux-2.6.30.5_orig//drivers/net/gianfar.c linux-2.6.30.5/drivers/net/gianfar.c
--- linux-2.6.30.5_orig//drivers/net/gianfar.c	2009-08-16 23:19:38.000000000 +0200
+++ linux-2.6.30.5/drivers/net/gianfar.c	2009-08-22 10:38:28.000000000 +0200
@@ -1309,6 +1309,7 @@ static int gfar_start_xmit(struct sk_buf
 	u32 bufaddr;
 	unsigned long flags;
 	unsigned int nr_frags, length;
+	u32 tempval;
 
 	base = priv->tx_bd_base;
 
@@ -1385,13 +1386,30 @@ static int gfar_start_xmit(struct sk_buf
 		gfar_tx_checksum(skb, fcb);
 	}
 
-	if (priv->vlgrp && vlan_tx_tag_present(skb)) {
-		if (unlikely(NULL == fcb)) {
-			fcb = gfar_add_fcb(skb);
-			lstatus |= BD_LFLAG(TXBD_TOE);
-		}
+	if (priv->vlgrp) {
+		if (vlan_tx_tag_present(skb)) {
+			if (unlikely(NULL == fcb)) {
+				fcb = gfar_add_fcb(skb);
+				lstatus |= BD_LFLAG(TXBD_TOE);
+			}
+
+			/* Enable VLAN tag insertion for frames from VLAN devices */
+			tempval = gfar_read(&priv->regs->tctrl);
+			if ( !(tempval & TCTRL_VLINS) ) {
+				tempval |= TCTRL_VLINS;
+				gfar_write(&priv->regs->tctrl, tempval);
+			}
 
-		gfar_tx_vlan(skb, fcb);
+			gfar_tx_vlan(skb, fcb);
+		}
+		else {
+			/* Disable VLAN tag insertion for frames that are not from a VLAN device */
+			tempval = gfar_read(&priv->regs->tctrl);
+			if ( tempval & TCTRL_VLINS ) {
+				tempval &= ~TCTRL_VLINS;
+				gfar_write(&priv->regs->tctrl, tempval);
+			}
+		}
 	}
 
 	/* setup the TxBD length and buffer pointer for the first BD */
@@ -1484,23 +1502,11 @@ static void gfar_vlan_rx_register(struct
 	priv->vlgrp = grp;
 
 	if (grp) {
-		/* Enable VLAN tag insertion */
-		tempval = gfar_read(&priv->regs->tctrl);
-		tempval |= TCTRL_VLINS;
-
-		gfar_write(&priv->regs->tctrl, tempval);
-
 		/* Enable VLAN tag extraction */
 		tempval = gfar_read(&priv->regs->rctrl);
-		tempval |= RCTRL_VLEX;
 		tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
 		gfar_write(&priv->regs->rctrl, tempval);
 	} else {
-		/* Disable VLAN tag insertion */
-		tempval = gfar_read(&priv->regs->tctrl);
-		tempval &= ~TCTRL_VLINS;
-		gfar_write(&priv->regs->tctrl, tempval);
-
 		/* Disable VLAN tag extraction */
 		tempval = gfar_read(&priv->regs->rctrl);
 		tempval &= ~RCTRL_VLEX;

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-08-25 17:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-24 16:10 gianfar.c: Unwanted VLAN tagging on TX frames Torsten Fleischer
2009-08-24 23:32 ` Andy Fleming
2009-08-25 17:08   ` Torsten Fleischer

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).