summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjfv <jfv@FreeBSD.org>2011-04-25 23:34:21 +0000
committerjfv <jfv@FreeBSD.org>2011-04-25 23:34:21 +0000
commitebe803c4913a501588fff3a8fb3afd3c96f618e6 (patch)
tree0eb80d777afa5bb05f7e5100673e35677c70f3b8
parent36482d28297049b6b64e5f85cfbb230833c32a36 (diff)
downloadFreeBSD-src-ebe803c4913a501588fff3a8fb3afd3c96f618e6.zip
FreeBSD-src-ebe803c4913a501588fff3a8fb3afd3c96f618e6.tar.gz
- Add the RX refresh changes from igb to ixgbe
- Also a couple minor tweaks to the TX code from the same source. - Add the INET ioctl code which has been missing from this driver, and which caused IP aliases to reset the interface. - Last, some minor logic changes that just reflect upcoming hardware support, but have no other functional effect now. MFC after a week
-rw-r--r--sys/dev/ixgbe/ixgbe.c116
-rw-r--r--sys/dev/ixgbe/ixgbe.h17
2 files changed, 84 insertions, 49 deletions
diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c
index 127f57d..f58adbe 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-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
/*$FreeBSD$*/
#ifdef HAVE_KERNEL_OPTION_HEADERS
-#include "opt_device_polling.h"
+#include "opt_inet.h"
#endif
#include "ixgbe.h"
@@ -46,7 +46,7 @@ int ixgbe_display_debug_stats = 0;
/*********************************************************************
* Driver version
*********************************************************************/
-char ixgbe_driver_version[] = "2.3.8";
+char ixgbe_driver_version[] = "2.3.10";
/*********************************************************************
* PCI Device ID Table
@@ -270,8 +270,8 @@ TUNABLE_INT("hw.ixgbe.hdr_split", &ixgbe_header_split);
/*
* Number of Queues, can be set to 0,
* it then autoconfigures based on the
- * number of cpus. Each queue is a pair
- * of RX and TX rings with a msix vector
+ * number of cpus with a max of 8. This
+ * can be overriden manually here.
*/
static int ixgbe_num_queues = 0;
TUNABLE_INT("hw.ixgbe.num_queues", &ixgbe_num_queues);
@@ -787,10 +787,6 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
return (err);
}
- /* Call cleanup if number of TX descriptors low */
- if (txr->tx_avail <= IXGBE_TX_CLEANUP_THRESHOLD)
- ixgbe_txeof(txr);
-
enqueued = 0;
if (m == NULL) {
next = drbr_dequeue(ifp, txr->br);
@@ -814,7 +810,9 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
ETHER_BPF_MTAP(ifp, next);
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
break;
- if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD) {
+ if (txr->tx_avail < IXGBE_TX_OP_THRESHOLD)
+ ixgbe_txeof(txr);
+ if (txr->tx_avail < IXGBE_TX_OP_THRESHOLD) {
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
@@ -864,10 +862,35 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
{
struct adapter *adapter = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *) data;
+#ifdef INET
+ struct ifaddr *ifa = (struct ifaddr *)data;
+#endif
int error = 0;
switch (command) {
+ case SIOCSIFADDR:
+#ifdef INET
+ if (ifa->ifa_addr->sa_family == AF_INET) {
+ /*
+ * Since resetting hardware takes a very long time
+ * and results in link renegotiation we only
+ * initialize the hardware only when it is absolutely
+ * required.
+ */
+ ifp->if_flags |= IFF_UP;
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ IXGBE_CORE_LOCK(adapter);
+ ixgbe_init_locked(adapter);
+ IXGBE_CORE_UNLOCK(adapter);
+ }
+ if (!(ifp->if_flags & IFF_NOARP))
+ arp_ifinit(ifp, ifa);
+ } else
+#endif
+ error = ether_ioctl(ifp, command, data);
+ break;
+
case SIOCSIFMTU:
IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - ETHER_HDR_LEN) {
@@ -989,7 +1012,7 @@ ixgbe_init_locked(struct adapter *adapter)
if (ifp->if_capenable & IFCAP_TXCSUM) {
ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
#if __FreeBSD_version >= 800000
- if (hw->mac.type == ixgbe_mac_82599EB)
+ if (hw->mac.type != ixgbe_mac_82598EB)
ifp->if_hwassist |= CSUM_SCTP;
#endif
}
@@ -1032,14 +1055,12 @@ ixgbe_init_locked(struct adapter *adapter)
gpie = IXGBE_READ_REG(&adapter->hw, IXGBE_GPIE);
- if (hw->mac.type == ixgbe_mac_82599EB) {
- gpie |= IXGBE_SDP1_GPIEN;
- gpie |= IXGBE_SDP2_GPIEN;
- }
-
/* Enable Fan Failure Interrupt */
- if (hw->device_id == IXGBE_DEV_ID_82598AT)
- gpie |= IXGBE_SDP1_GPIEN;
+ gpie |= IXGBE_SDP1_GPIEN;
+
+ /* Add for Thermal detection */
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ gpie |= IXGBE_SDP2_GPIEN;
if (adapter->msix > 1) {
/* Enable Enhanced MSIX mode */
@@ -1121,7 +1142,7 @@ ixgbe_init_locked(struct adapter *adapter)
#ifdef IXGBE_FDIR
/* Init Flow director */
- if (hw->mac.type == ixgbe_mac_82599EB)
+ if (hw->mac.type != ixgbe_mac_82598EB)
ixgbe_init_fdir_signature_82599(&adapter->hw, fdir_pballoc);
#endif
@@ -1338,8 +1359,6 @@ ixgbe_msix_que(void *arg)
more_tx = ixgbe_txeof(txr);
IXGBE_TX_UNLOCK(txr);
- more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
-
/* Do AIM now? */
if (ixgbe_enable_aim == FALSE)
@@ -1417,7 +1436,7 @@ ixgbe_msix_link(void *arg)
if (reg_eicr & IXGBE_EICR_LSC)
taskqueue_enqueue(adapter->tq, &adapter->link_task);
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
#ifdef IXGBE_FDIR
if (reg_eicr & IXGBE_EICR_FLOW_DIR) {
/* This is probably overkill :) */
@@ -2792,7 +2811,7 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr)
#ifdef IXGBE_FDIR
/* Set the rate at which we sample packets */
- if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ if (adapter->hw.mac.type != ixgbe_mac_82598EB)
txr->atr_sample = atr_sample_rate;
#endif
@@ -2874,7 +2893,7 @@ ixgbe_initialize_transmit_units(struct adapter *adapter)
}
- if (hw->mac.type == ixgbe_mac_82599EB) {
+ if (hw->mac.type != ixgbe_mac_82598EB) {
u32 dmatxctl, rttdcs;
dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
dmatxctl |= IXGBE_DMATXCTL_TE;
@@ -3386,11 +3405,15 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit)
bus_dma_segment_t pseg[1];
struct ixgbe_rx_buf *rxbuf;
struct mbuf *mh, *mp;
- int i, nsegs, error, cleaned;
+ int i, j, nsegs, error;
+ bool refreshed = FALSE;
- i = rxr->next_to_refresh;
- cleaned = -1; /* Signify no completions */
- while (i != limit) {
+ i = j = rxr->next_to_refresh;
+ /* Control the loop with one beyond */
+ if (++j == adapter->num_rx_desc)
+ j = 0;
+
+ while (j != limit) {
rxbuf = &rxr->rx_buffers[i];
if (rxr->hdr_split == FALSE)
goto no_split;
@@ -3418,7 +3441,8 @@ ixgbe_refresh_mbufs(struct rx_ring *rxr, int limit)
rxbuf->m_head = mh;
bus_dmamap_sync(rxr->htag, rxbuf->hmap,
BUS_DMASYNC_PREREAD);
- rxr->rx_base[i].read.hdr_addr = htole64(hseg[0].ds_addr);
+ rxr->rx_base[i].read.hdr_addr =
+ htole64(hseg[0].ds_addr);
no_split:
if (rxbuf->m_pack == NULL) {
@@ -3446,17 +3470,17 @@ no_split:
rxr->rx_base[i].read.pkt_addr =
htole64(pseg[0].ds_addr);
- cleaned = i;
- /* Calculate next index */
- if (++i == adapter->num_rx_desc)
- i = 0;
- /* This is the work marker for refresh */
+ refreshed = TRUE;
+ /* Next is precalculated */
+ i = j;
rxr->next_to_refresh = i;
+ if (++j == adapter->num_rx_desc)
+ j = 0;
}
update:
- if (cleaned != -1) /* If we refreshed some, bump tail */
+ if (refreshed) /* Update hardware tail index */
IXGBE_WRITE_REG(&adapter->hw,
- IXGBE_RDT(rxr->me), cleaned);
+ IXGBE_RDT(rxr->me), rxr->next_to_refresh);
return;
}
@@ -3727,6 +3751,7 @@ skip_head:
rxr->lro_enabled = FALSE;
rxr->rx_split_packets = 0;
rxr->rx_bytes = 0;
+ rxr->discard = FALSE;
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
@@ -3736,7 +3761,7 @@ skip_head:
** 82598 uses software LRO, the
** 82599 uses a hardware assist.
*/
- if ((adapter->hw.mac.type == ixgbe_mac_82599EB) &&
+ if ((adapter->hw.mac.type != ixgbe_mac_82598EB) &&
(ifp->if_capenable & IFCAP_RXCSUM) &&
(ifp->if_capenable & IFCAP_LRO))
ixgbe_setup_hw_rsc(rxr);
@@ -3862,8 +3887,7 @@ ixgbe_initialize_receive_units(struct adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_RDT(i), 0);
}
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
- /* PSRTYPE must be initialized in 82599 */
+ if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
IXGBE_PSRTYPE_UDPHDR |
IXGBE_PSRTYPE_IPV4HDR |
@@ -4307,10 +4331,8 @@ next_desc:
}
/* Refresh any remaining buf structs */
- if (processed != 0) {
+ if (ixgbe_rx_unrefreshed(rxr))
ixgbe_refresh_mbufs(rxr, i);
- processed = 0;
- }
rxr->next_to_check = i;
@@ -4472,7 +4494,7 @@ ixgbe_setup_vlan_hw_support(struct adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl);
/* On 82599 the VLAN enable is per/queue in RXDCTL */
- if (hw->mac.type == ixgbe_mac_82599EB)
+ if (hw->mac.type != ixgbe_mac_82598EB)
for (int i = 0; i < adapter->num_queues; i++) {
ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
ctrl |= IXGBE_RXDCTL_VME;
@@ -4491,9 +4513,7 @@ ixgbe_enable_intr(struct adapter *adapter)
/* Enable Fan Failure detection */
if (hw->device_id == IXGBE_DEV_ID_82598AT)
mask |= IXGBE_EIMS_GPI_SDP1;
-
- /* 82599 specific interrupts */
- if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ else {
mask |= IXGBE_EIMS_ECC;
mask |= IXGBE_EIMS_GPI_SDP1;
mask |= IXGBE_EIMS_GPI_SDP2;
@@ -4810,7 +4830,7 @@ ixgbe_update_stats_counters(struct adapter *adapter)
adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
adapter->stats.gprc -= missed_rx;
- if (hw->mac.type == ixgbe_mac_82599EB) {
+ if (hw->mac.type != ixgbe_mac_82598EB) {
adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL) +
((u64)IXGBE_READ_REG(hw, IXGBE_GORCH) << 32);
adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL) +
@@ -4878,7 +4898,7 @@ ixgbe_update_stats_counters(struct adapter *adapter)
adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
adapter->stats.fclast += IXGBE_READ_REG(hw, IXGBE_FCLAST);
/* Only read FCOE on 82599 */
- if (hw->mac.type == ixgbe_mac_82599EB) {
+ if (hw->mac.type != ixgbe_mac_82598EB) {
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);
diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h
index 9f40efe..54a2f2d 100644
--- a/sys/dev/ixgbe/ixgbe.h
+++ b/sys/dev/ixgbe/ixgbe.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2010, Intel Corporation
+ Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -497,4 +497,19 @@ drbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
}
#endif
+/*
+** Find the number of unrefreshed RX descriptors
+*/
+static inline u16
+ixgbe_rx_unrefreshed(struct rx_ring *rxr)
+{
+ struct adapter *adapter = rxr->adapter;
+
+ if (rxr->next_to_check > rxr->next_to_refresh)
+ return (rxr->next_to_check - rxr->next_to_refresh - 1);
+ else
+ return ((adapter->num_rx_desc + rxr->next_to_check) -
+ rxr->next_to_refresh - 1);
+}
+
#endif /* _IXGBE_H_ */
OpenPOWER on IntegriCloud