Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Add some code to support 82580[ER]. Tested on my...
details: https://anonhg.NetBSD.org/src/rev/8e4f1984545d
branches: trunk
changeset: 755849:8e4f1984545d
user: msaitoh <msaitoh%NetBSD.org@localhost>
date: Fri Jun 25 04:03:14 2010 +0000
description:
Add some code to support 82580[ER]. Tested on my own I340-T4.
- Fix CTRL_EXT_SWDPIN() and CTRL_EXT_SWDPIO() macros. The bit order of the
SW definable pin is not 6543 but 3654!!!
- Rewrite the code to read MAC address from eeprom.
- Add some code to support 82580.
TODO:
- ukphy -> somephy
diffstat:
sys/dev/pci/if_wm.c | 183 +++++++++++++++++++++++++++++++++++++++++-------
sys/dev/pci/if_wmreg.h | 23 +++++-
2 files changed, 175 insertions(+), 31 deletions(-)
diffs (truncated from 356 to 300 lines):
diff -r 412a83fd11da -r 8e4f1984545d sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Fri Jun 25 03:47:57 2010 +0000
+++ b/sys/dev/pci/if_wm.c Fri Jun 25 04:03:14 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.207 2010/05/25 01:17:55 msaitoh Exp $ */
+/* $NetBSD: if_wm.c,v 1.208 2010/06/25 04:03:14 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.207 2010/05/25 01:17:55 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.208 2010/06/25 04:03:14 msaitoh Exp $");
#include "rnd.h"
@@ -510,6 +510,7 @@
static int wm_read_eeprom(struct wm_softc *, int, int, u_int16_t *);
static int wm_read_eeprom_eerd(struct wm_softc *, int, int, u_int16_t *);
static int wm_validate_eeprom_checksum(struct wm_softc *);
+static int wm_read_mac_addr(struct wm_softc *, uint8_t *);
static void wm_tick(void *);
static void wm_set_filter(struct wm_softc *);
@@ -1098,7 +1099,7 @@
prop_data_t ea;
prop_number_t pn;
uint8_t enaddr[ETHER_ADDR_LEN];
- uint16_t myea[ETHER_ADDR_LEN / 2], cfg1, cfg2, swdpin, io3;
+ uint16_t cfg1, cfg2, swdpin, io3;
pcireg_t preg, memtype;
uint16_t eeprom_data, apme_mask;
uint32_t reg;
@@ -1246,7 +1247,8 @@
*/
if ((sc->sc_type == WM_T_82546) || (sc->sc_type == WM_T_82546_3)
|| (sc->sc_type == WM_T_82571) || (sc->sc_type == WM_T_80003)
- || (sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576))
+ || (sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576)
+ || (sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER))
sc->sc_funcid = (CSR_READ(sc, WMREG_STATUS)
>> STATUS_FUNCID_SHIFT) & STATUS_FUNCID_MASK;
else
@@ -1605,29 +1607,10 @@
KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);
memcpy(enaddr, prop_data_data_nocopy(ea), ETHER_ADDR_LEN);
} else {
- if (wm_read_eeprom(sc, EEPROM_OFF_MACADDR,
- sizeof(myea) / sizeof(myea[0]), myea)) {
+ if (wm_read_mac_addr(sc, enaddr) != 0)
aprint_error_dev(sc->sc_dev,
"unable to read Ethernet address\n");
- return;
- }
- enaddr[0] = myea[0] & 0xff;
- enaddr[1] = myea[0] >> 8;
- enaddr[2] = myea[1] & 0xff;
- enaddr[3] = myea[1] >> 8;
- enaddr[4] = myea[2] & 0xff;
- enaddr[5] = myea[2] >> 8;
- }
-
- /*
- * Toggle the LSB of the MAC address on the second port
- * of the dual port controller.
- */
- if ((sc->sc_type == WM_T_82546) || (sc->sc_type == WM_T_82546_3)
- || (sc->sc_type == WM_T_82571) || (sc->sc_type == WM_T_80003)
- || (sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576)) {
- if (sc->sc_funcid == 1)
- enaddr[5] ^= 1;
+ return;
}
aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
@@ -3595,6 +3578,8 @@
case WM_T_82574:
case WM_T_82575:
case WM_T_82576:
+ case WM_T_82580:
+ case WM_T_82580ER:
case WM_T_82583:
default:
/* Everything else can safely use the documented method. */
@@ -3653,6 +3638,8 @@
break;
case WM_T_82575:
case WM_T_82576:
+ case WM_T_82580:
+ case WM_T_82580ER:
case WM_T_80003:
case WM_T_ICH8:
case WM_T_ICH9:
@@ -3671,13 +3658,19 @@
switch (sc->sc_type) {
case WM_T_82575:
case WM_T_82576:
+#if 0 /* XXX */
case WM_T_82580:
+ case WM_T_82580ER:
+#endif
case WM_T_ICH8:
case WM_T_ICH9:
if ((CSR_READ(sc, WMREG_EECD) & EECD_EE_PRES) == 0) {
/* Not found */
sc->sc_flags |= WM_F_EEPROM_INVALID;
- if (sc->sc_type == WM_T_82575) /* 82575 only */
+ if ((sc->sc_type == WM_T_82575)
+ || (sc->sc_type == WM_T_82576)
+ || (sc->sc_type == WM_T_82580)
+ || (sc->sc_type == WM_T_82580ER))
wm_reset_init_script_82575(sc);
}
break;
@@ -3685,6 +3678,11 @@
break;
}
+ if ((sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER)) {
+ /* clear global device reset status bit */
+ CSR_WRITE(sc, WMREG_STATUS, STATUS_DEV_RST_SET);
+ }
+
/* Clear any pending interrupt events. */
CSR_WRITE(sc, WMREG_IMC, 0xffffffffU);
reg = CSR_READ(sc, WMREG_ICR);
@@ -4224,6 +4222,8 @@
case WM_T_82583:
case WM_T_82575:
case WM_T_82576:
+ case WM_T_82580:
+ case WM_T_82580ER:
case WM_T_80003:
case WM_T_ICH8:
case WM_T_ICH9:
@@ -4309,6 +4309,7 @@
case WM_T_82575:
case WM_T_82576:
case WM_T_82580:
+ case WM_T_82580ER:
mask = EEMNGCTL_CFGDONE_0 << sc->sc_funcid;
for (i = 0; i < WM_PHY_CFG_TIMEOUT; i++) {
if (CSR_READ(sc, WMREG_EEMNGCTL) & mask)
@@ -4692,6 +4693,101 @@
return done;
}
+static int
+wm_read_mac_addr(struct wm_softc *sc, uint8_t *enaddr)
+{
+ uint16_t myea[ETHER_ADDR_LEN / 2];
+ uint16_t offset;
+ int do_invert = 0;
+
+ if (sc->sc_funcid == 0)
+ offset = EEPROM_OFF_MACADDR;
+ else {
+ switch (sc->sc_type) {
+ case WM_T_82580:
+ case WM_T_82580ER:
+ switch (sc->sc_funcid) {
+ case 1:
+ offset = EEPROM_OFF_LAN1;
+ break;
+ case 2:
+ offset = EEPROM_OFF_LAN2;
+ break;
+ case 3:
+ offset = EEPROM_OFF_LAN3;
+ break;
+ default:
+ goto bad;
+ /* NOTREACHED */
+ break;
+ }
+ break;
+ case WM_T_82571:
+ case WM_T_82575:
+ case WM_T_82576:
+ case WM_T_80003:
+ if (wm_read_eeprom(sc, EEPROM_ALT_MAC_ADDR_PTR, 1,
+ &offset) != 0) {
+ goto bad;
+ }
+
+ /* no pointer */
+ if (offset == 0xffff) {
+ /* reset the offset to LAN0 */
+ offset = EEPROM_OFF_MACADDR;
+ do_invert = 1;
+ goto do_read;
+ }
+
+ switch (sc->sc_funcid) {
+ case 1:
+ offset += EEPROM_OFF_MACADDR_LAN1;
+ break;
+ case 2:
+ offset += EEPROM_OFF_MACADDR_LAN2;
+ break;
+ case 3:
+ offset += EEPROM_OFF_MACADDR_LAN3;
+ break;
+ default:
+ goto bad;
+ /* NOTREACHED */
+ break;
+ }
+ break;
+ default:
+ do_invert = 1;
+ break;
+ }
+ }
+ do_read:
+ if (wm_read_eeprom(sc, offset, sizeof(myea) / sizeof(myea[0]),
+ myea) != 0) {
+ goto bad;
+ }
+
+ enaddr[0] = myea[0] & 0xff;
+ enaddr[1] = myea[0] >> 8;
+ enaddr[2] = myea[1] & 0xff;
+ enaddr[3] = myea[1] >> 8;
+ enaddr[4] = myea[2] & 0xff;
+ enaddr[5] = myea[2] >> 8;
+
+ /*
+ * Toggle the LSB of the MAC address on the second port
+ * of some dual port cards.
+ */
+ if (do_invert != 0)
+ enaddr[5] ^= 1;
+
+ return 0;
+
+ bad:
+ aprint_error_dev(sc->sc_dev, "unable to read Ethernet address\n");
+
+ return -1;
+}
+
/*
* wm_add_rxbuf:
*
@@ -5494,8 +5590,35 @@
ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, wm_gmii_mediachange,
wm_gmii_mediastatus);
- mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
- MII_OFFSET_ANY, MIIF_DOPAUSE);
+ if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576)
+ || (sc->sc_type == WM_T_82580) || (sc->sc_type == WM_T_82580ER)) {
+ if ((sc->sc_flags & WM_F_SGMII) == 0) {
+ /* Attach only one port */
+ mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, 1,
+ MII_OFFSET_ANY, MIIF_DOPAUSE);
+ } else {
+ int i;
+ uint32_t ctrl_ext;
+
+ /* Power on sgmii phy if it is disabled */
+ ctrl_ext = CSR_READ(sc, WMREG_CTRL_EXT);
+ CSR_WRITE(sc, WMREG_CTRL_EXT,
+ ctrl_ext &~ CTRL_EXT_SWDPIN(3));
+ CSR_WRITE_FLUSH(sc);
+ delay(300*1000); /* XXX too long */
+
+ /* from 1 to 8 */
+ for (i = 1; i < 8; i++)
+ mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff,
+ i, MII_OFFSET_ANY, MIIF_DOPAUSE);
+
+ /* restore previous sfp cage power state */
+ CSR_WRITE(sc, WMREG_CTRL_EXT, ctrl_ext);
+ }
+ } else {
+ mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
+ MII_OFFSET_ANY, MIIF_DOPAUSE);
+ }
if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
/* if failed, retry with *_bm_* */
@@ -7290,6 +7413,10 @@
case WM_T_82574:
case WM_T_82575:
case WM_T_82576:
+#if 0 /* XXX */
+ case WM_T_82580:
+ case WM_T_82580ER:
+#endif
if ((CSR_READ(sc, WMREG_FWSM) & FWSM_MODE_MASK) != 0)
sc->sc_flags |= WM_F_ARC_SUBSYS_VALID;
sc->sc_flags |= WM_F_ASF_FIRMWARE_PRES;
diff -r 412a83fd11da -r 8e4f1984545d sys/dev/pci/if_wmreg.h
--- a/sys/dev/pci/if_wmreg.h Fri Jun 25 03:47:57 2010 +0000
+++ b/sys/dev/pci/if_wmreg.h Fri Jun 25 04:03:14 2010 +0000
@@ -1,4 +1,4 @@
Home |
Main Index |
Thread Index |
Old Index