Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174710155
D5424.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D5424.id.diff
View Options
Index: sys/dev/vnic/nic.h
===================================================================
--- sys/dev/vnic/nic.h
+++ sys/dev/vnic/nic.h
@@ -292,6 +292,7 @@
uint8_t max_queues;
struct resource *reg_base;
boolean_t link_up;
+ boolean_t hw_tso;
uint8_t duplex;
uint32_t speed;
uint8_t cpi_alg;
Index: sys/dev/vnic/nicvf_main.c
===================================================================
--- sys/dev/vnic/nicvf_main.c
+++ sys/dev/vnic/nicvf_main.c
@@ -66,6 +66,7 @@
#include <net/if_vlan_var.h>
#include <netinet/in.h>
+#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/tcp_lro.h>
@@ -194,6 +195,9 @@
nic->pnicvf = nic;
NICVF_CORE_LOCK_INIT(nic);
+ /* Enable HW TSO on Pass2 */
+ if (!pass1_silicon(dev))
+ nic->hw_tso = TRUE;
rid = VNIC_VF_REG_RID;
nic->reg_base = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
@@ -356,6 +360,14 @@
/* Set the default values */
if_setcapabilitiesbit(ifp, IFCAP_VLAN_MTU, 0);
if_setcapabilitiesbit(ifp, IFCAP_LRO, 0);
+ if (nic->hw_tso) {
+ /* TSO */
+ if_setcapabilitiesbit(ifp, IFCAP_TSO4, 0);
+ /* TSO parameters */
+ ifp->if_hw_tsomax = NICVF_TSO_MAXSIZE;
+ ifp->if_hw_tsomaxsegcount = NICVF_TSO_NSEGS;
+ ifp->if_hw_tsomaxsegsize = MCLBYTES;
+ }
/* IP/TCP/UDP HW checksums */
if_setcapabilitiesbit(ifp, IFCAP_HWCSUM, 0);
if_setcapabilitiesbit(ifp, IFCAP_HWSTATS, 0);
@@ -364,7 +376,8 @@
*/
if_clearhwassist(ifp);
if_sethwassistbits(ifp, (CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_SCTP), 0);
-
+ if (nic->hw_tso)
+ if_sethwassistbits(ifp, (CSUM_TSO), 0);
if_setcapenable(ifp, if_getcapabilities(ifp));
return (0);
@@ -513,6 +526,8 @@
ifp->if_capenable ^= IFCAP_TXCSUM;
if (mask & IFCAP_RXCSUM)
ifp->if_capenable ^= IFCAP_RXCSUM;
+ if ((mask & IFCAP_TSO4) && nic->hw_tso)
+ ifp->if_capenable ^= IFCAP_TSO4;
if (mask & IFCAP_LRO) {
/*
* Lock the driver for a moment to avoid
Index: sys/dev/vnic/nicvf_queues.h
===================================================================
--- sys/dev/vnic/nicvf_queues.h
+++ sys/dev/vnic/nicvf_queues.h
@@ -131,10 +131,13 @@
#define NICVF_RCV_BUF_ALIGN_LEN(addr) \
(NICVF_ALIGNED_ADDR((addr), NICVF_RCV_BUF_ALIGN_BYTES) - (addr))
-#define NICVF_TXBUF_MAXSIZE 9212 /* Total max payload without TSO */
+#define NICVF_TXBUF_MAXSIZE NIC_HW_MAX_FRS /* Total max payload without TSO */
#define NICVF_TXBUF_NSEGS 256 /* Single command is at most 256 buffers
(hdr + 255 subcmds) */
-
+/* TSO-related definitions */
+#define NICVF_TSO_MAXSIZE IP_MAXPACKET
+#define NICVF_TSO_NSEGS NICVF_TXBUF_NSEGS
+#define NICVF_TSO_HEADER_SIZE 128
/* Queue enable/disable */
#define NICVF_SQ_EN (1UL << 19)
Index: sys/dev/vnic/nicvf_queues.c
===================================================================
--- sys/dev/vnic/nicvf_queues.c
+++ sys/dev/vnic/nicvf_queues.c
@@ -1070,8 +1070,8 @@
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filtfunc, filtfuncarg */
- NICVF_TXBUF_MAXSIZE, /* maxsize */
- NICVF_TXBUF_NSEGS, /* nsegments */
+ NICVF_TSO_MAXSIZE, /* maxsize */
+ NICVF_TSO_NSEGS, /* nsegments */
MCLBYTES, /* maxsegsize */
0, /* flags */
NULL, NULL, /* lockfunc, lockfuncarg */
@@ -1727,14 +1727,18 @@
nicvf_sq_add_hdr_subdesc(struct snd_queue *sq, int qentry,
int subdesc_cnt, struct mbuf *mbuf, int len)
{
+ struct nicvf *nic;
struct sq_hdr_subdesc *hdr;
struct ether_vlan_header *eh;
#ifdef INET
struct ip *ip;
+ struct tcphdr *th;
#endif
uint16_t etype;
int ehdrlen, iphlen, poff;
+ nic = sq->nic;
+
hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, qentry);
sq->snd_buff[qentry].mbuf = mbuf;
@@ -1746,18 +1750,25 @@
hdr->subdesc_cnt = subdesc_cnt;
hdr->tot_len = len;
- if (mbuf->m_pkthdr.csum_flags != 0) {
- hdr->csum_l3 = 1; /* Enable IP csum calculation */
-
- eh = mtod(mbuf, struct ether_vlan_header *);
- if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
- ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
- etype = ntohs(eh->evl_proto);
- } else {
- ehdrlen = ETHER_HDR_LEN;
- etype = ntohs(eh->evl_encap_proto);
- }
+ eh = mtod(mbuf, struct ether_vlan_header *);
+ if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
+ ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+ etype = ntohs(eh->evl_proto);
+ } else {
+ ehdrlen = ETHER_HDR_LEN;
+ etype = ntohs(eh->evl_encap_proto);
+ }
+ switch (etype) {
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ /* ARM64TODO: Add support for IPv6 */
+ hdr->csum_l3 = 0;
+ sq->snd_buff[qentry].mbuf = NULL;
+ return (ENXIO);
+#endif
+#ifdef INET
+ case ETHERTYPE_IP:
if (mbuf->m_len < ehdrlen + sizeof(struct ip)) {
mbuf = m_pullup(mbuf, ehdrlen + sizeof(struct ip));
sq->snd_buff[qentry].mbuf = mbuf;
@@ -1765,21 +1776,13 @@
return (ENOBUFS);
}
- switch (etype) {
-#ifdef INET6
- case ETHERTYPE_IPV6:
- /* ARM64TODO: Add support for IPv6 */
- hdr->csum_l3 = 0;
- sq->snd_buff[qentry].mbuf = NULL;
- return (ENXIO);
-#endif
-#ifdef INET
- case ETHERTYPE_IP:
- ip = (struct ip *)(mbuf->m_data + ehdrlen);
- ip->ip_sum = 0;
- iphlen = ip->ip_hl << 2;
- poff = ehdrlen + iphlen;
+ ip = (struct ip *)(mbuf->m_data + ehdrlen);
+ ip->ip_sum = 0;
+ iphlen = ip->ip_hl << 2;
+ poff = ehdrlen + iphlen;
+ if (mbuf->m_pkthdr.csum_flags != 0) {
+ hdr->csum_l3 = 1; /* Enable IP csum calculation */
switch (ip->ip_p) {
case IPPROTO_TCP:
if ((mbuf->m_pkthdr.csum_flags & CSUM_TCP) == 0)
@@ -1820,17 +1823,28 @@
default:
break;
}
- break;
-#endif
- default:
- hdr->csum_l3 = 0;
- return (0);
+ hdr->l3_offset = ehdrlen;
+ hdr->l4_offset = ehdrlen + iphlen;
}
- hdr->l3_offset = ehdrlen;
- hdr->l4_offset = ehdrlen + iphlen;
- } else
+ if ((mbuf->m_pkthdr.tso_segsz != 0) && nic->hw_tso) {
+ /*
+ * Extract ip again as m_data could have been modified.
+ */
+ ip = (struct ip *)(mbuf->m_data + ehdrlen);
+ th = (struct tcphdr *)((caddr_t)ip + iphlen);
+
+ hdr->tso = 1;
+ hdr->tso_start = ehdrlen + iphlen + (th->th_off * 4);
+ hdr->tso_max_paysize = mbuf->m_pkthdr.tso_segsz;
+ hdr->inner_l3_offset = ehdrlen - 2;
+ nic->drv_stats.tx_tso++;
+ }
+ break;
+#endif
+ default:
hdr->csum_l3 = 0;
+ }
return (0);
}
@@ -1859,10 +1873,11 @@
nicvf_tx_mbuf_locked(struct snd_queue *sq, struct mbuf *mbuf)
{
bus_dma_segment_t segs[256];
+ struct nicvf *nic;
struct snd_buff *snd_buff;
size_t seg;
int nsegs, qentry;
- int subdesc_cnt = MIN_SQ_DESC_PER_PKT_XMIT - 1;
+ int subdesc_cnt;
int err;
NICVF_TX_LOCK_ASSERT(sq);
@@ -1880,7 +1895,11 @@
}
/* Set how many subdescriptors is required */
- subdesc_cnt += nsegs;
+ nic = sq->nic;
+ if (mbuf->m_pkthdr.tso_segsz != 0 && nic->hw_tso)
+ subdesc_cnt = MIN_SQ_DESC_PER_PKT_XMIT;
+ else
+ subdesc_cnt = MIN_SQ_DESC_PER_PKT_XMIT + nsegs - 1;
if (subdesc_cnt > sq->free_cnt) {
/* ARM64TODO: Add mbuf defragmentation if we lack descriptors */
Index: sys/dev/vnic/q_struct.h
===================================================================
--- sys/dev/vnic/q_struct.h
+++ sys/dev/vnic/q_struct.h
@@ -565,25 +565,28 @@
uint64_t subdesc_cnt:8;
uint64_t csum_l4:2;
uint64_t csum_l3:1;
- uint64_t rsvd0:5;
+ uint64_t csum_inner_l4:2;
+ uint64_t csum_inner_l3:1;
+ uint64_t rsvd0:2;
uint64_t l4_offset:8;
uint64_t l3_offset:8;
uint64_t rsvd1:4;
uint64_t tot_len:20; /* W0 */
- uint64_t tso_sdc_cont:8;
- uint64_t tso_sdc_first:8;
- uint64_t tso_l4_offset:8;
- uint64_t tso_flags_last:12;
- uint64_t tso_flags_first:12;
- uint64_t rsvd2:2;
+ uint64_t rsvd2:24;
+ uint64_t inner_l4_offset:8;
+ uint64_t inner_l3_offset:8;
+ uint64_t tso_start:8;
+ uint64_t rsvd3:2;
uint64_t tso_max_paysize:14; /* W1 */
#elif defined(__LITTLE_ENDIAN_BITFIELD)
uint64_t tot_len:20;
uint64_t rsvd1:4;
uint64_t l3_offset:8;
uint64_t l4_offset:8;
- uint64_t rsvd0:5;
+ uint64_t rsvd0:2;
+ uint64_t csum_inner_l3:1;
+ uint64_t csum_inner_l4:2;
uint64_t csum_l3:1;
uint64_t csum_l4:2;
uint64_t subdesc_cnt:8;
@@ -594,12 +597,11 @@
uint64_t subdesc_type:4; /* W0 */
uint64_t tso_max_paysize:14;
- uint64_t rsvd2:2;
- uint64_t tso_flags_first:12;
- uint64_t tso_flags_last:12;
- uint64_t tso_l4_offset:8;
- uint64_t tso_sdc_first:8;
- uint64_t tso_sdc_cont:8; /* W1 */
+ uint64_t rsvd3:2;
+ uint64_t tso_start:8;
+ uint64_t inner_l3_offset:8;
+ uint64_t inner_l4_offset:8;
+ uint64_t rsvd2:24;
#endif
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Oct 6, 9:39 AM (10 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40291307
Default Alt Text
D5424.id.diff (8 KB)
Attached To
Mode
D5424: Introduce HW TSO support for VNIC
Attached
Detach File
Event Timeline
Log In to Comment