Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci - Rewrite PHY related lock stuff. Almost the sam...
details: https://anonhg.NetBSD.org/src/rev/efb5e539082a
branches: trunk
changeset: 348505:efb5e539082a
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Fri Oct 21 04:41:09 2016 +0000
description:
- 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()
diffstat:
sys/dev/pci/if_wm.c | 626 ++++++++++++++++++++++++++++++++-------------------
1 files changed, 386 insertions(+), 240 deletions(-)
diffs (truncated from 1221 to 300 lines):
diff -r 40d9ff23ae95 -r efb5e539082a sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Fri Oct 21 03:04:33 2016 +0000
+++ b/sys/dev/pci/if_wm.c Fri Oct 21 04:41:09 2016 +0000
@@ -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_rxqueue wmq_rxq;
};
+struct wm_phyop {
+ int (*acquire)(struct wm_softc *);
+ void (*release)(struct wm_softc *);
+};
+
/*
* Software state per device.
*/
@@ -494,10 +499,17 @@
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 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 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 @@
* 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_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 @@
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 @@
|| (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 @@
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 @@
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 @@
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 @@
/* 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 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
break;
Home |
Main Index |
Thread Index |
Old Index