diff options
author | jfv <jfv@FreeBSD.org> | 2010-03-30 19:09:18 +0000 |
---|---|---|
committer | jfv <jfv@FreeBSD.org> | 2010-03-30 19:09:18 +0000 |
commit | 6244a53a85ffc2f56f41323d2488022695d9f5d9 (patch) | |
tree | 9f7aae6a02f077e52b614eba3171d9e849092f44 /sys/dev/ixgbe | |
parent | b82a4c003c3dc906ba00076ec7902ea35165ed04 (diff) | |
download | FreeBSD-src-6244a53a85ffc2f56f41323d2488022695d9f5d9.zip FreeBSD-src-6244a53a85ffc2f56f41323d2488022695d9f5d9.tar.gz |
Thanks to Michael Tuexen for adding SCTP support for 82599,
also for finding a one character bug that kept TSO from working.
Sometimes with direct attach cables a failure can occur in init,
the old method of calling detach was broken, there is no way to
return an error to the system from init, so I have changed it to
return failure thru the ioctl.
And, have fixed the ALTQ code changes of Max Laier, sorry Max :)
Diffstat (limited to 'sys/dev/ixgbe')
-rw-r--r-- | sys/dev/ixgbe/ixgbe.c | 100 | ||||
-rw-r--r-- | sys/dev/ixgbe/ixgbe.h | 8 |
2 files changed, 70 insertions, 38 deletions
diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index 2c303d9..42c46a7 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2010, Intel Corporation + Copyright (c) 2001-2009, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ int ixgbe_display_debug_stats = 0; /********************************************************************* * Driver version *********************************************************************/ -char ixgbe_driver_version[] = "2.1.6"; +char ixgbe_driver_version[] = "2.1.7"; /********************************************************************* * PCI Device ID Table @@ -106,8 +106,8 @@ static int ixgbe_mq_start_locked(struct ifnet *, static void ixgbe_qflush(struct ifnet *); #endif static int ixgbe_ioctl(struct ifnet *, u_long, caddr_t); -static void ixgbe_init(void *); -static void ixgbe_init_locked(struct adapter *); +static void ixgbe_init(void *); +static int ixgbe_init_locked(struct adapter *); static void ixgbe_stop(void *); static void ixgbe_media_status(struct ifnet *, struct ifmediareq *); static int ixgbe_media_change(struct ifnet *); @@ -142,7 +142,7 @@ static void ixgbe_disable_intr(struct adapter *); static void ixgbe_update_stats_counters(struct adapter *); static bool ixgbe_txeof(struct tx_ring *); static bool ixgbe_rxeof(struct ix_queue *, int); -static void ixgbe_rx_checksum(u32, struct mbuf *); +static void ixgbe_rx_checksum(u32, struct mbuf *, u32); static void ixgbe_set_promisc(struct adapter *); static void ixgbe_disable_promisc(struct adapter *); static void ixgbe_set_multi(struct adapter *); @@ -827,9 +827,13 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) } enqueued = 0; - if (m == NULL) + if (m == NULL) { next = drbr_dequeue(ifp, txr->br); - else + } else if (drbr_needs_enqueue(ifp, txr->br)) { + if ((err = drbr_enqueue(ifp, txr->br, m)) != 0) + return (err); + next = drbr_dequeue(ifp, txr->br); + } else next = m; /* Process the queue */ @@ -905,7 +909,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) ifp->if_mtu = ifr->ifr_mtu; adapter->max_frame_size = ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; - ixgbe_init_locked(adapter); + error = ixgbe_init_locked(adapter); IXGBE_CORE_UNLOCK(adapter); } break; @@ -920,7 +924,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) ixgbe_set_promisc(adapter); } } else - ixgbe_init_locked(adapter); + error = ixgbe_init_locked(adapter); } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) ixgbe_stop(adapter); @@ -955,8 +959,11 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) ifp->if_capenable ^= IFCAP_LRO; if (mask & IFCAP_VLAN_HWTAGGING) ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ixgbe_init(adapter); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + IXGBE_CORE_LOCK(adapter); + error = ixgbe_init_locked(adapter); + IXGBE_CORE_UNLOCK(adapter); + } VLAN_CAPABILITIES(ifp); break; } @@ -982,7 +989,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data) **********************************************************************/ #define IXGBE_MHADD_MFS_SHIFT 16 -static void +static int ixgbe_init_locked(struct adapter *adapter) { struct ifnet *ifp = adapter->ifp; @@ -990,7 +997,6 @@ ixgbe_init_locked(struct adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; u32 k, txdctl, mhadd, gpie; u32 rxdctl, rxctrl; - int err; mtx_assert(&adapter->core_mtx, MA_OWNED); INIT_DEBUGOUT("ixgbe_init: begin"); @@ -1012,7 +1018,7 @@ ixgbe_init_locked(struct adapter *adapter) if (ixgbe_setup_transmit_structures(adapter)) { device_printf(dev,"Could not setup transmit structures\n"); ixgbe_stop(adapter); - return; + return (ENOMEM); } ixgbe_init_hw(hw); @@ -1034,7 +1040,7 @@ ixgbe_init_locked(struct adapter *adapter) if (ixgbe_setup_receive_structures(adapter)) { device_printf(dev,"Could not setup receive structures\n"); ixgbe_stop(adapter); - return; + return (ENOMEM); } /* Configure RX settings */ @@ -1064,8 +1070,11 @@ ixgbe_init_locked(struct adapter *adapter) if (ifp->if_capenable & IFCAP_TSO4) ifp->if_hwassist |= CSUM_TSO; if (ifp->if_capenable & IFCAP_TXCSUM) - ifp->if_hwassist = (CSUM_TCP | CSUM_UDP); - + ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); +#if __FreeBSD_version >= 800000 + if (hw->mac.type == ixgbe_mac_82599EB) + ifp->if_hwassist |= CSUM_SCTP; +#endif /* Set MTU size */ if (ifp->if_mtu > ETHERMTU) { mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); @@ -1130,7 +1139,7 @@ ixgbe_init_locked(struct adapter *adapter) #ifdef IXGBE_FDIR /* Init Flow director */ - if (adapter->hw.mac.type == ixgbe_mac_82599EB) + if (hw->mac.type == ixgbe_mac_82599EB) ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc); #endif @@ -1138,13 +1147,14 @@ ixgbe_init_locked(struct adapter *adapter) ** Check on any SFP devices that ** need to be kick-started */ - err = hw->phy.ops.identify(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - device_printf(dev, - "Unsupported SFP+ module type was detected.\n"); - ixgbe_detach(dev); - return; - } + if (hw->phy.type == ixgbe_phy_none) { + int err = hw->phy.ops.identify(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + device_printf(dev, + "Unsupported SFP+ module type was detected.\n"); + return (EIO); + } + } /* Config/Enable Link */ ixgbe_config_link(adapter); @@ -1156,7 +1166,7 @@ ixgbe_init_locked(struct adapter *adapter) ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - return; + return (0); } static void @@ -3003,6 +3013,12 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_UDP; break; +#if __FreeBSD_version >= 800000 + case IPPROTO_SCTP: + if (mp->m_pkthdr.csum_flags & CSUM_SCTP) + type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; + break; +#endif default: offload = FALSE; break; @@ -3956,16 +3972,16 @@ ixgbe_rxeof(struct ix_queue *que, int count) IXGBE_RX_LOCK(rxr); + /* Sync the ring. */ + bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + for (i = rxr->next_to_check; count != 0;) { struct mbuf *sendmp, *mh, *mp; u32 rsc, ptype; u16 hlen, plen, hdr, vtag; bool eop; - /* Sync the ring. */ - bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, - BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); - cur = &rxr->rx_base[i]; staterr = le32toh(cur->wb.upper.status_error); @@ -4138,7 +4154,7 @@ ixgbe_rxeof(struct ix_queue *que, int count) rxr->bytes += sendmp->m_pkthdr.len; rxr->rx_bytes += sendmp->m_pkthdr.len; if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) - ixgbe_rx_checksum(staterr, sendmp); + ixgbe_rx_checksum(staterr, sendmp, ptype); #if __FreeBSD_version >= 800000 sendmp->m_pkthdr.flowid = que->msix; sendmp->m_flags |= M_FLOWID; @@ -4202,10 +4218,15 @@ next_desc: * *********************************************************************/ static void -ixgbe_rx_checksum(u32 staterr, struct mbuf * mp) +ixgbe_rx_checksum(u32 staterr, struct mbuf * mp, u32 ptype) { - u16 status = (u16) staterr; - u8 errors = (u8) (staterr >> 24); + u16 status = (u16) staterr; + u8 errors = (u8) (staterr >> 24); + bool sctp = FALSE; + + if ((ptype & IXGBE_RXDADV_PKTTYPE_ETQF) == 0 && + (ptype & IXGBE_RXDADV_PKTTYPE_SCTP) != 0) + sctp = TRUE; if (status & IXGBE_RXD_STAT_IPCS) { if (!(errors & IXGBE_RXD_ERR_IPE)) { @@ -4217,10 +4238,15 @@ ixgbe_rx_checksum(u32 staterr, struct mbuf * mp) mp->m_pkthdr.csum_flags = 0; } if (status & IXGBE_RXD_STAT_L4CS) { + u16 type = (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); +#if __FreeBSD_version >= 800000 + if (sctp) + type = CSUM_SCTP_VALID; +#endif if (!(errors & IXGBE_RXD_ERR_TCPE)) { - mp->m_pkthdr.csum_flags |= - (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); - mp->m_pkthdr.csum_data = htons(0xffff); + mp->m_pkthdr.csum_flags |= type; + if (!sctp) + mp->m_pkthdr.csum_data = htons(0xffff); } } return; diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h index 008d2c8..f598b8f 100644 --- a/sys/dev/ixgbe/ixgbe.h +++ b/sys/dev/ixgbe/ixgbe.h @@ -179,7 +179,13 @@ #define IXGBE_RX_HDR 128 #define IXGBE_VFTA_SIZE 128 #define IXGBE_BR_SIZE 4096 -#define CSUM_OFFLOAD 7 /* Bits in csum flags */ + +/* Offload bits in mbuf flag */ +#if __FreeBSD_version >= 800000 +#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP|CSUM_SCTP) +#else +#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP) +#endif /* For 6.X code compatibility */ #if !defined(ETHER_BPF_MTAP) |