From 8def654ae232472b34ab9d368532b10392a6ebe8 Mon Sep 17 00:00:00 2001 From: jfv Date: Thu, 27 Jan 2011 00:36:54 +0000 Subject: [PATCH] MFC ixgbe cummulative patch from stable/8 217712 Fix a couple of incorrect variable names in the sysctl code. 217713 - Panic on the 82598 adapter due to reading FCOE registers that don't exit - Make phy detection dynamic so adapters that support multiple types of media can be properly identified by the interface layer - Performance patch to the flow director (ixgbe_atr) code - Fix intermittent data corruption on the 82599 - Add missing support code for buffer size and descriptors when doing jumbo frames, also add 16K cluster support. - Release RX lock when calling stack, this removes LOR problems. 217795 Remove TX_UNLOCK from the error path in local_timer, there is no LOCK 217796 Add missing case for Direct Attach 82598 in the dynamic phy detection 217797 Performance: don't run flow control shared code if nothing has changed Approved by: re (bz) git-svn-id: svn://svn.freebsd.org/base/releng/8.2@217917 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/dev/ixgbe/ixgbe.c | 286 ++++++++--------- sys/dev/ixgbe/ixgbe.h | 1 + sys/dev/ixgbe/ixgbe_82599.c | 597 +++++++---------------------------- sys/dev/ixgbe/ixgbe_api.h | 34 +- sys/dev/ixgbe/ixgbe_common.c | 61 +++- sys/dev/ixgbe/ixgbe_common.h | 2 + sys/dev/ixgbe/ixgbe_mbx.c | 9 +- sys/dev/ixgbe/ixgbe_type.h | 44 ++- 8 files changed, 367 insertions(+), 667 deletions(-) diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index e246bf36..b0894503 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -46,7 +46,7 @@ int ixgbe_display_debug_stats = 0; /********************************************************************* * Driver version *********************************************************************/ -char ixgbe_driver_version[] = "2.3.7"; +char ixgbe_driver_version[] = "2.3.8"; /********************************************************************* * PCI Device ID Table @@ -175,6 +175,7 @@ static __inline void ixgbe_rx_input(struct rx_ring *, struct ifnet *, /* Support for pluggable optic modules */ static bool ixgbe_sfp_probe(struct adapter *); +static void ixgbe_setup_optics(struct adapter *); /* Legacy (single vector interrupt handler */ static void ixgbe_legacy_irq(void *); @@ -290,13 +291,6 @@ TUNABLE_INT("hw.ixgbe.rxd", &ixgbe_rxd); /* Keep running tab on them for sanity check */ static int ixgbe_total_ports; -/* -** The number of scatter-gather segments -** differs for 82598 and 82599, default to -** the former. -*/ -static int ixgbe_num_segs = IXGBE_82598_SCATTER; - #ifdef IXGBE_FDIR /* ** For Flow Director: this is the @@ -386,7 +380,7 @@ ixgbe_attach(device_t dev) struct adapter *adapter; struct ixgbe_hw *hw; int error = 0; - u16 pci_device_id, csum; + u16 csum; u32 ctrl_ext; INIT_DEBUGOUT("ixgbe_attach: begin"); @@ -399,52 +393,6 @@ ixgbe_attach(device_t dev) /* Core Lock Init*/ IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); - /* Keep track of optics */ - pci_device_id = pci_get_device(dev); - switch (pci_device_id) { - case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: - case IXGBE_DEV_ID_82598EB_CX4: - adapter->optics = IFM_10G_CX4; - break; - case IXGBE_DEV_ID_82598: - case IXGBE_DEV_ID_82598AF_DUAL_PORT: - case IXGBE_DEV_ID_82598AF_SINGLE_PORT: - case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: - case IXGBE_DEV_ID_82598EB_SFP_LOM: - case IXGBE_DEV_ID_82598AT: - adapter->optics = IFM_10G_SR; - break; - case IXGBE_DEV_ID_82598AT2: - adapter->optics = IFM_10G_T; - break; - case IXGBE_DEV_ID_82598EB_XF_LR: - adapter->optics = IFM_10G_LR; - break; - case IXGBE_DEV_ID_82599_SFP: - adapter->optics = IFM_10G_SR; - ixgbe_num_segs = IXGBE_82599_SCATTER; - break; - case IXGBE_DEV_ID_82598_DA_DUAL_PORT : - adapter->optics = IFM_10G_TWINAX; - break; - case IXGBE_DEV_ID_82599_KX4: - case IXGBE_DEV_ID_82599_KX4_MEZZ: - case IXGBE_DEV_ID_82599_CX4: - adapter->optics = IFM_10G_CX4; - ixgbe_num_segs = IXGBE_82599_SCATTER; - break; - case IXGBE_DEV_ID_82599_XAUI_LOM: - case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: - ixgbe_num_segs = IXGBE_82599_SCATTER; - break; - case IXGBE_DEV_ID_82599_T3_LOM: - ixgbe_num_segs = IXGBE_82599_SCATTER; - adapter->optics = IFM_10G_T; - default: - ixgbe_num_segs = IXGBE_82599_SCATTER; - break; - } - /* SYSCTL APIs */ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), @@ -547,10 +495,6 @@ ixgbe_attach(device_t dev) goto err_late; } - /* Pick up the smart speed setting */ - if (hw->mac.type == ixgbe_mac_82599EB) - hw->phy.smart_speed = ixgbe_smart_speed; - /* Get Hardware Flow Control setting */ hw->fc.requested_mode = ixgbe_fc_full; hw->fc.pause_time = IXGBE_FC_PAUSE; @@ -574,6 +518,9 @@ ixgbe_attach(device_t dev) goto err_late; } + /* Detect and set physical type */ + ixgbe_setup_optics(adapter); + if ((adapter->msix > 1) && (ixgbe_enable_msix)) error = ixgbe_allocate_msix(adapter); else @@ -1054,7 +1001,7 @@ ixgbe_init_locked(struct adapter *adapter) return; } - ixgbe_reset_hw(hw); + ixgbe_init_hw(hw); ixgbe_initialize_transmit_units(adapter); /* Setup Multicast table */ @@ -1068,8 +1015,10 @@ ixgbe_init_locked(struct adapter *adapter) adapter->rx_mbuf_sz = MCLBYTES; else if (adapter->max_frame_size <= 4096) adapter->rx_mbuf_sz = MJUMPAGESIZE; - else + else if (adapter->max_frame_size <= 9216) adapter->rx_mbuf_sz = MJUM9BYTES; + else + adapter->rx_mbuf_sz = MJUM16BYTES; /* Prepare receive descriptors and buffers */ if (ixgbe_setup_receive_structures(adapter)) { @@ -1600,7 +1549,7 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) int i, j, error, nsegs; int first, last = 0; struct mbuf *m_head; - bus_dma_segment_t segs[ixgbe_num_segs]; + bus_dma_segment_t segs[adapter->num_segs]; bus_dmamap_t map; struct ixgbe_tx_buf *txbuf, *txbuf_mapped; union ixgbe_adv_tx_desc *txd = NULL; @@ -1921,7 +1870,6 @@ hung: txr->me, txr->tx_avail, txr->next_to_clean); adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; adapter->watchdog_events++; - IXGBE_TX_UNLOCK(txr); ixgbe_init_locked(adapter); } @@ -2010,16 +1958,71 @@ static void ixgbe_identify_hardware(struct adapter *adapter) { device_t dev = adapter->dev; + struct ixgbe_hw *hw = &adapter->hw; /* Save off the information about this board */ - adapter->hw.vendor_id = pci_get_vendor(dev); - adapter->hw.device_id = pci_get_device(dev); - adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1); - adapter->hw.subsystem_vendor_id = + hw->vendor_id = pci_get_vendor(dev); + hw->device_id = pci_get_device(dev); + hw->revision_id = pci_read_config(dev, PCIR_REVID, 1); + hw->subsystem_vendor_id = pci_read_config(dev, PCIR_SUBVEND_0, 2); - adapter->hw.subsystem_device_id = + hw->subsystem_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2); + /* We need this here to set the num_segs below */ + ixgbe_set_mac_type(hw); + + /* Pick up the 82599 and VF settings */ + if (hw->mac.type != ixgbe_mac_82598EB) { + hw->phy.smart_speed = ixgbe_smart_speed; + adapter->num_segs = IXGBE_82599_SCATTER; + } else + adapter->num_segs = IXGBE_82598_SCATTER; + + return; +} + +/********************************************************************* + * + * Determine optic type + * + **********************************************************************/ +static void +ixgbe_setup_optics(struct adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int layer; + + layer = ixgbe_get_supported_physical_layer(hw); + switch (layer) { + case IXGBE_PHYSICAL_LAYER_10GBASE_T: + adapter->optics = IFM_10G_T; + break; + case IXGBE_PHYSICAL_LAYER_1000BASE_T: + adapter->optics = IFM_1000_T; + break; + case IXGBE_PHYSICAL_LAYER_10GBASE_LR: + case IXGBE_PHYSICAL_LAYER_10GBASE_LRM: + adapter->optics = IFM_10G_LR; + break; + case IXGBE_PHYSICAL_LAYER_10GBASE_SR: + adapter->optics = IFM_10G_SR; + break; + case IXGBE_PHYSICAL_LAYER_10GBASE_KX4: + case IXGBE_PHYSICAL_LAYER_10GBASE_CX4: + adapter->optics = IFM_10G_CX4; + break; + case IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU: + adapter->optics = IFM_10G_TWINAX; + break; + case IXGBE_PHYSICAL_LAYER_1000BASE_KX: + case IXGBE_PHYSICAL_LAYER_10GBASE_KR: + case IXGBE_PHYSICAL_LAYER_10GBASE_XAUI: + case IXGBE_PHYSICAL_LAYER_UNKNOWN: + default: + adapter->optics = IFM_ETHER | IFM_AUTO; + break; + } return; } @@ -2216,8 +2219,8 @@ ixgbe_setup_msix(struct adapter *adapter) if (ixgbe_num_queues != 0) queues = ixgbe_num_queues; - /* Set max queues to 8 */ - else if (queues > 8) + /* Set max queues to 8 when autoconfiguring */ + else if ((ixgbe_num_queues == 0) && (queues > 8)) queues = 8; /* @@ -2413,8 +2416,8 @@ ixgbe_setup_interface(device_t dev, struct adapter *adapter) */ ifmedia_init(&adapter->media, IFM_IMASK, ixgbe_media_change, ixgbe_media_status); - ifmedia_add(&adapter->media, IFM_ETHER | adapter->optics | - IFM_FDX, 0, NULL); + ifmedia_add(&adapter->media, IFM_ETHER | adapter->optics, 0, NULL); + ifmedia_set(&adapter->media, IFM_ETHER | adapter->optics); if (hw->device_id == IXGBE_DEV_ID_82598AT) { ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL); @@ -2718,7 +2721,7 @@ ixgbe_allocate_transmit_buffers(struct tx_ring *txr) BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ IXGBE_TSO_SIZE, /* maxsize */ - ixgbe_num_segs, /* nsegments */ + adapter->num_segs, /* nsegments */ PAGE_SIZE, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ @@ -3181,72 +3184,67 @@ ixgbe_atr(struct tx_ring *txr, struct mbuf *mp) { struct adapter *adapter = txr->adapter; struct ix_queue *que; - union ixgbe_atr_input atr_input; struct ip *ip; struct tcphdr *th; struct udphdr *uh; struct ether_vlan_header *eh; + union ixgbe_atr_hash_dword input = {.dword = 0}; + union ixgbe_atr_hash_dword common = {.dword = 0}; int ehdrlen, ip_hlen; - u16 etype, vlan_id, src_port, dst_port, flex_bytes; - u32 src_ipv4_addr, dst_ipv4_addr; - u8 l4type = 0, ipproto = 0; + u16 etype; eh = mtod(mp, struct ether_vlan_header *); - if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) + if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; - else + etype = eh->evl_proto; + } else { ehdrlen = ETHER_HDR_LEN; - etype = ntohs(eh->evl_proto); + etype = eh->evl_encap_proto; + } /* Only handling IPv4 */ - if (etype != ETHERTYPE_IP) + if (etype != htons(ETHERTYPE_IP)) return; ip = (struct ip *)(mp->m_data + ehdrlen); - ipproto = ip->ip_p; ip_hlen = ip->ip_hl << 2; - src_port = dst_port = 0; /* check if we're UDP or TCP */ - switch (ipproto) { + switch (ip->ip_p) { case IPPROTO_TCP: th = (struct tcphdr *)((caddr_t)ip + ip_hlen); - src_port = th->th_sport; - dst_port = th->th_dport; - l4type |= IXGBE_ATR_L4TYPE_TCP; + /* src and dst are inverted */ + common.port.dst ^= th->th_sport; + common.port.src ^= th->th_dport; + input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_TCPV4; break; case IPPROTO_UDP: uh = (struct udphdr *)((caddr_t)ip + ip_hlen); - src_port = uh->uh_sport; - dst_port = uh->uh_dport; - l4type |= IXGBE_ATR_L4TYPE_UDP; + /* src and dst are inverted */ + common.port.dst ^= uh->uh_sport; + common.port.src ^= uh->uh_dport; + input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_UDPV4; break; default: return; } - memset(&atr_input, 0, sizeof(union ixgbe_atr_input)); + input.formatted.vlan_id = htobe16(mp->m_pkthdr.ether_vtag); + if (mp->m_pkthdr.ether_vtag) + common.flex_bytes ^= htons(ETHERTYPE_VLAN); + else + common.flex_bytes ^= etype; + common.ip ^= ip->ip_src.s_addr ^ ip->ip_dst.s_addr; - vlan_id = htole16(mp->m_pkthdr.ether_vtag); - src_ipv4_addr = ip->ip_src.s_addr; - dst_ipv4_addr = ip->ip_dst.s_addr; - flex_bytes = etype; que = &adapter->queues[txr->me]; - - ixgbe_atr_set_vlan_id_82599(&atr_input, vlan_id); - ixgbe_atr_set_src_port_82599(&atr_input, dst_port); - ixgbe_atr_set_dst_port_82599(&atr_input, src_port); - ixgbe_atr_set_flex_byte_82599(&atr_input, flex_bytes); - ixgbe_atr_set_l4type_82599(&atr_input, l4type); - /* src and dst are inverted, think how the receiver sees them */ - ixgbe_atr_set_src_ipv4_82599(&atr_input, dst_ipv4_addr); - ixgbe_atr_set_dst_ipv4_82599(&atr_input, src_ipv4_addr); - - /* This assumes the Rx queue and Tx queue are bound to the same CPU */ + /* + ** This assumes the Rx queue and Tx + ** queue are bound to the same CPU + */ ixgbe_fdir_add_signature_filter_82599(&adapter->hw, - &atr_input, que->msix); + input, common, que->msix); } -#endif +#endif /* IXGBE_FDIR */ /********************************************************************** * @@ -3508,9 +3506,9 @@ ixgbe_allocate_receive_buffers(struct rx_ring *rxr) BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ - MJUM9BYTES, /* maxsize */ + MJUM16BYTES, /* maxsize */ 1, /* nsegments */ - MJUM9BYTES, /* maxsegsize */ + MJUM16BYTES, /* maxsegsize */ 0, /* flags */ NULL, /* lockfunc */ NULL, /* lockfuncarg */ @@ -3582,8 +3580,13 @@ ixgbe_setup_hw_rsc(struct rx_ring *rxr) */ if (adapter->rx_mbuf_sz == MCLBYTES) rscctrl |= IXGBE_RSCCTL_MAXDESC_16; - else /* using 4K clusters */ + else if (adapter->rx_mbuf_sz == MJUMPAGESIZE) rscctrl |= IXGBE_RSCCTL_MAXDESC_8; + else if (adapter->rx_mbuf_sz == MJUM9BYTES) + rscctrl |= IXGBE_RSCCTL_MAXDESC_4; + else /* Using 16K cluster */ + rscctrl |= IXGBE_RSCCTL_MAXDESC_1; + IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(rxr->me), rscctrl); /* Enable TCP header recognition */ @@ -3821,15 +3824,14 @@ ixgbe_initialize_receive_units(struct adapter *adapter) /* Set for Jumbo Frames? */ hlreg = IXGBE_READ_REG(hw, IXGBE_HLREG0); - if (ifp->if_mtu > ETHERMTU) { + if (ifp->if_mtu > ETHERMTU) hlreg |= IXGBE_HLREG0_JUMBOEN; - bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; - } else { + else hlreg &= ~IXGBE_HLREG0_JUMBOEN; - bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; - } IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg); + bufsz = adapter->rx_mbuf_sz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; + for (int i = 0; i < adapter->num_queues; i++, rxr++) { u64 rdba = rxr->rxdma.dma_paddr; @@ -4028,7 +4030,9 @@ ixgbe_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype if (tcp_lro_rx(&rxr->lro, m, 0) == 0) return; } + IXGBE_RX_UNLOCK(rxr); (*ifp->if_input)(ifp, m); + IXGBE_RX_LOCK(rxr); } static __inline void @@ -4289,8 +4293,11 @@ next_desc: i = 0; /* Now send to the stack or do LRO */ - if (sendmp != NULL) + if (sendmp != NULL) { + rxr->next_to_check = i; ixgbe_rx_input(rxr, ifp, sendmp, ptype); + i = rxr->next_to_check; + } /* Every 8 descriptors we go to refresh mbufs */ if (processed == 8) { @@ -4654,6 +4661,8 @@ static bool ixgbe_sfp_probe(struct adapter *adapter) device_printf(dev,"SFP+ module detected!\n"); /* We now have supported optics */ adapter->sfp_probe = FALSE; + /* Set the optics type so system reports correctly */ + ixgbe_setup_optics(adapter); result = TRUE; } out: @@ -4718,10 +4727,6 @@ ixgbe_handle_msf(void *context, int pending) hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiate); if (hw->mac.ops.setup_link) hw->mac.ops.setup_link(hw, autoneg, negotiate, TRUE); -#if 0 - ixgbe_check_link(&adapter->hw, &speed, &adapter->link_up, 0); - ixgbe_update_link_status(adapter); -#endif return; } @@ -4830,7 +4835,8 @@ ixgbe_update_stats_counters(struct adapter *adapter) bprc = IXGBE_READ_REG(hw, IXGBE_BPRC); adapter->stats.bprc += bprc; adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC); - adapter->stats.mprc -= bprc; + if (hw->mac.type == ixgbe_mac_82598EB) + adapter->stats.mprc -= bprc; adapter->stats.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64); adapter->stats.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127); @@ -4871,12 +4877,14 @@ ixgbe_update_stats_counters(struct adapter *adapter) adapter->stats.xec += IXGBE_READ_REG(hw, IXGBE_XEC); adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC); adapter->stats.fclast += IXGBE_READ_REG(hw, IXGBE_FCLAST); - adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); - adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC); - adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC); - adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); - adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); - + /* Only read FCOE on 82599 */ + if (hw->mac.type == ixgbe_mac_82599EB) { + adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); + adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC); + adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC); + adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); + adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); + } /* Fill out the OS statistics structure */ ifp->if_ipackets = adapter->stats.gprc; @@ -5012,18 +5020,6 @@ ixgbe_add_hw_stats(struct adapter *adapter) SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_defrag_failed", CTLFLAG_RD, &adapter->mbuf_defrag_failed, "m_defrag() failed"); -#if 0 - /* These counters are not updated by the software */ - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_header_failed", - CTLFLAG_RD, &adapter->mbuf_header_failed, - "???"); - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_packet_failed", - CTLFLAG_RD, &adapter->mbuf_packet_failed, - "???"); - SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "no_tx_map_avail", - CTLFLAG_RD, &adapter->no_tx_map_avail, - "???"); -#endif SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "no_tx_dma_setup", CTLFLAG_RD, &adapter->no_tx_dma_setup, "Driver tx dma failure in xmit"); @@ -5129,13 +5125,13 @@ ixgbe_add_hw_stats(struct adapter *adapter) CTLFLAG_RD, &stats->lxontxc, "Link XON Transmitted"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "link_xon_rcvd", - CTLFLAG_RD, &stats->lxontxc, + CTLFLAG_RD, &stats->lxonrxc, "Link XON Received"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "link_xoff_txd", CTLFLAG_RD, &stats->lxofftxc, "Link XOFF Transmitted"); SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "link_xoff_rcvd", - CTLFLAG_RD, &stats->lxofftxc, + CTLFLAG_RD, &stats->lxoffrxc, "Link XOFF Received"); /* Packet Reception Stats */ @@ -5271,13 +5267,17 @@ static int ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS) { int error; + int last = ixgbe_flow_control; struct adapter *adapter; error = sysctl_handle_int(oidp, &ixgbe_flow_control, 0, req); - if (error) return (error); + /* Don't bother if it's not changed */ + if (ixgbe_flow_control == last) + return (0); + adapter = (struct adapter *) arg1; switch (ixgbe_flow_control) { case ixgbe_fc_rx_pause: diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h index 1ad9b2d2..18072df3 100644 --- a/sys/dev/ixgbe/ixgbe.h +++ b/sys/dev/ixgbe/ixgbe.h @@ -385,6 +385,7 @@ struct adapter { int advertise; /* link speeds */ bool link_active; u16 max_frame_size; + u16 num_segs; u32 link_speed; bool link_up; u32 linkvec; diff --git a/sys/dev/ixgbe/ixgbe_82599.c b/sys/dev/ixgbe/ixgbe_82599.c index 8660bfb1..0c27e23d 100644 --- a/sys/dev/ixgbe/ixgbe_82599.c +++ b/sys/dev/ixgbe/ixgbe_82599.c @@ -67,13 +67,13 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw); s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val); s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val); s32 ixgbe_start_hw_rev_1_82599(struct ixgbe_hw *hw); -void ixgbe_enable_relaxed_ordering_82599(struct ixgbe_hw *hw); s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw); s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw); u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw); s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval); -s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps); static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); +bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw); + void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) { @@ -101,7 +101,8 @@ void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) } else { if ((ixgbe_get_media_type(hw) == ixgbe_media_type_backplane) && (hw->phy.smart_speed == ixgbe_smart_speed_auto || - hw->phy.smart_speed == ixgbe_smart_speed_on)) { + hw->phy.smart_speed == ixgbe_smart_speed_on) && + !ixgbe_verify_lesm_fw_enabled_82599(hw)) { mac->ops.setup_link = &ixgbe_setup_mac_link_smartspeed; } else { mac->ops.setup_link = &ixgbe_setup_mac_link_82599; @@ -253,7 +254,7 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) /* MAC */ mac->ops.reset_hw = &ixgbe_reset_hw_82599; - mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_82599; + mac->ops.enable_relaxed_ordering = &ixgbe_enable_relaxed_ordering_gen2; mac->ops.get_media_type = &ixgbe_get_media_type_82599; mac->ops.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599; @@ -263,7 +264,7 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) mac->ops.start_hw = &ixgbe_start_hw_rev_1_82599; mac->ops.get_san_mac_addr = &ixgbe_get_san_mac_addr_generic; mac->ops.set_san_mac_addr = &ixgbe_set_san_mac_addr_generic; - mac->ops.get_device_caps = &ixgbe_get_device_caps_82599; + mac->ops.get_device_caps = &ixgbe_get_device_caps_generic; mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic; mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic; @@ -1375,7 +1376,7 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) * @stream: input bitstream to compute the hash on * @key: 32-bit hash key **/ -u16 ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *atr_input, +u32 ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *atr_input, u32 key) { /* @@ -1419,54 +1420,45 @@ u16 ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *atr_input, * */ __be32 common_hash_dword = 0; - u32 hi_hash_dword, lo_hash_dword; - u16 hash_result = 0; - u8 i; + u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan; + u32 hash_result = 0; + u8 i; - /* - * the hi_hash_dword starts with vlan_id, the lo_hash_dword starts - * and ends with it, the vlan at the end is added via the word swapped - * xor with the hi_hash_dword a few lines down. - */ - hi_hash_dword = IXGBE_NTOHL(atr_input->dword_stream[0]) & 0x0000FFFF; - lo_hash_dword = hi_hash_dword; + /* record the flow_vm_vlan bits as they are a key part to the hash */ + flow_vm_vlan = IXGBE_NTOHL(atr_input->dword_stream[0]); /* generate common hash dword */ - for (i = 1; i < 11; i++) - common_hash_dword ^= (u32)atr_input->dword_stream[i]; - hi_hash_dword ^= IXGBE_NTOHL(common_hash_dword); + for (i = 10; i; i -= 2) + common_hash_dword ^= atr_input->dword_stream[i] ^ + atr_input->dword_stream[i - 1]; - /* low dword is word swapped version of common with vlan added */ - lo_hash_dword ^= (hi_hash_dword >> 16) | (hi_hash_dword << 16); + hi_hash_dword = IXGBE_NTOHL(common_hash_dword); - /* hi dword is common dword with l4type and vm_pool shifted */ - hi_hash_dword ^= IXGBE_NTOHL(atr_input->dword_stream[10]) << 16; + /* low dword is word swapped version of common */ + lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16); + + /* apply flow ID/VM pool/VLAN ID bits to hash words */ + hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16); + + /* Process bits 0 and 16 */ + if (key & 0x0001) hash_result ^= lo_hash_dword; + if (key & 0x00010000) hash_result ^= hi_hash_dword; /* - * Process all 32 bits of the 2 keys 2 bits at a time - * - * Bit flip vlan from hash result if hash key has bit 0 set, the - * reason for doing this is because the hash generation shouldn't - * start until bit 1 in the stream so we need to cancel out a vlan - * if it was added starting at bit 0. + * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to + * delay this because bit 0 of the stream should not be processed + * so we do not add the vlan until after bit 0 was processed */ - if (key & 0x0001) { - hash_result ^= IXGBE_NTOHL(atr_input->dword_stream[0]) & - 0x0FFFF; - hash_result ^= lo_hash_dword; - } - if (key & 0x00010000) - hash_result ^= hi_hash_dword; - - /* process the remaining bits in the key */ - for (i = 1; i < 16; i++) { - if (key & (0x0001 << i)) - hash_result ^= lo_hash_dword >> i; - if (key & (0x00010000 << i)) - hash_result ^= hi_hash_dword >> i; + lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16); + + + /* process the remaining 30 bits in the key 2 bits at a time */ + for (i = 15; i; i-- ) { + if (key & (0x0001 << i)) hash_result ^= lo_hash_dword >> i; + if (key & (0x00010000 << i)) hash_result ^= hi_hash_dword >> i; } - return hash_result; + return hash_result & IXGBE_ATR_HASH_MASK; } /* @@ -1479,30 +1471,18 @@ u16 ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *atr_input, #define IXGBE_COMPUTE_SIG_HASH_ITERATION(_n) \ do { \ u32 n = (_n); \ - if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << n)) { \ - if (n == 0) \ - common_hash ^= \ - IXGBE_NTOHL(atr_input->dword_stream[0]) & \ - 0x0000FFFF; \ + if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << n)) \ common_hash ^= lo_hash_dword >> n; \ - } else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) { \ - if (n == 0) \ - bucket_hash ^= \ - IXGBE_NTOHL(atr_input->dword_stream[0]) & \ - 0x0000FFFF; \ + else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << n)) \ bucket_hash ^= lo_hash_dword >> n; \ - } else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << n)) { \ - if (n == 0) \ - sig_hash ^= IXGBE_NTOHL(atr_input->dword_stream[0]) & \ - 0x0000FFFF; \ - sig_hash ^= lo_hash_dword >> n; \ - } \ - if (IXGBE_ATR_COMMON_HASH_KEY & (0x010000 << n)) \ + else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << n)) \ + sig_hash ^= lo_hash_dword << (16 - n); \ + if (IXGBE_ATR_COMMON_HASH_KEY & (0x01 << (n + 16))) \ common_hash ^= hi_hash_dword >> n; \ - else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x010000 << n)) \ + else if (IXGBE_ATR_BUCKET_HASH_KEY & (0x01 << (n + 16))) \ bucket_hash ^= hi_hash_dword >> n; \ - else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x010000 << n)) \ - sig_hash ^= hi_hash_dword >> n; \ + else if (IXGBE_ATR_SIGNATURE_HASH_KEY & (0x01 << (n + 16))) \ + sig_hash ^= hi_hash_dword << (16 - n); \ } while (0); /** @@ -1515,47 +1495,35 @@ do { \ * defines, and computing two keys at once since the hashed dword stream * will be the same for both keys. **/ -static u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_input *atr_input) +static u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_hash_dword input, + union ixgbe_atr_hash_dword common) { - u32 hi_hash_dword, lo_hash_dword; - u16 sig_hash = 0, bucket_hash = 0, common_hash = 0; + u32 hi_hash_dword, lo_hash_dword, flow_vm_vlan; + u32 sig_hash = 0, bucket_hash = 0, common_hash = 0; - /* - * the hi_hash_dword starts with vlan_id, the lo_hash_dword starts - * and ends with it, the vlan at the end is added via the word swapped - * xor with the hi_hash_dword a few lines down. The part masked off - * is the part of the hash reserved to 0. - */ - hi_hash_dword = IXGBE_NTOHL(atr_input->dword_stream[0]) & 0x0000FFFF; - lo_hash_dword = hi_hash_dword; + /* record the flow_vm_vlan bits as they are a key part to the hash */ + flow_vm_vlan = IXGBE_NTOHL(input.dword); /* generate common hash dword */ - hi_hash_dword ^= IXGBE_NTOHL(atr_input->dword_stream[1] ^ - atr_input->dword_stream[2] ^ - atr_input->dword_stream[3] ^ - atr_input->dword_stream[4] ^ - atr_input->dword_stream[5] ^ - atr_input->dword_stream[6] ^ - atr_input->dword_stream[7] ^ - atr_input->dword_stream[8] ^ - atr_input->dword_stream[9] ^ - atr_input->dword_stream[10]); + hi_hash_dword = IXGBE_NTOHL(common.dword); /* low dword is word swapped version of common */ - lo_hash_dword ^= (hi_hash_dword >> 16) | (hi_hash_dword << 16); + lo_hash_dword = (hi_hash_dword >> 16) | (hi_hash_dword << 16); + + /* apply flow ID/VM pool/VLAN ID bits to hash words */ + hi_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan >> 16); - /* hi dword is common dword with l4type and vm_pool added */ - hi_hash_dword ^= IXGBE_NTOHL(atr_input->dword_stream[10]) << 16; + /* Process bits 0 and 16 */ + IXGBE_COMPUTE_SIG_HASH_ITERATION(0); /* - * Process all 32 bits of the 2 keys 2 bits at a time - * - * Bit flip vlan from hash result if hash key has bit 0 set, the - * reason for doing this is because the hash generation shouldn't - * start until bit 1 in the stream so we need to cancel out a vlan - * if it was added starting at bit 0. + * apply flow ID/VM pool/VLAN ID bits to lo hash dword, we had to + * delay this because bit 0 of the stream should not be processed + * so we do not add the vlan until after bit 0 was processed */ - IXGBE_COMPUTE_SIG_HASH_ITERATION(0); + lo_hash_dword ^= flow_vm_vlan ^ (flow_vm_vlan << 16); + + /* Process remaining 30 bit of the key */ IXGBE_COMPUTE_SIG_HASH_ITERATION(1); IXGBE_COMPUTE_SIG_HASH_ITERATION(2); IXGBE_COMPUTE_SIG_HASH_ITERATION(3); @@ -1573,339 +1541,14 @@ static u32 ixgbe_atr_compute_sig_hash_82599(union ixgbe_atr_input *atr_input) IXGBE_COMPUTE_SIG_HASH_ITERATION(15); /* combine common_hash result with signature and bucket hashes */ - sig_hash ^= common_hash; bucket_hash ^= common_hash; + bucket_hash &= IXGBE_ATR_HASH_MASK; - /* return completed signature hash */ - return ((u32)sig_hash << 16) | (bucket_hash & IXGBE_ATR_HASH_MASK); -} - -/** - * ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream - * @input: input stream to modify - * @vlan: the VLAN id to load - **/ -s32 ixgbe_atr_set_vlan_id_82599(union ixgbe_atr_input *input, __be16 vlan) -{ - DEBUGFUNC("ixgbe_atr_set_vlan_id_82599"); - - input->formatted.vlan_id = vlan; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address - * @input: input stream to modify - * @src_addr: the IP address to load - **/ -s32 ixgbe_atr_set_src_ipv4_82599(union ixgbe_atr_input *input, __be32 src_addr) -{ - DEBUGFUNC("ixgbe_atr_set_src_ipv4_82599"); - - input->formatted.src_ip[0] = src_addr; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address - * @input: input stream to modify - * @dst_addr: the IP address to load - **/ -s32 ixgbe_atr_set_dst_ipv4_82599(union ixgbe_atr_input *input, __be32 dst_addr) -{ - DEBUGFUNC("ixgbe_atr_set_dst_ipv4_82599"); - - input->formatted.dst_ip[0] = dst_addr; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_set_src_ipv6_82599 - Sets the source IPv6 address - * @input: input stream to modify - * @src_addr_0: the first 4 bytes of the IP address to load - * @src_addr_1: the second 4 bytes of the IP address to load - * @src_addr_2: the third 4 bytes of the IP address to load - * @src_addr_3: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_set_src_ipv6_82599(union ixgbe_atr_input *input, - __be32 src_addr_0, __be32 src_addr_1, - __be32 src_addr_2, __be32 src_addr_3) -{ - DEBUGFUNC("ixgbe_atr_set_src_ipv6_82599"); - - input->formatted.src_ip[0] = src_addr_0; - input->formatted.src_ip[1] = src_addr_1; - input->formatted.src_ip[2] = src_addr_2; - input->formatted.src_ip[3] = src_addr_3; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_set_dst_ipv6_82599 - Sets the destination IPv6 address - * @input: input stream to modify - * @dst_addr_0: the first 4 bytes of the IP address to load - * @dst_addr_1: the second 4 bytes of the IP address to load - * @dst_addr_2: the third 4 bytes of the IP address to load - * @dst_addr_3: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_set_dst_ipv6_82599(union ixgbe_atr_input *input, - __be32 dst_addr_0, __be32 dst_addr_1, - __be32 dst_addr_2, __be32 dst_addr_3) -{ - DEBUGFUNC("ixgbe_atr_set_dst_ipv6_82599"); - - input->formatted.dst_ip[0] = dst_addr_0; - input->formatted.dst_ip[1] = dst_addr_1; - input->formatted.dst_ip[2] = dst_addr_2; - input->formatted.dst_ip[3] = dst_addr_3; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_set_src_port_82599 - Sets the source port - * @input: input stream to modify - * @src_port: the source port to load - **/ -s32 ixgbe_atr_set_src_port_82599(union ixgbe_atr_input *input, __be16 src_port) -{ - DEBUGFUNC("ixgbe_atr_set_src_port_82599"); - - input->formatted.src_port = src_port; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_set_dst_port_82599 - Sets the destination port - * @input: input stream to modify - * @dst_port: the destination port to load - **/ -s32 ixgbe_atr_set_dst_port_82599(union ixgbe_atr_input *input, __be16 dst_port) -{ - DEBUGFUNC("ixgbe_atr_set_dst_port_82599"); - - input->formatted.dst_port = dst_port; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_set_flex_byte_82599 - Sets the flexible bytes - * @input: input stream to modify - * @flex_bytes: the flexible bytes to load - **/ -s32 ixgbe_atr_set_flex_byte_82599(union ixgbe_atr_input *input, __be16 flex_bytes) -{ - DEBUGFUNC("ixgbe_atr_set_flex_byte_82599"); - - input->formatted.flex_bytes = flex_bytes; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_set_vm_pool_82599 - Sets the Virtual Machine pool - * @input: input stream to modify - * @vm_pool: the Virtual Machine pool to load - **/ -s32 ixgbe_atr_set_vm_pool_82599(union ixgbe_atr_input *input, u8 vm_pool) -{ - DEBUGFUNC("ixgbe_atr_set_vm_pool_82599"); - - input->formatted.vm_pool = vm_pool; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type - * @input: input stream to modify - * @l4type: the layer 4 type value to load - * - * This call is deprecated and should be replaced with a direct access to - * input->formatted.flow_type. - **/ -s32 ixgbe_atr_set_l4type_82599(union ixgbe_atr_input *input, u8 l4type) -{ - DEBUGFUNC("ixgbe_atr_set_l4type_82599"); - - input->formatted.flow_type = l4type; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_vlan_id_82599 - Gets the VLAN id from the ATR input stream - * @input: input stream to search - * @vlan: the VLAN id to load - **/ -s32 ixgbe_atr_get_vlan_id_82599(union ixgbe_atr_input *input, __be16 *vlan) -{ - DEBUGFUNC("ixgbe_atr_get_vlan_id_82599"); - - *vlan = input->formatted.vlan_id; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_src_ipv4_82599 - Gets the source IPv4 address - * @input: input stream to search - * @src_addr: the IP address to load - **/ -s32 ixgbe_atr_get_src_ipv4_82599(union ixgbe_atr_input *input, __be32 *src_addr) -{ - DEBUGFUNC("ixgbe_atr_get_src_ipv4_82599"); - - *src_addr = input->formatted.src_ip[0]; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_dst_ipv4_82599 - Gets the destination IPv4 address - * @input: input stream to search - * @dst_addr: the IP address to load - **/ -s32 ixgbe_atr_get_dst_ipv4_82599(union ixgbe_atr_input *input, __be32 *dst_addr) -{ - DEBUGFUNC("ixgbe_atr_get_dst_ipv4_82599"); - - *dst_addr = input->formatted.dst_ip[0]; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_src_ipv6_82599 - Gets the source IPv6 address - * @input: input stream to search - * @src_addr_0: the first 4 bytes of the IP address to load - * @src_addr_1: the second 4 bytes of the IP address to load - * @src_addr_2: the third 4 bytes of the IP address to load - * @src_addr_3: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_get_src_ipv6_82599(union ixgbe_atr_input *input, - __be32 *src_addr_0, __be32 *src_addr_1, - __be32 *src_addr_2, __be32 *src_addr_3) -{ - DEBUGFUNC("ixgbe_atr_get_src_ipv6_82599"); - - *src_addr_0 = input->formatted.src_ip[0]; - *src_addr_1 = input->formatted.src_ip[1]; - *src_addr_2 = input->formatted.src_ip[2]; - *src_addr_3 = input->formatted.src_ip[3]; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_dst_ipv6_82599 - Gets the destination IPv6 address - * @input: input stream to search - * @dst_addr_0: the first 4 bytes of the IP address to load - * @dst_addr_1: the second 4 bytes of the IP address to load - * @dst_addr_2: the third 4 bytes of the IP address to load - * @dst_addr_3: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_get_dst_ipv6_82599(union ixgbe_atr_input *input, - __be32 *dst_addr_0, __be32 *dst_addr_1, - __be32 *dst_addr_2, __be32 *dst_addr_3) -{ - DEBUGFUNC("ixgbe_atr_get_dst_ipv6_82599"); - - *dst_addr_0 = input->formatted.dst_ip[0]; - *dst_addr_1 = input->formatted.dst_ip[1]; - *dst_addr_2 = input->formatted.dst_ip[2]; - *dst_addr_3 = input->formatted.dst_ip[3]; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_src_port_82599 - Gets the source port - * @input: input stream to modify - * @src_port: the source port to load - * - * Even though the input is given in big-endian, the FDIRPORT registers - * expect the ports to be programmed in little-endian. Hence the need to swap - * endianness when retrieving the data. This can be confusing since the - * internal hash engine expects it to be big-endian. - **/ -s32 ixgbe_atr_get_src_port_82599(union ixgbe_atr_input *input, __be16 *src_port) -{ - DEBUGFUNC("ixgbe_atr_get_src_port_82599"); - - *src_port = input->formatted.src_port; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_dst_port_82599 - Gets the destination port - * @input: input stream to modify - * @dst_port: the destination port to load - * - * Even though the input is given in big-endian, the FDIRPORT registers - * expect the ports to be programmed in little-endian. Hence the need to swap - * endianness when retrieving the data. This can be confusing since the - * internal hash engine expects it to be big-endian. - **/ -s32 ixgbe_atr_get_dst_port_82599(union ixgbe_atr_input *input, __be16 *dst_port) -{ - DEBUGFUNC("ixgbe_atr_get_dst_port_82599"); - - *dst_port = input->formatted.dst_port; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_flex_byte_82599 - Gets the flexible bytes - * @input: input stream to modify - * @flex_bytes: the flexible bytes to load - **/ -s32 ixgbe_atr_get_flex_byte_82599(union ixgbe_atr_input *input, __be16 *flex_bytes) -{ - DEBUGFUNC("ixgbe_atr_get_flex_byte_82599"); - - *flex_bytes = input->formatted.flex_bytes; - - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_vm_pool_82599 - Gets the Virtual Machine pool - * @input: input stream to modify - * @vm_pool: the Virtual Machine pool to load - **/ -s32 ixgbe_atr_get_vm_pool_82599(union ixgbe_atr_input *input, u8 *vm_pool) -{ - DEBUGFUNC("ixgbe_atr_get_vm_pool_82599"); - - *vm_pool = input->formatted.vm_pool; + sig_hash ^= common_hash << 16; + sig_hash &= IXGBE_ATR_HASH_MASK << 16; - return IXGBE_SUCCESS; -} - -/** - * ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type - * @input: input stream to modify - * @l4type: the layer 4 type value to load - * - * This call is deprecated and should be replaced with a direct access to - * input->formatted.flow_type. - **/ -s32 ixgbe_atr_get_l4type_82599(union ixgbe_atr_input *input, u8 *l4type) -{ - DEBUGFUNC("ixgbe_atr_get_l4type__82599"); - - *l4type = input->formatted.flow_type; - - return IXGBE_SUCCESS; + /* return completed signature hash */ + return sig_hash ^ bucket_hash; } /** @@ -1915,7 +1558,8 @@ s32 ixgbe_atr_get_l4type_82599(union ixgbe_atr_input *input, u8 *l4type) * @queue: queue index to direct traffic to **/ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, - union ixgbe_atr_input *input, + union ixgbe_atr_hash_dword input, + union ixgbe_atr_hash_dword common, u8 queue) { u64 fdirhashcmd; @@ -1927,7 +1571,7 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, * Get the flow_type in order to program FDIRCMD properly * lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6 */ - switch (input->formatted.flow_type) { + switch (input.formatted.flow_type) { case IXGBE_ATR_FLOW_TYPE_TCPV4: case IXGBE_ATR_FLOW_TYPE_UDPV4: case IXGBE_ATR_FLOW_TYPE_SCTPV4: @@ -1943,15 +1587,15 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, /* configure FDIRCMD register */ fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE | IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN; - fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT; - fdircmd |= ((u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT); + fdircmd |= input.formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT; + fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; /* * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits * is for FDIRCMD. Then do a 64-bit register write from FDIRHASH. */ - fdirhashcmd = ((u64)fdircmd << 32) | - ixgbe_atr_compute_sig_hash_82599(input); + fdirhashcmd = (u64)fdircmd << 32; + fdirhashcmd |= ixgbe_atr_compute_sig_hash_82599(input, common); IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd); DEBUGOUT2("Tx Queue=%x hash=%x\n", queue, (u32)fdirhashcmd); @@ -2013,8 +1657,8 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, struct ixgbe_atr_input_masks *input_masks, u16 soft_id, u8 queue) { - u32 fdircmd = 0; u32 fdirhash; + u32 fdircmd; u32 fdirport, fdirtcpm; u32 fdirvlan; /* start with VLAN, flex bytes, VM pool, and IPv6 destination masked */ @@ -2127,21 +1771,18 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, /* record the source address (big-endian) */ IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRIPSA, input->formatted.src_ip[0]); - /* configure FDIRHASH register */ - fdirhash = ixgbe_atr_compute_sig_hash_82599(input); + /* configure FDIRCMD register */ + fdircmd = IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE | + IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN; + fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT; + fdircmd |= (u32)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; /* we only want the bucket hash so drop the upper 16 bits */ - fdirhash &= IXGBE_ATR_HASH_MASK; + fdirhash = ixgbe_atr_compute_hash_82599(input, + IXGBE_ATR_BUCKET_HASH_KEY); fdirhash |= soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT; - IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); - - fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW; - fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE; - fdircmd |= IXGBE_FDIRCMD_LAST; - fdircmd |= IXGBE_FDIRCMD_QUEUE_EN; - fdircmd |= input->formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT; - fdircmd |= queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT; + IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash); IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd); return IXGBE_SUCCESS; @@ -2430,23 +2071,6 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval) return IXGBE_SUCCESS; } -/** - * ixgbe_get_device_caps_82599 - Get additional device capabilities - * @hw: pointer to hardware structure - * @device_caps: the EEPROM word with the extra device capabilities - * - * This function will read the EEPROM location for the device capabilities, - * and return the word through device_caps. - **/ -s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps) -{ - DEBUGFUNC("ixgbe_get_device_caps_82599"); - - hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps); - - return IXGBE_SUCCESS; -} - /** * ixgbe_verify_fw_version_82599 - verify fw version for 82599 * @hw: pointer to hardware structure @@ -2496,30 +2120,49 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) fw_version_out: return status; } + /** - * ixgbe_enable_relaxed_ordering_82599 - Enable relaxed ordering + * ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state. * @hw: pointer to hardware structure * + * Returns TRUE if the LESM FW module is present and enabled. Otherwise + * returns FALSE. Smart Speed must be disabled if LESM FW module is enabled. **/ -void ixgbe_enable_relaxed_ordering_82599(struct ixgbe_hw *hw) +bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw) { - u32 regval; - u32 i; + bool lesm_enabled = FALSE; + u16 fw_offset, fw_lesm_param_offset, fw_lesm_state; + s32 status; - DEBUGFUNC("ixgbe_enable_relaxed_ordering_82599"); + DEBUGFUNC("ixgbe_verify_lesm_fw_enabled_82599"); - /* Enable relaxed ordering */ - for (i = 0; i < hw->mac.max_tx_queues; i++) { - regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); - regval |= IXGBE_DCA_TXCTRL_TX_WB_RO_EN; - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); - } + /* get the offset to the Firmware Module block */ + status = hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset); - for (i = 0; i < hw->mac.max_rx_queues; i++) { - regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); - regval |= (IXGBE_DCA_RXCTRL_DESC_WRO_EN | - IXGBE_DCA_RXCTRL_DESC_HSRO_EN); - IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); - } + if ((status != IXGBE_SUCCESS) || + (fw_offset == 0) || (fw_offset == 0xFFFF)) + goto out; + + /* get the offset to the LESM Parameters block */ + status = hw->eeprom.ops.read(hw, (fw_offset + + IXGBE_FW_LESM_PARAMETERS_PTR), + &fw_lesm_param_offset); + if ((status != IXGBE_SUCCESS) || + (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF)) + goto out; + + /* get the lesm state word */ + status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset + + IXGBE_FW_LESM_STATE_1), + &fw_lesm_state); + + if ((status == IXGBE_SUCCESS) && + (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED)) + lesm_enabled = TRUE; + +out: + return lesm_enabled; } + + diff --git a/sys/dev/ixgbe/ixgbe_api.h b/sys/dev/ixgbe/ixgbe_api.h index a27dfe6e..6460f2a2 100644 --- a/sys/dev/ixgbe/ixgbe_api.h +++ b/sys/dev/ixgbe/ixgbe_api.h @@ -124,43 +124,15 @@ s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc); s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc); s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, - union ixgbe_atr_input *input, + union ixgbe_atr_hash_dword input, + union ixgbe_atr_hash_dword common, u8 queue); s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, union ixgbe_atr_input *input, struct ixgbe_atr_input_masks *masks, u16 soft_id, u8 queue); -u16 ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *input, u32 key); -s32 ixgbe_atr_set_vlan_id_82599(union ixgbe_atr_input *input, __be16 vlan_id); -s32 ixgbe_atr_set_src_ipv4_82599(union ixgbe_atr_input *input, __be32 src_addr); -s32 ixgbe_atr_set_dst_ipv4_82599(union ixgbe_atr_input *input, __be32 dst_addr); -s32 ixgbe_atr_set_src_ipv6_82599(union ixgbe_atr_input *input, __be32 src_addr_0, - __be32 src_addr_1, __be32 src_addr_2, - __be32 src_addr_3); -s32 ixgbe_atr_set_dst_ipv6_82599(union ixgbe_atr_input *input, __be32 dst_addr_0, - __be32 dst_addr_1, __be32 dst_addr_2, - __be32 dst_addr_3); -s32 ixgbe_atr_set_src_port_82599(union ixgbe_atr_input *input, __be16 src_port); -s32 ixgbe_atr_set_dst_port_82599(union ixgbe_atr_input *input, __be16 dst_port); -s32 ixgbe_atr_set_flex_byte_82599(union ixgbe_atr_input *input, __be16 flex_byte); -s32 ixgbe_atr_set_vm_pool_82599(union ixgbe_atr_input *input, u8 vm_pool); -s32 ixgbe_atr_set_l4type_82599(union ixgbe_atr_input *input, u8 l4type); -s32 ixgbe_atr_get_vlan_id_82599(union ixgbe_atr_input *input, __be16 *vlan_id); -s32 ixgbe_atr_get_src_ipv4_82599(union ixgbe_atr_input *input, __be32 *src_addr); -s32 ixgbe_atr_get_dst_ipv4_82599(union ixgbe_atr_input *input, __be32 *dst_addr); -s32 ixgbe_atr_get_src_ipv6_82599(union ixgbe_atr_input *input, __be32 *src_addr_0, - __be32 *src_addr_1, __be32 *src_addr_2, - __be32 *src_addr_3); -s32 ixgbe_atr_get_dst_ipv6_82599(union ixgbe_atr_input *input, __be32 *dst_addr_0, - __be32 *dst_addr_1, __be32 *dst_addr_2, - __be32 *dst_addr_3); -s32 ixgbe_atr_get_src_port_82599(union ixgbe_atr_input *input, __be16 *src_port); -s32 ixgbe_atr_get_dst_port_82599(union ixgbe_atr_input *input, __be16 *dst_port); -s32 ixgbe_atr_get_flex_byte_82599(union ixgbe_atr_input *input, - __be16 *flex_byte); -s32 ixgbe_atr_get_vm_pool_82599(union ixgbe_atr_input *input, u8 *vm_pool); -s32 ixgbe_atr_get_l4type_82599(union ixgbe_atr_input *input, u8 *l4type); +u32 ixgbe_atr_compute_hash_82599(union ixgbe_atr_input *input, u32 key); s32 ixgbe_read_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data); s32 ixgbe_write_i2c_byte(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, diff --git a/sys/dev/ixgbe/ixgbe_common.c b/sys/dev/ixgbe/ixgbe_common.c index a5b972c9..da7d95c1 100644 --- a/sys/dev/ixgbe/ixgbe_common.c +++ b/sys/dev/ixgbe/ixgbe_common.c @@ -183,6 +183,7 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) * of 10 GbE devices. * Devices in the second generation: * 82599 + * X540 **/ s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) { @@ -1689,6 +1690,9 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) hw->mac.addr[4], hw->mac.addr[5]); hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); + + /* clear VMDq pool/queue selection for RAR 0 */ + hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL); } hw->addr_ctrl.overflow_promisc = 0; @@ -2524,7 +2528,7 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) - goto out; + goto check_device_status; usec_delay(100); } @@ -2532,12 +2536,10 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) status = IXGBE_ERR_MASTER_REQUESTS_PENDING; /* - * The GIO Master Disable bit didn't clear. There are multiple reasons - * for this listed in the datasheet 5.2.5.3.2 Master Disable, and they - * all require a double reset to recover from. Before proceeding, we - * first wait a little more to try to ensure that, at a minimum, the - * PCIe block has no transactions pending. + * Before proceeding, make sure that the PCIe block does not have + * transactions pending. */ +check_device_status: for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { if (!(IXGBE_READ_PCIE_WORD(hw, IXGBE_PCI_DEVICE_STATUS) & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) @@ -2547,6 +2549,8 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT) DEBUGOUT("PCIe transaction pending bit also did not clear.\n"); + else + goto out; /* * Two consecutive resets are required via CTRL.RST per datasheet @@ -3481,3 +3485,48 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf) pfvfspoof &= ~(1 << vf_target_shift); IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof); } + +/** + * ixgbe_get_device_caps_generic - Get additional device capabilities + * @hw: pointer to hardware structure + * @device_caps: the EEPROM word with the extra device capabilities + * + * This function will read the EEPROM location for the device capabilities, + * and return the word through device_caps. + **/ +s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps) +{ + DEBUGFUNC("ixgbe_get_device_caps_generic"); + + hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps); + + return IXGBE_SUCCESS; +} + +/** + * ixgbe_enable_relaxed_ordering_gen2 - Enable relaxed ordering + * @hw: pointer to hardware structure + * + **/ +void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw) +{ + u32 regval; + u32 i; + + DEBUGFUNC("ixgbe_enable_relaxed_ordering_gen2"); + + /* Enable relaxed ordering */ + for (i = 0; i < hw->mac.max_tx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); + regval |= IXGBE_DCA_TXCTRL_TX_WB_RO_EN; + IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); + } + + for (i = 0; i < hw->mac.max_rx_queues; i++) { + regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); + regval |= (IXGBE_DCA_RXCTRL_DESC_WRO_EN | + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); + } + +} diff --git a/sys/dev/ixgbe/ixgbe_common.h b/sys/dev/ixgbe/ixgbe_common.h index bd58b525..d37f521c 100644 --- a/sys/dev/ixgbe/ixgbe_common.h +++ b/sys/dev/ixgbe/ixgbe_common.h @@ -119,4 +119,6 @@ s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, s32 ixgbe_get_fcoe_boot_status_generic(struct ixgbe_hw *hw, u16 *bs); void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf); void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf); +s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps); +void ixgbe_enable_relaxed_ordering_gen2(struct ixgbe_hw *hw); #endif /* IXGBE_COMMON */ diff --git a/sys/dev/ixgbe/ixgbe_mbx.c b/sys/dev/ixgbe/ixgbe_mbx.c index fbc951d5..0e08ea56 100644 --- a/sys/dev/ixgbe/ixgbe_mbx.c +++ b/sys/dev/ixgbe/ixgbe_mbx.c @@ -592,8 +592,14 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) DEBUGFUNC("ixgbe_check_for_rst_pf"); - if (hw->mac.type == ixgbe_mac_82599EB) + switch (hw->mac.type) { + case ixgbe_mac_82599EB: vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); + break; + default: + goto out; + break; + } if (vflre & (1 << vf_shift)) { ret_val = IXGBE_SUCCESS; @@ -601,6 +607,7 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) hw->mbx.stats.rsts++; } +out: return ret_val; } diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h index 36810017..eaa86057 100644 --- a/sys/dev/ixgbe/ixgbe_type.h +++ b/sys/dev/ixgbe/ixgbe_type.h @@ -527,6 +527,11 @@ #define IXGBE_RTTDTECC_NO_BCN 0x00000100 #define IXGBE_RTTBCNRC 0x04984 +#define IXGBE_RTTBCNRC_RS_ENA 0x80000000 +#define IXGBE_RTTBCNRC_RF_DEC_MASK 0x00003FFF +#define IXGBE_RTTBCNRC_RF_INT_SHIFT 14 +#define IXGBE_RTTBCNRC_RF_INT_MASK \ + (IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT) /* BCN (for DCB) Registers */ #define IXGBE_RTTBCNRM 0x04980 @@ -984,8 +989,8 @@ #define IXGBE_MSCA_OP_CODE_SHIFT 26 /* OP CODE shift */ #define IXGBE_MSCA_ADDR_CYCLE 0x00000000 /* OP CODE 00 (addr cycle) */ #define IXGBE_MSCA_WRITE 0x04000000 /* OP CODE 01 (write) */ -#define IXGBE_MSCA_READ 0x08000000 /* OP CODE 10 (read) */ -#define IXGBE_MSCA_READ_AUTOINC 0x0C000000 /* OP CODE 11 (read, auto inc)*/ +#define IXGBE_MSCA_READ 0x0C000000 /* OP CODE 11 (read) */ +#define IXGBE_MSCA_READ_AUTOINC 0x08000000 /* OP CODE 10 (read, auto inc)*/ #define IXGBE_MSCA_ST_CODE_MASK 0x30000000 /* ST Code mask */ #define IXGBE_MSCA_ST_CODE_SHIFT 28 /* ST Code shift */ #define IXGBE_MSCA_NEW_PROTOCOL 0x00000000 /* ST CODE 00 (new protocol) */ @@ -1685,6 +1690,9 @@ #define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET 0x3 #define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1 #define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS 0x2 +#define IXGBE_FW_LESM_PARAMETERS_PTR 0x2 +#define IXGBE_FW_LESM_STATE_1 0x1 +#define IXGBE_FW_LESM_STATE_ENABLED 0x8000 /* LESM Enable bit */ #define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR 0x4 #define IXGBE_FW_PATCH_VERSION_4 0x7 #define IXGBE_FCOE_IBA_CAPS_BLK_PTR 0x33 /* iSCSI/FCOE block */ @@ -2302,32 +2310,50 @@ enum ixgbe_atr_flow_type { /* Flow Director ATR input struct. */ union ixgbe_atr_input { - /* Byte layout in order, all values with MSB first: + /* + * Byte layout in order, all values with MSB first: * - * rsvd0 - 2 bytes - space reserved must be 0. + * vm_pool - 1 byte + * flow_type - 1 byte * vlan_id - 2 bytes * src_ip - 16 bytes * dst_ip - 16 bytes * src_port - 2 bytes * dst_port - 2 bytes * flex_bytes - 2 bytes - * vm_pool - 1 byte - * flow_type - 1 byte + * rsvd0 - 2 bytes - space reserved must be 0. */ struct { - __be16 rsvd0; + u8 vm_pool; + u8 flow_type; __be16 vlan_id; __be32 dst_ip[4]; __be32 src_ip[4]; __be16 src_port; __be16 dst_port; __be16 flex_bytes; - u8 vm_pool; - u8 flow_type; + __be16 rsvd0; } formatted; __be32 dword_stream[11]; }; +/* Flow Director compressed ATR hash input struct */ +union ixgbe_atr_hash_dword { + struct { + u8 vm_pool; + u8 flow_type; + __be16 vlan_id; + } formatted; + __be32 ip; + struct { + __be16 src; + __be16 dst; + } port; + __be16 flex_bytes; + __be32 dword; +}; + + struct ixgbe_atr_input_masks { __be16 rsvd0; __be16 vlan_id_mask; -- 2.42.0