updated marvell_yukon to 1.26 for the source file and 1.11 for the header

should help with bug #1787


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23965 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2008-02-16 18:46:40 +00:00
parent e47368c84e
commit 2c5ab413c2
3 changed files with 112 additions and 179 deletions
@@ -99,7 +99,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/msk/if_msk.c,v 1.18 2007/07/20 00:25:20 yongari Exp $"); __FBSDID("$FreeBSD: src/sys/dev/msk/if_msk.c,v 1.26 2007/12/05 09:41:58 remko Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@@ -193,6 +193,8 @@ static struct msk_product {
"Marvell Yukon 88E8036 Gigabit Ethernet" }, "Marvell Yukon 88E8036 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_8038, { VENDORID_MARVELL, DEVICEID_MRVL_8038,
"Marvell Yukon 88E8038 Gigabit Ethernet" }, "Marvell Yukon 88E8038 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_8039,
"Marvell Yukon 88E8039 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4361, { VENDORID_MARVELL, DEVICEID_MRVL_4361,
"Marvell Yukon 88E8050 Gigabit Ethernet" }, "Marvell Yukon 88E8050 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4360, { VENDORID_MARVELL, DEVICEID_MRVL_4360,
@@ -203,6 +205,8 @@ static struct msk_product {
"Marvell Yukon 88E8055 Gigabit Ethernet" }, "Marvell Yukon 88E8055 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4364, { VENDORID_MARVELL, DEVICEID_MRVL_4364,
"Marvell Yukon 88E8056 Gigabit Ethernet" }, "Marvell Yukon 88E8056 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_436A,
"Marvell Yukon 88E8058 Gigabit Ethernet" },
{ VENDORID_DLINK, DEVICEID_DLINK_DGE550SX, { VENDORID_DLINK, DEVICEID_DLINK_DGE550SX,
"D-Link 550SX Gigabit Ethernet" }, "D-Link 550SX Gigabit Ethernet" },
{ VENDORID_DLINK, DEVICEID_DLINK_DGE560T, { VENDORID_DLINK, DEVICEID_DLINK_DGE560T,
@@ -220,7 +224,7 @@ static const char *model_name[] = {
static int mskc_probe(device_t); static int mskc_probe(device_t);
static int mskc_attach(device_t); static int mskc_attach(device_t);
static int mskc_detach(device_t); static int mskc_detach(device_t);
static void mskc_shutdown(device_t); static int mskc_shutdown(device_t);
static int mskc_setup_rambuffer(struct msk_softc *); static int mskc_setup_rambuffer(struct msk_softc *);
static int mskc_suspend(device_t); static int mskc_suspend(device_t);
static int mskc_resume(device_t); static int mskc_resume(device_t);
@@ -357,6 +361,11 @@ static struct resource_spec msk_irq_spec_legacy[] = {
}; };
static struct resource_spec msk_irq_spec_msi[] = { static struct resource_spec msk_irq_spec_msi[] = {
{ SYS_RES_IRQ, 1, RF_ACTIVE },
{ -1, 0, 0 }
};
static struct resource_spec msk_irq_spec_msi2[] = {
{ SYS_RES_IRQ, 1, RF_ACTIVE }, { SYS_RES_IRQ, 1, RF_ACTIVE },
{ SYS_RES_IRQ, 2, RF_ACTIVE }, { SYS_RES_IRQ, 2, RF_ACTIVE },
{ -1, 0, 0 } { -1, 0, 0 }
@@ -367,6 +376,9 @@ msk_miibus_readreg(device_t dev, int phy, int reg)
{ {
struct msk_if_softc *sc_if; struct msk_if_softc *sc_if;
if (phy != PHY_ADDR_MARV)
return (0);
sc_if = device_get_softc(dev); sc_if = device_get_softc(dev);
return (msk_phy_readreg(sc_if, phy, reg)); return (msk_phy_readreg(sc_if, phy, reg));
@@ -405,6 +417,9 @@ msk_miibus_writereg(device_t dev, int phy, int reg, int val)
{ {
struct msk_if_softc *sc_if; struct msk_if_softc *sc_if;
if (phy != PHY_ADDR_MARV)
return (0);
sc_if = device_get_softc(dev); sc_if = device_get_softc(dev);
return (msk_phy_writereg(sc_if, phy, reg, val)); return (msk_phy_writereg(sc_if, phy, reg, val));
@@ -516,17 +531,14 @@ msk_link_task(void *arg, int pending)
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), gmac); CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), gmac);
/* Enable PHY interrupt for FIFO underrun/overflow. */ /* Enable PHY interrupt for FIFO underrun/overflow. */
if (sc->msk_marvell_phy) msk_phy_writereg(sc_if, PHY_ADDR_MARV,
msk_phy_writereg(sc_if, PHY_ADDR_MARV, PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR);
PHY_MARV_INT_MASK, PHY_M_IS_FIFO_ERROR);
} else { } else {
/* /*
* Link state changed to down. * Link state changed to down.
* Disable PHY interrupts. * Disable PHY interrupts.
*/ */
if (sc->msk_marvell_phy) msk_phy_writereg(sc_if, PHY_ADDR_MARV, PHY_MARV_INT_MASK, 0);
msk_phy_writereg(sc_if, PHY_ADDR_MARV,
PHY_MARV_INT_MASK, 0);
/* Disable Rx/Tx MAC. */ /* Disable Rx/Tx MAC. */
gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL); gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL);
gmac &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); gmac &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
@@ -916,7 +928,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
error = EINVAL; error = EINVAL;
break; break;
} }
if (sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_EC_U && if (sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_FE &&
ifr->ifr_mtu > MSK_MAX_FRAMELEN) { ifr->ifr_mtu > MSK_MAX_FRAMELEN) {
error = EINVAL; error = EINVAL;
break; break;
@@ -983,6 +995,16 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
else else
ifp->if_hwassist &= ~CSUM_TSO; ifp->if_hwassist &= ~CSUM_TSO;
} }
if (sc_if->msk_framesize > MSK_MAX_FRAMELEN &&
sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_EC_U) {
/*
* In Yukon EC Ultra, TSO & checksum offload is not
* supported for jumbo frame.
*/
ifp->if_hwassist &= ~(MSK_CSUM_FEATURES | CSUM_TSO);
ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM);
}
VLAN_CAPABILITIES(ifp); VLAN_CAPABILITIES(ifp);
MSK_IF_UNLOCK(sc_if); MSK_IF_UNLOCK(sc_if);
break; break;
@@ -1018,64 +1040,38 @@ mskc_probe(device_t dev)
static int static int
mskc_setup_rambuffer(struct msk_softc *sc) mskc_setup_rambuffer(struct msk_softc *sc)
{ {
int totqsize, minqsize; int next;
int avail, next;
int i; int i;
uint8_t val; uint8_t val;
/* Get adapter SRAM size. */ /* Get adapter SRAM size. */
val = CSR_READ_1(sc, B2_E_0); val = CSR_READ_1(sc, B2_E_0);
sc->msk_ramsize = (val == 0) ? 128 : val * 4; sc->msk_ramsize = (val == 0) ? 128 : val * 4;
if (sc->msk_hw_id == CHIP_ID_YUKON_FE)
sc->msk_ramsize = 4 * 4;
if (bootverbose) if (bootverbose)
device_printf(sc->msk_dev, device_printf(sc->msk_dev,
"RAM buffer size : %dKB\n", sc->msk_ramsize); "RAM buffer size : %dKB\n", sc->msk_ramsize);
/*
totqsize = sc->msk_ramsize * sc->msk_num_port; * Give receiver 2/3 of memory and round down to the multiple
minqsize = MSK_MIN_RXQ_SIZE + MSK_MIN_TXQ_SIZE; * of 1024. Tx/Rx RAM buffer size of Yukon II shoud be multiple
if (minqsize > sc->msk_ramsize) * of 1024.
minqsize = sc->msk_ramsize; */
sc->msk_rxqsize = rounddown((sc->msk_ramsize * 1024 * 2) / 3, 1024);
if (minqsize * sc->msk_num_port > totqsize) { sc->msk_txqsize = (sc->msk_ramsize * 1024) - sc->msk_rxqsize;
device_printf(sc->msk_dev,
"not enough RAM buffer memory : %d/%dKB\n",
minqsize * sc->msk_num_port, totqsize);
return (ENOSPC);
}
avail = totqsize;
if (sc->msk_num_port > 1) {
/*
* Divide up the memory evenly so that everyone gets a
* fair share for dual port adapters.
*/
avail = sc->msk_ramsize;
}
/* Take away the minimum memory for active queues. */
avail -= minqsize;
/* Rx queue gets the minimum + 80% of the rest. */
sc->msk_rxqsize =
(avail * MSK_RAM_QUOTA_RX) / 100 + MSK_MIN_RXQ_SIZE;
avail -= (sc->msk_rxqsize - MSK_MIN_RXQ_SIZE);
sc->msk_txqsize = avail + MSK_MIN_TXQ_SIZE;
for (i = 0, next = 0; i < sc->msk_num_port; i++) { for (i = 0, next = 0; i < sc->msk_num_port; i++) {
sc->msk_rxqstart[i] = next; sc->msk_rxqstart[i] = next;
sc->msk_rxqend[i] = next + (sc->msk_rxqsize * 1024) - 1; sc->msk_rxqend[i] = next + sc->msk_rxqsize - 1;
next = sc->msk_rxqend[i] + 1; next = sc->msk_rxqend[i] + 1;
sc->msk_txqstart[i] = next; sc->msk_txqstart[i] = next;
sc->msk_txqend[i] = next + (sc->msk_txqsize * 1024) - 1; sc->msk_txqend[i] = next + sc->msk_txqsize - 1;
next = sc->msk_txqend[i] + 1; next = sc->msk_txqend[i] + 1;
if (bootverbose) { if (bootverbose) {
device_printf(sc->msk_dev, device_printf(sc->msk_dev,
"Port %d : Rx Queue %dKB(0x%08x:0x%08x)\n", i, "Port %d : Rx Queue %dKB(0x%08x:0x%08x)\n", i,
sc->msk_rxqsize, sc->msk_rxqstart[i], sc->msk_rxqsize / 1024, sc->msk_rxqstart[i],
sc->msk_rxqend[i]); sc->msk_rxqend[i]);
device_printf(sc->msk_dev, device_printf(sc->msk_dev,
"Port %d : Tx Queue %dKB(0x%08x:0x%08x)\n", i, "Port %d : Tx Queue %dKB(0x%08x:0x%08x)\n", i,
sc->msk_txqsize, sc->msk_txqstart[i], sc->msk_txqsize / 1024, sc->msk_txqstart[i],
sc->msk_txqend[i]); sc->msk_txqend[i]);
} }
} }
@@ -1345,7 +1341,8 @@ mskc_reset(struct msk_softc *sc)
CSR_WRITE_4(sc, STAT_LIST_ADDR_HI, MSK_ADDR_HI(addr)); CSR_WRITE_4(sc, STAT_LIST_ADDR_HI, MSK_ADDR_HI(addr));
/* Set the status list last index. */ /* Set the status list last index. */
CSR_WRITE_2(sc, STAT_LAST_IDX, MSK_STAT_RING_CNT - 1); CSR_WRITE_2(sc, STAT_LAST_IDX, MSK_STAT_RING_CNT - 1);
if (HW_FEATURE(sc, HWF_WA_DEV_43_418)) { if (sc->msk_hw_id == CHIP_ID_YUKON_EC &&
sc->msk_hw_rev == CHIP_REV_YU_EC_A1) {
/* WA for dev. #4.3 */ /* WA for dev. #4.3 */
CSR_WRITE_2(sc, STAT_TX_IDX_TH, ST_TXTH_IDX_MASK); CSR_WRITE_2(sc, STAT_TX_IDX_TH, ST_TXTH_IDX_MASK);
/* WA for dev. #4.18 */ /* WA for dev. #4.18 */
@@ -1354,8 +1351,11 @@ mskc_reset(struct msk_softc *sc)
} else { } else {
CSR_WRITE_2(sc, STAT_TX_IDX_TH, 0x0a); CSR_WRITE_2(sc, STAT_TX_IDX_TH, 0x0a);
CSR_WRITE_1(sc, STAT_FIFO_WM, 0x10); CSR_WRITE_1(sc, STAT_FIFO_WM, 0x10);
CSR_WRITE_1(sc, STAT_FIFO_ISR_WM, if (sc->msk_hw_id == CHIP_ID_YUKON_XL &&
HW_FEATURE(sc, HWF_WA_DEV_4109) ? 0x10 : 0x04); sc->msk_hw_rev == CHIP_REV_YU_XL_A0)
CSR_WRITE_1(sc, STAT_FIFO_ISR_WM, 0x04);
else
CSR_WRITE_1(sc, STAT_FIFO_ISR_WM, 0x10);
CSR_WRITE_4(sc, STAT_ISR_TIMER_INI, 0x0190); CSR_WRITE_4(sc, STAT_ISR_TIMER_INI, 0x0190);
} }
/* /*
@@ -1453,13 +1453,8 @@ msk_attach(device_t dev)
* compute the checksum? I think there is no reason to spend time to * compute the checksum? I think there is no reason to spend time to
* make Rx checksum offload work on Yukon II hardware. * make Rx checksum offload work on Yukon II hardware.
*/ */
ifp->if_capabilities = IFCAP_TXCSUM; ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_TSO4;
ifp->if_hwassist = MSK_CSUM_FEATURES; ifp->if_hwassist = MSK_CSUM_FEATURES | CSUM_TSO;
if (sc->msk_hw_id != CHIP_ID_YUKON_EC_U) {
/* It seems Yukon EC Ultra doesn't support TSO. */
ifp->if_capabilities |= IFCAP_TSO4;
ifp->if_hwassist |= CSUM_TSO;
}
ifp->if_capenable = ifp->if_capabilities; ifp->if_capenable = ifp->if_capabilities;
ifp->if_ioctl = msk_ioctl; ifp->if_ioctl = msk_ioctl;
ifp->if_start = msk_start; ifp->if_start = msk_start;
@@ -1505,6 +1500,9 @@ msk_attach(device_t dev)
*/ */
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
sc_if->msk_framesize = ifp->if_mtu + ETHER_HDR_LEN +
ETHER_VLAN_ENCAP_LEN;
/* /*
* Do miibus setup. * Do miibus setup.
*/ */
@@ -1517,10 +1515,6 @@ msk_attach(device_t dev)
error = ENXIO; error = ENXIO;
goto fail; goto fail;
} }
/* Check whether PHY Id is MARVELL. */
if (msk_phy_readreg(sc_if, PHY_ADDR_MARV, PHY_MARV_ID0)
== PHY_MARV_ID0_VAL)
sc->msk_marvell_phy = 1;
fail: fail:
if (error != 0) { if (error != 0) {
@@ -1540,7 +1534,7 @@ static int
mskc_attach(device_t dev) mskc_attach(device_t dev)
{ {
struct msk_softc *sc; struct msk_softc *sc;
int error, msic, *port, reg; int error, msic, msir, *port, reg;
sc = device_get_softc(dev); sc = device_get_softc(dev);
sc->msk_dev = dev; sc->msk_dev = dev;
@@ -1629,74 +1623,20 @@ mskc_attach(device_t dev)
else else
sc->msk_bustype = MSK_PCI_BUS; sc->msk_bustype = MSK_PCI_BUS;
/* Get H/W features(bugs). */
switch (sc->msk_hw_id) { switch (sc->msk_hw_id) {
case CHIP_ID_YUKON_EC: case CHIP_ID_YUKON_EC:
sc->msk_clock = 125; /* 125 Mhz */
if (sc->msk_hw_rev == CHIP_REV_YU_EC_A1) {
sc->msk_hw_feature =
HWF_WA_DEV_42 | HWF_WA_DEV_46 | HWF_WA_DEV_43_418 |
HWF_WA_DEV_420 | HWF_WA_DEV_423 |
HWF_WA_DEV_424 | HWF_WA_DEV_425 | HWF_WA_DEV_427 |
HWF_WA_DEV_428 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 |
HWF_WA_DEV_4152 | HWF_WA_DEV_4167;
} else {
/* A2/A3 */
sc->msk_hw_feature =
HWF_WA_DEV_424 | HWF_WA_DEV_425 | HWF_WA_DEV_427 |
HWF_WA_DEV_428 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 |
HWF_WA_DEV_4152 | HWF_WA_DEV_4167;
}
break;
case CHIP_ID_YUKON_EC_U: case CHIP_ID_YUKON_EC_U:
sc->msk_clock = 125; /* 125 Mhz */ sc->msk_clock = 125; /* 125 Mhz */
if (sc->msk_hw_rev == CHIP_REV_YU_EC_U_A0) {
sc->msk_hw_feature = HWF_WA_DEV_427 | HWF_WA_DEV_483 |
HWF_WA_DEV_4109;
} else if (sc->msk_hw_rev == CHIP_REV_YU_EC_A1) {
uint16_t v;
sc->msk_hw_feature = HWF_WA_DEV_427 | HWF_WA_DEV_4109 |
HWF_WA_DEV_4185;
v = CSR_READ_2(sc, Q_ADDR(Q_XA1, Q_WM));
if (v == 0)
sc->msk_hw_feature |= HWF_WA_DEV_4185CS |
HWF_WA_DEV_4200;
}
break; break;
case CHIP_ID_YUKON_FE: case CHIP_ID_YUKON_FE:
sc->msk_clock = 100; /* 100 Mhz */ sc->msk_clock = 100; /* 100 Mhz */
sc->msk_hw_feature = HWF_WA_DEV_427 | HWF_WA_DEV_4109 |
HWF_WA_DEV_4152 | HWF_WA_DEV_4167;
break; break;
case CHIP_ID_YUKON_XL: case CHIP_ID_YUKON_XL:
sc->msk_clock = 156; /* 156 Mhz */ sc->msk_clock = 156; /* 156 Mhz */
switch (sc->msk_hw_rev) {
case CHIP_REV_YU_XL_A0:
sc->msk_hw_feature =
HWF_WA_DEV_427 | HWF_WA_DEV_463 | HWF_WA_DEV_472 |
HWF_WA_DEV_479 | HWF_WA_DEV_483 | HWF_WA_DEV_4115 |
HWF_WA_DEV_4152 | HWF_WA_DEV_4167;
break;
case CHIP_REV_YU_XL_A1:
sc->msk_hw_feature =
HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 |
HWF_WA_DEV_4115 | HWF_WA_DEV_4152 | HWF_WA_DEV_4167;
break;
case CHIP_REV_YU_XL_A2:
sc->msk_hw_feature =
HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 |
HWF_WA_DEV_4115 | HWF_WA_DEV_4167;
break;
case CHIP_REV_YU_XL_A3:
sc->msk_hw_feature =
HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 |
HWF_WA_DEV_4115;
}
break; break;
default: default:
sc->msk_clock = 156; /* 156 Mhz */ sc->msk_clock = 156; /* 156 Mhz */
sc->msk_hw_feature = 0; break;
} }
/* Allocate IRQ resources. */ /* Allocate IRQ resources. */
@@ -1714,13 +1654,27 @@ mskc_attach(device_t dev)
*/ */
if (legacy_intr != 0) if (legacy_intr != 0)
msi_disable = 1; msi_disable = 1;
if (msic == 2 && msi_disable == 0 && sc->msk_num_port == 1 && if (msi_disable == 0) {
pci_alloc_msi(dev, &msic) == 0) { switch (msic) {
if (msic == 2) { case 2:
sc->msk_msi = 1; case 1: /* 88E8058 reports 1 MSI message */
sc->msk_irq_spec = msk_irq_spec_msi; msir = msic;
} else if (sc->msk_num_port == 1 &&
pci_release_msi(dev); pci_alloc_msi(dev, &msir) == 0) {
if (msic == msir) {
sc->msk_msi = 1;
sc->msk_irq_spec = msic == 2 ?
msk_irq_spec_msi2 :
msk_irq_spec_msi;
} else
pci_release_msi(dev);
}
break;
default:
device_printf(dev,
"Unexpected number of MSI messages : %d\n", msic);
break;
}
} }
error = bus_alloc_resources(dev, sc->msk_irq_spec, sc->msk_irq); error = bus_alloc_resources(dev, sc->msk_irq_spec, sc->msk_irq);
@@ -2964,7 +2918,7 @@ msk_watchdog(struct msk_if_softc *sc_if)
taskqueue_enqueue(taskqueue_fast, &sc_if->msk_tx_task); taskqueue_enqueue(taskqueue_fast, &sc_if->msk_tx_task);
} }
static void static int
mskc_shutdown(device_t dev) mskc_shutdown(device_t dev)
{ {
struct msk_softc *sc; struct msk_softc *sc;
@@ -2987,6 +2941,7 @@ mskc_shutdown(device_t dev)
CSR_WRITE_2(sc, B0_CTST, CS_RST_SET); CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
MSK_UNLOCK(sc); MSK_UNLOCK(sc);
return (0);
} }
static int static int
@@ -3226,15 +3181,12 @@ msk_intr_phy(struct msk_if_softc *sc_if)
{ {
uint16_t status; uint16_t status;
if (sc_if->msk_softc->msk_marvell_phy) { msk_phy_readreg(sc_if, PHY_ADDR_MARV, PHY_MARV_INT_STAT);
msk_phy_readreg(sc_if, PHY_ADDR_MARV, PHY_MARV_INT_STAT); status = msk_phy_readreg(sc_if, PHY_ADDR_MARV, PHY_MARV_INT_STAT);
status = msk_phy_readreg(sc_if, PHY_ADDR_MARV, /* Handle FIFO Underrun/Overflow? */
PHY_MARV_INT_STAT); if ((status & PHY_M_IS_FIFO_ERROR))
/* Handle FIFO Underrun/Overflow? */ device_printf(sc_if->msk_if_dev,
if ((status & PHY_M_IS_FIFO_ERROR)) "PHY FIFO underrun/overflow.\n");
device_printf(sc_if->msk_if_dev,
"PHY FIFO underrun/overflow.\n");
}
} }
static void static void
@@ -3706,6 +3658,15 @@ msk_init_locked(struct msk_if_softc *sc_if)
sc_if->msk_framesize = ifp->if_mtu + ETHER_HDR_LEN + sc_if->msk_framesize = ifp->if_mtu + ETHER_HDR_LEN +
ETHER_VLAN_ENCAP_LEN; ETHER_VLAN_ENCAP_LEN;
if (sc_if->msk_framesize > MSK_MAX_FRAMELEN &&
sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_EC_U) {
/*
* In Yukon EC Ultra, TSO & checksum offload is not
* supported for jumbo frame.
*/
ifp->if_hwassist &= ~(MSK_CSUM_FEATURES | CSUM_TSO);
ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM);
}
/* /*
* Initialize GMAC first. * Initialize GMAC first.
@@ -3796,9 +3757,6 @@ msk_init_locked(struct msk_if_softc *sc_if)
/* Configure hardware VLAN tag insertion/stripping. */ /* Configure hardware VLAN tag insertion/stripping. */
msk_setvlan(sc_if, ifp); msk_setvlan(sc_if, ifp);
/* XXX It seems STFW is requried for all cases. */
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), TX_STFW_ENA);
if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U) { if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U) {
/* Set Rx Pause threshould. */ /* Set Rx Pause threshould. */
CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, RX_GMF_LP_THR), CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, RX_GMF_LP_THR),
@@ -3807,16 +3765,17 @@ msk_init_locked(struct msk_if_softc *sc_if)
MSK_ECU_ULPP); MSK_ECU_ULPP);
if (sc_if->msk_framesize > MSK_MAX_FRAMELEN) { if (sc_if->msk_framesize > MSK_MAX_FRAMELEN) {
/* /*
* Can't sure the following code is needed as Yukon
* Yukon EC Ultra may not support jumbo frames.
*
* Set Tx GMAC FIFO Almost Empty Threshold. * Set Tx GMAC FIFO Almost Empty Threshold.
*/ */
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_AE_THR), CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_AE_THR),
MSK_ECU_AE_THR); MSK_ECU_JUMBO_WM << 16 | MSK_ECU_AE_THR);
/* Disable Store & Forward mode for Tx. */ /* Disable Store & Forward mode for Tx. */
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
TX_STFW_DIS); TX_JUMBO_ENA | TX_STFW_DIS);
} else {
/* Enable Store & Forward mode for Tx. */
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
TX_JUMBO_DIS | TX_STFW_ENA);
} }
} }
@@ -4035,8 +3994,7 @@ msk_stop(struct msk_if_softc *sc_if)
/* Disable all GMAC interrupt. */ /* Disable all GMAC interrupt. */
CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, GMAC_IRQ_MSK), 0); CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, GMAC_IRQ_MSK), 0);
/* Disable PHY interrupt. */ /* Disable PHY interrupt. */
if (sc->msk_marvell_phy) msk_phy_writereg(sc_if, PHY_ADDR_MARV, PHY_MARV_INT_MASK, 0);
msk_phy_writereg(sc_if, PHY_ADDR_MARV, PHY_MARV_INT_MASK, 0);
/* Disable the RAM Interface Arbiter. */ /* Disable the RAM Interface Arbiter. */
CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, TXA_CTRL), TXA_DIS_ARB); CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, TXA_CTRL), TXA_DIS_ARB);
@@ -93,7 +93,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/*$FreeBSD: src/sys/dev/msk/if_mskreg.h,v 1.6 2007/06/12 10:50:32 yongari Exp $*/ /*$FreeBSD: src/sys/dev/msk/if_mskreg.h,v 1.11 2007/12/05 09:41:58 remko Exp $*/
/* /*
* SysKonnect PCI vendor ID * SysKonnect PCI vendor ID
@@ -130,11 +130,13 @@
#define DEVICEID_MRVL_8035 0x4350 #define DEVICEID_MRVL_8035 0x4350
#define DEVICEID_MRVL_8036 0x4351 #define DEVICEID_MRVL_8036 0x4351
#define DEVICEID_MRVL_8038 0x4352 #define DEVICEID_MRVL_8038 0x4352
#define DEVICEID_MRVL_8039 0X4353
#define DEVICEID_MRVL_4360 0x4360 #define DEVICEID_MRVL_4360 0x4360
#define DEVICEID_MRVL_4361 0x4361 #define DEVICEID_MRVL_4361 0x4361
#define DEVICEID_MRVL_4362 0x4362 #define DEVICEID_MRVL_4362 0x4362
#define DEVICEID_MRVL_4363 0x4363 #define DEVICEID_MRVL_4363 0x4363
#define DEVICEID_MRVL_4364 0x4364 #define DEVICEID_MRVL_4364 0x4364
#define DEVICEID_MRVL_436A 0x436A
/* /*
* D-Link gigabit ethernet device ID * D-Link gigabit ethernet device ID
@@ -836,8 +838,8 @@
#define CHIP_REV_YU_EC_A2 1 /* Chip Rev. for Yukon-EC A2 */ #define CHIP_REV_YU_EC_A2 1 /* Chip Rev. for Yukon-EC A2 */
#define CHIP_REV_YU_EC_A3 2 /* Chip Rev. for Yukon-EC A3 */ #define CHIP_REV_YU_EC_A3 2 /* Chip Rev. for Yukon-EC A3 */
#define CHIP_REV_YU_EC_U_A0 0 #define CHIP_REV_YU_EC_U_A0 1
#define CHIP_REV_YU_EC_U_A1 1 #define CHIP_REV_YU_EC_U_A1 2
/* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ /* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */
#define Y2_STATUS_LNK2_INAC BIT_7 /* Status Link 2 inactiv (0 = activ) */ #define Y2_STATUS_LNK2_INAC BIT_7 /* Status Link 2 inactiv (0 = activ) */
@@ -1082,8 +1084,9 @@
/* Threshold values for Yukon-EC Ultra */ /* Threshold values for Yukon-EC Ultra */
#define MSK_ECU_ULPP 0x0080 /* Upper Pause Threshold (multiples of 8) */ #define MSK_ECU_ULPP 0x0080 /* Upper Pause Threshold (multiples of 8) */
#define MSK_ECU_LLPP 0x0060 /* Lower Pause Threshold (multiples of 8) */ #define MSK_ECU_LLPP 0x0060 /* Lower Pause Threshold (multiples of 8) */
#define MSK_ECU_AE_THR 0x0180 /* Almost Empty Threshold */ #define MSK_ECU_AE_THR 0x0070 /* Almost Empty Threshold */
#define MSK_ECU_TXFF_LEV 0x01a0 /* Tx BMU FIFO Level */ #define MSK_ECU_TXFF_LEV 0x01a0 /* Tx BMU FIFO Level */
#define MSK_ECU_JUMBO_WM 0x01
#define MSK_BMU_RX_WM 0x600 /* BMU Rx Watermark */ #define MSK_BMU_RX_WM 0x600 /* BMU Rx Watermark */
#define MSK_BMU_TX_WM 0x600 /* BMU Tx Watermark */ #define MSK_BMU_TX_WM 0x600 /* BMU Tx Watermark */
@@ -1863,6 +1866,8 @@
#define TX_STFW_ENA BIT_30 /* Enable Store & Forward (Yukon-EC Ultra) */ #define TX_STFW_ENA BIT_30 /* Enable Store & Forward (Yukon-EC Ultra) */
#define TX_VLAN_TAG_ON BIT_25 /* enable VLAN tagging */ #define TX_VLAN_TAG_ON BIT_25 /* enable VLAN tagging */
#define TX_VLAN_TAG_OFF BIT_24 /* disable VLAN tagging */ #define TX_VLAN_TAG_OFF BIT_24 /* disable VLAN tagging */
#define TX_JUMBO_ENA BIT_23 /* Enable Jumbo Mode (Yukon-EC Ultra) */
#define TX_JUMBO_DIS BIT_22 /* Disable Jumbo Mode (Yukon-EC Ultra) */
#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */ #define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */
#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */ #define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */
#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */ #define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */
@@ -2020,35 +2025,6 @@
/* GPHY address (bits 15..11 of SMI control reg) */ /* GPHY address (bits 15..11 of SMI control reg) */
#define PHY_ADDR_MARV 0 #define PHY_ADDR_MARV 0
/*-RMV- DWORD 1: Deviations */
#define HWF_WA_DEV_4200 0x10200000UL /*-RMV- 4.200 (D3 Blue Screen)*/
#define HWF_WA_DEV_4185CS 0x10100000UL /*-RMV- 4.185 (ECU 100 CS cal)*/
#define HWF_WA_DEV_4185 0x10080000UL /*-RMV- 4.185 (ECU Tx h check)*/
#define HWF_WA_DEV_4167 0x10040000UL /*-RMV- 4.167 (Rx OvSize Hang)*/
#define HWF_WA_DEV_4152 0x10020000UL /*-RMV- 4.152 (RSS issue) */
#define HWF_WA_DEV_4115 0x10010000UL /*-RMV- 4.115 (Rx MAC FIFO) */
#define HWF_WA_DEV_4109 0x10008000UL /*-RMV- 4.109 (BIU hang) */
#define HWF_WA_DEV_483 0x10004000UL /*-RMV- 4.83 (Rx TCP wrong) */
#define HWF_WA_DEV_479 0x10002000UL /*-RMV- 4.79 (Rx BMU hang II) */
#define HWF_WA_DEV_472 0x10001000UL /*-RMV- 4.72 (GPHY2 MDC clk) */
#define HWF_WA_DEV_463 0x10000800UL /*-RMV- 4.63 (Rx BMU hang I) */
#define HWF_WA_DEV_427 0x10000400UL /*-RMV- 4.27 (Tx Done Rep) */
#define HWF_WA_DEV_42 0x10000200UL /*-RMV- 4.2 (pref unit burst) */
#define HWF_WA_DEV_46 0x10000100UL /*-RMV- 4.6 (CPU crash II) */
#define HWF_WA_DEV_43_418 0x10000080UL /*-RMV- 4.3 & 4.18 (PCI unexp */
/*-RMV- compl&Stat BMU deadl) */
#define HWF_WA_DEV_420 0x10000040UL /*-RMV- 4.20 (Status BMU ov) */
#define HWF_WA_DEV_423 0x10000020UL /*-RMV- 4.23 (TCP Segm Hang) */
#define HWF_WA_DEV_424 0x10000010UL /*-RMV- 4.24 (MAC reg overwr) */
#define HWF_WA_DEV_425 0x10000008UL /*-RMV- 4.25 (Magic packet */
/*-RMV- with odd offset) */
#define HWF_WA_DEV_428 0x10000004UL /*-RMV- 4.28 (Poll-U &BigEndi)*/
#define HWF_WA_FIFO_FLUSH_YLA0 0x10000002UL /*-RMV- dis Rx GMAC FIFO Flush*/
#define HW_FEATURE(sc, f) \
(((((sc)->msk_hw_feature & 0x30000000) >> 28) & ((f) & 0x0fffffff)) != 0)
#define MSK_ADDR_LO(x) ((uint64_t) (x) & 0xffffffffUL) #define MSK_ADDR_LO(x) ((uint64_t) (x) & 0xffffffffUL)
#define MSK_ADDR_HI(x) ((uint64_t) (x) >> 32) #define MSK_ADDR_HI(x) ((uint64_t) (x) >> 32)
@@ -2331,9 +2307,7 @@ struct msk_softc {
uint32_t msk_intrmask; uint32_t msk_intrmask;
uint32_t msk_intrhwemask; uint32_t msk_intrhwemask;
int msk_suspended; int msk_suspended;
int msk_hw_feature;
int msk_clock; int msk_clock;
int msk_marvell_phy;
int msk_msi; int msk_msi;
struct msk_if_softc *msk_if[2]; struct msk_if_softc *msk_if[2];
device_t msk_devs[2]; device_t msk_devs[2];
@@ -48,5 +48,6 @@
#define ALIGN(x) ((((unsigned)x) + ALIGN_BYTES) & ~ALIGN_BYTES) #define ALIGN(x) ((((unsigned)x) + ALIGN_BYTES) & ~ALIGN_BYTES)
#define roundup2(x, y) (((x) + ((y) - 1)) & (~((y) - 1))) #define roundup2(x, y) (((x) + ((y) - 1)) & (~((y) - 1)))
#define rounddown(x, y) (((x) / (y)) * (y))
#endif /* _FBSD_COMPAT_SYS_PARAM_H_ */ #endif /* _FBSD_COMPAT_SYS_PARAM_H_ */