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:
parent
6e7b2160a4
commit
46222d084a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164329
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user