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:
parent
e3ae39ac24
commit
03eab9f7a6
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user