<br><br><div class="gmail_quote">On Mon, Aug 24, 2009 at 11:10 AM, Torsten Fleischer <span dir="ltr"><<a href="mailto:to-fleischer@t-online.de">to-fleischer@t-online.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hello everyone,<br>
<br>
I have the Freescale's MPC8313erdb eval board and run the latest stable linux<br>
kernel version (linux-2.6.30.5).<br>
<br>
After creating a VLAN device (e.g. eth0.2) a VLAN tag is also inserted into<br>
frames that don't relate to a VLAN device. This is the case for frames that<br>
are directly sent through a standard ethernet interface (e.g. eth0).<br>
<br>
When creating a VLAN device the gianfar driver enables the hardware supported<br>
VLAN tagging on TX frames. This is done by setting the VLINS bit of the TCTRL<br>
register inside the function gianfar_vlan_rx_register().<br>
The problem is that every outgoing frame will be tagged. For frames from an<br>
interface like eth0 the VLN bit of the FCB isn't set. Therefore the eTSEC uses<br>
the content of the Default VLAN control word register (DFVLAN) to tag the<br>
frame. As long as this register will not be modified after a reset of the<br>
controller the outgoing frames will be tagged with VID = 0 (priority tagged<br>
frames).<br>
<br>
The following patch solves this problem.<br>
<br>
diff -uprN linux-2.6.30.5_orig//drivers/net/gianfar.c linux-2.6.30.5/drivers/net/gianfar.c<br>
--- linux-2.6.30.5_orig//drivers/net/gianfar.c 2009-08-16 23:19:38.000000000 +0200<br>
+++ linux-2.6.30.5/drivers/net/gianfar.c 2009-08-22 10:38:28.000000000 +0200<br>
@@ -1309,6 +1309,7 @@ static int gfar_start_xmit(struct sk_buf<br>
u32 bufaddr;<br>
unsigned long flags;<br>
unsigned int nr_frags, length;<br>
+ u32 tempval;<br>
<br>
base = priv->tx_bd_base;<br>
<br>
@@ -1385,13 +1386,30 @@ static int gfar_start_xmit(struct sk_buf<br>
gfar_tx_checksum(skb, fcb);<br>
}<br>
<br>
- if (priv->vlgrp && vlan_tx_tag_present(skb)) {<br>
- if (unlikely(NULL == fcb)) {<br>
- fcb = gfar_add_fcb(skb);<br>
- lstatus |= BD_LFLAG(TXBD_TOE);<br>
- }<br>
+ if (priv->vlgrp) {<br>
+ if (vlan_tx_tag_present(skb)) {<br>
+ if (unlikely(NULL == fcb)) {<br>
+ fcb = gfar_add_fcb(skb);<br>
+ lstatus |= BD_LFLAG(TXBD_TOE);<br>
+ }<br>
+<br>
+ /* Enable VLAN tag insertion for frames from VLAN devices */<br>
+ tempval = gfar_read(&priv->regs->tctrl);<br>
+ if ( !(tempval & TCTRL_VLINS) ) {<br>
+ tempval |= TCTRL_VLINS;<br>
+ gfar_write(&priv->regs->tctrl, tempval);<br>
+ }<br>
<br>
- gfar_tx_vlan(skb, fcb);<br>
+ gfar_tx_vlan(skb, fcb);<br>
+ }<br>
+ else {<br>
+ /* Disable VLAN tag insertion for frames that are not from a VLAN device */<br>
+ tempval = gfar_read(&priv->regs->tctrl);<br>
+ if ( tempval & TCTRL_VLINS ) {<br>
+ tempval &= ~TCTRL_VLINS;<br>
+ gfar_write(&priv->regs->tctrl, tempval);<br>
+ }<br>
+ }<br>
}</blockquote><div><br></div><div><br></div><div>Hmmm....how have you tested this? This looks like it has a bad race condition. The TCTRL register applies to all packets, which means if you send a packet with VLAN tags, followed by one without, or visa versa, there's a reasonable chance that the second packet's VLAN tags (or lack thereof) will take precedence.</div>
<div><br></div><div>Without speaking for the company, I suspect that this is just how the eTSEC works with VLAN -- all, or nothing.</div><div><br></div><div>Andy </div></div><br>