@@ -1,4 +1,4 @@
-/* $NetBSD: ixgbe.c,v 1.199.2.1 2019/09/01 11:07:05 martin Exp $ */
+/* $NetBSD: ixgbe.c,v 1.199.2.2 2019/09/01 11:12:45 martin Exp $ */
/******************************************************************************
@@ -222,8 +222,8 @@
static void ixgbe_setup_vlan_hw_tagging(struct adapter *);
static void ixgbe_setup_vlan_hw_support(struct adapter *);
static int ixgbe_vlan_cb(struct ethercom *, uint16_t, bool);
-static int ixgbe_register_vlan(void *, struct ifnet *, u16);
-static int ixgbe_unregister_vlan(void *, struct ifnet *, u16);
+static int ixgbe_register_vlan(struct adapter *, u16);
+static int ixgbe_unregister_vlan(struct adapter *, u16);
static void ixgbe_add_device_sysctls(struct adapter *);
static void ixgbe_add_hw_stats(struct adapter *);
@@ -1489,6 +1489,8 @@
return (TRUE);
return (FALSE);
case ixgbe_mac_82599EB:
+ case ixgbe_mac_X550EM_x:
+ case ixgbe_mac_X550EM_a:
switch (hw->mac.ops.get_media_type(hw)) {
case ixgbe_media_type_fiber:
case ixgbe_media_type_fiber_qsfp:
@@ -1496,11 +1498,6 @@
default:
return (FALSE);
}
- case ixgbe_mac_X550EM_x:
- case ixgbe_mac_X550EM_a:
- if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber)
- return (TRUE);
- return (FALSE);
default:
return (FALSE);
}
@@ -2310,9 +2307,9 @@
int rv;
if (set)
- rv = ixgbe_register_vlan(ifp->if_softc, ifp, vid);
+ rv = ixgbe_register_vlan(adapter, vid);
else
- rv = ixgbe_unregister_vlan(ifp->if_softc, ifp, vid);
+ rv = ixgbe_unregister_vlan(adapter, vid);
if (rv != 0)
return rv;
@@ -2336,15 +2333,11 @@
* VFTA, init will repopulate the real table.
************************************************************************/
static int
-ixgbe_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
+ixgbe_register_vlan(struct adapter *adapter, u16 vtag)
{
- struct adapter *adapter = ifp->if_softc;
u16 index, bit;
int error;
- if (ifp->if_softc != arg) /* Not our event */
- return EINVAL;
-
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
return EINVAL;
@@ -2367,15 +2360,11 @@
* Run via vlan unconfig EVENT, remove our entry in the soft vfta.
************************************************************************/
static int
-ixgbe_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
+ixgbe_unregister_vlan(struct adapter *adapter, u16 vtag)
{
- struct adapter *adapter = ifp->if_softc;
u16 index, bit;
int error;
- if (ifp->if_softc != arg)
- return EINVAL;
-
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
return EINVAL;
@@ -3124,6 +3113,34 @@
/* Clear interrupt with write */
IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
+ if (ixgbe_is_sfp(hw)) {
+ /* Pluggable optics-related interrupt */
+ if (hw->mac.type >= ixgbe_mac_X540)
+ eicr_mask = IXGBE_EICR_GPI_SDP0_X540;
+ else
+ eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw);
+
+ /*
+ * An interrupt might not arrive when a module is inserted.
+ * When an link status change interrupt occurred and the driver
+ * still regard SFP as unplugged, issue the module softint
+ * and then issue LSC interrupt.
+ */
+ if ((eicr & eicr_mask)
+ || ((hw->phy.sfp_type == ixgbe_sfp_type_not_present)
+ && (eicr & IXGBE_EICR_LSC))) {
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask);
+ softint_schedule(adapter->mod_si);
+ }
+
+ if ((hw->mac.type == ixgbe_mac_82599EB) &&
+ (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) {
+ IXGBE_WRITE_REG(hw, IXGBE_EICR,
+ IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
+ softint_schedule(adapter->msf_si);
+ }
+ }
+
/* Link status change */
if (eicr & IXGBE_EICR_LSC) {
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
@@ -3180,26 +3197,6 @@
if ((adapter->feat_en & IXGBE_FEATURE_SRIOV) &&
(eicr & IXGBE_EICR_MAILBOX))
softint_schedule(adapter->mbx_si);
- }
-
- if (ixgbe_is_sfp(hw)) {
- /* Pluggable optics-related interrupt */
- if (hw->mac.type >= ixgbe_mac_X540)
- eicr_mask = IXGBE_EICR_GPI_SDP0_X540;
- else
- eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw);
-
- if (eicr & eicr_mask) {
- IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask);
- softint_schedule(adapter->mod_si);
- }
-
- if ((hw->mac.type == ixgbe_mac_82599EB) &&
- (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) {
- IXGBE_WRITE_REG(hw, IXGBE_EICR,
- IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
- softint_schedule(adapter->msf_si);
- }
}
/* Check for fan failure */
@@ -1,4 +1,4 @@
-/*$NetBSD: ixv.c,v 1.125.2.1 2019/09/01 11:07:05 martin Exp $*/
+/*$NetBSD: ixv.c,v 1.125.2.2 2019/09/01 11:12:45 martin Exp $*/
/******************************************************************************
@@ -123,8 +123,8 @@
static void ixv_setup_vlan_tagging(struct adapter *);
static int ixv_setup_vlan_support(struct adapter *);
static int ixv_vlan_cb(struct ethercom *, uint16_t, bool);
-static int ixv_register_vlan(void *, struct ifnet *, u16);
-static int ixv_unregister_vlan(void *, struct ifnet *, u16);
+static int ixv_register_vlan(struct adapter *, u16);
+static int ixv_unregister_vlan(struct adapter *, u16);
static void ixv_add_device_sysctls(struct adapter *);
static void ixv_save_stats(struct adapter *);
@@ -2058,9 +2058,9 @@
int rv;
if (set)
- rv = ixv_register_vlan(ifp->if_softc, ifp, vid);
+ rv = ixv_register_vlan(adapter, vid);
else
- rv = ixv_unregister_vlan(ifp->if_softc, ifp, vid);
+ rv = ixv_unregister_vlan(adapter, vid);
if (rv != 0)
return rv;
@@ -2084,16 +2084,12 @@
* will repopulate the real table.
************************************************************************/
static int
-ixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
+ixv_register_vlan(struct adapter *adapter, u16 vtag)
{
- struct adapter *adapter = ifp->if_softc;
struct ixgbe_hw *hw = &adapter->hw;
u16 index, bit;
int error;
- if (ifp->if_softc != arg) /* Not our event */
- return EINVAL;
-
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
return EINVAL;
IXGBE_CORE_LOCK(adapter);
@@ -2118,15 +2114,11 @@
* in the soft vfta.
************************************************************************/
static int
-ixv_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
+ixv_unregister_vlan(struct adapter *adapter, u16 vtag)
{
- struct adapter *adapter = ifp->if_softc;
struct ixgbe_hw *hw = &adapter->hw;
u16 index, bit;
int error;
-
- if (ifp->if_softc != arg)
- return EINVAL;
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
return EINVAL;