diff options
author | 2018-04-29 08:45:01 +0000 | |
---|---|---|
committer | 2018-04-29 08:45:01 +0000 | |
commit | fa0f1c7e10fbd6562392bd06c0b8c0e07856321b (patch) | |
tree | 910aed2698b1d7e06d73f0bdf19c4dff9e7b3e02 | |
parent | em: Improve access logic for software flag (diff) | |
download | wireguard-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.c | 12 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.h | 3 |
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 */ |