Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci/ixgbe Update our ixg(4) driver up to FreeBSD r23...
details: https://anonhg.NetBSD.org/src/rev/73ff9cefc752
branches: trunk
changeset: 337102:73ff9cefc752
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Thu Apr 02 09:26:55 2015 +0000
description:
Update our ixg(4) driver up to FreeBSD r238149:
- Add TSO6 support.
- The max size in dma tag is changed from 65535 to 262140 (IXGBE_TSO_SIZE).
The value is the same as other *BSDs. The change might cause a address
space shortage (ixgbe_dmamap_create() might fail) on some machines.
- Fix a lot of bugs.
- Improve performance.
diffstat:
sys/dev/pci/ixgbe/ixgbe.c | 229 +++++++---
sys/dev/pci/ixgbe/ixgbe.h | 6 +-
sys/dev/pci/ixgbe/ixgbe_82598.c | 104 ++--
sys/dev/pci/ixgbe/ixgbe_82598.h | 4 +-
sys/dev/pci/ixgbe/ixgbe_82599.c | 17 +-
sys/dev/pci/ixgbe/ixgbe_api.c | 26 +-
sys/dev/pci/ixgbe/ixgbe_api.h | 7 +-
sys/dev/pci/ixgbe/ixgbe_common.c | 839 ++++++++++++++++++++------------------
sys/dev/pci/ixgbe/ixgbe_common.h | 11 +-
sys/dev/pci/ixgbe/ixgbe_mbx.c | 2 +-
sys/dev/pci/ixgbe/ixgbe_mbx.h | 2 +-
sys/dev/pci/ixgbe/ixgbe_osdep.h | 5 +-
sys/dev/pci/ixgbe/ixgbe_phy.c | 69 ++-
sys/dev/pci/ixgbe/ixgbe_phy.h | 2 +-
sys/dev/pci/ixgbe/ixgbe_type.h | 97 +++-
sys/dev/pci/ixgbe/ixgbe_vf.c | 26 +-
sys/dev/pci/ixgbe/ixgbe_vf.h | 2 +-
sys/dev/pci/ixgbe/ixgbe_x540.c | 8 +-
sys/dev/pci/ixgbe/ixv.c | 12 +-
sys/dev/pci/ixgbe/ixv.h | 2 +-
20 files changed, 844 insertions(+), 626 deletions(-)
diffs (truncated from 2680 to 300 lines):
diff -r 1df02edfc655 -r 73ff9cefc752 sys/dev/pci/ixgbe/ixgbe.c
--- a/sys/dev/pci/ixgbe/ixgbe.c Thu Apr 02 06:23:04 2015 +0000
+++ b/sys/dev/pci/ixgbe/ixgbe.c Thu Apr 02 09:26:55 2015 +0000
@@ -58,8 +58,8 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-/*$FreeBSD: src/sys/dev/ixgbe/ixgbe.c,v 1.51 2011/04/25 23:34:21 jfv Exp $*/
-/*$NetBSD: ixgbe.c,v 1.24 2015/03/27 05:57:28 msaitoh Exp $*/
+/*$FreeBSD: head/sys/dev/ixgbe/ixgbe.c 238149 2012-07-05 20:51:44Z jfv $*/
+/*$NetBSD: ixgbe.c,v 1.25 2015/04/02 09:26:55 msaitoh Exp $*/
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -74,7 +74,7 @@
/*********************************************************************
* Driver version
*********************************************************************/
-char ixgbe_driver_version[] = "2.4.5";
+char ixgbe_driver_version[] = "2.4.8";
/*********************************************************************
* PCI Device ID Table
@@ -111,6 +111,7 @@
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_FCOE, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599EN_SFP, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_SFP_SF_QP, 0, 0, 0},
+ {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T1, 0, 0, 0},
{IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T, 0, 0, 0},
/* required last entry */
{0, 0, 0, 0, 0}
@@ -198,7 +199,7 @@
static void ixgbe_add_rx_process_limit(struct adapter *, const char *,
const char *, int *, int);
static u32 ixgbe_tx_ctx_setup(struct tx_ring *, struct mbuf *);
-static bool ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *);
+static bool ixgbe_tso_setup(struct tx_ring *, struct mbuf *, u32 *, u32 *);
static void ixgbe_set_ivar(struct adapter *, u8, u8, s8);
static void ixgbe_configure_ivars(struct adapter *);
static u8 * ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
@@ -357,7 +358,7 @@
* be a reference on how to implement netmap support in a driver.
* Additional comments are in ixgbe_netmap.h .
*
- * <dev/netma/ixgbe_netmap.h> contains functions for netmap support
+ * <dev/netmap/ixgbe_netmap.h> contains functions for netmap support
* that extend the standard driver.
*/
#include <dev/netmap/ixgbe_netmap.h>
@@ -595,28 +596,25 @@
goto err_late;
}
- /* Get Hardware Flow Control setting */
- hw->fc.requested_mode = ixgbe_fc_full;
- adapter->fc = hw->fc.requested_mode;
- hw->fc.pause_time = IXGBE_FC_PAUSE;
- hw->fc.low_water = IXGBE_FC_LO;
- hw->fc.high_water[0] = IXGBE_FC_HI;
- hw->fc.send_xon = TRUE;
-
error = ixgbe_init_hw(hw);
- if (error == IXGBE_ERR_EEPROM_VERSION) {
+ switch (error) {
+ case IXGBE_ERR_EEPROM_VERSION:
aprint_error_dev(dev, "This device is a pre-production adapter/"
"LOM. Please be aware there may be issues associated "
"with your hardware.\n If you are experiencing problems "
"please contact your Intel or hardware representative "
"who provided you with this hardware.\n");
- } else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ break;
+ case IXGBE_ERR_SFP_NOT_SUPPORTED:
aprint_error_dev(dev,"Unsupported SFP+ Module\n");
-
- if (error) {
error = EIO;
aprint_error_dev(dev,"Hardware Initialization Failure\n");
goto err_late;
+ case IXGBE_ERR_SFP_NOT_PRESENT:
+ device_printf(dev,"No SFP+ Module found\n");
+ /* falls thru */
+ default:
+ break;
}
/* Detect and set physical type */
@@ -1307,6 +1305,14 @@
txdctl |= IXGBE_TXDCTL_ENABLE;
/* Set WTHRESH to 8, burst writeback */
txdctl |= (8 << 16);
+ /*
+ * When the internal queue falls below PTHRESH (32),
+ * start prefetching as long as there are at least
+ * HTHRESH (1) buffers ready. The values are taken
+ * from the Intel linux driver 3.8.21.
+ * Prefetching enables tx line rate even with 1 queue.
+ */
+ txdctl |= (32 << 0) | (1 << 8);
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), txdctl);
}
@@ -1393,7 +1399,7 @@
#ifdef IXGBE_FDIR
/* Init Flow director */
if (hw->mac.type != ixgbe_mac_82598EB) {
- u32 hdrm = 64 << fdir_pballoc;
+ u32 hdrm = 32 << fdir_pballoc;
hw->mac.ops.setup_rxpba(hw, 0, hdrm, PBA_STRATEGY_EQUAL);
ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc);
@@ -1419,6 +1425,35 @@
/* Config/Enable Link */
ixgbe_config_link(adapter);
+ /* Hardware Packet Buffer & Flow Control setup */
+ {
+ u32 rxpb, frame, size, tmp;
+
+ frame = adapter->max_frame_size;
+
+ /* Calculate High Water */
+ if (hw->mac.type == ixgbe_mac_X540)
+ tmp = IXGBE_DV_X540(frame, frame);
+ else
+ tmp = IXGBE_DV(frame, frame);
+ size = IXGBE_BT2KB(tmp);
+ rxpb = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) >> 10;
+ hw->fc.high_water[0] = rxpb - size;
+
+ /* Now calculate Low Water */
+ if (hw->mac.type == ixgbe_mac_X540)
+ tmp = IXGBE_LOW_DV_X540(frame);
+ else
+ tmp = IXGBE_LOW_DV(frame);
+ hw->fc.low_water[0] = IXGBE_BT2KB(tmp);
+
+ adapter->fc = hw->fc.requested_mode = ixgbe_fc_full;
+ hw->fc.pause_time = IXGBE_FC_PAUSE;
+ hw->fc.send_xon = TRUE;
+ }
+ /* Initialize the FC settings */
+ ixgbe_start_hw(hw);
+
/* And now turn on interrupts */
ixgbe_enable_intr(adapter);
@@ -1527,7 +1562,7 @@
ixgbe_start_locked(txr, ifp);
#endif
IXGBE_TX_UNLOCK(txr);
- if (more || (ifp->if_flags & IFF_OACTIVE)) {
+ if (more) {
adapter->req.ev_count++;
softint_schedule(que->que_si);
return;
@@ -1724,10 +1759,8 @@
/* This is probably overkill :) */
if (!atomic_cmpset_int(&adapter->fdir_reinit, 0, 1))
return;
- /* Clear the interrupt */
- IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
- /* Turn off the interface */
- adapter->ifp->if_flags &= ~IFF_RUNNING;
+ /* Disable the interrupt */
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_FLOW_DIR);
softint_schedule(adapter->fdir_si);
} else
#endif
@@ -1925,9 +1958,8 @@
** a packet.
*/
if (m_head->m_pkthdr.csum_flags & (M_CSUM_TSOv4|M_CSUM_TSOv6)) {
- if (ixgbe_tso_setup(txr, m_head, &paylen)) {
+ if (ixgbe_tso_setup(txr, m_head, &paylen, &olinfo_status)) {
cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
- olinfo_status |= IXGBE_TXD_POPTS_IXSM << 8;
olinfo_status |= IXGBE_TXD_POPTS_TXSM << 8;
olinfo_status |= paylen << IXGBE_ADVTXD_PAYLEN_SHIFT;
++adapter->tso_tx.ev_count;
@@ -2220,6 +2252,8 @@
((adapter->link_speed == 128)? 10:1),
"Full Duplex");
adapter->link_active = TRUE;
+ /* Update any Flow Control changes */
+ ixgbe_fc_enable(&adapter->hw);
if_link_state_change(ifp, LINK_STATE_UP);
}
} else { /* Link down */
@@ -2783,7 +2817,7 @@
*/
ifp->if_hdrlen = sizeof(struct ether_vlan_header);
- ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSOv4;
+ ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSOv4 | IFCAP_TSOv6;
ifp->if_capenable = 0;
ec->ec_capabilities |= ETHERCAP_VLAN_HWCSUM;
@@ -3152,7 +3186,8 @@
for (i = 0; i < adapter->num_tx_desc; i++, txbuf++) {
error = ixgbe_dmamap_create(txr->txtag, 0, &txbuf->map);
if (error != 0) {
- aprint_error_dev(dev, "Unable to create TX DMA map\n");
+ aprint_error_dev(dev,
+ "Unable to create TX DMA map (%d)\n", error);
goto fail;
}
}
@@ -3214,14 +3249,11 @@
* Slots in the netmap ring (indexed by "si") are
* kring->nkr_hwofs positions "ahead" wrt the
* corresponding slot in the NIC ring. In some drivers
- * (not here) nkr_hwofs can be negative. When computing
- * si = i + kring->nkr_hwofs make sure to handle wraparounds.
+ * (not here) nkr_hwofs can be negative. Function
+ * netmap_idx_n2k() handles wraparounds properly.
*/
if (slot) {
- int si = i + na->tx_rings[txr->me].nkr_hwofs;
-
- if (si >= na->num_tx_desc)
- si -= na->num_tx_desc;
+ int si = netmap_idx_n2k(&na->tx_rings[txr->me], i);
netmap_load_map(txr->txtag, txbuf->map, NMB(slot + si));
}
#endif /* DEV_NETMAP */
@@ -3301,7 +3333,7 @@
txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
break;
}
- txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+ txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl);
@@ -3478,6 +3510,7 @@
case ETHERTYPE_IPV6:
m_copydata(mp, ehdrlen, sizeof(ip6), &ip6);
ip_hlen = sizeof(ip6);
+ /* XXX-BZ this will go badly in case of ext hdrs. */
ipproto = ip6.ip6_nxt;
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV6;
break;
@@ -3526,7 +3559,8 @@
*
**********************************************************************/
static bool
-ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen)
+ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *paylen,
+ u32 *olinfo_status)
{
struct m_tag *mtag;
struct adapter *adapter = txr->adapter;
@@ -3534,11 +3568,16 @@
struct ixgbe_adv_tx_context_desc *TXD;
struct ixgbe_tx_buf *tx_buffer;
u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
- u32 mss_l4len_idx = 0;
- u16 vtag = 0;
- int ctxd, ehdrlen, hdrlen, ip_hlen, tcp_hlen;
+ u32 mss_l4len_idx = 0, len;
+ u16 vtag = 0, eh_type;
+ int ctxd, ehdrlen, ip_hlen, tcp_hlen;
struct ether_vlan_header *eh;
+#ifdef INET6
+ struct ip6_hdr *ip6;
+#endif
+#ifdef INET
struct ip *ip;
+#endif
struct tcphdr *th;
@@ -3547,33 +3586,63 @@
* Jump over vlan headers if already present
*/
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
+ eh_type = eh->evl_proto;
+ } else {
ehdrlen = ETHER_HDR_LEN;
+ eh_type = eh->evl_encap_proto;
+ }
/* Ensure we have at least the IP+TCP header in the first mbuf. */
- if (mp->m_len < ehdrlen + sizeof(struct ip) + sizeof(struct tcphdr))
- return FALSE;
+ len = ehdrlen + sizeof(struct tcphdr);
+ switch (ntohs(eh_type)) {
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ if (mp->m_len < len + sizeof(struct ip6_hdr))
+ return FALSE;
+ ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
+ /* XXX-BZ For now we do not pretend to support ext. hdrs. */
+ if (ip6->ip6_nxt != IPPROTO_TCP)
+ return FALSE;
Home |
Main Index |
Thread Index |
Old Index