summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsf <sf@openbsd.org>2018-04-29 08:45:01 +0000
committersf <sf@openbsd.org>2018-04-29 08:45:01 +0000
commitfa0f1c7e10fbd6562392bd06c0b8c0e07856321b (patch)
tree910aed2698b1d7e06d73f0bdf19c4dff9e7b3e02
parentem: Improve access logic for software flag (diff)
downloadwireguard-openbsd-fa0f1c7e10fbd6562392bd06c0b8c0e07856321b.tar.xz
wireguard-openbsd-fa0f1c7e10fbd6562392bd06c0b8c0e07856321b.zip
em: Make em_get_software_flag() recursive
The em driver calls em_get_software_flag() recursively, which causes the semaphore to be unlocked too early. Make em_get_software_flag and em_release_software_flag handle this correctly. Freebsd does not do this, but they have a mutex that probably allows them to detect recursive calls to e1000_acquire_swflag_ich8lan(). Reworking the openbsd driver to not recursively get the semaphore would be very invasive. ok mikeb@
-rw-r--r--sys/dev/pci/if_em_hw.c12
-rw-r--r--sys/dev/pci/if_em_hw.h3
2 files changed, 13 insertions, 2 deletions
diff --git a/sys/dev/pci/if_em_hw.c b/sys/dev/pci/if_em_hw.c
index a18214f270f..d7df8ebecac 100644
--- a/sys/dev/pci/if_em_hw.c
+++ b/sys/dev/pci/if_em_hw.c
@@ -31,7 +31,7 @@
*******************************************************************************/
-/* $OpenBSD: if_em_hw.c,v 1.100 2018/04/29 08:42:16 sf Exp $ */
+/* $OpenBSD: if_em_hw.c,v 1.101 2018/04/29 08:45:01 sf Exp $ */
/*
* if_em_hw.c Shared functions for accessing and configuring the MAC
*/
@@ -945,6 +945,8 @@ em_reset_hw(struct em_hw *hw)
}
em_get_software_flag(hw);
E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+ /* HW reset releases software_flag */
+ hw->sw_flag = 0;
msec_delay(20);
/* Ungate automatic PHY configuration on non-managed 82579 */
@@ -9611,6 +9613,10 @@ em_get_software_flag(struct em_hw *hw)
DEBUGFUNC("em_get_software_flag");
if (IS_ICH8(hw->mac_type)) {
+ if (hw->sw_flag) {
+ hw->sw_flag++;
+ return E1000_SUCCESS;
+ }
while (timeout) {
extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG))
@@ -9644,6 +9650,7 @@ em_get_software_flag(struct em_hw *hw)
return -E1000_ERR_CONFIG;
}
}
+ hw->sw_flag++;
return E1000_SUCCESS;
}
@@ -9663,6 +9670,9 @@ em_release_software_flag(struct em_hw *hw)
DEBUGFUNC("em_release_software_flag");
if (IS_ICH8(hw->mac_type)) {
+ KASSERT(hw->sw_flag > 0);
+ if (--hw->sw_flag > 0)
+ return;
extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
diff --git a/sys/dev/pci/if_em_hw.h b/sys/dev/pci/if_em_hw.h
index bb0a5d4fdb2..7ad3b5f0759 100644
--- a/sys/dev/pci/if_em_hw.h
+++ b/sys/dev/pci/if_em_hw.h
@@ -31,7 +31,7 @@
*******************************************************************************/
-/* $OpenBSD: if_em_hw.h,v 1.75 2018/04/29 08:42:16 sf Exp $ */
+/* $OpenBSD: if_em_hw.h,v 1.76 2018/04/29 08:45:01 sf Exp $ */
/* $FreeBSD: if_em_hw.h,v 1.15 2005/05/26 23:32:02 tackerman Exp $ */
/* if_em_hw.h
@@ -1634,6 +1634,7 @@ struct em_hw {
uint8_t bus_func;
uint16_t swfw;
boolean_t eee_enable;
+ int sw_flag;
};
#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */