Module Name: src
Committed By: martin
Date: Wed Apr 4 16:18:49 UTC 2018
Modified Files:
src/sys/dev/pci/ixgbe [netbsd-8]: ix_txrx.c ixgbe.c ixgbe.h
ixgbe_82599.c ixgbe_api.h ixgbe_common.c ixgbe_common.h
ixgbe_x550.c ixgbe_x550.h ixv.c
Log Message:
Pull up following revision(s) (requested by msaitoh in ticket #690):
sys/dev/pci/ixgbe/ixgbe_82599.c: revision 1.17
sys/dev/pci/ixgbe/ixgbe.c: revision 1.138
sys/dev/pci/ixgbe/ixv.c: revision 1.90
sys/dev/pci/ixgbe/ixgbe.c: revision 1.139
sys/dev/pci/ixgbe/ixgbe_common.c: revision 1.19
sys/dev/pci/ixgbe/ixgbe_common.h: revision 1.11
sys/dev/pci/ixgbe/ixgbe.h: revision 1.38
sys/dev/pci/ixgbe/ixgbe_api.h: revision 1.12
sys/dev/pci/ixgbe/ixgbe.h: revision 1.39
sys/dev/pci/ixgbe/ixgbe_x550.c: revision 1.10
sys/dev/pci/ixgbe/ixgbe_x550.c: revision 1.11
sys/dev/pci/ixgbe/ix_txrx.c: revision 1.37
sys/dev/pci/ixgbe/ix_txrx.c: revision 1.38
sys/dev/pci/ixgbe/ixgbe.c: revision 1.140
sys/dev/pci/ixgbe/ixgbe_common.c: revision 1.20
sys/dev/pci/ixgbe/ixgbe.c: revision 1.141
sys/dev/pci/ixgbe/ixgbe.c: revision 1.142
sys/dev/pci/ixgbe/ixgbe.c: revision 1.143
sys/dev/pci/ixgbe/ixgbe.h: revision 1.40
sys/dev/pci/ixgbe/ixgbe_x550.h: revision 1.4
Fix the problem between eitr and link_speed.
In ixgbe_msix_que(), que->eitr_setting is limited to IXGBE_MIN_RSC_EITR_10G1G
when link_speed is 1Gbps or 10Gbps. However, que->eitr_setting is set to EITR
register in the *next* Tx/Rx interrupt. If link_speed changes from 100Mbps to
1Gbps ro 10Gbps, que->eitr_setting which is not limited can be set to EITR
register, that is, the problem fixed by ixgbe.c:r1.124 can occur in this case.
To fix this case, que->eitr_setting should be clear when link_speed is changed
or link state is changed.
Furthermore, expand the variants used for AIM (txr->bytes, txr->packets,
rxr->bytes and rxr->packets) from u32 to u64 to avoid wraparound which causes
que->eitr_setting calculation mistake.
XXX pullup-8
Don't write EIMC directly. It is required to manage with struct ix_queue status.
XXX pullup-8
- Add missing IFM_NONE support. If a interface support linkdown,
"ifconfig ixgN media none" drpos link. Not all interface can do link down.
Tested:
82598 AT2 (T)
92599 SF+(SFI) (X520-DA2)
X540
X550-T1
X550EM_x (X10SDV-8C-TLN4F)
X550EM_a (A2SDi-H-TP4F port 0, 1 (T))
Doesn't work:
X550EM_a (A2SDi-H-TP4F port 2, 3 (SFP+ (KR)))
X550EM_a (MA10-ST0 port 2, 3 (SFP+ (SFI)))
(Denverton SFP+ can't force link down because SFP+'s TX_DISABLE pin is
pull down. Is there a way to shutdown SFP+ cage's power?)
Not tested:
82598 fiber.
- Change some functions static.
Avoid issues caused by sending old packets at next link-up time.
This modification consists by the following two parts.
- drain packets in if_snd queue or corresponding txr->txr_interq
when link_active == false in ifp->if_start(), ifp->if_transmit(),
and deferred Tx processing
- drain packets in if_snd queue and all of txr->txr_interq's
at link-down time
ok by [email protected].
Fix long standing bug that 82598 SFP+ panics in ixgbe_handle_mod() because
hw->mac.ops.setup_sfp is NULL. This change is a part of FreeBSD r327031.
Fix a bug that "ifconfig ixgN down up" forgot IFM_NONE setting.
- Don't assume autoneg == 0 is the first call of ixgbe_config_link().
Check ifm_media, too.
- Don't override autoneg_advertised in ixgbe_get_phy_id_fw() to not to
be inconsistent with if_media value.
To generate a diff of this commit:
cvs rdiff -u -r1.24.2.8 -r1.24.2.9 src/sys/dev/pci/ixgbe/ix_txrx.c
cvs rdiff -u -r1.88.2.15 -r1.88.2.16 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.24.6.8 -r1.24.6.9 src/sys/dev/pci/ixgbe/ixgbe.h
cvs rdiff -u -r1.14.8.1 -r1.14.8.2 src/sys/dev/pci/ixgbe/ixgbe_82599.c
cvs rdiff -u -r1.9.8.1 -r1.9.8.2 src/sys/dev/pci/ixgbe/ixgbe_api.h
cvs rdiff -u -r1.13.2.2 -r1.13.2.3 src/sys/dev/pci/ixgbe/ixgbe_common.c
cvs rdiff -u -r1.7.8.2 -r1.7.8.3 src/sys/dev/pci/ixgbe/ixgbe_common.h
cvs rdiff -u -r1.5.6.2 -r1.5.6.3 src/sys/dev/pci/ixgbe/ixgbe_x550.c
cvs rdiff -u -r1.2.12.1 -r1.2.12.2 src/sys/dev/pci/ixgbe/ixgbe_x550.h
cvs rdiff -u -r1.56.2.12 -r1.56.2.13 src/sys/dev/pci/ixgbe/ixv.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/ixgbe/ix_txrx.c
diff -u src/sys/dev/pci/ixgbe/ix_txrx.c:1.24.2.8 src/sys/dev/pci/ixgbe/ix_txrx.c:1.24.2.9
--- src/sys/dev/pci/ixgbe/ix_txrx.c:1.24.2.8 Fri Mar 30 12:07:34 2018
+++ src/sys/dev/pci/ixgbe/ix_txrx.c Wed Apr 4 16:18:49 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ix_txrx.c,v 1.24.2.8 2018/03/30 12:07:34 martin Exp $ */
+/* $NetBSD: ix_txrx.c,v 1.24.2.9 2018/04/04 16:18:49 martin Exp $ */
/******************************************************************************
@@ -103,6 +103,7 @@ static void ixgbe_free_receive_
static void ixgbe_rx_checksum(u32, struct mbuf *, u32,
struct ixgbe_hw_stats *);
static void ixgbe_refresh_mbufs(struct rx_ring *, int);
+static void ixgbe_drain(struct ifnet *, struct tx_ring *);
static int ixgbe_xmit(struct tx_ring *, struct mbuf *);
static int ixgbe_tx_ctx_setup(struct tx_ring *,
struct mbuf *, u32 *, u32 *);
@@ -135,9 +136,15 @@ ixgbe_legacy_start_locked(struct ifnet *
IXGBE_TX_LOCK_ASSERT(txr);
- if ((ifp->if_flags & IFF_RUNNING) == 0)
+ if (!adapter->link_active) {
+ /*
+ * discard all packets buffered in IFQ to avoid
+ * sending old packets at next link up timing.
+ */
+ ixgbe_drain(ifp, txr);
return (ENETDOWN);
- if (!adapter->link_active)
+ }
+ if ((ifp->if_flags & IFF_RUNNING) == 0)
return (ENETDOWN);
while (!IFQ_IS_EMPTY(&ifp->if_snd)) {
@@ -271,9 +278,15 @@ ixgbe_mq_start_locked(struct ifnet *ifp,
struct mbuf *next;
int enqueued = 0, err = 0;
- if ((ifp->if_flags & IFF_RUNNING) == 0)
+ if (!txr->adapter->link_active) {
+ /*
+ * discard all packets buffered in txr_interq to avoid
+ * sending old packets at next link up timing.
+ */
+ ixgbe_drain(ifp, txr);
return (ENETDOWN);
- if (txr->adapter->link_active == 0)
+ }
+ if ((ifp->if_flags & IFF_RUNNING) == 0)
return (ENETDOWN);
/* Process the queue */
@@ -342,6 +355,23 @@ ixgbe_deferred_mq_start_work(struct work
ixgbe_deferred_mq_start(txr);
} /* ixgbe_deferred_mq_start */
+/************************************************************************
+ * ixgbe_drain_all
+ ************************************************************************/
+void
+ixgbe_drain_all(struct adapter *adapter)
+{
+ struct ifnet *ifp = adapter->ifp;
+ struct ix_queue *que = adapter->queues;
+
+ for (int i = 0; i < adapter->num_queues; i++, que++) {
+ struct tx_ring *txr = que->txr;
+
+ IXGBE_TX_LOCK(txr);
+ ixgbe_drain(ifp, txr);
+ IXGBE_TX_UNLOCK(txr);
+ }
+}
/************************************************************************
* ixgbe_xmit
@@ -515,6 +545,29 @@ retry:
return (0);
} /* ixgbe_xmit */
+/************************************************************************
+ * ixgbe_drain
+ ************************************************************************/
+static void
+ixgbe_drain(struct ifnet *ifp, struct tx_ring *txr)
+{
+ struct mbuf *m;
+
+ IXGBE_TX_LOCK_ASSERT(txr);
+
+ if (txr->me == 0) {
+ while (!IFQ_IS_EMPTY(&ifp->if_snd)) {
+ IFQ_DEQUEUE(&ifp->if_snd, m);
+ m_freem(m);
+ IF_DROP(&ifp->if_snd);
+ }
+ }
+
+ while ((m = pcq_get(txr->txr_interq)) != NULL) {
+ m_freem(m);
+ txr->pcq_drops.ev_count++;
+ }
+}
/************************************************************************
* ixgbe_allocate_transmit_buffers
@@ -2298,8 +2351,8 @@ ixgbe_allocate_queues(struct adapter *ad
que->txr = &adapter->tx_rings[i];
que->rxr = &adapter->rx_rings[i];
- mutex_init(&que->im_mtx, MUTEX_DEFAULT, IPL_NET);
- que->im_nest = 0;
+ mutex_init(&que->dc_mtx, MUTEX_DEFAULT, IPL_NET);
+ que->disabled_count = 0;
}
return (0);
Index: src/sys/dev/pci/ixgbe/ixgbe.c
diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.88.2.15 src/sys/dev/pci/ixgbe/ixgbe.c:1.88.2.16
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.88.2.15 Fri Mar 30 12:07:34 2018
+++ src/sys/dev/pci/ixgbe/ixgbe.c Wed Apr 4 16:18:49 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.88.2.15 2018/03/30 12:07:34 martin Exp $ */
+/* $NetBSD: ixgbe.c,v 1.88.2.16 2018/04/04 16:18:49 martin Exp $ */
/******************************************************************************
@@ -1378,6 +1378,8 @@ ixgbe_add_media_types(struct adapter *ad
#define ADD(mm, dd) \
ifmedia_add(&adapter->media, IFM_ETHER | (mm), (dd), NULL);
+ ADD(IFM_NONE, 0);
+
/* Media types with matching NetBSD media defines */
if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) {
ADD(IFM_10G_T | IFM_FDX, 0);
@@ -1509,13 +1511,21 @@ ixgbe_config_link(struct adapter *adapte
kpreempt_enable();
}
} else {
+ struct ifmedia *ifm = &adapter->media;
+
if (hw->mac.ops.check_link)
err = ixgbe_check_link(hw, &adapter->link_speed,
&adapter->link_up, FALSE);
if (err)
goto out;
+
+ /*
+ * Check if it's the first call. If it's the first call,
+ * get value for auto negotiation.
+ */
autoneg = hw->phy.autoneg_advertised;
- if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
+ if ((IFM_SUBTYPE(ifm->ifm_cur->ifm_media) != IFM_NONE)
+ && ((!autoneg) && (hw->mac.ops.get_link_capabilities)))
err = hw->mac.ops.get_link_capabilities(hw, &autoneg,
&negotiate);
if (err)
@@ -2410,8 +2420,8 @@ ixgbe_enable_queue(struct adapter *adapt
u64 queue = (u64)(1ULL << vector);
u32 mask;
- mutex_enter(&que->im_mtx);
- if (que->im_nest > 0 && --que->im_nest > 0)
+ mutex_enter(&que->dc_mtx);
+ if (que->disabled_count > 0 && --que->disabled_count > 0)
goto out;
if (hw->mac.type == ixgbe_mac_82598EB) {
@@ -2426,23 +2436,28 @@ ixgbe_enable_queue(struct adapter *adapt
IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
}
out:
- mutex_exit(&que->im_mtx);
+ mutex_exit(&que->dc_mtx);
} /* ixgbe_enable_queue */
/************************************************************************
- * ixgbe_disable_queue
+ * ixgbe_disable_queue_internal
************************************************************************/
static inline void
-ixgbe_disable_queue(struct adapter *adapter, u32 vector)
+ixgbe_disable_queue_internal(struct adapter *adapter, u32 vector, bool nestok)
{
struct ixgbe_hw *hw = &adapter->hw;
struct ix_queue *que = &adapter->queues[vector];
u64 queue = (u64)(1ULL << vector);
u32 mask;
- mutex_enter(&que->im_mtx);
- if (que->im_nest++ > 0)
- goto out;
+ mutex_enter(&que->dc_mtx);
+
+ if (que->disabled_count > 0) {
+ if (nestok)
+ que->disabled_count++;
+ goto out;
+ }
+ que->disabled_count++;
if (hw->mac.type == ixgbe_mac_82598EB) {
mask = (IXGBE_EIMS_RTX_QUEUE & queue);
@@ -2456,7 +2471,17 @@ ixgbe_disable_queue(struct adapter *adap
IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask);
}
out:
- mutex_exit(&que->im_mtx);
+ mutex_exit(&que->dc_mtx);
+} /* ixgbe_disable_queue_internal */
+
+/************************************************************************
+ * ixgbe_disable_queue
+ ************************************************************************/
+static inline void
+ixgbe_disable_queue(struct adapter *adapter, u32 vector)
+{
+
+ ixgbe_disable_queue_internal(adapter, vector, true);
} /* ixgbe_disable_queue */
/************************************************************************
@@ -2814,6 +2839,8 @@ ixgbe_media_change(struct ifnet *ifp)
case IFM_10_T:
speed |= IXGBE_LINK_SPEED_10_FULL;
break;
+ case IFM_NONE:
+ break;
default:
goto invalid;
}
@@ -3511,7 +3538,7 @@ ixgbe_detach(device_t dev, int flags)
ixgbe_free_receive_structures(adapter);
for (int i = 0; i < adapter->num_queues; i++) {
struct ix_queue * que = &adapter->queues[i];
- mutex_destroy(&que->im_mtx);
+ mutex_destroy(&que->dc_mtx);
}
free(adapter->queues, M_DEVBUF);
free(adapter->mta, M_DEVBUF);
@@ -4012,6 +4039,13 @@ ixgbe_configure_ivars(struct adapter *ad
ixgbe_set_ivar(adapter, txr->me, que->msix, 1);
/* Set an Initial EITR value */
ixgbe_eitr_write(que, newitr);
+ /*
+ * To eliminate influence of the previous state.
+ * At this point, Tx/Rx interrupt handler
+ * (ixgbe_msix_que()) cannot be called, so both
+ * IXGBE_TX_LOCK and IXGBE_RX_LOCK are not required.
+ */
+ que->eitr_setting = 0;
}
/* For the Link interrupt */
@@ -4288,11 +4322,11 @@ ixgbe_local_timer1(void *arg)
else if (queues != 0) { /* Force an IRQ on queues with work */
que = adapter->queues;
for (i = 0; i < adapter->num_queues; i++, que++) {
- mutex_enter(&que->im_mtx);
- if (que->im_nest == 0)
+ mutex_enter(&que->dc_mtx);
+ if (que->disabled_count == 0)
ixgbe_rearm_queues(adapter,
queues & ((u64)1 << i));
- mutex_exit(&que->im_mtx);
+ mutex_exit(&que->dc_mtx);
}
}
@@ -4379,7 +4413,11 @@ ixgbe_handle_mod(void *context)
return;
}
- err = hw->mac.ops.setup_sfp(hw);
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ err = hw->phy.ops.reset(hw);
+ else
+ err = hw->mac.ops.setup_sfp(hw);
+
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
device_printf(dev,
"Setup failure - unsupported SFP+ module type.\n");
@@ -4509,6 +4547,14 @@ ixgbe_update_link_status(struct adapter
if (adapter->link_up) {
if (adapter->link_active == FALSE) {
+ /*
+ * To eliminate influence of the previous state
+ * in the same way as ixgbe_init_locked().
+ */
+ struct ix_queue *que = adapter->queues;
+ for (int i = 0; i < adapter->num_queues; i++, que++)
+ que->eitr_setting = 0;
+
if (adapter->link_speed == IXGBE_LINK_SPEED_10GB_FULL){
/*
* Discard count for both MAC Local Fault and
@@ -4566,6 +4612,7 @@ ixgbe_update_link_status(struct adapter
adapter->link_active = FALSE;
if (adapter->feat_en & IXGBE_FEATURE_SRIOV)
ixgbe_ping_all_vfs(adapter);
+ ixgbe_drain_all(adapter);
}
}
} /* ixgbe_update_link_status */
@@ -4682,10 +4729,10 @@ ixgbe_enable_intr(struct adapter *adapte
} /* ixgbe_enable_intr */
/************************************************************************
- * ixgbe_disable_intr
+ * ixgbe_disable_intr_internal
************************************************************************/
static void
-ixgbe_disable_intr(struct adapter *adapter)
+ixgbe_disable_intr_internal(struct adapter *adapter, bool nestok)
{
struct ix_queue *que = adapter->queues;
@@ -4696,13 +4743,33 @@ ixgbe_disable_intr(struct adapter *adapt
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, 0);
for (int i = 0; i < adapter->num_queues; i++, que++)
- ixgbe_disable_queue(adapter, que->msix);
+ ixgbe_disable_queue_internal(adapter, que->msix, nestok);
IXGBE_WRITE_FLUSH(&adapter->hw);
+} /* ixgbe_do_disable_intr_internal */
+
+/************************************************************************
+ * ixgbe_disable_intr
+ ************************************************************************/
+static void
+ixgbe_disable_intr(struct adapter *adapter)
+{
+
+ ixgbe_disable_intr_internal(adapter, true);
} /* ixgbe_disable_intr */
/************************************************************************
+ * ixgbe_ensure_disabled_intr
+ ************************************************************************/
+void
+ixgbe_ensure_disabled_intr(struct adapter *adapter)
+{
+
+ ixgbe_disable_intr_internal(adapter, false);
+} /* ixgbe_ensure_disabled_intr */
+
+/************************************************************************
* ixgbe_legacy_irq - Legacy Interrupt Service routine
************************************************************************/
static int
Index: src/sys/dev/pci/ixgbe/ixgbe.h
diff -u src/sys/dev/pci/ixgbe/ixgbe.h:1.24.6.8 src/sys/dev/pci/ixgbe/ixgbe.h:1.24.6.9
--- src/sys/dev/pci/ixgbe/ixgbe.h:1.24.6.8 Fri Mar 30 12:07:34 2018
+++ src/sys/dev/pci/ixgbe/ixgbe.h Wed Apr 4 16:18:49 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.h,v 1.24.6.8 2018/03/30 12:07:34 martin Exp $ */
+/* $NetBSD: ixgbe.h,v 1.24.6.9 2018/04/04 16:18:49 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -339,8 +339,13 @@ struct ix_queue {
char namebuf[32];
char evnamebuf[32];
- kmutex_t im_mtx; /* lock for im_nest and this queue's EIMS/EIMC bit */
- int im_nest;
+ kmutex_t dc_mtx; /* lock for disabled_count and this queue's EIMS/EIMC bit */
+ int disabled_count;/*
+ * means
+ * 0 : this queue is enabled
+ * > 0 : this queue is disabled
+ * the value is ixgbe_disable_queue() called count
+ */
};
/*
@@ -370,8 +375,8 @@ struct tx_ring {
u16 atr_sample;
u16 atr_count;
- u32 bytes; /* used for AIM */
- u32 packets;
+ u64 bytes; /* used for AIM */
+ u64 packets;
/* Soft Stats */
struct evcnt tso_tx;
struct evcnt no_desc_avail;
@@ -413,8 +418,8 @@ struct rx_ring {
struct ixgbe_rx_buf *rx_buffers;
ixgbe_dma_tag_t *ptag;
- u32 bytes; /* Used for AIM calc */
- u32 packets;
+ u64 bytes; /* Used for AIM calc */
+ u64 packets;
/* Soft stats */
struct evcnt rx_copies;
@@ -741,6 +746,7 @@ int ixgbe_mq_start(struct ifnet *, stru
int ixgbe_mq_start_locked(struct ifnet *, struct tx_ring *);
void ixgbe_deferred_mq_start(void *);
void ixgbe_deferred_mq_start_work(struct work *, void *);
+void ixgbe_drain_all(struct adapter *);
int ixgbe_allocate_queues(struct adapter *);
int ixgbe_setup_transmit_structures(struct adapter *);
Index: src/sys/dev/pci/ixgbe/ixgbe_82599.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_82599.c:1.14.8.1 src/sys/dev/pci/ixgbe/ixgbe_82599.c:1.14.8.2
--- src/sys/dev/pci/ixgbe/ixgbe_82599.c:1.14.8.1 Thu Dec 21 19:28:54 2017
+++ src/sys/dev/pci/ixgbe/ixgbe_82599.c Wed Apr 4 16:18:49 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_82599.c,v 1.14.8.1 2017/12/21 19:28:54 snj Exp $ */
+/* $NetBSD: ixgbe_82599.c,v 1.14.8.2 2018/04/04 16:18:49 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -56,6 +56,7 @@ static s32 ixgbe_read_eeprom_82599(struc
u16 offset, u16 *data);
static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data);
+static s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw);
static s32 ixgbe_read_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 *data);
static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
@@ -914,9 +915,13 @@ s32 ixgbe_setup_mac_link_82599(struct ix
speed &= link_capabilities;
- if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
- status = IXGBE_ERR_LINK_SETUP;
- goto out;
+ if (speed == 0) {
+ ixgbe_disable_tx_laser(hw); /* For fiber */
+ ixgbe_set_phy_power(hw, false); /* For copper */
+ } else {
+ /* In case previous media setting was none(down) */
+ ixgbe_enable_tx_laser(hw); /* for Fiber */
+ ixgbe_set_phy_power(hw, true); /* For copper */
}
/* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
@@ -2475,7 +2480,7 @@ static s32 ixgbe_read_eeprom_82599(struc
* Reset pipeline by asserting Restart_AN together with LMS change to ensure
* full pipeline reset. This function assumes the SW/FW lock is held.
**/
-s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
{
s32 ret_val;
u32 anlp1_reg = 0;
Index: src/sys/dev/pci/ixgbe/ixgbe_api.h
diff -u src/sys/dev/pci/ixgbe/ixgbe_api.h:1.9.8.1 src/sys/dev/pci/ixgbe/ixgbe_api.h:1.9.8.2
--- src/sys/dev/pci/ixgbe/ixgbe_api.h:1.9.8.1 Thu Dec 21 19:28:54 2017
+++ src/sys/dev/pci/ixgbe/ixgbe_api.h Wed Apr 4 16:18:49 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_api.h,v 1.9.8.1 2017/12/21 19:28:54 snj Exp $ */
+/* $NetBSD: ixgbe_api.h,v 1.9.8.2 2018/04/04 16:18:49 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -227,4 +227,6 @@ void ixgbe_enable_rx(struct ixgbe_hw *hw
s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
+void ixgbe_ensure_disabled_intr(struct adapter *);
+
#endif /* _IXGBE_API_H_ */
Index: src/sys/dev/pci/ixgbe/ixgbe_common.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_common.c:1.13.2.2 src/sys/dev/pci/ixgbe/ixgbe_common.c:1.13.2.3
--- src/sys/dev/pci/ixgbe/ixgbe_common.c:1.13.2.2 Fri Mar 30 12:07:34 2018
+++ src/sys/dev/pci/ixgbe/ixgbe_common.c Wed Apr 4 16:18:49 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_common.c,v 1.13.2.2 2018/03/30 12:07:34 martin Exp $ */
+/* $NetBSD: ixgbe_common.c,v 1.13.2.3 2018/04/04 16:18:49 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -1130,7 +1130,27 @@ s32 ixgbe_stop_adapter_generic(struct ix
ixgbe_disable_rx(hw);
/* Clear interrupt mask to stop interrupts from being generated */
- IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
+ /*
+ * XXX
+ * This function is called in the state of both interrupt disabled
+ * and interrupt enabled, e.g.
+ * + interrupt disabled case:
+ * - ixgbe_stop()
+ * - ixgbe_disable_intr() // interrupt disabled here
+ * - ixgbe_stop_adapter()
+ * - hw->mac.ops.stop_adapter()
+ * == this function
+ * + interrupt enabled case:
+ * - ixgbe_local_timer1()
+ * - ixgbe_init_locked()
+ * - ixgbe_stop_adapter()
+ * - hw->mac.ops.stop_adapter()
+ * == this function
+ * Therefore, it causes nest status breaking to nest the status
+ * (that is, que->im_nest++) at all times. So, this function must
+ * use ixgbe_ensure_disabled_intr() instead of ixgbe_disable_intr().
+ */
+ ixgbe_ensure_disabled_intr(hw->back);
/* Clear any pending interrupts, flush previous writes */
IXGBE_READ_REG(hw, IXGBE_EICR);
@@ -5407,6 +5427,13 @@ s32 ixgbe_setup_mac_link_multispeed_fibe
goto out;
}
+ if (speed == 0) {
+ /* Disable the Tx laser for media none */
+ ixgbe_disable_tx_laser(hw);
+
+ goto out;
+ }
+
/* We didn't get link. Configure back to the highest speed we tried,
* (if there was more than one). We call ourselves back with just the
* single highest speed that the user requested.
Index: src/sys/dev/pci/ixgbe/ixgbe_common.h
diff -u src/sys/dev/pci/ixgbe/ixgbe_common.h:1.7.8.2 src/sys/dev/pci/ixgbe/ixgbe_common.h:1.7.8.3
--- src/sys/dev/pci/ixgbe/ixgbe_common.h:1.7.8.2 Fri Mar 30 12:07:34 2018
+++ src/sys/dev/pci/ixgbe/ixgbe_common.h Wed Apr 4 16:18:49 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe_common.h,v 1.7.8.2 2018/03/30 12:07:34 martin Exp $ */
+/* $NetBSD: ixgbe_common.h,v 1.7.8.3 2018/04/04 16:18:49 martin Exp $ */
/******************************************************************************
SPDX-License-Identifier: BSD-3-Clause
@@ -177,7 +177,6 @@ s32 ixgbe_bypass_set_generic(struct ixgb
u32 action);
s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value);
-extern s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw);
extern void ixgbe_stop_mac_link_on_d3_82599(struct ixgbe_hw *hw);
bool ixgbe_mng_present(struct ixgbe_hw *hw);
bool ixgbe_mng_enabled(struct ixgbe_hw *hw);
Index: src/sys/dev/pci/ixgbe/ixgbe_x550.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_x550.c:1.5.6.2 src/sys/dev/pci/ixgbe/ixgbe_x550.c:1.5.6.3
--- src/sys/dev/pci/ixgbe/ixgbe_x550.c:1.5.6.2 Fri Mar 30 12:07:34 2018
+++ src/sys/dev/pci/ixgbe/ixgbe_x550.c Wed Apr 4 16:18:49 2018
@@ -41,6 +41,9 @@
#include <dev/mii/mii.h>
static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed);
+static s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg_wait_to_complete);
static s32 ixgbe_acquire_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
static void ixgbe_release_swfw_sync_X550a(struct ixgbe_hw *, u32 mask);
static s32 ixgbe_read_mng_if_sel_x550em(struct ixgbe_hw *hw);
@@ -566,8 +569,15 @@ static s32 ixgbe_get_phy_id_fw(struct ix
if (phy_speeds & ixgbe_fw_map[i].fw_speed)
hw->phy.speeds_supported |= ixgbe_fw_map[i].phy_speed;
}
+
+#if 0
+ /*
+ * Don't set autoneg_advertised here to not to be inconsistent with
+ * if_media value.
+ */
if (!hw->phy.autoneg_advertised)
hw->phy.autoneg_advertised = hw->phy.speeds_supported;
+#endif
hw->phy.id = info[0] & FW_PHY_INFO_ID_HI_MASK;
phy_id_lo = info[1] & FW_PHY_INFO_ID_LO_MASK;
@@ -2840,6 +2850,9 @@ static s32 ixgbe_setup_sfi_x550a(struct
case IXGBE_LINK_SPEED_1GB_FULL:
reg_val |= IXGBE_KRM_PMD_FLX_MASK_ST20_SPEED_1G;
break;
+ case 0:
+ /* media none (linkdown) */
+ break;
default:
/* Other link speeds are not supported by internal PHY. */
return IXGBE_ERR_LINK_SETUP;
@@ -2861,7 +2874,7 @@ static s32 ixgbe_setup_sfi_x550a(struct
*
* Configure the the integrated PHY for SFP support.
**/
-s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
+static s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg_wait_to_complete)
{
Index: src/sys/dev/pci/ixgbe/ixgbe_x550.h
diff -u src/sys/dev/pci/ixgbe/ixgbe_x550.h:1.2.12.1 src/sys/dev/pci/ixgbe/ixgbe_x550.h:1.2.12.2
--- src/sys/dev/pci/ixgbe/ixgbe_x550.h:1.2.12.1 Thu Dec 21 19:28:54 2017
+++ src/sys/dev/pci/ixgbe/ixgbe_x550.h Wed Apr 4 16:18:49 2018
@@ -99,9 +99,6 @@ s32 ixgbe_setup_fc_X550em(struct ixgbe_h
s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg_wait_to_complete);
-s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
- ixgbe_link_speed speed,
- bool autoneg_wait_to_complete);
s32 ixgbe_read_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
u32 device_type, u16 *phy_data);
s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
Index: src/sys/dev/pci/ixgbe/ixv.c
diff -u src/sys/dev/pci/ixgbe/ixv.c:1.56.2.12 src/sys/dev/pci/ixgbe/ixv.c:1.56.2.13
--- src/sys/dev/pci/ixgbe/ixv.c:1.56.2.12 Fri Mar 30 12:07:34 2018
+++ src/sys/dev/pci/ixgbe/ixv.c Wed Apr 4 16:18:49 2018
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.56.2.12 2018/03/30 12:07:34 martin Exp $*/
+/*$NetBSD: ixv.c,v 1.56.2.13 2018/04/04 16:18:49 martin Exp $*/
/******************************************************************************
@@ -701,7 +701,7 @@ ixv_detach(device_t dev, int flags)
ixgbe_free_receive_structures(adapter);
for (int i = 0; i < adapter->num_queues; i++) {
struct ix_queue *lque = &adapter->queues[i];
- mutex_destroy(&lque->im_mtx);
+ mutex_destroy(&lque->dc_mtx);
}
free(adapter->queues, M_DEVBUF);
@@ -846,14 +846,14 @@ ixv_enable_queue(struct adapter *adapter
u32 queue = 1 << vector;
u32 mask;
- mutex_enter(&que->im_mtx);
- if (que->im_nest > 0 && --que->im_nest > 0)
+ mutex_enter(&que->dc_mtx);
+ if (que->disabled_count > 0 && --que->disabled_count > 0)
goto out;
mask = (IXGBE_EIMS_RTX_QUEUE & queue);
IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
out:
- mutex_exit(&que->im_mtx);
+ mutex_exit(&que->dc_mtx);
} /* ixv_enable_queue */
/************************************************************************
@@ -867,14 +867,14 @@ ixv_disable_queue(struct adapter *adapte
u64 queue = (u64)(1 << vector);
u32 mask;
- mutex_enter(&que->im_mtx);
- if (que->im_nest++ > 0)
+ mutex_enter(&que->dc_mtx);
+ if (que->disabled_count++ > 0)
goto out;
mask = (IXGBE_EIMS_RTX_QUEUE & queue);
IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, mask);
out:
- mutex_exit(&que->im_mtx);
+ mutex_exit(&que->dc_mtx);
} /* ixv_disable_queue */
static inline void