return (ENOBUFS);
m->m_len = m->m_pkthdr.len = MCLBYTES;
- m_adj(m, ETHER_ALIGN);
+ if ((sc_if->msk_flags & MSK_FLAG_RAMBUF) == 0)
+ m_adj(m, ETHER_ALIGN);
error = bus_dmamap_load_mbuf_segment(sc_if->msk_cdata.msk_rx_tag,
sc_if->msk_cdata.msk_rx_sparemap,
{
int next;
int i;
- uint8_t val;
/* Get adapter SRAM size. */
- val = CSR_READ_1(sc, B2_E_0);
- sc->msk_ramsize = (val == 0) ? 128 : val * 4;
+ sc->msk_ramsize = CSR_READ_1(sc, B2_E_0) * 4;
if (bootverbose) {
device_printf(sc->msk_dev,
"RAM buffer size : %dKB\n", sc->msk_ramsize);
}
+ if (sc->msk_ramsize == 0)
+ return (0);
+ sc->msk_pflags |= MSK_FLAG_RAMBUF;
+
/*
* Give receiver 2/3 of memory and round down to the multiple
* of 1024. Tx/Rx RAM buffer size of Yukon II shoud be multiple
sc_if->msk_port = port;
sc_if->msk_softc = sc;
sc_if->msk_ifp = ifp;
+ sc_if->msk_flags = sc->msk_pflags;
sc->msk_if[port] = sc_if;
/* Setup Tx/Rx queue register offsets. */
struct msk_jpool_entry *entry;
uint8_t *ptr;
#endif
+ bus_size_t rxalign;
/* Create parent DMA tag. */
/*
}
}
+ /*
+ * Workaround hardware hang which seems to happen when Rx buffer
+ * is not aligned on multiple of FIFO word(8 bytes).
+ */
+ if (sc_if->msk_flags & MSK_FLAG_RAMBUF)
+ rxalign = MSK_RX_BUF_ALIGN;
+ else
+ rxalign = 1;
+
/* Create tag for Rx buffers. */
error = bus_dma_tag_create(sc_if->msk_cdata.msk_parent_tag,/* parent */
- 1, 0, /* alignment, boundary */
+ rxalign, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
MCLBYTES, /* maxsize */
1, /* nsegments */
MCLBYTES, /* maxsegsize */
- BUS_DMA_ALLOCNOW | BUS_DMA_WAITOK,/* flags */
+ BUS_DMA_ALLOCNOW | BUS_DMA_ALIGNED |
+ BUS_DMA_WAITOK, /* flags */
&sc_if->msk_cdata.msk_rx_tag);
if (error) {
device_printf(sc_if->msk_if_dev,
/* Configure hardware VLAN tag insertion/stripping. */
msk_setvlan(sc_if, ifp);
- if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U) {
+ if ((sc_if->msk_flags & MSK_FLAG_RAMBUF) == 0) {
/* Set Rx Pause threshould. */
CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, RX_GMF_LP_THR),
MSK_ECU_LLPP);
struct msk_softc *sc;
int ltpp, utpp;
+ if ((sc_if->msk_flags & MSK_FLAG_RAMBUF) == 0)
+ return;
+
sc = sc_if->msk_softc;
/* Setup Rx Queue. */
#define MSK_TX_RING_CNT 256
#define MSK_RX_RING_CNT 256
+#define MSK_RX_BUF_ALIGN 8
#define MSK_JUMBO_RX_RING_CNT MSK_RX_RING_CNT
#define MSK_STAT_RING_CNT ((1 + 3) * (MSK_TX_RING_CNT + MSK_RX_RING_CNT))
#define MSK_MAXTXSEGS 32
uint32_t msk_coppertype;
uint32_t msk_intrmask;
uint32_t msk_intrhwemask;
+ uint32_t msk_pflags;
int msk_suspended;
int msk_clock;
struct msk_if_softc *msk_if[2];
int msk_phytype;
int msk_phyaddr;
int msk_link;
+ uint32_t msk_flags;
+#define MSK_FLAG_RAMBUF 0x0010
struct callout msk_tick_ch;
uint32_t msk_txq; /* Tx. Async Queue offset */
uint32_t msk_txsq; /* Tx. Syn Queue offset */