From: Alexander Bluhm Subject: Re: em(4) TSO support -- 2nd try To: Marcus Glocker Cc: tech@openbsd.org Date: Fri, 16 Feb 2024 14:04:53 +0100 On Thu, Feb 15, 2024 at 08:07:00PM +0100, Marcus Glocker wrote: > @@ -2403,6 +2429,73 @@ em_free_transmit_structures(struct em_so > 0, que->tx.sc_tx_dma.dma_map->dm_mapsize, > BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); > } > +} > + > +u_int > +em_tso_setup(struct em_queue *que, struct mbuf *mp, u_int head, > + u_int32_t *olinfo_status, u_int32_t *cmd_type_len) > +{ > + struct ether_extracted ext; > + struct e1000_adv_tx_context_desc *TD; > + uint32_t vlan_macip_lens = 0, type_tucmd_mlhl = 0, mss_l4len_idx = 0; > + > + *olinfo_status = 0; > + *cmd_type_len = 0; > + TD = (struct e1000_adv_tx_context_desc *)&que->tx.sc_tx_desc_ring[head]; > + > +#if NVLAN > 0 > + if (ISSET(mp->m_flags, M_VLANTAG)) { > + uint32_t vtag = mp->m_pkthdr.ether_vtag; > + vlan_macip_lens |= vtag << E1000_ADVTXD_VLAN_SHIFT; > + *cmd_type_len |= E1000_ADVTXD_DCMD_VLE; > + } > +#endif > + > + ether_extract_headers(mp, &ext); > + if (ext.tcp == NULL) > + goto out; > + > + vlan_macip_lens |= (sizeof(*ext.eh) << E1000_ADVTXD_MACLEN_SHIFT); > + > + if (ext.ip4) { > + type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4; > + *olinfo_status |= E1000_TXD_POPTS_IXSM << 8; > +#ifdef INET6 > + } else if (ext.ip6) { > + type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV6; > +#endif > + } else { > + goto out; > + } > + > + *cmd_type_len |= E1000_ADVTXD_DTYP_DATA | E1000_ADVTXD_DCMD_IFCS; > + *cmd_type_len |= E1000_ADVTXD_DCMD_DEXT | E1000_ADVTXD_DCMD_TSE; > + *olinfo_status |= ext.paylen << E1000_ADVTXD_PAYLEN_SHIFT; > + vlan_macip_lens |= ext.iphlen; > + type_tucmd_mlhl |= E1000_ADVTXD_DCMD_DEXT | E1000_ADVTXD_DTYP_CTXT; > + > + type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_TCP; > + *olinfo_status |= E1000_TXD_POPTS_TXSM << 8; > + > + mss_l4len_idx |= mp->m_pkthdr.ph_mss << E1000_ADVTXD_MSS_SHIFT; > + mss_l4len_idx |= (ext.tcp->th_off << 2) << E1000_ADVTXD_L4LEN_SHIFT; Here it crashes on sparc64. Use ext.tcphlen. > + /* 82575 needs the queue index added */ > + if (que->sc->hw.mac_type == em_82575) > + mss_l4len_idx |= (que->me & 0xff) << 4; > + > + htolem32(&TD->vlan_macip_lens, vlan_macip_lens); > + htolem32(&TD->type_tucmd_mlhl, type_tucmd_mlhl); > + htolem32(&TD->u.seqnum_seed, 0); > + htolem32(&TD->mss_l4len_idx, mss_l4len_idx); > + > + tcpstat_add(tcps_outpkttso, (ext.paylen + mp->m_pkthdr.ph_mss - 1) / > + mp->m_pkthdr.ph_mss); > + > + return 1; > + > +out: > + tcpstat_inc(tcps_outbadtso); > + return 0; > } > > u_int > Index: dev/pci/if_em.h > =================================================================== > RCS file: /cvs/src/sys/dev/pci/if_em.h,v > diff -u -p -u -p -r1.82 if_em.h > --- dev/pci/if_em.h 28 Jan 2024 18:42:58 -0000 1.82 > +++ dev/pci/if_em.h 15 Feb 2024 18:33:35 -0000 > @@ -55,11 +55,14 @@ POSSIBILITY OF SUCH DAMAGE. > > #include > #include > +#include > > #include > #include > #include > #include > +#include > +#include > #include > > #if NBPFILTER > 0 > @@ -269,6 +272,7 @@ typedef int boolean_t; > > #define EM_MAX_SCATTER 64 > #define EM_TSO_SIZE 65535 > +#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */ > > struct em_packet { > int pkt_eop; /* Index of the desc to watch */ > Index: dev/pci/if_em_hw.h > =================================================================== > RCS file: /cvs/src/sys/dev/pci/if_em_hw.h,v > diff -u -p -u -p -r1.92 if_em_hw.h > --- dev/pci/if_em_hw.h 28 Jan 2024 18:42:58 -0000 1.92 > +++ dev/pci/if_em_hw.h 15 Feb 2024 18:33:36 -0000 > @@ -2150,6 +2150,7 @@ struct e1000_adv_tx_context_desc { > #define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ > #define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */ > #define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */ > +#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */ > #define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */ > > /* Adv Transmit Descriptor Config Masks */ > @@ -2159,6 +2160,10 @@ struct e1000_adv_tx_context_desc { > #define E1000_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */ > #define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */ > #define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ > + > +/* Req requires Markers and CRC */ > +#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ > +#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ > > /* Multiple Receive Queue Control */ > #define E1000_MRQC_ENABLE_MASK 0x00000003