Fix the hardware VLAN tagging. TX was broken on little-endian

machines and both TX and RX were broken on big-endian machines.

The chip design is crazy -- on RX, it puts the 16-bit VLAN tag
in network byte order (big-endian) in the 32-bit little-endian
register!

Thanks to John Baldwin for helping me document this change! ;-)

Tested by:	sat (amd64), test program (sparc64)
PR:		kern/105054
MFC after:	3 days
This commit is contained in:
Ruslan Ermilov 2006-11-30 21:01:59 +00:00
parent e3ae39ac24
commit 03eab9f7a6

View File

@ -1453,8 +1453,13 @@ vge_rxeof(sc)
}
if (rxstat & VGE_RDSTS_VTAG) {
/*
* The 32-bit rxctl register is stored in little-endian.
* However, the 16-bit vlan tag is stored in big-endian,
* so we have to byte swap it.
*/
m->m_pkthdr.ether_vtag =
ntohs((rxctl & VGE_RDCTL_VLANID));
bswap16(rxctl & VGE_RDCTL_VLANID);
m->m_flags |= M_VLANTAG;
}
@ -1767,7 +1772,7 @@ vge_encap(sc, m_head, idx)
if (m_head->m_flags & M_VLANTAG)
sc->vge_ldata.vge_tx_list[idx].vge_ctl |=
htole32(htons(m_head->m_pkthdr.ether_vtag) | VGE_TDCTL_VTAG);
htole32(m_head->m_pkthdr.ether_vtag | VGE_TDCTL_VTAG);
sc->vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);