summaryrefslogtreecommitdiffstats
path: root/sys/dev/bce
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2006-11-16 06:28:54 +0000
committerscottl <scottl@FreeBSD.org>2006-11-16 06:28:54 +0000
commit458d936e9456dcc295c5890cad69165d4e6d171f (patch)
tree9d031bb0e35778cfba6cfacb38b1ae33bcc63d52 /sys/dev/bce
parent8b8b39ee6f0b7c6eb45607e9dcc17c0197580fdf (diff)
downloadFreeBSD-src-458d936e9456dcc295c5890cad69165d4e6d171f.zip
FreeBSD-src-458d936e9456dcc295c5890cad69165d4e6d171f.tar.gz
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
Diffstat (limited to 'sys/dev/bce')
-rw-r--r--sys/dev/bce/if_bce.c29
-rw-r--r--sys/dev/bce/if_bcereg.h3
2 files changed, 18 insertions, 14 deletions
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 7f09135..cd82fa1 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -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);
}
diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h
index e6eae0e..ec37324 100644
--- a/sys/dev/bce/if_bcereg.h
+++ b/sys/dev/bce/if_bcereg.h
@@ -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)
OpenPOWER on IntegriCloud