VLAN hardware tag information should be set for all desciptors of a

multi-descriptor transmission attempt. Datasheet said nothing about
this requirements. This should fix a long-standing VLAN hardware
tagging issues with re(4).

Reported by:	Giulio Ferro ( auryn AT zirakzigil DOT org )
Tested by:	Giulio Ferro ( auryn AT zirakzigil DOT org )
This commit is contained in:
Pyun YongHyeon 2008-03-23 05:06:16 +00:00
parent 70acaecfd0
commit ccf34c81f8

View File

@ -2137,7 +2137,7 @@ re_encap(sc, m_head)
int nsegs, prod; int nsegs, prod;
int i, error, ei, si; int i, error, ei, si;
int padlen; int padlen;
uint32_t cmdstat, csum_flags; uint32_t cmdstat, csum_flags, vlanctl;
RL_LOCK_ASSERT(sc); RL_LOCK_ASSERT(sc);
M_ASSERTPKTHDR((*m_head)); M_ASSERTPKTHDR((*m_head));
@ -2247,10 +2247,21 @@ re_encap(sc, m_head)
csum_flags |= RL_TDESC_CMD_UDPCSUM; csum_flags |= RL_TDESC_CMD_UDPCSUM;
} }
/*
* Set up hardware VLAN tagging. Note: vlan tag info must
* appear in all descriptors of a multi-descriptor
* transmission attempt.
*/
vlanctl = 0;
if ((*m_head)->m_flags & M_VLANTAG)
vlanctl =
htole32(htons((*m_head)->m_pkthdr.ether_vtag) |
RL_TDESC_VLANCTL_TAG);
si = prod; si = prod;
for (i = 0; i < nsegs; i++, prod = RL_TX_DESC_NXT(sc, prod)) { for (i = 0; i < nsegs; i++, prod = RL_TX_DESC_NXT(sc, prod)) {
desc = &sc->rl_ldata.rl_tx_list[prod]; desc = &sc->rl_ldata.rl_tx_list[prod];
desc->rl_vlanctl = 0; desc->rl_vlanctl = vlanctl;
desc->rl_bufaddr_lo = htole32(RL_ADDR_LO(segs[i].ds_addr)); desc->rl_bufaddr_lo = htole32(RL_ADDR_LO(segs[i].ds_addr));
desc->rl_bufaddr_hi = htole32(RL_ADDR_HI(segs[i].ds_addr)); desc->rl_bufaddr_hi = htole32(RL_ADDR_HI(segs[i].ds_addr));
cmdstat = segs[i].ds_len; cmdstat = segs[i].ds_len;
@ -2270,15 +2281,6 @@ re_encap(sc, m_head)
desc->rl_cmdstat |= htole32(RL_TDESC_CMD_EOF); desc->rl_cmdstat |= htole32(RL_TDESC_CMD_EOF);
desc = &sc->rl_ldata.rl_tx_list[si]; desc = &sc->rl_ldata.rl_tx_list[si];
/*
* Set up hardware VLAN tagging. Note: vlan tag info must
* appear in the first descriptor of a multi-descriptor
* transmission attempt.
*/
if ((*m_head)->m_flags & M_VLANTAG)
desc->rl_vlanctl =
htole32(htons((*m_head)->m_pkthdr.ether_vtag) |
RL_TDESC_VLANCTL_TAG);
/* Set SOF and transfer ownership of packet to the chip. */ /* Set SOF and transfer ownership of packet to the chip. */
desc->rl_cmdstat |= htole32(RL_TDESC_CMD_OWN | RL_TDESC_CMD_SOF); desc->rl_cmdstat |= htole32(RL_TDESC_CMD_OWN | RL_TDESC_CMD_SOF);