Set the TX hardware checksum offload bits on all the descriptors of a
multi-fragment transmission. I'm not sure if this is a bug or a requirement that I overlooked with going through the documentation, but the sample 8169 NIC that I have seems to require it at least some of the time or else it botches TCP checksums on segments that span multiple descriptors.
This commit is contained in:
parent
4dbc6e51df
commit
f3300b2f0b
@ -1140,7 +1140,7 @@ rl_dma_map_desc(arg, segs, nseg, mapsize, error)
|
|||||||
cmdstat |= RL_TDESC_CMD_OWN;
|
cmdstat |= RL_TDESC_CMD_OWN;
|
||||||
if (idx == (RL_RX_DESC_CNT - 1))
|
if (idx == (RL_RX_DESC_CNT - 1))
|
||||||
cmdstat |= RL_TDESC_CMD_EOR;
|
cmdstat |= RL_TDESC_CMD_EOR;
|
||||||
d->rl_cmdstat = htole32(cmdstat);
|
d->rl_cmdstat = htole32(cmdstat | ctx->rl_flags);
|
||||||
i++;
|
i++;
|
||||||
if (i == nseg)
|
if (i == nseg)
|
||||||
break;
|
break;
|
||||||
@ -1716,6 +1716,7 @@ rl_newbuf (sc, idx, m)
|
|||||||
arg.sc = sc;
|
arg.sc = sc;
|
||||||
arg.rl_idx = idx;
|
arg.rl_idx = idx;
|
||||||
arg.rl_maxsegs = 1;
|
arg.rl_maxsegs = 1;
|
||||||
|
arg.rl_flags = 0;
|
||||||
arg.rl_ring = sc->rl_ldata.rl_rx_list;
|
arg.rl_ring = sc->rl_ldata.rl_rx_list;
|
||||||
|
|
||||||
error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag,
|
error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag,
|
||||||
@ -2373,12 +2374,27 @@ rl_encapcplus(sc, m_head, idx)
|
|||||||
struct rl_dmaload_arg arg;
|
struct rl_dmaload_arg arg;
|
||||||
bus_dmamap_t map;
|
bus_dmamap_t map;
|
||||||
int error;
|
int error;
|
||||||
u_int32_t csumcmd = RL_TDESC_CMD_OWN;
|
|
||||||
struct m_tag *mtag;
|
struct m_tag *mtag;
|
||||||
|
|
||||||
if (sc->rl_ldata.rl_tx_free < 4)
|
if (sc->rl_ldata.rl_tx_free < 4)
|
||||||
return(EFBIG);
|
return(EFBIG);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up checksum offload. Note: checksum offload bits must
|
||||||
|
* appear in all descriptors of a multi-descriptor transmit
|
||||||
|
* attempt. (This is according to testing done with an 8169
|
||||||
|
* chip. I'm not sure if this is a requirement or a bug.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
arg.rl_flags = 0;
|
||||||
|
|
||||||
|
if (m_head->m_pkthdr.csum_flags & CSUM_IP)
|
||||||
|
arg.rl_flags |= RL_TDESC_CMD_IPCSUM;
|
||||||
|
if (m_head->m_pkthdr.csum_flags & CSUM_TCP)
|
||||||
|
arg.rl_flags |= RL_TDESC_CMD_TCPCSUM;
|
||||||
|
if (m_head->m_pkthdr.csum_flags & CSUM_UDP)
|
||||||
|
arg.rl_flags |= RL_TDESC_CMD_UDPCSUM;
|
||||||
|
|
||||||
arg.sc = sc;
|
arg.sc = sc;
|
||||||
arg.rl_idx = *idx;
|
arg.rl_idx = *idx;
|
||||||
arg.rl_maxsegs = sc->rl_ldata.rl_tx_free;
|
arg.rl_maxsegs = sc->rl_ldata.rl_tx_free;
|
||||||
@ -2439,24 +2455,13 @@ rl_encapcplus(sc, m_head, idx)
|
|||||||
sc->rl_ldata.rl_tx_list[*idx].rl_vlanctl =
|
sc->rl_ldata.rl_tx_list[*idx].rl_vlanctl =
|
||||||
htole32(htons(VLAN_TAG_VALUE(mtag)) | RL_TDESC_VLANCTL_TAG);
|
htole32(htons(VLAN_TAG_VALUE(mtag)) | RL_TDESC_VLANCTL_TAG);
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up checksum offload. Note: checksum offload bits must
|
|
||||||
* appear in the first descriptor of a multi-descriptor
|
|
||||||
* transmission attempt.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (m_head->m_pkthdr.csum_flags & CSUM_IP)
|
|
||||||
csumcmd |= RL_TDESC_CMD_IPCSUM;
|
|
||||||
if (m_head->m_pkthdr.csum_flags & CSUM_TCP)
|
|
||||||
csumcmd |= RL_TDESC_CMD_TCPCSUM;
|
|
||||||
if (m_head->m_pkthdr.csum_flags & CSUM_UDP)
|
|
||||||
csumcmd |= RL_TDESC_CMD_UDPCSUM;
|
|
||||||
|
|
||||||
/* Transfer ownership of packet to the chip. */
|
/* Transfer ownership of packet to the chip. */
|
||||||
|
|
||||||
sc->rl_ldata.rl_tx_list[arg.rl_idx].rl_cmdstat |= htole32(csumcmd);
|
sc->rl_ldata.rl_tx_list[arg.rl_idx].rl_cmdstat |=
|
||||||
|
htole32(RL_TDESC_CMD_OWN);
|
||||||
if (*idx != arg.rl_idx)
|
if (*idx != arg.rl_idx)
|
||||||
sc->rl_ldata.rl_tx_list[*idx].rl_cmdstat |= htole32(csumcmd);
|
sc->rl_ldata.rl_tx_list[*idx].rl_cmdstat |=
|
||||||
|
htole32(RL_TDESC_CMD_OWN);
|
||||||
|
|
||||||
RL_DESC_INC(arg.rl_idx);
|
RL_DESC_INC(arg.rl_idx);
|
||||||
*idx = arg.rl_idx;
|
*idx = arg.rl_idx;
|
||||||
|
@ -602,6 +602,7 @@ struct rl_dmaload_arg {
|
|||||||
struct rl_softc *sc;
|
struct rl_softc *sc;
|
||||||
int rl_idx;
|
int rl_idx;
|
||||||
int rl_maxsegs;
|
int rl_maxsegs;
|
||||||
|
u_int32_t rl_flags;
|
||||||
struct rl_desc *rl_ring;
|
struct rl_desc *rl_ring;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user