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
This commit is contained in:
parent
d6d8c40941
commit
5e478d2ed7
|
@ -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_add_rxbuf(struct wm_softc *, int);
|
|||
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 @@ wm_attach(device_t parent, device_t self, void *aux)
|
|||
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 @@ wm_attach(device_t parent, device_t self, void *aux)
|
|||
*/
|
||||
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 @@ wm_attach(device_t parent, device_t self, void *aux)
|
|||
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 @@ wm_reset(struct wm_softc *sc)
|
|||
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 @@ wm_reset(struct wm_softc *sc)
|
|||
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 @@ wm_reset(struct wm_softc *sc)
|
|||
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 @@ wm_reset(struct wm_softc *sc)
|
|||
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 @@ wm_get_auto_rd_done(struct wm_softc *sc)
|
|||
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 @@ wm_get_cfg_done(struct wm_softc *sc)
|
|||
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 @@ wm_poll_eerd_eewr_done(struct wm_softc *sc, int rw)
|
|||
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 @@ wm_gmii_mediainit(struct wm_softc *sc, pci_product_id_t prodid)
|
|||
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 @@ wm_get_wakeup(struct wm_softc *sc)
|
|||
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;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_wmreg.h,v 1.41 2010/06/25 03:47:57 msaitoh Exp $ */
|
||||
/* $NetBSD: if_wmreg.h,v 1.42 2010/06/25 04:03:14 msaitoh Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Wasabi Systems, Inc.
|
||||
|
@ -232,6 +232,7 @@ struct livengood_tcpip_ctxdesc {
|
|||
#define STATUS_PCIXSPD_100_133 STATUS_PCIXSPD(2)
|
||||
#define STATUS_PCIXSPD_MASK STATUS_PCIXSPD(3)
|
||||
#define STATUS_GIO_M_ENA (1U << 19) /* GIO master enable */
|
||||
#define STATUS_DEV_RST_SET (1U << 20) /* Device Reset Set */
|
||||
|
||||
#define WMREG_EECD 0x0010 /* EEPROM Control Register */
|
||||
#define EECD_SK (1U << 0) /* clock */
|
||||
|
@ -280,6 +281,7 @@ struct livengood_tcpip_ctxdesc {
|
|||
#define EEPROM_OFF_K1_CONFIG 0x1b /* NVM K1 Config */
|
||||
#define EEPROM_OFF_SWDPIN 0x20 /* SWD Pins (Cordova) */
|
||||
#define EEPROM_OFF_CFG3_PORTA 0x24 /* config word 3 */
|
||||
#define EEPROM_ALT_MAC_ADDR_PTR 0x37 /* to the alternative MAC addresses */
|
||||
|
||||
#define EEPROM_CFG1_LVDID (1U << 0)
|
||||
#define EEPROM_CFG1_LSSID (1U << 1)
|
||||
|
@ -323,6 +325,18 @@ struct livengood_tcpip_ctxdesc {
|
|||
|
||||
#define EEPROM_CFG3_APME (1U << 10)
|
||||
|
||||
#define EEPROM_OFF_MACADDR_LAN1 3 /* macaddr offset from PTR (port 1) */
|
||||
#define EEPROM_OFF_MACADDR_LAN2 6 /* macaddr offset from PTR (port 2) */
|
||||
#define EEPROM_OFF_MACADDR_LAN3 9 /* macaddr offset from PTR (port 3) */
|
||||
|
||||
/*
|
||||
* EEPROM Partitioning. See Table 6-1, "EEPROM Top Level Partitioning"
|
||||
* in 82580's datasheet.
|
||||
*/
|
||||
#define EEPROM_OFF_LAN1 0x0080 /* Offset for LAN1 (82580)*/
|
||||
#define EEPROM_OFF_LAN2 0x00c0 /* Offset for LAN1 (82580)*/
|
||||
#define EEPROM_OFF_LAN3 0x0100 /* Offset for LAN1 (82580)*/
|
||||
|
||||
#define WMREG_EERD 0x0014 /* EEPROM read */
|
||||
#define EERD_DONE 0x02 /* done bit */
|
||||
#define EERD_START 0x01 /* First bit for telling part to start operation */
|
||||
|
@ -333,10 +347,13 @@ struct livengood_tcpip_ctxdesc {
|
|||
#define CTRL_EXT_GPI_EN(x) (1U << (x)) /* gpin interrupt enable */
|
||||
#define CTRL_EXT_SWDPINS_SHIFT 4
|
||||
#define CTRL_EXT_SWDPINS_MASK 0x0d
|
||||
#define CTRL_EXT_SWDPIN(x) (1U << (CTRL_EXT_SWDPINS_SHIFT + (x) - 4))
|
||||
/* The bit order of the SW Definable pin is not 6543 but 3654! */
|
||||
#define CTRL_EXT_SWDPIN(x) (1U << (CTRL_EXT_SWDPINS_SHIFT \
|
||||
+ ((x) == 3 ? 3 : ((x) - 4))))
|
||||
#define CTRL_EXT_SWDPIO_SHIFT 8
|
||||
#define CTRL_EXT_SWDPIO_MASK 0x0d
|
||||
#define CTRL_EXT_SWDPIO(x) (1U << (CTRL_EXT_SWDPIO_SHIFT + (x) - 4))
|
||||
#define CTRL_EXT_SWDPIO(x) (1U << (CTRL_EXT_SWDPIO_SHIFT \
|
||||
+ ((x) == 3 ? 3 : ((x) - 4))))
|
||||
#define CTRL_EXT_ASDCHK (1U << 12) /* ASD check */
|
||||
#define CTRL_EXT_EE_RST (1U << 13) /* EEPROM reset */
|
||||
#define CTRL_EXT_IPS (1U << 14) /* invert power state bit 0 */
|
||||
|
|
Loading…
Reference in New Issue