mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-02 19:22:47 +00:00
cxgb(4): IPv6 rx/tx hw checksum, IPv6 TSO and LRO too.
(Some parts already worked, this makes it complete).
This commit is contained in:
parent
932b1a5f1d
commit
0a7049095f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=237832
@ -265,15 +265,6 @@ struct sge_txq {
|
||||
struct sg_ent txq_sgl[TX_MAX_SEGS / 2 + 1];
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
SGE_PSTAT_TSO, /* # of TSO requests */
|
||||
SGE_PSTAT_RX_CSUM_GOOD, /* # of successful RX csum offloads */
|
||||
SGE_PSTAT_TX_CSUM, /* # of TX checksum offloads */
|
||||
SGE_PSTAT_VLANEX, /* # of VLAN tag extractions */
|
||||
SGE_PSTAT_VLANINS, /* # of VLAN tag insertions */
|
||||
};
|
||||
|
||||
#define SGE_PSTAT_MAX (SGE_PSTAT_VLANINS+1)
|
||||
|
||||
#define QS_EXITING 0x1
|
||||
@ -288,7 +279,6 @@ struct sge_qset {
|
||||
struct lro_state lro;
|
||||
struct sge_txq txq[SGE_TXQ_PER_SET];
|
||||
uint32_t txq_stopped; /* which Tx queues are stopped */
|
||||
uint64_t port_stats[SGE_PSTAT_MAX];
|
||||
struct port_info *port;
|
||||
struct adapter *adap;
|
||||
int idx; /* qset # */
|
||||
@ -538,7 +528,7 @@ int t3_sge_reset_adapter(adapter_t *);
|
||||
int t3_sge_init_port(struct port_info *);
|
||||
void t3_free_tx_desc(struct sge_qset *qs, int n, int qid);
|
||||
|
||||
void t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad);
|
||||
void t3_rx_eth(struct adapter *adap, struct mbuf *m, int ethpad);
|
||||
|
||||
void t3_add_attach_sysctls(adapter_t *sc);
|
||||
void t3_add_configured_sysctls(adapter_t *sc);
|
||||
|
@ -986,7 +986,7 @@ cxgb_makedev(struct port_info *pi)
|
||||
|
||||
#define CXGB_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \
|
||||
IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \
|
||||
IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE)
|
||||
IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWCSUM_IPV6)
|
||||
#define CXGB_CAP_ENABLE CXGB_CAP
|
||||
|
||||
static int
|
||||
@ -1027,7 +1027,8 @@ cxgb_port_attach(device_t dev)
|
||||
ifp->if_capabilities |= IFCAP_TOE4;
|
||||
#endif
|
||||
ifp->if_capenable = CXGB_CAP_ENABLE;
|
||||
ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO;
|
||||
ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO |
|
||||
CSUM_UDP_IPV6 | CSUM_TCP_IPV6;
|
||||
|
||||
/*
|
||||
* Disable TSO on 4-port - it isn't supported by the firmware.
|
||||
@ -1950,31 +1951,52 @@ fail:
|
||||
ifp->if_capenable ^= IFCAP_TXCSUM;
|
||||
ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
|
||||
|
||||
if (IFCAP_TSO & ifp->if_capenable &&
|
||||
if (IFCAP_TSO4 & ifp->if_capenable &&
|
||||
!(IFCAP_TXCSUM & ifp->if_capenable)) {
|
||||
ifp->if_capenable &= ~IFCAP_TSO;
|
||||
ifp->if_hwassist &= ~CSUM_TSO;
|
||||
ifp->if_capenable &= ~IFCAP_TSO4;
|
||||
if_printf(ifp,
|
||||
"tso disabled due to -txcsum.\n");
|
||||
"tso4 disabled due to -txcsum.\n");
|
||||
}
|
||||
}
|
||||
if (mask & IFCAP_TXCSUM_IPV6) {
|
||||
ifp->if_capenable ^= IFCAP_TXCSUM_IPV6;
|
||||
ifp->if_hwassist ^= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6);
|
||||
|
||||
if (IFCAP_TSO6 & ifp->if_capenable &&
|
||||
!(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) {
|
||||
ifp->if_capenable &= ~IFCAP_TSO6;
|
||||
if_printf(ifp,
|
||||
"tso6 disabled due to -txcsum6.\n");
|
||||
}
|
||||
}
|
||||
if (mask & IFCAP_RXCSUM)
|
||||
ifp->if_capenable ^= IFCAP_RXCSUM;
|
||||
if (mask & IFCAP_TSO) {
|
||||
ifp->if_capenable ^= IFCAP_TSO;
|
||||
if (mask & IFCAP_RXCSUM_IPV6)
|
||||
ifp->if_capenable ^= IFCAP_RXCSUM_IPV6;
|
||||
|
||||
if (IFCAP_TSO & ifp->if_capenable) {
|
||||
if (IFCAP_TXCSUM & ifp->if_capenable)
|
||||
ifp->if_hwassist |= CSUM_TSO;
|
||||
else {
|
||||
ifp->if_capenable &= ~IFCAP_TSO;
|
||||
ifp->if_hwassist &= ~CSUM_TSO;
|
||||
if_printf(ifp,
|
||||
"enable txcsum first.\n");
|
||||
error = EAGAIN;
|
||||
}
|
||||
} else
|
||||
ifp->if_hwassist &= ~CSUM_TSO;
|
||||
/*
|
||||
* Note that we leave CSUM_TSO alone (it is always set). The
|
||||
* kernel takes both IFCAP_TSOx and CSUM_TSO into account before
|
||||
* sending a TSO request our way, so it's sufficient to toggle
|
||||
* IFCAP_TSOx only.
|
||||
*/
|
||||
if (mask & IFCAP_TSO4) {
|
||||
if (!(IFCAP_TSO4 & ifp->if_capenable) &&
|
||||
!(IFCAP_TXCSUM & ifp->if_capenable)) {
|
||||
if_printf(ifp, "enable txcsum first.\n");
|
||||
error = EAGAIN;
|
||||
goto fail;
|
||||
}
|
||||
ifp->if_capenable ^= IFCAP_TSO4;
|
||||
}
|
||||
if (mask & IFCAP_TSO6) {
|
||||
if (!(IFCAP_TSO6 & ifp->if_capenable) &&
|
||||
!(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) {
|
||||
if_printf(ifp, "enable txcsum6 first.\n");
|
||||
error = EAGAIN;
|
||||
goto fail;
|
||||
}
|
||||
ifp->if_capenable ^= IFCAP_TSO6;
|
||||
}
|
||||
if (mask & IFCAP_LRO) {
|
||||
ifp->if_capenable ^= IFCAP_LRO;
|
||||
|
@ -1432,7 +1432,8 @@ t3_encap(struct sge_qset *qs, struct mbuf **m)
|
||||
cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT);
|
||||
if (__predict_false(!(cflags & CSUM_IP)))
|
||||
cntrl |= F_TXPKT_IPCSUM_DIS;
|
||||
if (__predict_false(!(cflags & (CSUM_TCP | CSUM_UDP))))
|
||||
if (__predict_false(!(cflags & (CSUM_TCP | CSUM_UDP |
|
||||
CSUM_UDP_IPV6 | CSUM_TCP_IPV6))))
|
||||
cntrl |= F_TXPKT_L4CSUM_DIS;
|
||||
|
||||
hflit[0] = htonl(cntrl);
|
||||
@ -1547,7 +1548,8 @@ t3_encap(struct sge_qset *qs, struct mbuf **m)
|
||||
cntrl |= V_TXPKT_OPCODE(CPL_TX_PKT);
|
||||
if (__predict_false(!(m0->m_pkthdr.csum_flags & CSUM_IP)))
|
||||
cntrl |= F_TXPKT_IPCSUM_DIS;
|
||||
if (__predict_false(!(m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))))
|
||||
if (__predict_false(!(m0->m_pkthdr.csum_flags & (CSUM_TCP |
|
||||
CSUM_UDP | CSUM_UDP_IPV6 | CSUM_TCP_IPV6))))
|
||||
cntrl |= F_TXPKT_L4CSUM_DIS;
|
||||
cpl->cntrl = htonl(cntrl);
|
||||
cpl->len = htonl(mlen | 0x80000000);
|
||||
@ -2620,20 +2622,12 @@ err:
|
||||
* will also be taken into account here.
|
||||
*/
|
||||
void
|
||||
t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad)
|
||||
t3_rx_eth(struct adapter *adap, struct mbuf *m, int ethpad)
|
||||
{
|
||||
struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + ethpad);
|
||||
struct port_info *pi = &adap->port[adap->rxpkt_map[cpl->iff]];
|
||||
struct ifnet *ifp = pi->ifp;
|
||||
|
||||
if ((ifp->if_capenable & IFCAP_RXCSUM) && !cpl->fragment &&
|
||||
cpl->csum_valid && cpl->csum == 0xffff) {
|
||||
m->m_pkthdr.csum_flags = (CSUM_IP_CHECKED|CSUM_IP_VALID);
|
||||
rspq_to_qset(rq)->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
|
||||
m->m_pkthdr.csum_flags = (CSUM_IP_CHECKED|CSUM_IP_VALID|CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
|
||||
m->m_pkthdr.csum_data = 0xffff;
|
||||
}
|
||||
|
||||
if (cpl->vlan_valid) {
|
||||
m->m_pkthdr.ether_vtag = ntohs(cpl->vlan);
|
||||
m->m_flags |= M_VLANTAG;
|
||||
@ -2647,6 +2641,30 @@ t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad)
|
||||
m->m_pkthdr.len -= (sizeof(*cpl) + ethpad);
|
||||
m->m_len -= (sizeof(*cpl) + ethpad);
|
||||
m->m_data += (sizeof(*cpl) + ethpad);
|
||||
|
||||
if (!cpl->fragment && cpl->csum_valid && cpl->csum == 0xffff) {
|
||||
struct ether_header *eh = mtod(m, void *);
|
||||
uint16_t eh_type;
|
||||
|
||||
if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
|
||||
struct ether_vlan_header *evh = mtod(m, void *);
|
||||
|
||||
eh_type = evh->evl_proto;
|
||||
} else
|
||||
eh_type = eh->ether_type;
|
||||
|
||||
if (ifp->if_capenable & IFCAP_RXCSUM &&
|
||||
eh_type == htons(ETHERTYPE_IP)) {
|
||||
m->m_pkthdr.csum_flags = (CSUM_IP_CHECKED |
|
||||
CSUM_IP_VALID | CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
|
||||
m->m_pkthdr.csum_data = 0xffff;
|
||||
} else if (ifp->if_capenable & IFCAP_RXCSUM_IPV6 &&
|
||||
eh_type == htons(ETHERTYPE_IPV6)) {
|
||||
m->m_pkthdr.csum_flags = (CSUM_DATA_VALID_IPV6 |
|
||||
CSUM_PSEUDO_HDR);
|
||||
m->m_pkthdr.csum_data = 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2913,7 +2931,7 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
|
||||
} else if (eth && eop) {
|
||||
struct mbuf *m = mh->mh_head;
|
||||
|
||||
t3_rx_eth(adap, rspq, m, ethpad);
|
||||
t3_rx_eth(adap, m, ethpad);
|
||||
|
||||
/*
|
||||
* The T304 sends incoming packets on any qset. If LRO
|
||||
|
Loading…
Reference in New Issue
Block a user