Module Name: src
Committed By: msaitoh
Date: Fri Oct 21 04:41:09 UTC 2016
Modified Files:
src/sys/dev/pci: if_wm.c
Log Message:
- Rewrite PHY related lock stuff. Almost the same as FreeBSD.
This change will fix a bug that PHY read/write fail on some cases.
- Increase delay in wm_phy_resetisblocked(). Same as FreeBSD.
- Use semaphore in wm_hv_phy_workaround_ich8lan() and wm_k1_gig_workaround_hv()
To generate a diff of this commit:
cvs rdiff -u -r1.423 -r1.424 src/sys/dev/pci/if_wm.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/if_wm.c
diff -u src/sys/dev/pci/if_wm.c:1.423 src/sys/dev/pci/if_wm.c:1.424
--- src/sys/dev/pci/if_wm.c:1.423 Thu Oct 20 08:03:13 2016
+++ src/sys/dev/pci/if_wm.c Fri Oct 21 04:41:09 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.423 2016/10/20 08:03:13 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.424 2016/10/21 04:41:09 msaitoh Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -84,7 +84,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.423 2016/10/20 08:03:13 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.424 2016/10/21 04:41:09 msaitoh Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -389,6 +389,11 @@ struct wm_queue {
struct wm_rxqueue wmq_rxq;
};
+struct wm_phyop {
+ int (*acquire)(struct wm_softc *);
+ void (*release)(struct wm_softc *);
+};
+
/*
* Software state per device.
*/
@@ -494,10 +499,17 @@ struct wm_softc {
krndsource_t rnd_source; /* random source */
+ struct if_percpuq *sc_ipq; /* softint-based input queues */
+
kmutex_t *sc_core_lock; /* lock for softc operations */
+ kmutex_t *sc_ich_phymtx; /*
+ * 82574/82583/ICH/PCH specific PHY
+ * mutex. For 82574/82583, the mutex
+ * is used for both PHY and NVM.
+ */
kmutex_t *sc_ich_nvmmtx; /* ICH/PCH specific NVM mutex */
- struct if_percpuq *sc_ipq; /* softint-based input queues */
+ struct wm_phyop phy;
};
#define WM_CORE_LOCK(_sc) if ((_sc)->sc_core_lock) mutex_enter((_sc)->sc_core_lock)
@@ -699,6 +711,8 @@ static void wm_i82543_mii_sendbits(struc
static uint32_t wm_i82543_mii_recvbits(struct wm_softc *);
static int wm_gmii_i82543_readreg(device_t, int, int);
static void wm_gmii_i82543_writereg(device_t, int, int, int);
+static int wm_gmii_mdic_readreg(device_t, int, int);
+static void wm_gmii_mdic_writereg(device_t, int, int, int);
static int wm_gmii_i82544_readreg(device_t, int, int);
static void wm_gmii_i82544_writereg(device_t, int, int, int);
static int wm_gmii_i80003_readreg(device_t, int, int);
@@ -707,14 +721,18 @@ static int wm_gmii_bm_readreg(device_t,
static void wm_gmii_bm_writereg(device_t, int, int, int);
static void wm_access_phy_wakeup_reg_bm(device_t, int, int16_t *, int);
static int wm_gmii_hv_readreg(device_t, int, int);
+static int wm_gmii_hv_readreg_locked(device_t, int, int);
static void wm_gmii_hv_writereg(device_t, int, int, int);
+static void wm_gmii_hv_writereg_locked(device_t, int, int, int);
static int wm_gmii_82580_readreg(device_t, int, int);
static void wm_gmii_82580_writereg(device_t, int, int, int);
static int wm_gmii_gs40g_readreg(device_t, int, int);
static void wm_gmii_gs40g_writereg(device_t, int, int, int);
static void wm_gmii_statchg(struct ifnet *);
static int wm_kmrn_readreg(struct wm_softc *, int);
+static int wm_kmrn_readreg_locked(struct wm_softc *, int);
static void wm_kmrn_writereg(struct wm_softc *, int, int);
+static void wm_kmrn_writereg_locked(struct wm_softc *, int, int);
/* SGMII */
static bool wm_sgmii_uses_mdio(struct wm_softc *);
static int wm_sgmii_readreg(device_t, int, int);
@@ -779,12 +797,18 @@ static int wm_nvm_read(struct wm_softc *
* Hardware semaphores.
* Very complexed...
*/
-static int wm_get_swsm_semaphore(struct wm_softc *);
+static int wm_get_null(struct wm_softc *);
+static void wm_put_null(struct wm_softc *);
+static int wm_get_swsm_semaphore(struct wm_softc *); /* 8257[123] */
static void wm_put_swsm_semaphore(struct wm_softc *);
static int wm_get_swfw_semaphore(struct wm_softc *, uint16_t);
static void wm_put_swfw_semaphore(struct wm_softc *, uint16_t);
-static int wm_get_swfwhw_semaphore(struct wm_softc *);
+static int wm_get_phy_82575(struct wm_softc *);
+static void wm_put_phy_82575(struct wm_softc *);
+static int wm_get_swfwhw_semaphore(struct wm_softc *); /* For 574/583 */
static void wm_put_swfwhw_semaphore(struct wm_softc *);
+static int wm_get_swflag_ich8lan(struct wm_softc *); /* For PHY */
+static void wm_put_swflag_ich8lan(struct wm_softc *);
static int wm_get_nvm_ich8lan(struct wm_softc *); /* For NVM */
static void wm_put_nvm_ich8lan(struct wm_softc *);
static int wm_get_hw_semaphore_82573(struct wm_softc *);
@@ -828,7 +852,7 @@ static void wm_kmrn_lock_loss_workaround
static void wm_gig_downshift_workaround_ich8lan(struct wm_softc *);
static void wm_hv_phy_workaround_ich8lan(struct wm_softc *);
static void wm_lv_phy_workaround_ich8lan(struct wm_softc *);
-static void wm_k1_gig_workaround_hv(struct wm_softc *, int);
+static int wm_k1_gig_workaround_hv(struct wm_softc *, int);
static void wm_set_mdio_slow_mode_hv(struct wm_softc *);
static void wm_configure_k1_ich8lan(struct wm_softc *, int);
static void wm_reset_init_script_82575(struct wm_softc *);
@@ -1596,6 +1620,11 @@ wm_attach(device_t parent, device_t self
pci_aprint_devinfo_fancy(pa, "Ethernet controller", wmp->wmp_name, 1);
sc->sc_type = wmp->wmp_type;
+
+ /* Set default function pointers */
+ sc->phy.acquire = wm_get_null;
+ sc->phy.release = wm_put_null;
+
if (sc->sc_type < WM_T_82543) {
if (sc->sc_rev < 2) {
aprint_error_dev(sc->sc_dev,
@@ -1899,6 +1928,9 @@ alloc_retry:
|| (sc->sc_type == WM_T_PCH_LPT) || (sc->sc_type == WM_T_PCH_SPT))
wm_smbustopci(sc);
+ if ((sc->sc_type == WM_T_82574) || (sc->sc_type == WM_T_82583)
+ || (sc->sc_type >= WM_T_ICH8))
+ sc->sc_ich_phymtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
if (sc->sc_type >= WM_T_ICH8)
sc->sc_ich_nvmmtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
@@ -1955,12 +1987,24 @@ alloc_retry:
sc->sc_flags |= WM_F_EEPROM_SPI;
wm_nvm_set_addrbits_size_eecd(sc);
sc->sc_flags |= WM_F_LOCK_EECD | WM_F_LOCK_SWSM;
+ sc->phy.acquire = wm_get_swsm_semaphore;
+ sc->phy.release = wm_put_swsm_semaphore;
break;
case WM_T_82573:
- sc->sc_flags |= WM_F_LOCK_SWSM;
- /* FALLTHROUGH */
case WM_T_82574:
case WM_T_82583:
+ if (sc->sc_type == WM_T_82573) {
+ sc->sc_flags |= WM_F_LOCK_SWSM;
+ sc->phy.acquire = wm_get_swsm_semaphore;
+ sc->phy.release = wm_put_swsm_semaphore;
+ } else {
+ sc->sc_flags |= WM_F_LOCK_EXTCNF;
+ /* Both PHY and NVM use the same semaphore. */
+ sc->phy.acquire
+ = wm_get_swfwhw_semaphore;
+ sc->phy.release
+ = wm_put_swfwhw_semaphore;
+ }
if (wm_nvm_is_onboard_eeprom(sc) == 0) {
sc->sc_flags |= WM_F_EEPROM_FLASH;
sc->sc_nvm_wordsize = 2048;
@@ -1982,6 +2026,8 @@ alloc_retry:
wm_nvm_set_addrbits_size_eecd(sc);
sc->sc_flags |= WM_F_EEPROM_EERDEEWR | WM_F_LOCK_SWFW
| WM_F_LOCK_SWSM;
+ sc->phy.acquire = wm_get_phy_82575;
+ sc->phy.release = wm_put_phy_82575;
break;
case WM_T_ICH8:
case WM_T_ICH9:
@@ -2008,6 +2054,8 @@ alloc_retry:
sc->sc_ich8_flash_bank_size *= ICH_FLASH_SECTOR_SIZE;
sc->sc_ich8_flash_bank_size /= 2 * sizeof(uint16_t);
sc->sc_flashreg_offset = 0;
+ sc->phy.acquire = wm_get_swflag_ich8lan;
+ sc->phy.release = wm_put_swflag_ich8lan;
break;
case WM_T_PCH_SPT:
/* SPT has no GFPREG; flash registers mapped through BAR0 */
@@ -2023,18 +2071,22 @@ alloc_retry:
/* assume 2 banks */
sc->sc_ich8_flash_bank_size = sc->sc_nvm_wordsize / 2;
sc->sc_flashreg_offset = WM_PCH_SPT_FLASHOFFSET;
+ sc->phy.acquire = wm_get_swflag_ich8lan;
+ sc->phy.release = wm_put_swflag_ich8lan;
break;
case WM_T_I210:
case WM_T_I211:
if (wm_nvm_get_flash_presence_i210(sc)) {
wm_nvm_set_addrbits_size_eecd(sc);
sc->sc_flags |= WM_F_EEPROM_FLASH_HW;
- sc->sc_flags |= WM_F_EEPROM_EERDEEWR | WM_F_LOCK_SWFW;
+ sc->sc_flags |= WM_F_EEPROM_EERDEEWR;
} else {
sc->sc_nvm_wordsize = INVM_SIZE;
sc->sc_flags |= WM_F_EEPROM_INVM;
- sc->sc_flags |= WM_F_LOCK_SWFW;
}
+ sc->sc_flags |= WM_F_LOCK_SWFW | WM_F_LOCK_SWSM;
+ sc->phy.acquire = wm_get_phy_82575;
+ sc->phy.release = wm_put_phy_82575;
break;
default:
break;
@@ -2667,6 +2719,8 @@ wm_detach(device_t self, int flags __unu
if (sc->sc_core_lock)
mutex_obj_free(sc->sc_core_lock);
+ if (sc->sc_ich_phymtx)
+ mutex_obj_free(sc->sc_ich_phymtx);
if (sc->sc_ich_nvmmtx)
mutex_obj_free(sc->sc_ich_nvmmtx);
@@ -3016,8 +3070,7 @@ wm_read_mac_addr(struct wm_softc *sc, ui
break;
}
- if (wm_nvm_read(sc, offset, sizeof(myea) / sizeof(myea[0]),
- myea) != 0)
+ if (wm_nvm_read(sc, offset, sizeof(myea) / sizeof(myea[0]), myea) != 0)
goto bad;
enaddr[0] = myea[0] & 0xff;
@@ -3687,7 +3740,7 @@ wm_reset(struct wm_softc *sc)
{
int phy_reset = 0;
int i, error = 0;
- uint32_t reg, mask;
+ uint32_t reg;
DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
@@ -3861,11 +3914,10 @@ wm_reset(struct wm_softc *sc)
CSR_WRITE(sc, WMREG_CTRL_SHADOW, CTRL_RST);
break;
case WM_T_80003:
- mask = swfwphysem[sc->sc_funcid];
reg = CSR_READ(sc, WMREG_CTRL) | CTRL_RST;
- wm_get_swfw_semaphore(sc, mask);
+ sc->phy.acquire(sc);
CSR_WRITE(sc, WMREG_CTRL, reg);
- wm_put_swfw_semaphore(sc, mask);
+ sc->phy.release(sc);
break;
case WM_T_ICH8:
case WM_T_ICH9:
@@ -3889,11 +3941,11 @@ wm_reset(struct wm_softc *sc)
phy_reset = 1;
} else
printf("XXX reset is blocked!!!\n");
- wm_get_swfwhw_semaphore(sc);
+ sc->phy.acquire(sc);
CSR_WRITE(sc, WMREG_CTRL, reg);
/* Don't insert a completion barrier when reset */
delay(20*1000);
- wm_put_swfwhw_semaphore(sc);
+ mutex_exit(sc->sc_ich_phymtx);
break;
case WM_T_82580:
case WM_T_I350:
@@ -7805,40 +7857,7 @@ wm_gmii_reset(struct wm_softc *sc)
DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
- /* Get phy semaphore */
- switch (sc->sc_type) {
- case WM_T_82571:
- case WM_T_82572:
- case WM_T_82573:
- case WM_T_82574:
- case WM_T_82583:
- /* XXX should get sw semaphore, too */
- rv = wm_get_swsm_semaphore(sc);
- break;
- case WM_T_82575:
- case WM_T_82576:
- case WM_T_82580:
- case WM_T_I350:
- case WM_T_I354:
- case WM_T_I210:
- case WM_T_I211:
- case WM_T_80003:
- rv = wm_get_swfw_semaphore(sc, swfwphysem[sc->sc_funcid]);
- break;
- case WM_T_ICH8:
- case WM_T_ICH9:
- case WM_T_ICH10:
- case WM_T_PCH:
- case WM_T_PCH2:
- case WM_T_PCH_LPT:
- case WM_T_PCH_SPT:
- rv = wm_get_swfwhw_semaphore(sc);
- break;
- default:
- /* nothing to do*/
- rv = 0;
- break;
- }
+ rv = sc->phy.acquire(sc);
if (rv != 0) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
@@ -7938,40 +7957,7 @@ wm_gmii_reset(struct wm_softc *sc)
break;
}
- /* release PHY semaphore */
- switch (sc->sc_type) {
- case WM_T_82571:
- case WM_T_82572:
- case WM_T_82573:
- case WM_T_82574:
- case WM_T_82583:
- /* XXX should put sw semaphore, too */
- wm_put_swsm_semaphore(sc);
- break;
- case WM_T_82575:
- case WM_T_82576:
- case WM_T_82580:
- case WM_T_I350:
- case WM_T_I354:
- case WM_T_I210:
- case WM_T_I211:
- case WM_T_80003:
- wm_put_swfw_semaphore(sc, swfwphysem[sc->sc_funcid]);
- break;
- case WM_T_ICH8:
- case WM_T_ICH9:
- case WM_T_ICH10:
- case WM_T_PCH:
- case WM_T_PCH2:
- case WM_T_PCH_LPT:
- case WM_T_PCH_SPT:
- wm_put_swfwhw_semaphore(sc);
- break;
- default:
- /* nothing to do */
- rv = 0;
- break;
- }
+ sc->phy.release(sc);
/* get_cfg_done */
wm_get_cfg_done(sc);
@@ -8479,12 +8465,12 @@ wm_gmii_i82543_writereg(device_t self, i
}
/*
- * wm_gmii_i82544_readreg: [mii interface function]
+ * wm_gmii_mdic_readreg: [mii interface function]
*
* Read a PHY register on the GMII.
*/
static int
-wm_gmii_i82544_readreg(device_t self, int phy, int reg)
+wm_gmii_mdic_readreg(device_t self, int phy, int reg)
{
struct wm_softc *sc = device_private(self);
uint32_t mdic = 0;
@@ -8520,12 +8506,12 @@ wm_gmii_i82544_readreg(device_t self, in
}
/*
- * wm_gmii_i82544_writereg: [mii interface function]
+ * wm_gmii_mdic_writereg: [mii interface function]
*
* Write a PHY register on the GMII.
*/
static void
-wm_gmii_i82544_writereg(device_t self, int phy, int reg, int val)
+wm_gmii_mdic_writereg(device_t self, int phy, int reg, int val)
{
struct wm_softc *sc = device_private(self);
uint32_t mdic = 0;
@@ -8550,6 +8536,46 @@ wm_gmii_i82544_writereg(device_t self, i
}
/*
+ * wm_gmii_i82544_readreg: [mii interface function]
+ *
+ * Read a PHY register on the GMII.
+ */
+static int
+wm_gmii_i82544_readreg(device_t self, int phy, int reg)
+{
+ struct wm_softc *sc = device_private(self);
+ int rv;
+
+ if (sc->phy.acquire(sc)) {
+ aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+ __func__);
+ return 0;
+ }
+ rv = wm_gmii_mdic_readreg(self, phy, reg);
+ sc->phy.release(sc);
+
+ return rv;
+}
+
+/*
+ * wm_gmii_i82544_writereg: [mii interface function]
+ *
+ * Write a PHY register on the GMII.
+ */
+static void
+wm_gmii_i82544_writereg(device_t self, int phy, int reg, int val)
+{
+ struct wm_softc *sc = device_private(self);
+
+ if (sc->phy.acquire(sc)) {
+ aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
+ __func__);
+ }
+ wm_gmii_mdic_writereg(self, phy, reg, val);
+ sc->phy.release(sc);
+}
+
+/*
* wm_gmii_i80003_readreg: [mii interface function]
*
* Read a PHY register on the kumeran
@@ -8560,32 +8586,30 @@ static int
wm_gmii_i80003_readreg(device_t self, int phy, int reg)
{
struct wm_softc *sc = device_private(self);
- int sem;
int rv;
if (phy != 1) /* only one PHY on kumeran bus */
return 0;
- sem = swfwphysem[sc->sc_funcid];
- if (wm_get_swfw_semaphore(sc, sem)) {
+ if (sc->phy.acquire(sc)) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return 0;
}
if ((reg & GG82563_MAX_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
- wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT,
+ wm_gmii_mdic_writereg(self, phy, GG82563_PHY_PAGE_SELECT,
reg >> GG82563_PAGE_SHIFT);
} else {
- wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT_ALT,
+ wm_gmii_mdic_writereg(self, phy, GG82563_PHY_PAGE_SELECT_ALT,
reg >> GG82563_PAGE_SHIFT);
}
/* Wait more 200us for a bug of the ready bit in the MDIC register */
delay(200);
- rv = wm_gmii_i82544_readreg(self, phy, reg & GG82563_MAX_REG_ADDRESS);
+ rv = wm_gmii_mdic_readreg(self, phy, reg & GG82563_MAX_REG_ADDRESS);
delay(200);
+ sc->phy.release(sc);
- wm_put_swfw_semaphore(sc, sem);
return rv;
}
@@ -8600,31 +8624,29 @@ static void
wm_gmii_i80003_writereg(device_t self, int phy, int reg, int val)
{
struct wm_softc *sc = device_private(self);
- int sem;
if (phy != 1) /* only one PHY on kumeran bus */
return;
- sem = swfwphysem[sc->sc_funcid];
- if (wm_get_swfw_semaphore(sc, sem)) {
+ if (sc->phy.acquire(sc)) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return;
}
if ((reg & GG82563_MAX_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
- wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT,
+ wm_gmii_mdic_writereg(self, phy, GG82563_PHY_PAGE_SELECT,
reg >> GG82563_PAGE_SHIFT);
} else {
- wm_gmii_i82544_writereg(self, phy, GG82563_PHY_PAGE_SELECT_ALT,
+ wm_gmii_mdic_writereg(self, phy, GG82563_PHY_PAGE_SELECT_ALT,
reg >> GG82563_PAGE_SHIFT);
}
/* Wait more 200us for a bug of the ready bit in the MDIC register */
delay(200);
- wm_gmii_i82544_writereg(self, phy, reg & GG82563_MAX_REG_ADDRESS, val);
+ wm_gmii_mdic_writereg(self, phy, reg & GG82563_MAX_REG_ADDRESS, val);
delay(200);
- wm_put_swfw_semaphore(sc, sem);
+ sc->phy.release(sc);
}
/*
@@ -8638,11 +8660,9 @@ static int
wm_gmii_bm_readreg(device_t self, int phy, int reg)
{
struct wm_softc *sc = device_private(self);
- int sem;
int rv;
- sem = swfwphysem[sc->sc_funcid];
- if (wm_get_swfw_semaphore(sc, sem)) {
+ if (sc->phy.acquire(sc)) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return 0;
@@ -8650,16 +8670,16 @@ wm_gmii_bm_readreg(device_t self, int ph
if (reg > BME1000_MAX_MULTI_PAGE_REG) {
if (phy == 1)
- wm_gmii_i82544_writereg(self, phy,
+ wm_gmii_mdic_writereg(self, phy,
MII_IGPHY_PAGE_SELECT, reg);
else
- wm_gmii_i82544_writereg(self, phy,
+ wm_gmii_mdic_writereg(self, phy,
GG82563_PHY_PAGE_SELECT,
reg >> GG82563_PAGE_SHIFT);
}
- rv = wm_gmii_i82544_readreg(self, phy, reg & GG82563_MAX_REG_ADDRESS);
- wm_put_swfw_semaphore(sc, sem);
+ rv = wm_gmii_mdic_readreg(self, phy, reg & GG82563_MAX_REG_ADDRESS);
+ sc->phy.release(sc);
return rv;
}
@@ -8674,10 +8694,8 @@ static void
wm_gmii_bm_writereg(device_t self, int phy, int reg, int val)
{
struct wm_softc *sc = device_private(self);
- int sem;
- sem = swfwphysem[sc->sc_funcid];
- if (wm_get_swfw_semaphore(sc, sem)) {
+ if (sc->phy.acquire(sc)) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return;
@@ -8685,16 +8703,16 @@ wm_gmii_bm_writereg(device_t self, int p
if (reg > BME1000_MAX_MULTI_PAGE_REG) {
if (phy == 1)
- wm_gmii_i82544_writereg(self, phy,
+ wm_gmii_mdic_writereg(self, phy,
MII_IGPHY_PAGE_SELECT, reg);
else
- wm_gmii_i82544_writereg(self, phy,
+ wm_gmii_mdic_writereg(self, phy,
GG82563_PHY_PAGE_SELECT,
reg >> GG82563_PAGE_SHIFT);
}
- wm_gmii_i82544_writereg(self, phy, reg & GG82563_MAX_REG_ADDRESS, val);
- wm_put_swfw_semaphore(sc, sem);
+ wm_gmii_mdic_writereg(self, phy, reg & GG82563_MAX_REG_ADDRESS, val);
+ sc->phy.release(sc);
}
static void
@@ -8749,17 +8767,28 @@ static int
wm_gmii_hv_readreg(device_t self, int phy, int reg)
{
struct wm_softc *sc = device_private(self);
- uint16_t page = BM_PHY_REG_PAGE(reg);
- uint16_t regnum = BM_PHY_REG_NUM(reg);
- uint16_t val;
int rv;
- if (wm_get_swfwhw_semaphore(sc)) {
+ if (sc->phy.acquire(sc)) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return 0;
}
+ rv = wm_gmii_hv_readreg_locked(self, phy, reg);
+ sc->phy.release(sc);
+ return rv;
+}
+
+static int
+wm_gmii_hv_readreg_locked(device_t self, int phy, int reg)
+{
+ struct wm_softc *sc = device_private(self);
+ uint16_t page = BM_PHY_REG_PAGE(reg);
+ uint16_t regnum = BM_PHY_REG_NUM(reg);
+ uint16_t val;
+ int rv;
+
/* XXX Workaround failure in MDIO access while cable is disconnected */
if (sc->sc_phytype == WMPHY_82577) {
/* XXX must write */
@@ -8781,12 +8810,11 @@ wm_gmii_hv_readreg(device_t self, int ph
}
if (regnum > BME1000_MAX_MULTI_PAGE_REG) {
- wm_gmii_i82544_writereg(self, 1, MII_IGPHY_PAGE_SELECT,
+ wm_gmii_mdic_writereg(self, 1, MII_IGPHY_PAGE_SELECT,
page << BME1000_PAGE_SHIFT);
}
- rv = wm_gmii_i82544_readreg(self, phy, regnum & IGPHY_MAXREGADDR);
- wm_put_swfwhw_semaphore(sc);
+ rv = wm_gmii_mdic_readreg(self, phy, regnum & IGPHY_MAXREGADDR);
return rv;
}
@@ -8801,15 +8829,23 @@ static void
wm_gmii_hv_writereg(device_t self, int phy, int reg, int val)
{
struct wm_softc *sc = device_private(self);
- uint16_t page = BM_PHY_REG_PAGE(reg);
- uint16_t regnum = BM_PHY_REG_NUM(reg);
- if (wm_get_swfwhw_semaphore(sc)) {
+ if (sc->phy.acquire(sc)) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return;
}
+ wm_gmii_hv_writereg_locked(self, phy, reg, val);
+ sc->phy.release(sc);
+}
+
+static void
+wm_gmii_hv_writereg_locked(device_t self, int phy, int reg, int val)
+{
+ uint16_t page = BM_PHY_REG_PAGE(reg);
+ uint16_t regnum = BM_PHY_REG_NUM(reg);
+
/* XXX Workaround failure in MDIO access while cable is disconnected */
/* Page 800 works differently than the rest so it has its own func */
@@ -8836,12 +8872,11 @@ wm_gmii_hv_writereg(device_t self, int p
*/
if (regnum > BME1000_MAX_MULTI_PAGE_REG) {
- wm_gmii_i82544_writereg(self, 1, MII_IGPHY_PAGE_SELECT,
+ wm_gmii_mdic_writereg(self, 1, MII_IGPHY_PAGE_SELECT,
page << BME1000_PAGE_SHIFT);
}
- wm_gmii_i82544_writereg(self, phy, regnum & IGPHY_MAXREGADDR, val);
- wm_put_swfwhw_semaphore(sc);
+ wm_gmii_mdic_writereg(self, phy, regnum & IGPHY_MAXREGADDR, val);
}
/*
@@ -8855,19 +8890,17 @@ static int
wm_gmii_82580_readreg(device_t self, int phy, int reg)
{
struct wm_softc *sc = device_private(self);
- int sem;
int rv;
- sem = swfwphysem[sc->sc_funcid];
- if (wm_get_swfw_semaphore(sc, sem)) {
+ if (sc->phy.acquire(sc) != 0) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return 0;
}
- rv = wm_gmii_i82544_readreg(self, phy, reg);
+ rv = wm_gmii_mdic_readreg(self, phy, reg);
- wm_put_swfw_semaphore(sc, sem);
+ sc->phy.release(sc);
return rv;
}
@@ -8882,18 +8915,16 @@ static void
wm_gmii_82580_writereg(device_t self, int phy, int reg, int val)
{
struct wm_softc *sc = device_private(self);
- int sem;
- sem = swfwphysem[sc->sc_funcid];
- if (wm_get_swfw_semaphore(sc, sem)) {
+ if (sc->phy.acquire(sc) != 0) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return;
}
- wm_gmii_i82544_writereg(self, phy, reg, val);
+ wm_gmii_mdic_writereg(self, phy, reg, val);
- wm_put_swfw_semaphore(sc, sem);
+ sc->phy.release(sc);
}
/*
@@ -8907,13 +8938,11 @@ static int
wm_gmii_gs40g_readreg(device_t self, int phy, int reg)
{
struct wm_softc *sc = device_private(self);
- int sem;
int page, offset;
int rv;
/* Acquire semaphore */
- sem = swfwphysem[sc->sc_funcid];
- if (wm_get_swfw_semaphore(sc, sem)) {
+ if (sc->phy.acquire(sc)) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return 0;
@@ -8921,13 +8950,13 @@ wm_gmii_gs40g_readreg(device_t self, int
/* Page select */
page = reg >> GS40G_PAGE_SHIFT;
- wm_gmii_i82544_writereg(self, phy, GS40G_PAGE_SELECT, page);
+ wm_gmii_mdic_writereg(self, phy, GS40G_PAGE_SELECT, page);
/* Read reg */
offset = reg & GS40G_OFFSET_MASK;
- rv = wm_gmii_i82544_readreg(self, phy, offset);
+ rv = wm_gmii_mdic_readreg(self, phy, offset);
- wm_put_swfw_semaphore(sc, sem);
+ sc->phy.release(sc);
return rv;
}
@@ -8942,12 +8971,10 @@ static void
wm_gmii_gs40g_writereg(device_t self, int phy, int reg, int val)
{
struct wm_softc *sc = device_private(self);
- int sem;
int page, offset;
/* Acquire semaphore */
- sem = swfwphysem[sc->sc_funcid];
- if (wm_get_swfw_semaphore(sc, sem)) {
+ if (sc->phy.acquire(sc)) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return;
@@ -8955,14 +8982,14 @@ wm_gmii_gs40g_writereg(device_t self, in
/* Page select */
page = reg >> GS40G_PAGE_SHIFT;
- wm_gmii_i82544_writereg(self, phy, GS40G_PAGE_SELECT, page);
+ wm_gmii_mdic_writereg(self, phy, GS40G_PAGE_SELECT, page);
/* Write reg */
offset = reg & GS40G_OFFSET_MASK;
- wm_gmii_i82544_writereg(self, phy, offset, val);
+ wm_gmii_mdic_writereg(self, phy, offset, val);
/* Release semaphore */
- wm_put_swfw_semaphore(sc, sem);
+ sc->phy.release(sc);
}
/*
@@ -9039,20 +9066,31 @@ wm_kmrn_readreg(struct wm_softc *sc, int
{
int rv;
- if (sc->sc_flags & WM_F_LOCK_SWFW) {
- if (wm_get_swfw_semaphore(sc, SWFW_MAC_CSR_SM)) {
- aprint_error_dev(sc->sc_dev,
- "%s: failed to get semaphore\n", __func__);
- return 0;
- }
- } else if (sc->sc_flags & WM_F_LOCK_EXTCNF) {
- if (wm_get_swfwhw_semaphore(sc)) {
- aprint_error_dev(sc->sc_dev,
- "%s: failed to get semaphore\n", __func__);
- return 0;
- }
+ if (sc->sc_type == WM_T_80003)
+ rv = wm_get_swfw_semaphore(sc, SWFW_MAC_CSR_SM);
+ else
+ rv = sc->phy.acquire(sc);
+ if (rv != 0) {
+ aprint_error_dev(sc->sc_dev,
+ "%s: failed to get semaphore\n", __func__);
+ return 0;
}
+ wm_kmrn_readreg_locked(sc, reg);
+
+ if (sc->sc_type == WM_T_80003)
+ wm_put_swfw_semaphore(sc, SWFW_MAC_CSR_SM);
+ else
+ sc->phy.release(sc);
+
+ return rv;
+}
+
+static int
+wm_kmrn_readreg_locked(struct wm_softc *sc, int reg)
+{
+ int rv;
+
CSR_WRITE(sc, WMREG_KUMCTRLSTA,
((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) |
KUMCTRLSTA_REN);
@@ -9061,11 +9099,6 @@ wm_kmrn_readreg(struct wm_softc *sc, int
rv = CSR_READ(sc, WMREG_KUMCTRLSTA) & KUMCTRLSTA_MASK;
- if (sc->sc_flags & WM_F_LOCK_SWFW)
- wm_put_swfw_semaphore(sc, SWFW_MAC_CSR_SM);
- else if (sc->sc_flags & WM_F_LOCK_EXTCNF)
- wm_put_swfwhw_semaphore(sc);
-
return rv;
}
@@ -9077,29 +9110,33 @@ wm_kmrn_readreg(struct wm_softc *sc, int
static void
wm_kmrn_writereg(struct wm_softc *sc, int reg, int val)
{
+ int rv;
- if (sc->sc_flags & WM_F_LOCK_SWFW) {
- if (wm_get_swfw_semaphore(sc, SWFW_MAC_CSR_SM)) {
- aprint_error_dev(sc->sc_dev,
- "%s: failed to get semaphore\n", __func__);
- return;
- }
- } else if (sc->sc_flags & WM_F_LOCK_EXTCNF) {
- if (wm_get_swfwhw_semaphore(sc)) {
- aprint_error_dev(sc->sc_dev,
- "%s: failed to get semaphore\n", __func__);
- return;
- }
+ if (sc->sc_type == WM_T_80003)
+ rv = wm_get_swfw_semaphore(sc, SWFW_MAC_CSR_SM);
+ else
+ rv = sc->phy.acquire(sc);
+ if (rv != 0) {
+ aprint_error_dev(sc->sc_dev,
+ "%s: failed to get semaphore\n", __func__);
+ return;
}
+ wm_kmrn_writereg_locked(sc, reg, val);
+
+ if (sc->sc_type == WM_T_80003)
+ wm_put_swfw_semaphore(sc, SWFW_MAC_CSR_SM);
+ else
+ sc->phy.release(sc);
+}
+
+static void
+wm_kmrn_writereg_locked(struct wm_softc *sc, int reg, int val)
+{
+
CSR_WRITE(sc, WMREG_KUMCTRLSTA,
((reg << KUMCTRLSTA_OFFSET_SHIFT) & KUMCTRLSTA_OFFSET) |
(val & KUMCTRLSTA_MASK));
-
- if (sc->sc_flags & WM_F_LOCK_SWFW)
- wm_put_swfw_semaphore(sc, SWFW_MAC_CSR_SM);
- else if (sc->sc_flags & WM_F_LOCK_EXTCNF)
- wm_put_swfwhw_semaphore(sc);
}
/* SGMII related */
@@ -9151,7 +9188,7 @@ wm_sgmii_readreg(device_t self, int phy,
uint32_t i2ccmd;
int i, rv;
- if (wm_get_swfw_semaphore(sc, swfwphysem[sc->sc_funcid])) {
+ if (sc->phy.acquire(sc)) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return 0;
@@ -9176,7 +9213,7 @@ wm_sgmii_readreg(device_t self, int phy,
rv = ((i2ccmd >> 8) & 0x00ff) | ((i2ccmd << 8) & 0xff00);
- wm_put_swfw_semaphore(sc, swfwphysem[sc->sc_funcid]);
+ sc->phy.release(sc);
return rv;
}
@@ -9195,7 +9232,7 @@ wm_sgmii_writereg(device_t self, int phy
int i;
int val_swapped;
- if (wm_get_swfw_semaphore(sc, swfwphysem[sc->sc_funcid])) {
+ if (sc->phy.acquire(sc) != 0) {
aprint_error_dev(sc->sc_dev, "%s: failed to get semaphore\n",
__func__);
return;
@@ -9219,7 +9256,7 @@ wm_sgmii_writereg(device_t self, int phy
if ((i2ccmd & I2CCMD_ERROR) != 0)
aprint_error_dev(sc->sc_dev, "I2CCMD Error bit set\n");
- wm_put_swfw_semaphore(sc, SWFW_PHY0_SM);
+ sc->phy.release(sc);
}
/* TBI related */
@@ -10204,8 +10241,8 @@ wm_nvm_valid_bank_detect_ich8lan(struct
*bank = CSR_READ(sc, WMREG_CTRL_EXT) & CTRL_EXT_NVMVS;
if ((*bank == 0) || (*bank == 1)) {
aprint_error_dev(sc->sc_dev,
- "%s: no valid NVM bank present\n",
- __func__);
+ "%s: no valid NVM bank present (%u)\n", __func__,
+ *bank);
return -1;
} else {
*bank = *bank - 2;
@@ -11106,6 +11143,28 @@ wm_nvm_read(struct wm_softc *sc, int wor
*/
static int
+wm_get_null(struct wm_softc *sc)
+{
+
+ DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
+ return 0;
+}
+
+static void
+wm_put_null(struct wm_softc *sc)
+{
+
+ DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
+ return;
+}
+
+/*
+ * Get hardware semaphore.
+ * Same as e1000_get_hw_semaphore_generic()
+ */
+static int
wm_get_swsm_semaphore(struct wm_softc *sc)
{
int32_t timeout;
@@ -11113,25 +11172,24 @@ wm_get_swsm_semaphore(struct wm_softc *s
DPRINTF(WM_DEBUG_NVM, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
+ KASSERT(sc->sc_nvm_wordsize > 0);
- if (sc->sc_flags & WM_F_LOCK_SWSM) {
- /* Get the SW semaphore. */
- timeout = sc->sc_nvm_wordsize + 1;
- while (timeout) {
- swsm = CSR_READ(sc, WMREG_SWSM);
+ /* Get the SW semaphore. */
+ timeout = sc->sc_nvm_wordsize + 1;
+ while (timeout) {
+ swsm = CSR_READ(sc, WMREG_SWSM);
- if ((swsm & SWSM_SMBI) == 0)
- break;
+ if ((swsm & SWSM_SMBI) == 0)
+ break;
- delay(50);
- timeout--;
- }
+ delay(50);
+ timeout--;
+ }
- if (timeout == 0) {
- aprint_error_dev(sc->sc_dev,
- "could not acquire SWSM SMBI\n");
- return 1;
- }
+ if (timeout == 0) {
+ aprint_error_dev(sc->sc_dev,
+ "could not acquire SWSM SMBI\n");
+ return 1;
}
/* Get the FW semaphore. */
@@ -11190,6 +11248,7 @@ wm_get_swfw_semaphore(struct wm_softc *s
DPRINTF(WM_DEBUG_NVM, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
+ KASSERT((sc->sc_flags & WM_F_LOCK_SWSM) != 0);
for (timeout = 0; timeout < 200; timeout++) {
if (sc->sc_flags & WM_F_LOCK_SWSM) {
@@ -11224,6 +11283,7 @@ wm_put_swfw_semaphore(struct wm_softc *s
DPRINTF(WM_DEBUG_NVM, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
+ KASSERT((sc->sc_flags & WM_F_LOCK_SWSM) != 0);
if (sc->sc_flags & WM_F_LOCK_SWSM) {
while (wm_get_swsm_semaphore(sc) != 0)
@@ -11237,6 +11297,24 @@ wm_put_swfw_semaphore(struct wm_softc *s
}
static int
+wm_get_phy_82575(struct wm_softc *sc)
+{
+
+ DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
+ return wm_get_swfw_semaphore(sc, swfwphysem[sc->sc_funcid]);
+}
+
+static void
+wm_put_phy_82575(struct wm_softc *sc)
+{
+
+ DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
+ return wm_put_swfw_semaphore(sc, swfwphysem[sc->sc_funcid]);
+}
+
+static int
wm_get_swfwhw_semaphore(struct wm_softc *sc)
{
uint32_t ext_ctrl;
@@ -11245,6 +11323,7 @@ wm_get_swfwhw_semaphore(struct wm_softc
DPRINTF(WM_DEBUG_NVM, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
+ mutex_enter(sc->sc_ich_phymtx); /* Use PHY mtx for both PHY and NVM */
for (timeout = 0; timeout < 200; timeout++) {
ext_ctrl = CSR_READ(sc, WMREG_EXTCNFCTR);
ext_ctrl |= EXTCNFCTR_MDIO_SW_OWNERSHIP;
@@ -11257,6 +11336,7 @@ wm_get_swfwhw_semaphore(struct wm_softc
}
printf("%s: failed to get swfwhw semaphore ext_ctrl 0x%x\n",
device_xname(sc->sc_dev), ext_ctrl);
+ mutex_exit(sc->sc_ich_phymtx); /* Use PHY mtx for both PHY and NVM */
return 1;
}
@@ -11271,6 +11351,70 @@ wm_put_swfwhw_semaphore(struct wm_softc
ext_ctrl = CSR_READ(sc, WMREG_EXTCNFCTR);
ext_ctrl &= ~EXTCNFCTR_MDIO_SW_OWNERSHIP;
CSR_WRITE(sc, WMREG_EXTCNFCTR, ext_ctrl);
+
+ mutex_exit(sc->sc_ich_phymtx); /* Use PHY mtx for both PHY and NVM */
+}
+
+static int
+wm_get_swflag_ich8lan(struct wm_softc *sc)
+{
+ uint32_t ext_ctrl;
+ int timeout;
+
+ DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
+ mutex_enter(sc->sc_ich_phymtx);
+ for (timeout = 0; timeout < WM_PHY_CFG_TIMEOUT; timeout++) {
+ ext_ctrl = CSR_READ(sc, WMREG_EXTCNFCTR);
+ if ((ext_ctrl & EXTCNFCTR_MDIO_SW_OWNERSHIP) == 0)
+ break;
+ delay(1000);
+ }
+ if (timeout >= WM_PHY_CFG_TIMEOUT) {
+ printf("%s: SW has already locked the resource\n",
+ device_xname(sc->sc_dev));
+ goto out;
+ }
+
+ ext_ctrl |= EXTCNFCTR_MDIO_SW_OWNERSHIP;
+ CSR_WRITE(sc, WMREG_EXTCNFCTR, ext_ctrl);
+ for (timeout = 0; timeout < 1000; timeout++) {
+ ext_ctrl = CSR_READ(sc, WMREG_EXTCNFCTR);
+ if (ext_ctrl & EXTCNFCTR_MDIO_SW_OWNERSHIP)
+ break;
+ delay(1000);
+ }
+ if (timeout >= 1000) {
+ printf("%s: failed to acquire semaphore\n",
+ device_xname(sc->sc_dev));
+ ext_ctrl &= ~EXTCNFCTR_MDIO_SW_OWNERSHIP;
+ CSR_WRITE(sc, WMREG_EXTCNFCTR, ext_ctrl);
+ goto out;
+ }
+ return 0;
+
+out:
+ mutex_exit(sc->sc_ich_phymtx);
+ return 1;
+}
+
+static void
+wm_put_swflag_ich8lan(struct wm_softc *sc)
+{
+ uint32_t ext_ctrl;
+
+ DPRINTF(WM_DEBUG_LOCK, ("%s: %s called\n",
+ device_xname(sc->sc_dev), __func__));
+ ext_ctrl = CSR_READ(sc, WMREG_EXTCNFCTR);
+ if (ext_ctrl & EXTCNFCTR_MDIO_SW_OWNERSHIP) {
+ ext_ctrl &= ~EXTCNFCTR_MDIO_SW_OWNERSHIP;
+ CSR_WRITE(sc, WMREG_EXTCNFCTR, ext_ctrl);
+ } else {
+ printf("%s: Semaphore unexpectedly released\n",
+ device_xname(sc->sc_dev));
+ }
+
+ mutex_exit(sc->sc_ich_phymtx);
}
static int
@@ -11482,7 +11626,7 @@ wm_phy_resetisblocked(struct wm_softc *s
continue;
}
blocked = false;
- } while (blocked && (i++ < 10));
+ } while (blocked && (i++ < 30));
return blocked;
break;
case WM_T_82571:
@@ -11591,8 +11735,8 @@ wm_smbustopci(struct wm_softc *sc)
/* Gate automatic PHY configuration by hardware on non-managed 82579 */
wm_gate_hw_phy_config_ich8lan(sc, true);
- /* Acquire semaphore */
- wm_get_swfwhw_semaphore(sc);
+ /* Acquire PHY semaphore */
+ sc->phy.acquire(sc);
fwsm = CSR_READ(sc, WMREG_FWSM);
if (((fwsm & FWSM_FW_VALID) == 0)
@@ -11624,7 +11768,7 @@ wm_smbustopci(struct wm_softc *sc)
}
/* Release semaphore */
- wm_put_swfwhw_semaphore(sc);
+ sc->phy.release(sc);
/*
* Ungate automatic PHY configuration by hardware on non-managed 82579
@@ -12032,9 +12176,9 @@ wm_hv_phy_workaround_ich8lan(struct wm_s
/* Select page 0 */
- /* XXX acquire semaphore */
- wm_gmii_i82544_writereg(sc->sc_dev, 1, MII_IGPHY_PAGE_SELECT, 0);
- /* XXX release semaphore */
+ sc->phy.acquire(sc);
+ wm_gmii_mdic_writereg(sc->sc_dev, 1, MII_IGPHY_PAGE_SELECT, 0);
+ sc->phy.release(sc);
/*
* Configure the K1 Si workaround during phy reset assuming there is
@@ -12052,7 +12196,7 @@ wm_lv_phy_workaround_ich8lan(struct wm_s
wm_set_mdio_slow_mode_hv(sc);
}
-static void
+static int
wm_k1_gig_workaround_hv(struct wm_softc *sc, int link)
{
int k1_enable = sc->sc_nvm_k1_enabled;
@@ -12060,21 +12204,23 @@ wm_k1_gig_workaround_hv(struct wm_softc
DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
- /* XXX acquire semaphore */
+ if (sc->phy.acquire(sc) != 0)
+ return -1;
if (link) {
k1_enable = 0;
/* Link stall fix for link up */
- wm_gmii_hv_writereg(sc->sc_dev, 1, IGP3_KMRN_DIAG, 0x0100);
+ wm_gmii_hv_writereg_locked(sc->sc_dev, 1, IGP3_KMRN_DIAG, 0x0100);
} else {
/* Link stall fix for link down */
- wm_gmii_hv_writereg(sc->sc_dev, 1, IGP3_KMRN_DIAG, 0x4100);
+ wm_gmii_hv_writereg_locked(sc->sc_dev, 1, IGP3_KMRN_DIAG, 0x4100);
}
wm_configure_k1_ich8lan(sc, k1_enable);
+ sc->phy.release(sc);
- /* XXX release semaphore */
+ return 0;
}
static void
@@ -12093,14 +12239,14 @@ wm_configure_k1_ich8lan(struct wm_softc
uint32_t ctrl, ctrl_ext, tmp;
uint16_t kmrn_reg;
- kmrn_reg = wm_kmrn_readreg(sc, KUMCTRLSTA_OFFSET_K1_CONFIG);
+ kmrn_reg = wm_kmrn_readreg_locked(sc, KUMCTRLSTA_OFFSET_K1_CONFIG);
if (k1_enable)
kmrn_reg |= KUMCTRLSTA_K1_ENABLE;
else
kmrn_reg &= ~KUMCTRLSTA_K1_ENABLE;
- wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_K1_CONFIG, kmrn_reg);
+ wm_kmrn_writereg_locked(sc, KUMCTRLSTA_OFFSET_K1_CONFIG, kmrn_reg);
delay(20);