[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#628954: if_msk driver causes kernel panic



Package: kfreebsd-image-8.1-1-amd64
Version: 8.1+dfsg-8
Severity: grave
Tags: patch

Details at http://www.freebsd.org/cgi/query-pr.cgi?pr=154591

Upstream developer (yongari@freebsd.org) provided a fix by backporting
the if_msk driver from HEAD.  I've verified that this resolves the
problem when applied to kernel of FreeBSD 8.2.

-- System Information:
Debian Release: 6.0.1
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: kfreebsd-amd64 (x86_64)

Kernel: kFreeBSD 8.1-1-amd64
Locale: LANG=ca_AD.utf8, LC_CTYPE=ca_AD.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages kfreebsd-image-8.1-1-amd64 depends on:
ii  freebsd-utils                 8.1-4+b1   FreeBSD utilities needed for GNU/k
ii  kldutils                      8.1-4+b1   tools for managing kFreeBSD module

kfreebsd-image-8.1-1-amd64 recommends no packages.

kfreebsd-image-8.1-1-amd64 suggests no packages.

-- no debconf information
diff -ur sys/dev/msk.old/if_msk.c sys/dev/msk/if_msk.c
--- sys/dev/msk.old/if_msk.c	2010-11-26 21:37:19.000000000 +0100
+++ sys/dev/msk/if_msk.c	2011-05-28 02:22:07.000000000 +0200
@@ -99,7 +99,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/dev/msk/if_msk.c 222269 2011-05-24 20:39:07Z yongari $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -221,6 +221,10 @@
 	    "Marvell Yukon 88E8071 Gigabit Ethernet" },
 	{ VENDORID_MARVELL, DEVICEID_MRVL_436C,
 	    "Marvell Yukon 88E8072 Gigabit Ethernet" },
+	{ VENDORID_MARVELL, DEVICEID_MRVL_436D,
+	    "Marvell Yukon 88E8055 Gigabit Ethernet" },
+	{ VENDORID_MARVELL, DEVICEID_MRVL_4370,
+	    "Marvell Yukon 88E8075 Gigabit Ethernet" },
 	{ VENDORID_MARVELL, DEVICEID_MRVL_4380,
 	    "Marvell Yukon 88E8057 Gigabit Ethernet" },
 	{ VENDORID_MARVELL, DEVICEID_MRVL_4381,
@@ -270,6 +274,7 @@
 #ifndef __NO_STRICT_ALIGNMENT
 static __inline void msk_fixup_rx(struct mbuf *);
 #endif
+static __inline void msk_rxcsum(struct msk_if_softc *, uint32_t, struct mbuf *);
 static void msk_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
 static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
 static void msk_txeof(struct msk_if_softc *, int);
@@ -294,6 +299,7 @@
 static int msk_rx_dma_jalloc(struct msk_if_softc *);
 static void msk_txrx_dma_free(struct msk_if_softc *);
 static void msk_rx_dma_jfree(struct msk_if_softc *);
+static int msk_rx_fill(struct msk_if_softc *, int);
 static int msk_init_rx_ring(struct msk_if_softc *);
 static int msk_init_jumbo_rx_ring(struct msk_if_softc *);
 static void msk_init_tx_ring(struct msk_if_softc *);
@@ -642,6 +648,54 @@
 }
 
 static int
+msk_rx_fill(struct msk_if_softc *sc_if, int jumbo)
+{
+	uint16_t idx;
+	int i;
+
+	if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+	    (sc_if->msk_ifp->if_capenable & IFCAP_RXCSUM) != 0) {
+		/* Wait until controller executes OP_TCPSTART command. */
+		for (i = 10; i > 0; i--) {
+			DELAY(10);
+			idx = CSR_READ_2(sc_if->msk_softc,
+			    Y2_PREF_Q_ADDR(sc_if->msk_rxq,
+			    PREF_UNIT_GET_IDX_REG));
+			if (idx != 0)
+				break;
+		}
+		if (i == 0) {
+			device_printf(sc_if->msk_if_dev,
+			    "prefetch unit stuck?\n");
+			return (ETIMEDOUT);
+		}
+		/*
+		 * Fill consumed LE with free buffer. This can be done
+		 * in Rx handler but we don't want to add special code
+		 * in fast handler.
+		 */
+		if (jumbo > 0) {
+			if (msk_jumbo_newbuf(sc_if, 0) != 0)
+				return (ENOBUFS);
+			bus_dmamap_sync(sc_if->msk_cdata.msk_jumbo_rx_ring_tag,
+			    sc_if->msk_cdata.msk_jumbo_rx_ring_map,
+			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+		} else {
+			if (msk_newbuf(sc_if, 0) != 0)
+				return (ENOBUFS);
+			bus_dmamap_sync(sc_if->msk_cdata.msk_rx_ring_tag,
+			    sc_if->msk_cdata.msk_rx_ring_map,
+			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+		}
+		sc_if->msk_cdata.msk_rx_prod = 0;
+		CSR_WRITE_2(sc_if->msk_softc,
+		    Y2_PREF_Q_ADDR(sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG),
+		    sc_if->msk_cdata.msk_rx_prod);
+	}
+	return (0);
+}
+
+static int
 msk_init_rx_ring(struct msk_if_softc *sc_if)
 {
 	struct msk_ring_data *rd;
@@ -657,7 +711,21 @@
 	rd = &sc_if->msk_rdata;
 	bzero(rd->msk_rx_ring, sizeof(struct msk_rx_desc) * MSK_RX_RING_CNT);
 	prod = sc_if->msk_cdata.msk_rx_prod;
-	for (i = 0; i < MSK_RX_RING_CNT; i++) {
+	i = 0;
+	/* Have controller know how to compute Rx checksum. */
+	if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+	    (sc_if->msk_ifp->if_capenable & IFCAP_RXCSUM) != 0) {
+		rxd = &sc_if->msk_cdata.msk_rxdesc[prod];
+		rxd->rx_m = NULL;
+		rxd->rx_le = &rd->msk_rx_ring[prod];
+		rxd->rx_le->msk_addr = htole32(ETHER_HDR_LEN << 16 |
+		    ETHER_HDR_LEN);
+		rxd->rx_le->msk_control = htole32(OP_TCPSTART | HW_OWNER);
+		MSK_INC(prod, MSK_RX_RING_CNT);
+		MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_RX_RING_CNT);
+		i++;
+	}
+	for (; i < MSK_RX_RING_CNT; i++) {
 		rxd = &sc_if->msk_cdata.msk_rxdesc[prod];
 		rxd->rx_m = NULL;
 		rxd->rx_le = &rd->msk_rx_ring[prod];
@@ -675,7 +743,8 @@
 	CSR_WRITE_2(sc_if->msk_softc,
 	    Y2_PREF_Q_ADDR(sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG),
 	    sc_if->msk_cdata.msk_rx_prod);
-
+	if (msk_rx_fill(sc_if, 0) != 0)
+		return (ENOBUFS);
 	return (0);
 }
 
@@ -696,7 +765,21 @@
 	bzero(rd->msk_jumbo_rx_ring,
 	    sizeof(struct msk_rx_desc) * MSK_JUMBO_RX_RING_CNT);
 	prod = sc_if->msk_cdata.msk_rx_prod;
-	for (i = 0; i < MSK_JUMBO_RX_RING_CNT; i++) {
+	i = 0;
+	/* Have controller know how to compute Rx checksum. */
+	if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+	    (sc_if->msk_ifp->if_capenable & IFCAP_RXCSUM) != 0) {
+		rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[prod];
+		rxd->rx_m = NULL;
+		rxd->rx_le = &rd->msk_jumbo_rx_ring[prod];
+		rxd->rx_le->msk_addr = htole32(ETHER_HDR_LEN << 16 |
+		    ETHER_HDR_LEN);
+		rxd->rx_le->msk_control = htole32(OP_TCPSTART | HW_OWNER);
+		MSK_INC(prod, MSK_JUMBO_RX_RING_CNT);
+		MSK_INC(sc_if->msk_cdata.msk_rx_cons, MSK_JUMBO_RX_RING_CNT);
+		i++;
+	}
+	for (; i < MSK_JUMBO_RX_RING_CNT; i++) {
 		rxd = &sc_if->msk_cdata.msk_jumbo_rxdesc[prod];
 		rxd->rx_m = NULL;
 		rxd->rx_le = &rd->msk_jumbo_rx_ring[prod];
@@ -713,7 +796,8 @@
 	CSR_WRITE_2(sc_if->msk_softc,
 	    Y2_PREF_Q_ADDR(sc_if->msk_rxq, PREF_UNIT_PUT_IDX_REG),
 	    sc_if->msk_cdata.msk_rx_prod);
-
+	if (msk_rx_fill(sc_if, 1) != 0)
+		return (ENOBUFS);
 	return (0);
 }
 
@@ -922,7 +1006,7 @@
 	struct msk_if_softc *sc_if;
 	struct ifreq *ifr;
 	struct mii_data	*mii;
-	int error, mask;
+	int error, mask, reinit;
 
 	sc_if = ifp->if_softc;
 	ifr = (struct ifreq *)data;
@@ -934,7 +1018,7 @@
 		if (ifr->ifr_mtu > MSK_JUMBO_MTU || ifr->ifr_mtu < ETHERMIN)
 			error = EINVAL;
 		else if (ifp->if_mtu != ifr->ifr_mtu) {
- 			if (ifr->ifr_mtu > ETHERMTU) {
+			if (ifr->ifr_mtu > ETHERMTU) {
 				if ((sc_if->msk_flags & MSK_FLAG_JUMBO) == 0) {
 					error = EINVAL;
 					MSK_IF_UNLOCK(sc_if);
@@ -950,7 +1034,10 @@
 				}
 			}
 			ifp->if_mtu = ifr->ifr_mtu;
-			msk_init_locked(sc_if);
+			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+				ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+				msk_init_locked(sc_if);
+			}
 		}
 		MSK_IF_UNLOCK(sc_if);
 		break;
@@ -981,6 +1068,7 @@
 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 		break;
 	case SIOCSIFCAP:
+		reinit = 0;
 		MSK_IF_LOCK(sc_if);
 		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 		if ((mask & IFCAP_TXCSUM) != 0 &&
@@ -992,8 +1080,11 @@
 				ifp->if_hwassist &= ~MSK_CSUM_FEATURES;
 		}
 		if ((mask & IFCAP_RXCSUM) != 0 &&
-		    (IFCAP_RXCSUM & ifp->if_capabilities) != 0)
+		    (IFCAP_RXCSUM & ifp->if_capabilities) != 0) {
 			ifp->if_capenable ^= IFCAP_RXCSUM;
+			if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0)
+				reinit = 1;
+		}
 		if ((mask & IFCAP_VLAN_HWCSUM) != 0 &&
 		    (IFCAP_VLAN_HWCSUM & ifp->if_capabilities) != 0)
 			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
@@ -1021,8 +1112,11 @@
 			ifp->if_hwassist &= ~(MSK_CSUM_FEATURES | CSUM_TSO);
 			ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM);
 		}
-
 		VLAN_CAPABILITIES(ifp);
+		if (reinit > 0 && (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+			msk_init_locked(sc_if);
+		}
 		MSK_IF_UNLOCK(sc_if);
 		break;
 	default:
@@ -1125,37 +1219,30 @@
 		 */
 		CSR_WRITE_1(sc, B2_Y2_CLK_GATE, val);
 
-		val = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
-		val &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+		our = CSR_PCI_READ_4(sc, PCI_OUR_REG_1);
+		our &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
 		if (sc->msk_hw_id == CHIP_ID_YUKON_XL) {
 			if (sc->msk_hw_rev > CHIP_REV_YU_XL_A1) {
 				/* Deassert Low Power for 1st PHY. */
-				val |= PCI_Y2_PHY1_COMA;
+				our |= PCI_Y2_PHY1_COMA;
 				if (sc->msk_num_port > 1)
-					val |= PCI_Y2_PHY2_COMA;
+					our |= PCI_Y2_PHY2_COMA;
 			}
 		}
-		/* Release PHY from PowerDown/COMA mode. */
-		CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, val);
-		switch (sc->msk_hw_id) {
-		case CHIP_ID_YUKON_EC_U:
-		case CHIP_ID_YUKON_EX:
-		case CHIP_ID_YUKON_FE_P:
-		case CHIP_ID_YUKON_UL_2:
-		case CHIP_ID_YUKON_OPT:
-			CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF);
-
-			/* Enable all clocks. */
-			CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
-			our = CSR_PCI_READ_4(sc, PCI_OUR_REG_4);
-			our &= (PCI_FORCE_ASPM_REQUEST|PCI_ASPM_GPHY_LINK_DOWN|
-			    PCI_ASPM_INT_FIFO_EMPTY|PCI_ASPM_CLKRUN_REQUEST);
+		if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U ||
+		    sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+		    sc->msk_hw_id >= CHIP_ID_YUKON_FE_P) {
+			val = CSR_PCI_READ_4(sc, PCI_OUR_REG_4);
+			val &= (PCI_FORCE_ASPM_REQUEST |
+			    PCI_ASPM_GPHY_LINK_DOWN | PCI_ASPM_INT_FIFO_EMPTY |
+			    PCI_ASPM_CLKRUN_REQUEST);
 			/* Set all bits to 0 except bits 15..12. */
-			CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, our);
-			our = CSR_PCI_READ_4(sc, PCI_OUR_REG_5);
-			our &= PCI_CTL_TIM_VMAIN_AV_MSK;
-			CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, our);
+			CSR_PCI_WRITE_4(sc, PCI_OUR_REG_4, val);
+			val = CSR_PCI_READ_4(sc, PCI_OUR_REG_5);
+			val &= PCI_CTL_TIM_VMAIN_AV_MSK;
+			CSR_PCI_WRITE_4(sc, PCI_OUR_REG_5, val);
 			CSR_PCI_WRITE_4(sc, PCI_CFG_REG_1, 0);
+			CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_ON);
 			/*
 			 * Disable status race, workaround for
 			 * Yukon EC Ultra & Yukon EX.
@@ -1164,10 +1251,10 @@
 			val |= GLB_GPIO_STAT_RACE_DIS;
 			CSR_WRITE_4(sc, B2_GP_IO, val);
 			CSR_READ_4(sc, B2_GP_IO);
-			break;
-		default:
-			break;
 		}
+		/* Release PHY from PowerDown/COMA mode. */
+		CSR_PCI_WRITE_4(sc, PCI_OUR_REG_1, our);
+
 		for (i = 0; i < sc->msk_num_port; i++) {
 			CSR_WRITE_2(sc, MR_ADDR(i, GMAC_LINK_CTRL),
 			    GMLC_RST_SET);
@@ -1213,28 +1300,33 @@
 	bus_addr_t addr;
 	uint16_t status;
 	uint32_t val;
-	int i;
-
-	CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
+	int i, initram;
 
 	/* Disable ASF. */
-	if (sc->msk_hw_id == CHIP_ID_YUKON_EX) {
-		status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR);
-		/* Clear AHB bridge & microcontroller reset. */
-		status &= ~(Y2_ASF_HCU_CCSR_AHB_RST |
-		    Y2_ASF_HCU_CCSR_CPU_RST_MODE);
-		/* Clear ASF microcontroller state. */
-		status &= ~ Y2_ASF_HCU_CCSR_UC_STATE_MSK;
-		CSR_WRITE_2(sc, B28_Y2_ASF_HCU_CCSR, status);
-	} else
-		CSR_WRITE_1(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
-	CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE);
-
-	/*
-	 * Since we disabled ASF, S/W reset is required for Power Management.
-	 */
-	CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
-	CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
+	if (sc->msk_hw_id >= CHIP_ID_YUKON_XL &&
+	    sc->msk_hw_id <= CHIP_ID_YUKON_SUPR) {
+		if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+		    sc->msk_hw_id == CHIP_ID_YUKON_SUPR) {
+			CSR_WRITE_4(sc, B28_Y2_CPU_WDOG, 0);
+			status = CSR_READ_2(sc, B28_Y2_ASF_HCU_CCSR);
+			/* Clear AHB bridge & microcontroller reset. */
+			status &= ~(Y2_ASF_HCU_CCSR_AHB_RST |
+			    Y2_ASF_HCU_CCSR_CPU_RST_MODE);
+			/* Clear ASF microcontroller state. */
+			status &= ~Y2_ASF_HCU_CCSR_UC_STATE_MSK;
+			status &= ~Y2_ASF_HCU_CCSR_CPU_CLK_DIVIDE_MSK;
+			CSR_WRITE_2(sc, B28_Y2_ASF_HCU_CCSR, status);
+			CSR_WRITE_4(sc, B28_Y2_CPU_WDOG, 0);
+		} else
+			CSR_WRITE_1(sc, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
+		CSR_WRITE_2(sc, B0_CTST, Y2_ASF_DISABLE);
+		/*
+		 * Since we disabled ASF, S/W reset is required for
+		 * Power Management.
+		 */
+		CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
+		CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
+	}
 
 	/* Clear all error bits in the PCI status register. */
 	status = pci_read_config(sc->msk_dev, PCIR_STATUS, 2);
@@ -1242,7 +1334,7 @@
 
 	pci_write_config(sc->msk_dev, PCIR_STATUS, status |
 	    PCIM_STATUS_PERR | PCIM_STATUS_SERR | PCIM_STATUS_RMABORT |
-	    PCIM_STATUS_RTABORT | PCIM_STATUS_PERRREPORT, 2);
+	    PCIM_STATUS_RTABORT | PCIM_STATUS_MDPERR, 2);
 	CSR_WRITE_2(sc, B0_CTST, CS_MRST_CLR);
 
 	switch (sc->msk_bustype) {
@@ -1275,17 +1367,22 @@
 	/* Reset GPHY/GMAC Control */
 	for (i = 0; i < sc->msk_num_port; i++) {
 		/* GPHY Control reset. */
-		CSR_WRITE_4(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_SET);
-		CSR_WRITE_4(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_CLR);
+		CSR_WRITE_1(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_SET);
+		CSR_WRITE_1(sc, MR_ADDR(i, GPHY_CTRL), GPC_RST_CLR);
 		/* GMAC Control reset. */
 		CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_SET);
 		CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_RST_CLR);
 		CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL), GMC_F_LOOPB_OFF);
-		if (sc->msk_hw_id == CHIP_ID_YUKON_EX)
+		if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+		    sc->msk_hw_id == CHIP_ID_YUKON_SUPR)
 			CSR_WRITE_4(sc, MR_ADDR(i, GMAC_CTRL),
 			    GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON |
 			    GMC_BYP_RETR_ON);
 	}
+
+	if (sc->msk_hw_id == CHIP_ID_YUKON_SUPR &&
+	    sc->msk_hw_rev > CHIP_REV_YU_SU_B0)
+		CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, PCI_CLK_MACSEC_DIS);
 	if (sc->msk_hw_id == CHIP_ID_YUKON_OPT && sc->msk_hw_rev == 0) {
 		/* Disable PCIe PHY powerdown(reg 0x80, bit7). */
 		CSR_WRITE_4(sc, Y2_PEX_PHY_DATA, (0x0080 << 16) | 0x0080);
@@ -1309,8 +1406,14 @@
 	CSR_WRITE_1(sc, GMAC_TI_ST_CTRL, GMT_ST_STOP);
 	CSR_WRITE_1(sc, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
 
+	initram = 0;
+	if (sc->msk_hw_id == CHIP_ID_YUKON_XL ||
+	    sc->msk_hw_id == CHIP_ID_YUKON_EC ||
+	    sc->msk_hw_id == CHIP_ID_YUKON_FE)
+		initram++;
+
 	/* Configure timeout values. */
-	for (i = 0; i < sc->msk_num_port; i++) {
+	for (i = 0; initram > 0 && i < sc->msk_num_port; i++) {
 		CSR_WRITE_2(sc, SELECT_RAM_BUFFER(i, B3_RI_CTRL), RI_RST_SET);
 		CSR_WRITE_2(sc, SELECT_RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
 		CSR_WRITE_1(sc, SELECT_RAM_BUFFER(i, B3_RI_WTO_R1),
@@ -1485,23 +1588,14 @@
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_mtu = ETHERMTU;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-	/*
-	 * IFCAP_RXCSUM capability is intentionally disabled as the hardware
-	 * has serious bug in Rx checksum offload for all Yukon II family
-	 * hardware. It seems there is a workaround to make it work somtimes.
-	 * However, the workaround also have to check OP code sequences to
-	 * verify whether the OP code is correct. Sometimes it should compute
-	 * IP/TCP/UDP checksum in driver in order to verify correctness of
-	 * checksum computed by hardware. If you have to compute checksum
-	 * with software to verify the hardware's checksum why have hardware
-	 * compute the checksum? I think there is no reason to spend time to
-	 * make Rx checksum offload work on Yukon II hardware.
-	 */
 	ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_TSO4;
 	/*
-	 * Enable Rx checksum offloading if controller support new
-	 * descriptor format.
+	 * Enable Rx checksum offloading if controller supports
+	 * new descriptor formant and controller is not Yukon XL.
 	 */
+	if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+	    sc->msk_hw_id != CHIP_ID_YUKON_XL)
+		ifp->if_capabilities |= IFCAP_RXCSUM;
 	if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0 &&
 	    (sc_if->msk_flags & MSK_FLAG_NORX_CSUM) == 0)
 		ifp->if_capabilities |= IFCAP_RXCSUM;
@@ -1509,8 +1603,6 @@
 	ifp->if_capenable = ifp->if_capabilities;
 	ifp->if_ioctl = msk_ioctl;
 	ifp->if_start = msk_start;
-	ifp->if_timer = 0;
-	ifp->if_watchdog = NULL;
 	ifp->if_init = msk_init;
 	IFQ_SET_MAXLEN(&ifp->if_snd, MSK_TX_RING_CNT - 1);
 	ifp->if_snd.ifq_drv_maxlen = MSK_TX_RING_CNT - 1;
@@ -1544,7 +1636,7 @@
 		 * this workaround does not work so disable checksum offload
 		 * for VLAN interface.
 		 */
-        	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO;
+		ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO;
 		/*
 		 * Enable Rx checksum offloading for VLAN tagged frames
 		 * if controller support new descriptor format.
@@ -1630,13 +1722,15 @@
 		}
 	}
 
+	/* Enable all clocks before accessing any registers. */
+	CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
+
 	CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
 	sc->msk_hw_id = CSR_READ_1(sc, B2_CHIP_ID);
 	sc->msk_hw_rev = (CSR_READ_1(sc, B2_MAC_CFG) >> 4) & 0x0f;
 	/* Bail out if chip is not recognized. */
 	if (sc->msk_hw_id < CHIP_ID_YUKON_XL ||
 	    sc->msk_hw_id > CHIP_ID_YUKON_OPT ||
-	    sc->msk_hw_id == CHIP_ID_YUKON_SUPR ||
 	    sc->msk_hw_id == CHIP_ID_YUKON_UNKNOWN) {
 		device_printf(dev, "unknown device: id=0x%02x, rev=0x%02x\n",
 		    sc->msk_hw_id, sc->msk_hw_rev);
@@ -1670,9 +1764,6 @@
 	resource_int_value(device_get_name(dev), device_get_unit(dev),
 	    "int_holdoff", &sc->msk_int_holdoff);
 
-	/* Soft reset. */
-	CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
-	CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
 	sc->msk_pmd = CSR_READ_1(sc, B2_PMD_TYP);
 	/* Check number of MACs. */
 	sc->msk_num_port = 1;
@@ -1746,6 +1837,11 @@
 		sc->msk_clock = 156;	/* 156 MHz */
 		sc->msk_pflags |= MSK_FLAG_JUMBO;
 		break;
+	case CHIP_ID_YUKON_SUPR:
+		sc->msk_clock = 125;	/* 125 MHz */
+		sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_DESCV2 |
+		    MSK_FLAG_AUTOTX_CSUM;
+		break;
 	case CHIP_ID_YUKON_UL_2:
 		sc->msk_clock = 125;	/* 125 MHz */
 		sc->msk_pflags |= MSK_FLAG_JUMBO;
@@ -1811,7 +1907,7 @@
 	}
 	mmd->port = MSK_PORT_A;
 	mmd->pmd = sc->msk_pmd;
-	mmd->mii_flags |= MIIF_DOPAUSE | MIIF_FORCEPAUSE;
+	mmd->mii_flags |= MIIF_DOPAUSE;
 	if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S')
 		mmd->mii_flags |= MIIF_HAVEFIBER;
 	if (sc->msk_pmd == 'P')
@@ -1825,7 +1921,8 @@
 			error = ENXIO;
 			goto fail;
 		}
-		mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK | M_ZERO);
+		mmd = malloc(sizeof(struct msk_mii_data), M_DEVBUF, M_WAITOK |
+		    M_ZERO);
 		if (mmd == NULL) {
 			device_printf(dev, "failed to allocate memory for "
 			    "ivars of PORT_B\n");
@@ -1834,9 +1931,9 @@
 		}
 		mmd->port = MSK_PORT_B;
 		mmd->pmd = sc->msk_pmd;
-	 	if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S')
+		if (sc->msk_pmd == 'L' || sc->msk_pmd == 'S')
 			mmd->mii_flags |= MIIF_HAVEFIBER;
-	 	if (sc->msk_pmd == 'P')
+		if (sc->msk_pmd == 'P')
 			mmd->mii_flags |= MIIF_HAVEFIBER | MIIF_MACPRIV0;
 		device_set_ivars(sc->msk_devs[MSK_PORT_B], mmd);
 	}
@@ -1888,7 +1985,8 @@
 		/* Can't hold locks while calling detach. */
 		MSK_IF_UNLOCK(sc_if);
 		callout_drain(&sc_if->msk_tick_ch);
-		ether_ifdetach(ifp);
+		if (ifp)
+			ether_ifdetach(ifp);
 		MSK_IF_LOCK(sc_if);
 	}
 
@@ -1990,7 +2088,7 @@
 	error = bus_dma_tag_create(
 		    bus_get_dma_tag(sc->msk_dev),	/* parent */
 		    MSK_STAT_ALIGN, 0,		/* alignment, boundary */
-		    BUS_SPACE_MAXADDR,		/* lowaddr */
+		    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
 		    BUS_SPACE_MAXADDR,		/* highaddr */
 		    NULL, NULL,			/* filter, filterarg */
 		    MSK_STAT_RING_SZ,		/* maxsize */
@@ -2886,6 +2984,7 @@
 
 	MSK_LOCK(sc);
 
+	CSR_PCI_WRITE_4(sc, PCI_OUR_REG_3, 0);
 	mskc_reset(sc);
 	for (i = 0; i < sc->msk_num_port; i++) {
 		if (sc->msk_if[i] != NULL && sc->msk_if[i]->msk_ifp != NULL &&
@@ -2919,6 +3018,96 @@
 }
 #endif
 
+static __inline void
+msk_rxcsum(struct msk_if_softc *sc_if, uint32_t control, struct mbuf *m)
+{
+	struct ether_header *eh;
+	struct ip *ip;
+	struct udphdr *uh;
+	int32_t hlen, len, pktlen, temp32;
+	uint16_t csum, *opts;
+
+	if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0) {
+		if ((control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
+			m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+			if ((control & CSS_IPV4_CSUM_OK) != 0)
+				m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+			if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
+			    (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
+				m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
+				    CSUM_PSEUDO_HDR;
+				m->m_pkthdr.csum_data = 0xffff;
+			}
+		}
+		return;
+	}
+	/*
+	 * Marvell Yukon controllers that support OP_RXCHKS has known
+	 * to have various Rx checksum offloading bugs. These
+	 * controllers can be configured to compute simple checksum
+	 * at two different positions. So we can compute IP and TCP/UDP
+	 * checksum at the same time. We intentionally have controller
+	 * compute TCP/UDP checksum twice by specifying the same
+	 * checksum start position and compare the result. If the value
+	 * is different it would indicate the hardware logic was wrong.
+	 */
+	if ((sc_if->msk_csum & 0xFFFF) != (sc_if->msk_csum >> 16)) {
+		if (bootverbose)
+			device_printf(sc_if->msk_if_dev,
+			    "Rx checksum value mismatch!\n");
+		return;
+	}
+	pktlen = m->m_pkthdr.len;
+	if (pktlen < sizeof(struct ether_header) + sizeof(struct ip))
+		return;
+	eh = mtod(m, struct ether_header *);
+	if (eh->ether_type != htons(ETHERTYPE_IP))
+		return;
+	ip = (struct ip *)(eh + 1);
+	if (ip->ip_v != IPVERSION)
+		return;
+
+	hlen = ip->ip_hl << 2;
+	pktlen -= sizeof(struct ether_header);
+	if (hlen < sizeof(struct ip))
+		return;
+	if (ntohs(ip->ip_len) < hlen)
+		return;
+	if (ntohs(ip->ip_len) != pktlen)
+		return;
+	if (ip->ip_off & htons(IP_MF | IP_OFFMASK))
+		return;	/* can't handle fragmented packet. */
+
+	switch (ip->ip_p) {
+	case IPPROTO_TCP:
+		if (pktlen < (hlen + sizeof(struct tcphdr)))
+			return;
+		break;
+	case IPPROTO_UDP:
+		if (pktlen < (hlen + sizeof(struct udphdr)))
+			return;
+		uh = (struct udphdr *)((caddr_t)ip + hlen);
+		if (uh->uh_sum == 0)
+			return; /* no checksum */
+		break;
+	default:
+		return;
+	}
+	csum = bswap16(sc_if->msk_csum & 0xFFFF);
+	/* Checksum fixup for IP options. */
+	len = hlen - sizeof(struct ip);
+	if (len > 0) {
+		opts = (uint16_t *)(ip + 1);
+		for (; len > 0; len -= sizeof(uint16_t), opts++) {
+			temp32 = csum - *opts;
+			temp32 = (temp32 >> 16) + (temp32 & 65535);
+			csum = temp32 & 65535;
+		}
+	}
+	m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
+	m->m_pkthdr.csum_data = csum;
+}
+
 static void
 msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, uint32_t control,
     int len)
@@ -2973,18 +3162,8 @@
 			msk_fixup_rx(m);
 #endif
 		ifp->if_ipackets++;
-		if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
-		    (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
-			m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
-			if ((control & CSS_IPV4_CSUM_OK) != 0)
-				m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
-			if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
-			    (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
-				m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
-				    CSUM_PSEUDO_HDR;
-				m->m_pkthdr.csum_data = 0xffff;
-			}
-		}
+		if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
+			msk_rxcsum(sc_if, control, m);
 		/* Check for VLAN tagged packets. */
 		if ((status & GMR_FS_VLAN) != 0 &&
 		    (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
@@ -3043,18 +3222,8 @@
 			msk_fixup_rx(m);
 #endif
 		ifp->if_ipackets++;
-		if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
-		    (control & (CSS_IPV4 | CSS_IPFRAG)) == CSS_IPV4) {
-			m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
-			if ((control & CSS_IPV4_CSUM_OK) != 0)
-				m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
-			if ((control & (CSS_TCP | CSS_UDP)) != 0 &&
-			    (control & (CSS_TCPUDP_CSUM_OK)) != 0) {
-				m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
-				    CSUM_PSEUDO_HDR;
-				m->m_pkthdr.csum_data = 0xffff;
-			}
-		}
+		if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
+			msk_rxcsum(sc_if, control, m);
 		/* Check for VLAN tagged packets. */
 		if ((status & GMR_FS_VLAN) != 0 &&
 		    (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
@@ -3260,7 +3429,7 @@
 		CSR_WRITE_1(sc, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 		pci_write_config(sc->msk_dev, PCIR_STATUS, v16 |
 		    PCIM_STATUS_PERR | PCIM_STATUS_SERR | PCIM_STATUS_RMABORT |
-		    PCIM_STATUS_RTABORT | PCIM_STATUS_PERRREPORT, 2);
+		    PCIM_STATUS_RTABORT | PCIM_STATUS_MDPERR, 2);
 		CSR_WRITE_1(sc, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 	}
 
@@ -3371,6 +3540,9 @@
 			break;
 		case OP_RXCHKSVLAN:
 			sc_if->msk_vtag = ntohs(len);
+			/* FALLTHROUGH */
+		case OP_RXCHKS:
+			sc_if->msk_csum = status;
 			break;
 		case OP_RXSTAT:
 			if (!(sc_if->msk_ifp->if_drv_flags & IFF_DRV_RUNNING))
@@ -3504,37 +3676,24 @@
 
 	ifp = sc_if->msk_ifp;
 	sc = sc_if->msk_softc;
-	switch (sc->msk_hw_id) {
-	case CHIP_ID_YUKON_EX:
-		if (sc->msk_hw_rev == CHIP_REV_YU_EX_A0)
-			goto yukon_ex_workaround;
-		if (ifp->if_mtu > ETHERMTU)
-			CSR_WRITE_4(sc,
-			    MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
-			    TX_JUMBO_ENA | TX_STFW_ENA);
-		else
-			CSR_WRITE_4(sc,
-			    MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
-			    TX_JUMBO_DIS | TX_STFW_ENA);
-		break;
-	default:
-yukon_ex_workaround:
+	if ((sc->msk_hw_id == CHIP_ID_YUKON_EX &&
+	    sc->msk_hw_rev != CHIP_REV_YU_EX_A0) ||
+	    sc->msk_hw_id >= CHIP_ID_YUKON_SUPR) {
+		CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+		    TX_STFW_ENA);
+	} else {
 		if (ifp->if_mtu > ETHERMTU) {
 			/* Set Tx GMAC FIFO Almost Empty Threshold. */
 			CSR_WRITE_4(sc,
 			    MR_ADDR(sc_if->msk_port, TX_GMF_AE_THR),
 			    MSK_ECU_JUMBO_WM << 16 | MSK_ECU_AE_THR);
 			/* Disable Store & Forward mode for Tx. */
-			CSR_WRITE_4(sc,
-			    MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
-			    TX_JUMBO_ENA | TX_STFW_DIS);
+			CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+			    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);
+			CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T),
+			    TX_STFW_ENA);
 		}
-		break;
 	}
 }
 
@@ -3583,11 +3742,12 @@
 		ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM);
 	}
 
- 	/* GMAC Control reset. */
- 	CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET);
- 	CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR);
- 	CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF);
-	if (sc->msk_hw_id == CHIP_ID_YUKON_EX)
+	/* GMAC Control reset. */
+	CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET);
+	CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR);
+	CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF);
+	if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+	    sc->msk_hw_id == CHIP_ID_YUKON_SUPR)
 		CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL),
 		    GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON |
 		    GMC_BYP_RETR_ON);
@@ -3695,13 +3855,13 @@
 		msk_set_tx_stfwd(sc_if);
 	}
 
- 	if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P &&
- 	    sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
- 		/* Disable dynamic watermark - from Linux. */
- 		reg = CSR_READ_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA));
- 		reg &= ~0x03;
- 		CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA), reg);
- 	}
+	if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P &&
+	    sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
+		/* Disable dynamic watermark - from Linux. */
+		reg = CSR_READ_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA));
+		reg &= ~0x03;
+		CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA), reg);
+	}
 
 	/*
 	 * Disable Force Sync bit and Alloc bit in Tx RAM interface
@@ -3758,8 +3918,13 @@
 	msk_init_tx_ring(sc_if);
 
 	/* Disable Rx checksum offload and RSS hash. */
-	CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_rxq, Q_CSR),
-	    BMU_DIS_RX_CHKSUM | BMU_DIS_RX_RSS_HASH);
+	reg = BMU_DIS_RX_RSS_HASH;
+	if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
+	    (ifp->if_capenable & IFCAP_RXCSUM) != 0)
+		reg |= BMU_ENA_RX_CHKSUM;
+	else
+		reg |= BMU_DIS_RX_CHKSUM;
+	CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_rxq, Q_CSR), reg);
 	if (sc_if->msk_framesize > (MCLBYTES - MSK_RX_BUF_ALIGN)) {
 		msk_set_prefetch(sc, sc_if->msk_rxq,
 		    sc_if->msk_rdata.msk_jumbo_rx_ring_paddr,
@@ -3777,7 +3942,8 @@
 		msk_stop(sc_if);
 		return;
 	}
-	if (sc->msk_hw_id == CHIP_ID_YUKON_EX) {
+	if (sc->msk_hw_id == CHIP_ID_YUKON_EX ||
+	    sc->msk_hw_id == CHIP_ID_YUKON_SUPR) {
 		/* Disable flushing of non-ASF packets. */
 		CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T),
 		    GMF_RX_MACSEC_FLUSH_OFF);
diff -ur sys/dev/msk.old/if_mskreg.h sys/dev/msk/if_mskreg.h
--- sys/dev/msk.old/if_mskreg.h	2010-05-06 20:47:16.000000000 +0200
+++ sys/dev/msk/if_mskreg.h	2011-05-28 02:22:07.000000000 +0200
@@ -93,7 +93,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/*$FreeBSD$*/
+/*$FreeBSD: head/sys/dev/msk/if_mskreg.h 222230 2011-05-23 21:51:47Z yongari $*/
 
 /*
  * SysKonnect PCI vendor ID
@@ -144,6 +144,8 @@
 #define DEVICEID_MRVL_436A	0x436A
 #define DEVICEID_MRVL_436B	0x436B
 #define DEVICEID_MRVL_436C	0x436C
+#define DEVICEID_MRVL_436D	0x436D
+#define DEVICEID_MRVL_4370	0x4370
 #define DEVICEID_MRVL_4380	0x4380
 #define DEVICEID_MRVL_4381	0x4381
 
@@ -321,6 +323,9 @@
 #define PCI_OS_SPD_X100		2	/* PCI-X 100MHz Bus */
 #define PCI_OS_SPD_X133		3	/* PCI-X 133MHz Bus */
 
+/* PCI_OUR_REG_3	32 bit	Our Register 3 (Yukon-ECU only) */
+#define	PCI_CLK_MACSEC_DIS	BIT_17	/* Disable Clock MACSec. */
+
 /* PCI_OUR_REG_4	32 bit	Our Register 4 (Yukon-ECU only) */
 #define	PCI_TIMER_VALUE_MSK	(0xff<<16)	/* Bit 23..16:	Timer Value Mask */
 #define	PCI_FORCE_ASPM_REQUEST	BIT_15	/* Force ASPM Request (A1 only) */
@@ -677,6 +682,7 @@
 /* ASF Subsystem Registers (Yukon-2 only) */
 #define B28_Y2_SMB_CONFIG	0x0e40	/* 32 bit ASF SMBus Config Register */
 #define B28_Y2_SMB_CSD_REG	0x0e44	/* 32 bit ASF SMB Control/Status/Data */
+#define B28_Y2_CPU_WDOG		0x0e48	/* 32 bit Watchdog Register */
 #define B28_Y2_ASF_IRQ_V_BASE	0x0e60	/* 32 bit ASF IRQ Vector Base */
 #define B28_Y2_ASF_STAT_CMD	0x0e68	/* 32 bit ASF Status and Command Reg */
 #define B28_Y2_ASF_HCU_CCSR	0x0e68	/* 32 bit ASF HCU CCSR (Yukon EX) */
@@ -918,6 +924,10 @@
 #define	CHIP_REV_YU_EX_A0	1 /* Chip Rev. for Yukon-2 EX A0 */
 #define	CHIP_REV_YU_EX_B0	2 /* Chip Rev. for Yukon-2 EX B0 */
 
+#define	CHIP_REV_YU_SU_A0	0 /* Chip Rev. for Yukon-2 SUPR A0 */
+#define	CHIP_REV_YU_SU_B0	1 /* Chip Rev. for Yukon-2 SUPR B0 */
+#define	CHIP_REV_YU_SU_B1	3 /* Chip Rev. for Yukon-2 SUPR B1 */
+
 /*	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_CLK_GAT_LNK2_DIS	BIT_6	/* Disable clock gating Link 2 */
@@ -2555,6 +2565,7 @@
 	struct msk_hw_stats	msk_stats;
 	int			msk_if_flags;
 	uint16_t		msk_vtag;	/* VLAN tag id. */
+	uint32_t		msk_csum;
 };
 
 #define MSK_TIMEOUT	1000

Reply to: