Fix up the RealTek 8139 driver to work on FreeBSD/alpha. This involves a

few changes:

- there was a bug in rl_list_tx_init(): it was calculating the registers
  to initialize incorrectly. Not a problem on the x86 where unaligned
  access are allowed, but a problem on the alpha.

- set rl_btag accordingly depending on the machine type

- rl_rxeof() needs to be sure to longword-align the packet data. This
  is a little tricky since we copy the data out of the receive buffer
  using m_devget(), however there's no way to tell m_devget() to fill
  in the mbufs starting at a particular offset. To get around this,
  we tell m_devget to copy bytes+2 bytes starting at offset offset-2. This
  results in the proper alignment, and we can trim off the two leading
  bytes afterwards with m_adj(). We also allocate some extra space before
  the start of the receive buffer so that we don't get into trouble in
  the case where offset == 0.

- redefine vtophys() in if_rlreg.h for the alpha.

Making this chipset work on the alpha is sort of the inverse of putting
a jet engine on a rowboat (putting a propeller on a 747?) but when
you can get these things for $5 a pop, it's hard to stop people from
buying them.
This commit is contained in:
wpaul 1999-06-19 20:17:38 +00:00
parent ff77319196
commit bf694850c4
2 changed files with 47 additions and 9 deletions

View File

@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_rl.c,v 1.15 1999/05/09 17:06:58 peter Exp $
* $Id: if_rl.c,v 1.32 1999/06/19 20:01:32 wpaul Exp wpaul $
*/
/*
@ -127,7 +127,7 @@
#ifndef lint
static const char rcsid[] =
"$Id: if_rl.c,v 1.15 1999/05/09 17:06:58 peter Exp $";
"$Id: if_rl.c,v 1.32 1999/06/19 20:01:32 wpaul Exp wpaul $";
#endif
/*
@ -1080,7 +1080,12 @@ rl_attach(config_id, unit)
printf ("rl%d: couldn't map ports\n", unit);
goto fail;
}
#ifdef __i386__
sc->rl_btag = I386_BUS_SPACE_IO;
#endif
#ifdef __alpha__
sc->rl_btag = ALPHA_BUS_SPACE_IO;
#endif
#else
if (!(command & PCIM_CMD_MEMEN)) {
printf("rl%d: failed to enable memory mapping!\n", unit);
@ -1091,7 +1096,12 @@ rl_attach(config_id, unit)
printf ("rl%d: couldn't map memory\n", unit);
goto fail;
}
#ifdef __i386__
sc->rl_btag = I386_BUS_SPACE_MEM;
#endif
#ifdef __alpha__
sc->rl_btag = ALPHA_BUS_SPACE_MEM;
#endif
sc->rl_bhandle = vbase;
#endif
@ -1135,7 +1145,7 @@ rl_attach(config_id, unit)
goto fail;
}
sc->rl_cdata.rl_rx_buf = contigmalloc(RL_RXBUFLEN + 16, M_DEVBUF,
sc->rl_cdata.rl_rx_buf = contigmalloc(RL_RXBUFLEN + 32, M_DEVBUF,
M_NOWAIT, 0x100000, 0xffffffff, PAGE_SIZE, 0);
if (sc->rl_cdata.rl_rx_buf == NULL) {
@ -1144,6 +1154,10 @@ rl_attach(config_id, unit)
goto fail;
}
/* Leave a few bytes before the start of the RX ring buffer. */
sc->rl_cdata.rl_rx_buf_ptr = sc->rl_cdata.rl_rx_buf;
sc->rl_cdata.rl_rx_buf += sizeof(u_int64_t);
ifp = &sc->arpcom.ac_if;
ifp->if_softc = sc;
ifp->if_unit = unit;
@ -1242,7 +1256,8 @@ static int rl_list_tx_init(sc)
cd = &sc->rl_cdata;
for (i = 0; i < RL_TX_LIST_CNT; i++) {
cd->rl_tx_chain[i] = NULL;
CSR_WRITE_4(sc, RL_TXADDR0 + i, 0x0000000);
CSR_WRITE_4(sc,
RL_TXADDR0 + (i * sizeof(u_int32_t)), 0x0000000);
}
sc->rl_cdata.cur_tx = 0;
@ -1267,6 +1282,16 @@ static int rl_list_tx_init(sc)
* the status word) is also 32-bit aligned. The frame length is in the
* first 16 bits of the status word; the lower 15 bits correspond with
* the 'rx status register' mentioned in the datasheet.
*
* Note: to make the Alpha happy, the frame payload needs to be aligned
* on a 32-bit boundary. To achieve this, we cheat a bit by copying from
* the ring buffer starting at an address two bytes before the actual
* data location. We can then shave off the first two bytes using m_adj().
* The reason we do this is because m_devget() doesn't let us specify an
* offset into the mbuf storage space, so we have to artificially create
* one. The ring is allocated in such a way that there are a few unused
* bytes of space preceecing it so that it will be safe for us to do the
* 2-byte backstep even if reading from the ring at offset 0.
*/
static void rl_rxeof(sc)
struct rl_softc *sc;
@ -1355,23 +1380,28 @@ static void rl_rxeof(sc)
wrap = (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN) - rxbufpos;
if (total_len > wrap) {
m = m_devget(rxbufpos, wrap, 0, ifp, NULL);
m = m_devget(rxbufpos - RL_ETHER_ALIGN,
wrap + RL_ETHER_ALIGN, 0, ifp, NULL);
if (m == NULL) {
ifp->if_ierrors++;
printf("rl%d: out of mbufs, tried to "
"copy %d bytes\n", sc->rl_unit, wrap);
}
else
else {
m_adj(m, RL_ETHER_ALIGN);
m_copyback(m, wrap, total_len - wrap,
sc->rl_cdata.rl_rx_buf);
}
cur_rx = (total_len - wrap + ETHER_CRC_LEN);
} else {
m = m_devget(rxbufpos, total_len, 0, ifp, NULL);
m = m_devget(rxbufpos - RL_ETHER_ALIGN,
total_len + RL_ETHER_ALIGN, 0, ifp, NULL);
if (m == NULL) {
ifp->if_ierrors++;
printf("rl%d: out of mbufs, tried to "
"copy %d bytes\n", sc->rl_unit, total_len);
}
} else
m_adj(m, RL_ETHER_ALIGN);
cur_rx += total_len + 4 + ETHER_CRC_LEN;
}

View File

@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: if_rlreg.h,v 1.18 1999/05/30 18:48:01 wpaul Exp $
* $Id: if_rlreg.h,v 1.19 1999/06/19 20:01:32 wpaul Exp wpaul $
*/
/*
@ -307,9 +307,12 @@
#define RL_RXCFG_CONFIG (RL_RX_FIFOTHRESH|RL_RX_MAXDMA|RL_RX_BUF_SZ)
#define RL_TXCFG_CONFIG (RL_TXCFG_IFG|RL_TX_MAXDMA)
#define RL_ETHER_ALIGN 2
struct rl_chain_data {
u_int16_t cur_rx;
caddr_t rl_rx_buf;
caddr_t rl_rx_buf_ptr;
struct mbuf *rl_tx_chain[RL_TX_LIST_CNT];
u_int8_t last_tx;
@ -608,3 +611,8 @@ struct rl_softc {
#define PHY_BMSR_LINKSTAT 0x0004
#define PHY_BMSR_JABBER 0x0002
#define PHY_BMSR_EXTENDED 0x0001
#ifdef __alpha__
#undef vtophys
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va)
#endif