Module Name:    src
Committed By:   msaitoh
Date:           Fri Jul 11 02:23:44 UTC 2014

Modified Files:
        src/sys/dev/pci: if_wm.c if_wmreg.h

Log Message:
Fix some bugs realted to semaphore. This change fixes a problem which
was exposed in if_wm.c rev. 1.271. Tested by riastradh@.
- Clear the SMBI bit in SWSM register before accessing NVM and PHY in
  wm_attach(). Same as FreeBSD.
- Fix a bug that 82573 doesn't put the hardware semaphore. Same as
  FreeBSD r256200.


To generate a diff of this commit:
cvs rdiff -u -r1.272 -r1.273 src/sys/dev/pci/if_wm.c
cvs rdiff -u -r1.56 -r1.57 src/sys/dev/pci/if_wmreg.h

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.272 src/sys/dev/pci/if_wm.c:1.273
--- src/sys/dev/pci/if_wm.c:1.272	Tue Jul  1 10:35:18 2014
+++ src/sys/dev/pci/if_wm.c	Fri Jul 11 02:23:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wm.c,v 1.272 2014/07/01 10:35:18 ozaki-r Exp $	*/
+/*	$NetBSD: if_wm.c,v 1.273 2014/07/11 02:23:44 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.272 2014/07/01 10:35:18 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.273 2014/07/11 02:23:44 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1202,6 +1202,7 @@ wm_attach(device_t parent, device_t self
 	uint16_t cfg1, cfg2, swdpin, io3;
 	pcireg_t preg, memtype;
 	uint16_t eeprom_data, apme_mask;
+	bool force_clear_smbi;
 	uint32_t reg;
 	char intrbuf[PCI_INTRSTR_LEN];
 
@@ -1393,7 +1394,6 @@ wm_attach(device_t parent, device_t self
 		    && (sc->sc_type != WM_T_PCH)
 		    && (sc->sc_type != WM_T_PCH2)
 		    && (sc->sc_type != WM_T_PCH_LPT)) {
-			sc->sc_flags |= WM_F_EEPROM_SEMAPHORE;
 			/* ICH* and PCH* have no PCIe capability registers */
 			if (pci_get_capability(pa->pa_pc, pa->pa_tag,
 				PCI_CAP_PCIEXPRESS, &sc->sc_pcixe_capoff,
@@ -1611,9 +1611,12 @@ wm_attach(device_t parent, device_t self
 	case WM_T_82572:
 		/* SPI */
 		wm_set_spiaddrbits(sc);
+		sc->sc_flags |= WM_F_EEPROM_SEMAPHORE;
 		sc->sc_flags |= WM_F_EEPROM_HANDSHAKE;
 		break;
 	case WM_T_82573:
+		sc->sc_flags |= WM_F_EEPROM_SEMAPHORE;
+		/* FALLTHROUGH */
 	case WM_T_82574:
 	case WM_T_82583:
 		if (wm_is_onboard_nvm_eeprom(sc) == 0)
@@ -1669,6 +1672,29 @@ wm_attach(device_t parent, device_t self
 		break;
 	}
 
+	/* Ensure the SMBI bit is clear before first NVM or PHY access */
+	switch (sc->sc_type) {
+	case WM_T_82571:
+	case WM_T_82572:
+		reg = CSR_READ(sc, WMREG_SWSM2);
+		if ((reg & SWSM2_LOCK) != 0) {
+			CSR_WRITE(sc, WMREG_SWSM2, reg | SWSM2_LOCK);
+			force_clear_smbi = true;
+		} else
+			force_clear_smbi = false;
+		break;
+	default:
+		force_clear_smbi = true;
+		break;
+	}
+	if (force_clear_smbi) {
+		reg = CSR_READ(sc, WMREG_SWSM);
+		if ((reg & ~SWSM_SMBI) != 0)
+			aprint_error_dev(sc->sc_dev,
+			    "Please update the Bootagent\n");
+		CSR_WRITE(sc, WMREG_SWSM, reg & ~SWSM_SMBI);
+	}
+
 	/*
 	 * Defer printing the EEPROM type until after verifying the checksum
 	 * This allows the EEPROM type to be printed correctly in the case
@@ -4196,6 +4222,7 @@ static void
 wm_reset(struct wm_softc *sc)
 {
 	int phy_reset = 0;
+	int error = 0;
 	uint32_t reg, mask;
 
 	/*
@@ -4298,7 +4325,7 @@ wm_reset(struct wm_softc *sc)
 	case WM_T_82573:
 	case WM_T_82574:
 	case WM_T_82583:
-		wm_get_hw_semaphore_82573(sc);
+		error = wm_get_hw_semaphore_82573(sc);
 		break;
 	default:
 		break;
@@ -4404,9 +4431,11 @@ wm_reset(struct wm_softc *sc)
 
 	/* Must release the MDIO ownership after MAC reset */
 	switch (sc->sc_type) {
+	case WM_T_82573:
 	case WM_T_82574:
 	case WM_T_82583:
-		wm_put_hw_semaphore_82573(sc);
+		if (error == 0)
+			wm_put_hw_semaphore_82573(sc);
 		break;
 	default:
 		break;

Index: src/sys/dev/pci/if_wmreg.h
diff -u src/sys/dev/pci/if_wmreg.h:1.56 src/sys/dev/pci/if_wmreg.h:1.57
--- src/sys/dev/pci/if_wmreg.h:1.56	Fri Apr 11 04:42:34 2014
+++ src/sys/dev/pci/if_wmreg.h	Fri Jul 11 02:23:44 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wmreg.h,v 1.56 2014/04/11 04:42:34 msaitoh Exp $	*/
+/*	$NetBSD: if_wmreg.h,v 1.57 2014/07/11 02:23:44 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -928,6 +928,9 @@ struct livengood_tcpip_ctxdesc {
 #define FWSM_RSPCIPHY		0x00000040	/* Reset PHY on PCI reset */
 #define FWSM_FW_VALID		0x00008000 /* FW established a valid mode */
 
+#define	WMREG_SWSM2	0x5b58	/* SW Semaphore 2 */
+#define SWSM2_LOCK		0x00000002 /* Secondary driver semaphore bit */
+
 #define	WMREG_SW_FW_SYNC 0x5b5c	/* software-firmware semaphore */
 #define	SWFW_EEP_SM		0x0001 /* eeprom access */
 #define	SWFW_PHY0_SM		0x0002 /* first ctrl phy access */

Reply via email to