]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ixgbe/ix_txrx.c
Merge llvm-project release/13.x llvmorg-13.0.0-rc1-97-g23ba3732246a
[FreeBSD/FreeBSD.git] / sys / dev / ixgbe / ix_txrx.c
1 /******************************************************************************
2
3   Copyright (c) 2001-2017, Intel Corporation
4   All rights reserved.
5
6   Redistribution and use in source and binary forms, with or without
7   modification, are permitted provided that the following conditions are met:
8
9    1. Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11
12    2. Redistributions in binary form must reproduce the above copyright
13       notice, this list of conditions and the following disclaimer in the
14       documentation and/or other materials provided with the distribution.
15
16    3. Neither the name of the Intel Corporation nor the names of its
17       contributors may be used to endorse or promote products derived from
18       this software without specific prior written permission.
19
20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   POSSIBILITY OF SUCH DAMAGE.
31
32 ******************************************************************************/
33 /*$FreeBSD$*/
34
35 #ifndef IXGBE_STANDALONE_BUILD
36 #include "opt_inet.h"
37 #include "opt_inet6.h"
38 #include "opt_rss.h"
39 #endif
40
41 #include "ixgbe.h"
42
43 /************************************************************************
44  * Local Function prototypes
45  ************************************************************************/
46 static int ixgbe_isc_txd_encap(void *, if_pkt_info_t);
47 static void ixgbe_isc_txd_flush(void *, uint16_t, qidx_t);
48 static int ixgbe_isc_txd_credits_update(void *, uint16_t, bool);
49
50 static void ixgbe_isc_rxd_refill(void *, if_rxd_update_t);
51 static void ixgbe_isc_rxd_flush(void *, uint16_t, uint8_t, qidx_t);
52 static int ixgbe_isc_rxd_available(void *, uint16_t, qidx_t, qidx_t);
53 static int ixgbe_isc_rxd_pkt_get(void *, if_rxd_info_t);
54
55 static void ixgbe_rx_checksum(uint32_t, if_rxd_info_t, uint32_t);
56 static int ixgbe_tx_ctx_setup(struct ixgbe_adv_tx_context_desc *,
57     if_pkt_info_t);
58
59 extern void ixgbe_if_enable_intr(if_ctx_t ctx);
60 static int ixgbe_determine_rsstype(uint16_t pkt_info);
61
62 struct if_txrx ixgbe_txrx  = {
63         .ift_txd_encap = ixgbe_isc_txd_encap,
64         .ift_txd_flush = ixgbe_isc_txd_flush,
65         .ift_txd_credits_update = ixgbe_isc_txd_credits_update,
66         .ift_rxd_available = ixgbe_isc_rxd_available,
67         .ift_rxd_pkt_get = ixgbe_isc_rxd_pkt_get,
68         .ift_rxd_refill = ixgbe_isc_rxd_refill,
69         .ift_rxd_flush = ixgbe_isc_rxd_flush,
70         .ift_legacy_intr = NULL
71 };
72
73 /************************************************************************
74  * ixgbe_tx_ctx_setup
75  *
76  *   Advanced Context Descriptor setup for VLAN, CSUM or TSO
77  *
78  ************************************************************************/
79 static int
80 ixgbe_tx_ctx_setup(struct ixgbe_adv_tx_context_desc *TXD, if_pkt_info_t pi)
81 {
82         uint32_t vlan_macip_lens, type_tucmd_mlhl;
83         uint32_t olinfo_status, mss_l4len_idx, pktlen, offload;
84         u8  ehdrlen;
85
86         offload = true;
87         olinfo_status = mss_l4len_idx = vlan_macip_lens = type_tucmd_mlhl = 0;
88         /* VLAN MACLEN IPLEN */
89         vlan_macip_lens |= (htole16(pi->ipi_vtag) << IXGBE_ADVTXD_VLAN_SHIFT);
90
91         /*
92          * Some of our VF devices need a context descriptor for every
93          * packet.  That means the ehdrlen needs to be non-zero in order
94          * for the host driver not to flag a malicious event. The stack
95          * will most likely populate this for all other reasons of why
96          * this function was called.
97          */
98         if (pi->ipi_ehdrlen == 0) {
99                 ehdrlen = ETHER_HDR_LEN;
100                 ehdrlen += (pi->ipi_vtag != 0) ? ETHER_VLAN_ENCAP_LEN : 0;
101         } else
102                 ehdrlen = pi->ipi_ehdrlen;
103         vlan_macip_lens |= ehdrlen << IXGBE_ADVTXD_MACLEN_SHIFT;
104
105         pktlen = pi->ipi_len;
106         /* First check if TSO is to be used */
107         if (pi->ipi_csum_flags & CSUM_TSO) {
108                 /* This is used in the transmit desc in encap */
109                 pktlen = pi->ipi_len - ehdrlen - pi->ipi_ip_hlen - pi->ipi_tcp_hlen;
110                 mss_l4len_idx |= (pi->ipi_tso_segsz << IXGBE_ADVTXD_MSS_SHIFT);
111                 mss_l4len_idx |= (pi->ipi_tcp_hlen << IXGBE_ADVTXD_L4LEN_SHIFT);
112         }
113
114         olinfo_status |= pktlen << IXGBE_ADVTXD_PAYLEN_SHIFT;
115
116         if (pi->ipi_flags & IPI_TX_IPV4) {
117                 type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
118                 /* Tell transmit desc to also do IPv4 checksum. */
119                 if (pi->ipi_csum_flags & (CSUM_IP|CSUM_TSO))
120                         olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8;
121         } else if (pi->ipi_flags & IPI_TX_IPV6)
122                 type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
123         else
124                 offload = false;
125
126         vlan_macip_lens |= pi->ipi_ip_hlen;
127
128         switch (pi->ipi_ipproto) {
129         case IPPROTO_TCP:
130                 if (pi->ipi_csum_flags & (CSUM_IP_TCP | CSUM_IP6_TCP | CSUM_TSO))
131                         type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
132                 else
133                         offload = false;
134                 break;
135         case IPPROTO_UDP:
136                 if (pi->ipi_csum_flags & (CSUM_IP_UDP | CSUM_IP6_UDP))
137                         type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP;
138                 else
139                         offload = false;
140                 break;
141         case IPPROTO_SCTP:
142                 if (pi->ipi_csum_flags & (CSUM_IP_SCTP | CSUM_IP6_SCTP))
143                         type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_SCTP;
144                 else
145                         offload = false;
146                 break;
147         default:
148                 offload = false;
149                 break;
150         }
151         /* Insert L4 checksum into data descriptors */
152         if (offload)
153                 olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8;
154
155         type_tucmd_mlhl |= IXGBE_ADVTXD_DCMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
156
157         /* Now copy bits into descriptor */
158         TXD->vlan_macip_lens = htole32(vlan_macip_lens);
159         TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl);
160         TXD->seqnum_seed = htole32(0);
161         TXD->mss_l4len_idx = htole32(mss_l4len_idx);
162
163         return (olinfo_status);
164 } /* ixgbe_tx_ctx_setup */
165
166 /************************************************************************
167  * ixgbe_isc_txd_encap
168  ************************************************************************/
169 static int
170 ixgbe_isc_txd_encap(void *arg, if_pkt_info_t pi)
171 {
172         struct ixgbe_softc               *sc = arg;
173         if_softc_ctx_t                   scctx = sc->shared;
174         struct ix_tx_queue               *que = &sc->tx_queues[pi->ipi_qsidx];
175         struct tx_ring                   *txr = &que->txr;
176         int                              nsegs = pi->ipi_nsegs;
177         bus_dma_segment_t                *segs = pi->ipi_segs;
178         union ixgbe_adv_tx_desc          *txd = NULL;
179         struct ixgbe_adv_tx_context_desc *TXD;
180         int                              i, j, first, pidx_last;
181         uint32_t                         olinfo_status, cmd, flags;
182         qidx_t                           ntxd;
183
184         cmd =  (IXGBE_ADVTXD_DTYP_DATA |
185                 IXGBE_ADVTXD_DCMD_IFCS | IXGBE_ADVTXD_DCMD_DEXT);
186
187         if (pi->ipi_mflags & M_VLANTAG)
188                 cmd |= IXGBE_ADVTXD_DCMD_VLE;
189
190         i = first = pi->ipi_pidx;
191         flags = (pi->ipi_flags & IPI_TX_INTR) ? IXGBE_TXD_CMD_RS : 0;
192         ntxd = scctx->isc_ntxd[0];
193
194         TXD = (struct ixgbe_adv_tx_context_desc *) &txr->tx_base[first];
195         if ((pi->ipi_csum_flags & CSUM_OFFLOAD) ||
196             (sc->feat_en & IXGBE_FEATURE_NEEDS_CTXD) ||
197             pi->ipi_vtag) {
198                 /*********************************************
199                  * Set up the appropriate offload context
200                  * this will consume the first descriptor
201                  *********************************************/
202                 olinfo_status = ixgbe_tx_ctx_setup(TXD, pi);
203                 if (pi->ipi_csum_flags & CSUM_TSO) {
204                         cmd |= IXGBE_ADVTXD_DCMD_TSE;
205                         ++txr->tso_tx;
206                 }
207
208                 if (++i == scctx->isc_ntxd[0])
209                         i = 0;
210         } else {
211                 /* Indicate the whole packet as payload when not doing TSO */
212                 olinfo_status = pi->ipi_len << IXGBE_ADVTXD_PAYLEN_SHIFT;
213         }
214
215         olinfo_status |= IXGBE_ADVTXD_CC;
216         pidx_last = 0;
217         for (j = 0; j < nsegs; j++) {
218                 bus_size_t seglen;
219
220                 txd = &txr->tx_base[i];
221                 seglen = segs[j].ds_len;
222
223                 txd->read.buffer_addr = htole64(segs[j].ds_addr);
224                 txd->read.cmd_type_len = htole32(cmd | seglen);
225                 txd->read.olinfo_status = htole32(olinfo_status);
226
227                 pidx_last = i;
228                 if (++i == scctx->isc_ntxd[0]) {
229                         i = 0;
230                 }
231         }
232
233         if (flags) {
234                 txr->tx_rsq[txr->tx_rs_pidx] = pidx_last;
235                 txr->tx_rs_pidx = (txr->tx_rs_pidx + 1) & (ntxd - 1);
236         }
237         txd->read.cmd_type_len |= htole32(IXGBE_TXD_CMD_EOP | flags);
238
239         txr->bytes += pi->ipi_len;
240         pi->ipi_new_pidx = i;
241
242         ++txr->total_packets;
243
244         return (0);
245 } /* ixgbe_isc_txd_encap */
246
247 /************************************************************************
248  * ixgbe_isc_txd_flush
249  ************************************************************************/
250 static void
251 ixgbe_isc_txd_flush(void *arg, uint16_t txqid, qidx_t pidx)
252 {
253         struct ixgbe_softc     *sc = arg;
254         struct ix_tx_queue *que = &sc->tx_queues[txqid];
255         struct tx_ring     *txr = &que->txr;
256
257         IXGBE_WRITE_REG(&sc->hw, txr->tail, pidx);
258 } /* ixgbe_isc_txd_flush */
259
260 /************************************************************************
261  * ixgbe_isc_txd_credits_update
262  ************************************************************************/
263 static int
264 ixgbe_isc_txd_credits_update(void *arg, uint16_t txqid, bool clear)
265 {
266         struct ixgbe_softc *sc = arg;
267         if_softc_ctx_t     scctx = sc->shared;
268         struct ix_tx_queue *que = &sc->tx_queues[txqid];
269         struct tx_ring     *txr = &que->txr;
270         qidx_t             processed = 0;
271         int                updated;
272         qidx_t             cur, prev, ntxd, rs_cidx;
273         int32_t            delta;
274         uint8_t            status;
275
276         rs_cidx = txr->tx_rs_cidx;
277         if (rs_cidx == txr->tx_rs_pidx)
278                 return (0);
279
280         cur = txr->tx_rsq[rs_cidx];
281         status = txr->tx_base[cur].wb.status;
282         updated = !!(status & IXGBE_TXD_STAT_DD);
283
284         if (!updated)
285                 return (0);
286
287         /* If clear is false just let caller know that there
288          * are descriptors to reclaim */
289         if (!clear)
290                 return (1);
291
292         prev = txr->tx_cidx_processed;
293         ntxd = scctx->isc_ntxd[0];
294         do {
295                 MPASS(prev != cur);
296                 delta = (int32_t)cur - (int32_t)prev;
297                 if (delta < 0)
298                         delta += ntxd;
299                 MPASS(delta > 0);
300
301                 processed += delta;
302                 prev = cur;
303                 rs_cidx = (rs_cidx + 1) & (ntxd - 1);
304                 if (rs_cidx == txr->tx_rs_pidx)
305                         break;
306
307                 cur = txr->tx_rsq[rs_cidx];
308                 status = txr->tx_base[cur].wb.status;
309         } while ((status & IXGBE_TXD_STAT_DD));
310
311         txr->tx_rs_cidx = rs_cidx;
312         txr->tx_cidx_processed = prev;
313
314         return (processed);
315 } /* ixgbe_isc_txd_credits_update */
316
317 /************************************************************************
318  * ixgbe_isc_rxd_refill
319  ************************************************************************/
320 static void
321 ixgbe_isc_rxd_refill(void *arg, if_rxd_update_t iru)
322 {
323         struct ixgbe_softc *sc   = arg;
324         struct ix_rx_queue *que  = &sc->rx_queues[iru->iru_qsidx];
325         struct rx_ring *rxr      = &que->rxr;
326         uint64_t *paddrs;
327         int i;
328         uint32_t next_pidx, pidx;
329         uint16_t count;
330
331         paddrs = iru->iru_paddrs;
332         pidx = iru->iru_pidx;
333         count = iru->iru_count;
334
335         for (i = 0, next_pidx = pidx; i < count; i++) {
336                 rxr->rx_base[next_pidx].read.pkt_addr = htole64(paddrs[i]);
337                 if (++next_pidx == sc->shared->isc_nrxd[0])
338                         next_pidx = 0;
339         }
340 } /* ixgbe_isc_rxd_refill */
341
342 /************************************************************************
343  * ixgbe_isc_rxd_flush
344  ************************************************************************/
345 static void
346 ixgbe_isc_rxd_flush(void *arg, uint16_t qsidx, uint8_t flidx __unused, qidx_t pidx)
347 {
348         struct ixgbe_softc *sc  = arg;
349         struct ix_rx_queue *que = &sc->rx_queues[qsidx];
350         struct rx_ring     *rxr = &que->rxr;
351
352         IXGBE_WRITE_REG(&sc->hw, rxr->tail, pidx);
353 } /* ixgbe_isc_rxd_flush */
354
355 /************************************************************************
356  * ixgbe_isc_rxd_available
357  ************************************************************************/
358 static int
359 ixgbe_isc_rxd_available(void *arg, uint16_t qsidx, qidx_t pidx, qidx_t budget)
360 {
361         struct ixgbe_softc      *sc = arg;
362         struct ix_rx_queue      *que = &sc->rx_queues[qsidx];
363         struct rx_ring          *rxr = &que->rxr;
364         union ixgbe_adv_rx_desc *rxd;
365         uint32_t                 staterr;
366         int                      cnt, i, nrxd;
367
368         nrxd = sc->shared->isc_nrxd[0];
369         for (cnt = 0, i = pidx; cnt < nrxd && cnt <= budget;) {
370                 rxd = &rxr->rx_base[i];
371                 staterr = le32toh(rxd->wb.upper.status_error);
372
373                 if ((staterr & IXGBE_RXD_STAT_DD) == 0)
374                         break;
375                 if (++i == nrxd)
376                         i = 0;
377                 if (staterr & IXGBE_RXD_STAT_EOP)
378                         cnt++;
379         }
380         return (cnt);
381 } /* ixgbe_isc_rxd_available */
382
383 /************************************************************************
384  * ixgbe_isc_rxd_pkt_get
385  *
386  *   Routine sends data which has been dma'ed into host memory
387  *   to upper layer. Initialize ri structure.
388  *
389  *   Returns 0 upon success, errno on failure
390  ************************************************************************/
391
392 static int
393 ixgbe_isc_rxd_pkt_get(void *arg, if_rxd_info_t ri)
394 {
395         struct ixgbe_softc       *sc = arg;
396         struct ix_rx_queue       *que = &sc->rx_queues[ri->iri_qsidx];
397         struct rx_ring           *rxr = &que->rxr;
398         struct ifnet             *ifp = iflib_get_ifp(sc->ctx);
399         union ixgbe_adv_rx_desc  *rxd;
400
401         uint16_t                  pkt_info, len, cidx, i;
402         uint16_t                  vtag = 0;
403         uint32_t                  ptype;
404         uint32_t                  staterr = 0;
405         bool                      eop;
406
407         i = 0;
408         cidx = ri->iri_cidx;
409         do {
410                 rxd = &rxr->rx_base[cidx];
411                 staterr = le32toh(rxd->wb.upper.status_error);
412                 pkt_info = le16toh(rxd->wb.lower.lo_dword.hs_rss.pkt_info);
413
414                 /* Error Checking then decrement count */
415                 MPASS ((staterr & IXGBE_RXD_STAT_DD) != 0);
416
417                 len = le16toh(rxd->wb.upper.length);
418                 ptype = le32toh(rxd->wb.lower.lo_dword.data) &
419                         IXGBE_RXDADV_PKTTYPE_MASK;
420
421                 ri->iri_len += len;
422                 rxr->bytes += len;
423
424                 rxd->wb.upper.status_error = 0;
425                 eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0);
426
427                 if ( (rxr->vtag_strip) && (staterr & IXGBE_RXD_STAT_VP) ) {
428                         vtag = le16toh(rxd->wb.upper.vlan);
429                 } else {
430                         vtag = 0;
431                 }
432
433                 /* Make sure bad packets are discarded */
434                 if (eop && (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) {
435                         if (sc->feat_en & IXGBE_FEATURE_VF)
436                                 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
437
438                         rxr->rx_discarded++;
439                         return (EBADMSG);
440                 }
441                 ri->iri_frags[i].irf_flid = 0;
442                 ri->iri_frags[i].irf_idx = cidx;
443                 ri->iri_frags[i].irf_len = len;
444                 if (++cidx == sc->shared->isc_nrxd[0])
445                         cidx = 0;
446                 i++;
447                 /* even a 16K packet shouldn't consume more than 8 clusters */
448                 MPASS(i < 9);
449         } while (!eop);
450
451         rxr->rx_packets++;
452         rxr->packets++;
453         rxr->rx_bytes += ri->iri_len;
454
455         if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
456                 ixgbe_rx_checksum(staterr, ri,  ptype);
457
458         ri->iri_flowid = le32toh(rxd->wb.lower.hi_dword.rss);
459         ri->iri_rsstype = ixgbe_determine_rsstype(pkt_info);
460         if ((sc->feat_en & IXGBE_FEATURE_RSS) == 0) {
461                 if (ri->iri_rsstype == M_HASHTYPE_OPAQUE)
462                         ri->iri_rsstype = M_HASHTYPE_NONE;
463                 else
464                         ri->iri_rsstype = M_HASHTYPE_OPAQUE_HASH;
465         }
466         ri->iri_vtag = vtag;
467         ri->iri_nfrags = i;
468         if (vtag)
469                 ri->iri_flags |= M_VLANTAG;
470         return (0);
471 } /* ixgbe_isc_rxd_pkt_get */
472
473 /************************************************************************
474  * ixgbe_rx_checksum
475  *
476  *   Verify that the hardware indicated that the checksum is valid.
477  *   Inform the stack about the status of checksum so that stack
478  *   doesn't spend time verifying the checksum.
479  ************************************************************************/
480 static void
481 ixgbe_rx_checksum(uint32_t staterr, if_rxd_info_t ri, uint32_t ptype)
482 {
483         uint16_t status = (uint16_t)staterr;
484         uint8_t errors = (uint8_t)(staterr >> 24);
485
486         /* If there is a layer 3 or 4 error we are done */
487         if (__predict_false(errors & (IXGBE_RXD_ERR_IPE | IXGBE_RXD_ERR_TCPE)))
488                 return;
489
490         /* IP Checksum Good */
491         if (status & IXGBE_RXD_STAT_IPCS)
492                 ri->iri_csum_flags = (CSUM_IP_CHECKED | CSUM_IP_VALID);
493
494         /* Valid L4E checksum */
495         if (__predict_true(status & IXGBE_RXD_STAT_L4CS)) {
496                 /* SCTP header present. */
497                 if (__predict_false((ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 &&
498                     (ptype & IXGBE_RXDADV_PKTTYPE_SCTP) != 0)) {
499                         ri->iri_csum_flags |= CSUM_SCTP_VALID;
500                 } else {
501                         ri->iri_csum_flags |= CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
502                         ri->iri_csum_data = htons(0xffff);
503                 }
504         }
505 } /* ixgbe_rx_checksum */
506
507 /************************************************************************
508  * ixgbe_determine_rsstype
509  *
510  *   Parse the packet type to determine the appropriate hash
511  ************************************************************************/
512 static int
513 ixgbe_determine_rsstype(uint16_t pkt_info)
514 {
515         switch (pkt_info & IXGBE_RXDADV_RSSTYPE_MASK) {
516         case IXGBE_RXDADV_RSSTYPE_IPV4_TCP:
517                 return M_HASHTYPE_RSS_TCP_IPV4;
518         case IXGBE_RXDADV_RSSTYPE_IPV4:
519                 return M_HASHTYPE_RSS_IPV4;
520         case IXGBE_RXDADV_RSSTYPE_IPV6_TCP:
521                 return M_HASHTYPE_RSS_TCP_IPV6;
522         case IXGBE_RXDADV_RSSTYPE_IPV6_EX:
523                 return M_HASHTYPE_RSS_IPV6_EX;
524         case IXGBE_RXDADV_RSSTYPE_IPV6:
525                 return M_HASHTYPE_RSS_IPV6;
526         case IXGBE_RXDADV_RSSTYPE_IPV6_TCP_EX:
527                 return M_HASHTYPE_RSS_TCP_IPV6_EX;
528         case IXGBE_RXDADV_RSSTYPE_IPV4_UDP:
529                 return M_HASHTYPE_RSS_UDP_IPV4;
530         case IXGBE_RXDADV_RSSTYPE_IPV6_UDP:
531                 return M_HASHTYPE_RSS_UDP_IPV6;
532         case IXGBE_RXDADV_RSSTYPE_IPV6_UDP_EX:
533                 return M_HASHTYPE_RSS_UDP_IPV6_EX;
534         default:
535                 return M_HASHTYPE_OPAQUE;
536         }
537 } /* ixgbe_determine_rsstype */