Due to an incorrect macro, it appears that this driver has always been

accidentally truncating off the VLAN tag field in the TX descriptor.  Fix
this by splitting up the vlan_tag and flags fields into separate fields,
and handling them appropriately.

Sponsored by: Ironport
MFC After: 3 days
This commit is contained in:
Scott Long 2006-11-16 06:28:54 +00:00
parent 6e7b2160a4
commit 46222d084a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164329
2 changed files with 18 additions and 14 deletions

View File

@ -4261,7 +4261,7 @@ bce_tx_intr(struct bce_softc *sc)
if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
/* Validate that this is the last tx_bd. */
DBRUNIF((!(txbd->tx_bd_vlan_tag_flags & TX_BD_FLAGS_END)),
DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
BCE_PRINTF(sc, "%s(%d): tx_bd END flag not set but "
"txmbuf == NULL!\n", __FILE__, __LINE__);
bce_breakpoint(sc));
@ -4529,9 +4529,9 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
bus_dmamap_t map;
struct tx_bd *txbd = NULL;
struct mbuf *m0;
u32 vlan_tag_flags = 0;
u32 prod_bseq;
u16 vlan_tag = 0, flags = 0;
u16 chain_prod, prod;
u32 prod_bseq;
#ifdef BCE_DEBUG
u16 debug_prod;
@ -4542,15 +4542,16 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
m0 = *m_head;
if (m0->m_pkthdr.csum_flags) {
if (m0->m_pkthdr.csum_flags & CSUM_IP)
vlan_tag_flags |= TX_BD_FLAGS_IP_CKSUM;
flags |= TX_BD_FLAGS_IP_CKSUM;
if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
}
/* Transfer any VLAN tags to the bd. */
if (m0->m_flags & M_VLANTAG)
vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG |
(m0->m_pkthdr.ether_vtag << 16));
if (m0->m_flags & M_VLANTAG) {
flags |= TX_BD_FLAGS_VLAN_TAG;
vlan_tag = m0->m_pkthdr.ether_vtag;
}
/* Map the mbuf into DMAable memory. */
prod = sc->tx_prod;
@ -4634,15 +4635,16 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr));
txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr));
txbd->tx_bd_mss_nbytes = htole16(segs[i].ds_len);
txbd->tx_bd_vlan_tag_flags = htole16(vlan_tag_flags);
txbd->tx_bd_vlan_tag = htole16(vlan_tag);
txbd->tx_bd_flags = htole16(flags);
prod_bseq += segs[i].ds_len;
if (i == 0)
txbd->tx_bd_vlan_tag_flags |=htole16(TX_BD_FLAGS_START);
txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
prod = NEXT_TX_BD(prod);
}
/* Set the END flag on the last TX buffer descriptor. */
txbd->tx_bd_vlan_tag_flags |= htole16(TX_BD_FLAGS_END);
txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
DBRUN(BCE_INFO_SEND, bce_dump_tx_chain(sc, debug_prod, nseg));
@ -6161,9 +6163,10 @@ bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
else
/* Normal tx_bd entry. */
BCE_PRINTF(sc, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
"flags = 0x%08X\n", idx,
"vlan tag= 0x%4X, "flags = 0x%04X\n", idx,
txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag_flags);
txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
txbd->tx_bd_flags);
}

View File

@ -737,7 +737,8 @@ struct tx_bd {
u32 tx_bd_haddr_hi;
u32 tx_bd_haddr_lo;
u32 tx_bd_mss_nbytes;
u32 tx_bd_vlan_tag_flags;
u16 tx_bd_flags;
u16 tx_bd_vlan_tag;
#define TX_BD_FLAGS_CONN_FAULT (1<<0)
#define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1)
#define TX_BD_FLAGS_IP_CKSUM (1<<2)