"Marvell Yukon 88E8038 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_8039,
"Marvell Yukon 88E8039 Gigabit Ethernet" },
+ { VENDORID_MARVELL, DEVICEID_MRVL_8040,
+ "Marvell Yukon 88E8040 Fast Ethernet" },
+ { VENDORID_MARVELL, DEVICEID_MRVL_8040T,
+ "Marvell Yukon 88E8040T Fast Ethernet" },
+ { VENDORID_MARVELL, DEVICEID_MRVL_8048,
+ "Marvell Yukon 88E8048 Fast Ethernet" },
+ { VENDORID_MARVELL, DEVICEID_MRVL_8070,
+ "Marvell Yukon 88E8070 Fast Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4361,
"Marvell Yukon 88E8050 Gigabit Ethernet" },
{ VENDORID_MARVELL, DEVICEID_MRVL_4360,
static const char *model_name[] = {
"Yukon XL",
- "Yukon EC Ultra",
- "Yukon Unknown",
- "Yukon EC",
- "Yukon FE"
+ "Yukon EC Ultra",
+ "Yukon Unknown",
+ "Yukon EC",
+ "Yukon FE",
+ "Yukon FE+"
};
static int mskc_probe(device_t);
}
break;
case CHIP_ID_YUKON_EC_U:
+ case CHIP_ID_YUKON_FE_P:
CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF);
/* Enable all clocks. */
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_FE) {
+ sc->msk_hw_id > CHIP_ID_YUKON_FE_P) {
device_printf(dev, "unknown device: id=0x%02x, rev=0x%02x\n",
sc->msk_hw_id, sc->msk_hw_rev);
error = ENXIO;
sc->msk_clock = 100; /* 100 Mhz */
sc->msk_pflags |= MSK_FLAG_FASTETHER;
break;
+ case CHIP_ID_YUKON_FE_P:
+ sc->msk_clock = 50; /* 50 Mhz */
+ /* DESCV2 */
+ sc->msk_pflags |= MSK_FLAG_FASTETHER;
+ if (sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) {
+ /*
+ * XXX
+ * FE+ A0 has status LE writeback bug so msk(4)
+ * does not rely on status word of received frame
+ * in msk_rxeof() which in turn disables all
+ * hardware assistance bits reported by the status
+ * word as well as validity of the recevied frame.
+ * Just pass received frames to upper stack with
+ * minimal test and let upper stack handle them.
+ */
+ sc->msk_pflags |= MSK_FLAG_NORXCHK;
+ }
+ break;
case CHIP_ID_YUKON_XL:
sc->msk_clock = 156; /* 156 Mhz */
break;
if ((status & GMR_FS_VLAN) != 0 &&
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0)
rxlen -= EVL_ENCAPLEN;
- if (len > sc_if->msk_framesize ||
+ if (sc_if->msk_flags & MSK_FLAG_NORXCHK) {
+ /*
+ * For controllers that returns bogus status code
+ * just do minimal check and let upper stack
+ * handle this frame.
+ */
+ if (len > MSK_MAX_FRAMELEN || len < ETHER_HDR_LEN) {
+ ifp->if_ierrors++;
+ msk_discard_rxbuf(sc_if, cons);
+ break;
+ }
+ } else if (len > sc_if->msk_framesize ||
((status & GMR_FS_ANY_ERR) != 0) ||
((status & GMR_FS_RX_OK) == 0) || (rxlen != len)) {
/* Don't count flow-control packet as errors. */
struct mii_data *mii;
uint16_t eaddr[ETHER_ADDR_LEN / 2];
uint16_t gmac;
+ uint32_t reg;
int error, i;
ASSERT_SERIALIZED(ifp->if_serializer);
/* Configure Rx MAC FIFO. */
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), GMF_RST_SET);
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), GMF_RST_CLR);
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T),
- GMF_OPER_ON | GMF_RX_F_FL_ON);
+ reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
+ if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P)
+ reg |= GMF_RX_OVER_ON;
+ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), reg);
/* Set receive filter. */
msk_rxfilter(sc_if);
* Set Rx FIFO flush threshold to 64 bytes 1 FIFO word
* due to hardware hang on receipt of pause frames.
*/
- CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_THR),
- RX_GMF_FL_THR_DEF + 1);
+ reg = RX_GMF_FL_THR_DEF + 1;
+ /* Another magic for Yukon FE+ - From Linux. */
+ if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P &&
+ sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0)
+ reg = 0x178;
+ CSR_WRITE_2(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_THR), reg);
+
/* Configure Tx MAC FIFO. */
CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), GMF_RST_SET);
}
}
+ 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
* arbiter as we don't use Sync Tx queue.
#define DEVICEID_MRVL_8036 0x4351
#define DEVICEID_MRVL_8038 0x4352
#define DEVICEID_MRVL_8039 0x4353
+#define DEVICEID_MRVL_8040 0x4354
+#define DEVICEID_MRVL_8040T 0x4355
+#define DEVICEID_MRVL_8048 0x435A
#define DEVICEID_MRVL_4360 0x4360
#define DEVICEID_MRVL_4361 0x4361
#define DEVICEID_MRVL_4362 0x4362
#define DEVICEID_MRVL_4363 0x4363
#define DEVICEID_MRVL_4364 0x4364
+#define DEVICEID_MRVL_8070 0x4365
#define DEVICEID_MRVL_436A 0x436A
/*
#define CHIP_ID_YUKON_EC_U 0xb4 /* Chip ID for YUKON-2 EC Ultra */
#define CHIP_ID_YUKON_EC 0xb6 /* Chip ID for YUKON-2 EC */
#define CHIP_ID_YUKON_FE 0xb7 /* Chip ID for YUKON-2 FE */
+#define CHIP_ID_YUKON_FE_P 0xb8 /* Chip ID for YUKON-2 FE+ */
#define CHIP_REV_YU_XL_A0 0 /* Chip Rev. for Yukon-2 A0 */
#define CHIP_REV_YU_XL_A1 1 /* Chip Rev. for Yukon-2 A1 */
#define CHIP_REV_YU_EC_U_A0 1
#define CHIP_REV_YU_EC_U_A1 2
+#define CHIP_REV_YU_FE_P_A0 0 /* Chip Rev. for Yukon-2 FE+ A0 */
+
/* 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 */
#define RX_TRUNC_OFF BIT_26 /* disable packet truncation */
#define RX_VLAN_STRIP_ON BIT_25 /* enable VLAN stripping */
#define RX_VLAN_STRIP_OFF BIT_24 /* disable VLAN stripping */
+#define GMF_RX_OVER_ON BIT_19 /* enable flushing on receive overrun */
+#define GMF_RX_OVER_OFF BIT_18 /* disable flushing on receive overrun */
+#define GMF_ASF_RX_OVER_ON BIT_17 /* enable flushing of ASF when overrun */
+#define GMF_ASF_RX_OVER_OFF BIT_16 /* disable flushing of ASF when overrun */
#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */
#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */
#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */
uint32_t msk_flags;
#define MSK_FLAG_FASTETHER 0x0004
#define MSK_FLAG_RAMBUF 0x0010
+#define MSK_FLAG_NORXCHK 0x0100
struct callout msk_tick_ch;
uint32_t msk_txq; /* Tx. Async Queue offset */
uint32_t msk_txsq; /* Tx. Syn Queue offset */