sync with OpenBSD -current
This commit is contained in:
parent
7768d1f254
commit
c9341f2e4a
65 changed files with 2158 additions and 1228 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: dwqe.c,v 1.19 2024/04/25 08:51:37 jmatthew Exp $ */
|
||||
/* $OpenBSD: dwqe.c,v 1.20 2024/05/03 13:02:18 stsp Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org>
|
||||
* Copyright (c) 2017, 2022 Patrick Wildt <patrick@blueri.se>
|
||||
|
@ -643,6 +643,66 @@ dwqe_tx_proc(struct dwqe_softc *sc)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
dwqe_have_rx_csum_offload(struct dwqe_softc *sc)
|
||||
{
|
||||
return (sc->sc_hw_feature[0] & GMAC_MAC_HW_FEATURE0_RXCOESEL);
|
||||
}
|
||||
|
||||
void
|
||||
dwqe_rx_csum(struct dwqe_softc *sc, struct mbuf *m, struct dwqe_desc *rxd)
|
||||
{
|
||||
uint16_t csum_flags = 0;
|
||||
|
||||
/*
|
||||
* Checksum offload must be supported, the Last-Descriptor bit
|
||||
* must be set, RDES1 must be valid, and checksumming must not
|
||||
* have been bypassed (happens for unknown packet types), and
|
||||
* an IP header must have been detected.
|
||||
*/
|
||||
if (!dwqe_have_rx_csum_offload(sc) ||
|
||||
(rxd->sd_tdes3 & RDES3_LD) == 0 ||
|
||||
(rxd->sd_tdes3 & RDES3_RDES1_VALID) == 0 ||
|
||||
(rxd->sd_tdes1 & RDES1_IP_CSUM_BYPASS) ||
|
||||
(rxd->sd_tdes1 & (RDES1_IPV4_HDR | RDES1_IPV6_HDR)) == 0)
|
||||
return;
|
||||
|
||||
/* If the IP header checksum is invalid then the payload is ignored. */
|
||||
if (rxd->sd_tdes1 & RDES1_IP_HDR_ERROR) {
|
||||
if (rxd->sd_tdes1 & RDES1_IPV4_HDR)
|
||||
csum_flags |= M_IPV4_CSUM_IN_BAD;
|
||||
} else {
|
||||
if (rxd->sd_tdes1 & RDES1_IPV4_HDR)
|
||||
csum_flags |= M_IPV4_CSUM_IN_OK;
|
||||
|
||||
/* Detect payload type and corresponding checksum errors. */
|
||||
switch (rxd->sd_tdes1 & RDES1_IP_PAYLOAD_TYPE) {
|
||||
case RDES1_IP_PAYLOAD_UDP:
|
||||
if (rxd->sd_tdes1 & RDES1_IP_PAYLOAD_ERROR)
|
||||
csum_flags |= M_UDP_CSUM_IN_BAD;
|
||||
else
|
||||
csum_flags |= M_UDP_CSUM_IN_OK;
|
||||
break;
|
||||
case RDES1_IP_PAYLOAD_TCP:
|
||||
if (rxd->sd_tdes1 & RDES1_IP_PAYLOAD_ERROR)
|
||||
csum_flags |= M_TCP_CSUM_IN_BAD;
|
||||
else
|
||||
csum_flags |= M_TCP_CSUM_IN_OK;
|
||||
break;
|
||||
case RDES1_IP_PAYLOAD_ICMP:
|
||||
if (rxd->sd_tdes1 & RDES1_IP_PAYLOAD_ERROR)
|
||||
csum_flags |= M_ICMP_CSUM_IN_BAD;
|
||||
else
|
||||
csum_flags |= M_ICMP_CSUM_IN_OK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m->m_pkthdr.csum_flags |= csum_flags;
|
||||
}
|
||||
|
||||
void
|
||||
dwqe_rx_proc(struct dwqe_softc *sc)
|
||||
{
|
||||
|
@ -691,6 +751,7 @@ dwqe_rx_proc(struct dwqe_softc *sc)
|
|||
|
||||
m->m_pkthdr.len = m->m_len = len;
|
||||
|
||||
dwqe_rx_csum(sc, m, rxd);
|
||||
ml_enqueue(&ml, m);
|
||||
}
|
||||
|
||||
|
@ -866,6 +927,12 @@ dwqe_up(struct dwqe_softc *sc)
|
|||
|
||||
if (!sc->sc_fixed_link)
|
||||
timeout_add_sec(&sc->sc_phy_tick, 1);
|
||||
|
||||
if (dwqe_have_rx_csum_offload(sc)) {
|
||||
reg = dwqe_read(sc, GMAC_MAC_CONF);
|
||||
reg |= GMAC_MAC_CONF_IPC;
|
||||
dwqe_write(sc, GMAC_MAC_CONF, reg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: dwqereg.h,v 1.7 2024/04/25 11:37:39 stsp Exp $ */
|
||||
/* $OpenBSD: dwqereg.h,v 1.8 2024/05/03 13:02:18 stsp Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org>
|
||||
* Copyright (c) 2017, 2022 Patrick Wildt <patrick@blueri.se>
|
||||
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
|
||||
#define GMAC_MAC_CONF 0x0000
|
||||
#define GMAC_MAC_CONF_IPC (1 << 27)
|
||||
#define GMAC_MAC_CONF_CST (1 << 21)
|
||||
#define GMAC_MAC_CONF_ACS (1 << 20)
|
||||
#define GMAC_MAC_CONF_BE (1 << 18)
|
||||
|
@ -61,6 +62,8 @@
|
|||
#define GMAC_VERSION 0x0110
|
||||
#define GMAC_VERSION_SNPS_MASK 0xff
|
||||
#define GMAC_MAC_HW_FEATURE(x) (0x011c + (x) * 0x4)
|
||||
#define GMAC_MAC_HW_FEATURE0_TXCOESEL (1 << 14)
|
||||
#define GMAC_MAC_HW_FEATURE0_RXCOESEL (1 << 16)
|
||||
#define GMAC_MAC_HW_FEATURE1_TXFIFOSIZE(x) (((x) >> 6) & 0x1f)
|
||||
#define GMAC_MAC_HW_FEATURE1_RXFIFOSIZE(x) (((x) >> 0) & 0x1f)
|
||||
#define GMAC_MAC_MDIO_ADDR 0x0200
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: qwx.c,v 1.58 2024/03/09 23:29:53 stsp Exp $ */
|
||||
/* $OpenBSD: qwx.c,v 1.59 2024/05/03 14:32:11 stsp Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2023 Stefan Sperling <stsp@openbsd.org>
|
||||
|
@ -206,10 +206,6 @@ qwx_init(struct ifnet *ifp)
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
/* Configure channel information obtained from firmware. */
|
||||
ieee80211_channel_init(ifp);
|
||||
ieee80211_media_init(ifp, qwx_media_change, ieee80211_media_status);
|
||||
|
||||
if (sc->attached) {
|
||||
/* Update MAC in case the upper layers changed it. */
|
||||
IEEE80211_ADDR_COPY(ic->ic_myaddr,
|
||||
|
@ -217,12 +213,18 @@ qwx_init(struct ifnet *ifp)
|
|||
} else {
|
||||
sc->attached = 1;
|
||||
|
||||
/* Configure channel information obtained from firmware. */
|
||||
ieee80211_channel_init(ifp);
|
||||
|
||||
/* Configure initial MAC address. */
|
||||
error = if_setlladdr(ifp, ic->ic_myaddr);
|
||||
if (error)
|
||||
printf("%s: could not set MAC address %s: %d\n",
|
||||
sc->sc_dev.dv_xname, ether_sprintf(ic->ic_myaddr),
|
||||
error);
|
||||
|
||||
ieee80211_media_init(ifp, qwx_media_change,
|
||||
ieee80211_media_status);
|
||||
}
|
||||
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
|
@ -24336,6 +24338,13 @@ qwx_scan(struct qwx_softc *sc)
|
|||
#ifdef notyet
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
#endif
|
||||
} else {
|
||||
/*
|
||||
* The current mode might have been fixed during association.
|
||||
* Ensure all channels get scanned.
|
||||
*/
|
||||
if (IFM_SUBTYPE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO)
|
||||
ieee80211_setmode(ic, IEEE80211_MODE_AUTO);
|
||||
}
|
||||
#if 0
|
||||
timeout_add_msec(&sc->scan.timeout, scan_timeout);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: if_ix.c,v 1.211 2024/03/07 17:09:02 jan Exp $ */
|
||||
/* $OpenBSD: if_ix.c,v 1.212 2024/05/01 10:43:42 jan Exp $ */
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
|
@ -154,7 +154,7 @@ void ixgbe_enable_intr(struct ix_softc *);
|
|||
void ixgbe_disable_intr(struct ix_softc *);
|
||||
int ixgbe_txeof(struct tx_ring *);
|
||||
int ixgbe_rxeof(struct rx_ring *);
|
||||
void ixgbe_rx_checksum(uint32_t, struct mbuf *);
|
||||
void ixgbe_rx_offload(uint32_t, uint16_t, struct mbuf *);
|
||||
void ixgbe_iff(struct ix_softc *);
|
||||
void ixgbe_map_queue_statistics(struct ix_softc *);
|
||||
void ixgbe_update_link_status(struct ix_softc *);
|
||||
|
@ -3245,67 +3245,13 @@ ixgbe_rxeof(struct rx_ring *rxr)
|
|||
sendmp = NULL;
|
||||
mp->m_next = nxbuf->buf;
|
||||
} else { /* Sending this frame? */
|
||||
uint16_t pkts;
|
||||
ixgbe_rx_offload(staterr, vtag, sendmp);
|
||||
|
||||
ixgbe_rx_checksum(staterr, sendmp);
|
||||
#if NVLAN > 0
|
||||
if (staterr & IXGBE_RXD_STAT_VP) {
|
||||
sendmp->m_pkthdr.ether_vtag = vtag;
|
||||
SET(sendmp->m_flags, M_VLANTAG);
|
||||
}
|
||||
#endif
|
||||
if (hashtype != IXGBE_RXDADV_RSSTYPE_NONE) {
|
||||
sendmp->m_pkthdr.ph_flowid = hash;
|
||||
SET(sendmp->m_pkthdr.csum_flags, M_FLOWID);
|
||||
}
|
||||
|
||||
pkts = sendmp->m_pkthdr.ph_mss;
|
||||
sendmp->m_pkthdr.ph_mss = 0;
|
||||
|
||||
if (pkts > 1) {
|
||||
struct ether_extracted ext;
|
||||
uint32_t paylen;
|
||||
|
||||
/*
|
||||
* Calculate the payload size:
|
||||
*
|
||||
* The packet length returned by the NIC
|
||||
* (sendmp->m_pkthdr.len) can contain
|
||||
* padding, which we don't want to count
|
||||
* in to the payload size. Therefore, we
|
||||
* calculate the real payload size based
|
||||
* on the total ip length field (ext.iplen).
|
||||
*/
|
||||
ether_extract_headers(sendmp, &ext);
|
||||
paylen = ext.iplen;
|
||||
if (ext.ip4 || ext.ip6)
|
||||
paylen -= ext.iphlen;
|
||||
if (ext.tcp) {
|
||||
paylen -= ext.tcphlen;
|
||||
tcpstat_inc(tcps_inhwlro);
|
||||
tcpstat_add(tcps_inpktlro, pkts);
|
||||
} else {
|
||||
tcpstat_inc(tcps_inbadlro);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we gonna forward this packet, we have to
|
||||
* mark it as TSO, set a correct mss,
|
||||
* and recalculate the TCP checksum.
|
||||
*/
|
||||
if (ext.tcp && paylen >= pkts) {
|
||||
SET(sendmp->m_pkthdr.csum_flags,
|
||||
M_TCP_TSO);
|
||||
sendmp->m_pkthdr.ph_mss = paylen / pkts;
|
||||
}
|
||||
if (ext.tcp &&
|
||||
ISSET(sendmp->m_pkthdr.csum_flags,
|
||||
M_TCP_CSUM_IN_OK)) {
|
||||
SET(sendmp->m_pkthdr.csum_flags,
|
||||
M_TCP_CSUM_OUT);
|
||||
}
|
||||
}
|
||||
|
||||
ml_enqueue(&ml, sendmp);
|
||||
}
|
||||
next_desc:
|
||||
|
@ -3330,29 +3276,103 @@ next_desc:
|
|||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Check VLAN indication from hardware and inform the stack about the
|
||||
* annotated TAG.
|
||||
*
|
||||
* Verify that the hardware indicated that the checksum is valid.
|
||||
* Inform the stack about the status of checksum so that stack
|
||||
* doesn't spend time verifying the checksum.
|
||||
*
|
||||
* Propagate TCP LRO packet from hardware to the stack with MSS annotation.
|
||||
*
|
||||
*********************************************************************/
|
||||
void
|
||||
ixgbe_rx_checksum(uint32_t staterr, struct mbuf * mp)
|
||||
ixgbe_rx_offload(uint32_t staterr, uint16_t vtag, struct mbuf *m)
|
||||
{
|
||||
uint16_t status = (uint16_t) staterr;
|
||||
uint8_t errors = (uint8_t) (staterr >> 24);
|
||||
int16_t pkts;
|
||||
|
||||
if (status & IXGBE_RXD_STAT_IPCS) {
|
||||
if (!(errors & IXGBE_RXD_ERR_IPE)) {
|
||||
/* IP Checksum Good */
|
||||
mp->m_pkthdr.csum_flags = M_IPV4_CSUM_IN_OK;
|
||||
} else
|
||||
mp->m_pkthdr.csum_flags = 0;
|
||||
/*
|
||||
* VLAN Offload
|
||||
*/
|
||||
|
||||
#if NVLAN > 0
|
||||
if (ISSET(staterr, IXGBE_RXD_STAT_VP)) {
|
||||
m->m_pkthdr.ether_vtag = vtag;
|
||||
SET(m->m_flags, M_VLANTAG);
|
||||
}
|
||||
if (status & IXGBE_RXD_STAT_L4CS) {
|
||||
if (!(errors & IXGBE_RXD_ERR_TCPE))
|
||||
mp->m_pkthdr.csum_flags |=
|
||||
M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Checksum Offload
|
||||
*/
|
||||
|
||||
if (ISSET(status, IXGBE_RXD_STAT_IPCS)) {
|
||||
if (ISSET(errors, IXGBE_RXD_ERR_IPE))
|
||||
SET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_IN_BAD);
|
||||
else
|
||||
SET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_IN_OK);
|
||||
}
|
||||
if (ISSET(status, IXGBE_RXD_STAT_L4CS) &&
|
||||
!ISSET(status, IXGBE_RXD_STAT_UDPCS)) {
|
||||
if (ISSET(errors, IXGBE_RXD_ERR_TCPE)) {
|
||||
/* on some hardware IPv6 + TCP + Bad is broken */
|
||||
if (ISSET(status, IXGBE_RXD_STAT_IPCS))
|
||||
SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_IN_BAD);
|
||||
} else
|
||||
SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_IN_OK);
|
||||
}
|
||||
if (ISSET(status, IXGBE_RXD_STAT_L4CS) &&
|
||||
ISSET(status, IXGBE_RXD_STAT_UDPCS)) {
|
||||
if (ISSET(errors, IXGBE_RXD_ERR_TCPE))
|
||||
SET(m->m_pkthdr.csum_flags, M_UDP_CSUM_IN_BAD);
|
||||
else
|
||||
SET(m->m_pkthdr.csum_flags, M_UDP_CSUM_IN_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* TCP Large Receive Offload
|
||||
*/
|
||||
|
||||
pkts = m->m_pkthdr.ph_mss;
|
||||
m->m_pkthdr.ph_mss = 0;
|
||||
|
||||
if (pkts > 1) {
|
||||
struct ether_extracted ext;
|
||||
uint32_t paylen;
|
||||
|
||||
/*
|
||||
* Calculate the payload size:
|
||||
*
|
||||
* The packet length returned by the NIC (m->m_pkthdr.len)
|
||||
* can contain padding, which we don't want to count in to the
|
||||
* payload size. Therefore, we calculate the real payload size
|
||||
* based on the total ip length field (ext.iplen).
|
||||
*/
|
||||
ether_extract_headers(m, &ext);
|
||||
paylen = ext.iplen;
|
||||
if (ext.ip4 || ext.ip6)
|
||||
paylen -= ext.iphlen;
|
||||
if (ext.tcp) {
|
||||
paylen -= ext.tcphlen;
|
||||
tcpstat_inc(tcps_inhwlro);
|
||||
tcpstat_add(tcps_inpktlro, pkts);
|
||||
} else {
|
||||
tcpstat_inc(tcps_inbadlro);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we gonna forward this packet, we have to mark it as TSO,
|
||||
* set a correct mss, and recalculate the TCP checksum.
|
||||
*/
|
||||
if (ext.tcp && paylen >= pkts) {
|
||||
SET(m->m_pkthdr.csum_flags, M_TCP_TSO);
|
||||
m->m_pkthdr.ph_mss = paylen / pkts;
|
||||
}
|
||||
if (ext.tcp && ISSET(m->m_pkthdr.csum_flags, M_TCP_CSUM_IN_OK))
|
||||
SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_OUT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue