Make the xl and pn drivers work on FreeBSD/alpha and add them to
sys/alpha/conf/GENERIC. Note: the PNIC ignores the lower few bits of the RX buffer DMA address, which means we have to add yet another kludge to make it happy. Since we can't offset the packet data, we copy the first few bytes of the received data into a separate mbuf with proper alignment. This puts the IP header where it needs to be to prevent unaligned accesses. Also modified the PNIC driver to use a non-interrupt driven TX strategy. This improves performance somewhat on x86/SMP systems where interrupt delivery doesn't seem to be as fast with an SMP kernel as with a UP kernel.
This commit is contained in:
parent
fa93788041
commit
8fe2c75e31
@ -11,7 +11,7 @@
|
||||
# device lines is present in the ./LINT configuration file. If you are
|
||||
# in doubt as to the purpose or necessity of a line, check first in LINT.
|
||||
#
|
||||
# $Id: GENERIC,v 1.14 1999/01/18 20:26:50 gallatin Exp $
|
||||
# $Id: GENERIC,v 1.15 1999/01/23 16:53:26 dfr Exp $
|
||||
|
||||
machine "alpha"
|
||||
cpu "EV4"
|
||||
@ -100,6 +100,8 @@ device sio1 at isa0 port "IO_COM2" irq 3 flags 0x50
|
||||
device de0
|
||||
device fxp0
|
||||
device le0
|
||||
device pn0
|
||||
device xl0
|
||||
|
||||
pseudo-device loop
|
||||
pseudo-device ether
|
||||
|
@ -11,7 +11,7 @@
|
||||
# device lines is present in the ./LINT configuration file. If you are
|
||||
# in doubt as to the purpose or necessity of a line, check first in LINT.
|
||||
#
|
||||
# $Id: GENERIC,v 1.14 1999/01/18 20:26:50 gallatin Exp $
|
||||
# $Id: GENERIC,v 1.15 1999/01/23 16:53:26 dfr Exp $
|
||||
|
||||
machine "alpha"
|
||||
cpu "EV4"
|
||||
@ -100,6 +100,8 @@ device sio1 at isa0 port "IO_COM2" irq 3 flags 0x50
|
||||
device de0
|
||||
device fxp0
|
||||
device le0
|
||||
device pn0
|
||||
device xl0
|
||||
|
||||
pseudo-device loop
|
||||
pseudo-device ether
|
||||
|
@ -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_pn.c,v 1.37 1999/02/26 07:49:31 wpaul Exp $
|
||||
* $Id: if_pn.c,v 1.41 1999/03/27 20:32:32 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -97,7 +97,7 @@
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$Id: if_pn.c,v 1.37 1999/02/26 07:49:31 wpaul Exp $";
|
||||
"$Id: if_pn.c,v 1.41 1999/03/27 20:32:32 wpaul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -855,7 +855,12 @@ pn_attach(config_id, unit)
|
||||
printf ("pn%d: couldn't map ports\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
#ifdef __i386__
|
||||
sc->pn_btag = I386_BUS_SPACE_IO;
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
sc->pn_btag = ALPHA_BUS_SPACE_IO;
|
||||
#endif
|
||||
#else
|
||||
if (!(command & PCIM_CMD_MEMEN)) {
|
||||
printf("pn%d: failed to enable memory mapping!\n", unit);
|
||||
@ -867,7 +872,12 @@ pn_attach(config_id, unit)
|
||||
goto fail;
|
||||
}
|
||||
sc->pn_bhandle = vbase;
|
||||
#ifdef __i386__
|
||||
sc->pn_btag = I386_BUS_SPACE_MEM;
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
sc->pn_btag = ALPHA_BUS_SPACE_MEM;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Allocate interrupt */
|
||||
@ -1246,6 +1256,9 @@ static void pn_rxeof(sc)
|
||||
|
||||
while(!((rxstat = sc->pn_cdata.pn_rx_head->pn_ptr->pn_status) &
|
||||
PN_RXSTAT_OWN)) {
|
||||
#ifdef __alpha__
|
||||
struct mbuf *m0 = NULL;
|
||||
#endif
|
||||
cur_rx = sc->pn_cdata.pn_rx_head;
|
||||
sc->pn_cdata.pn_rx_head = cur_rx->pn_nextdesc;
|
||||
|
||||
@ -1305,10 +1318,51 @@ static void pn_rxeof(sc)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef __alpha__
|
||||
/*
|
||||
* Grrrr! On the alpha platform, the start of the
|
||||
* packet data must be longword aligned so that ip_input()
|
||||
* doesn't perform any unaligned accesses when it tries
|
||||
* to fiddle with the IP header. But the PNIC is stupid
|
||||
* and wants RX buffers to start on longword boundaries.
|
||||
* So we can't just shift the DMA address over a few
|
||||
* bytes to alter the payload alignment. Instead, we
|
||||
* have to chop out ethernet and IP header parts of
|
||||
* the packet and place then in a separate mbuf with
|
||||
* the alignment fixed up properly.
|
||||
*
|
||||
* As if this chip wasn't broken enough already.
|
||||
*/
|
||||
MGETHDR(m0, M_DONTWAIT, MT_DATA);
|
||||
if (m0 == NULL) {
|
||||
ifp->if_ierrors++;
|
||||
cur_rx->pn_ptr->pn_status = PN_RXSTAT;
|
||||
cur_rx->pn_ptr->pn_ctl = PN_RXCTL_RLINK | PN_RXLEN;
|
||||
bzero((char *)mtod(cur_rx->pn_mbuf, char *), MCLBYTES);
|
||||
continue;
|
||||
}
|
||||
|
||||
m0->m_data += 2;
|
||||
if (total_len <= (MHLEN - 2)) {
|
||||
bcopy(mtod(m, caddr_t), mtod(m0, caddr_t), total_len); m_freem(m);
|
||||
m = m0;
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
} else {
|
||||
bcopy(mtod(m, caddr_t), mtod(m0, caddr_t), (MHLEN - 2));
|
||||
m->m_len = total_len - (MHLEN - 2);
|
||||
m->m_data += (MHLEN - 2);
|
||||
m0->m_next = m;
|
||||
m0->m_len = (MHLEN - 2);
|
||||
m = m0;
|
||||
m->m_pkthdr.len = total_len;
|
||||
}
|
||||
#else
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
#endif
|
||||
ifp->if_ipackets++;
|
||||
eh = mtod(m, struct ether_header *);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.len = m->m_len = total_len;
|
||||
|
||||
#if NBPFILTER > 0
|
||||
/*
|
||||
* Handle BPF listeners. Let the BPF user see the packet, but
|
||||
@ -1377,7 +1431,7 @@ static void pn_txeof(sc)
|
||||
cur_tx = sc->pn_cdata.pn_tx_head;
|
||||
txstat = PN_TXSTATUS(cur_tx);
|
||||
|
||||
if ((txstat & PN_TXSTAT_OWN) || txstat == PN_UNSENT)
|
||||
if (txstat & PN_TXSTAT_OWN)
|
||||
break;
|
||||
|
||||
if (txstat & PN_TXSTAT_ERRSUM) {
|
||||
@ -1424,12 +1478,6 @@ static void pn_txeoc(sc)
|
||||
sc->pn_cdata.pn_tx_tail = NULL;
|
||||
if (sc->pn_want_auto)
|
||||
pn_autoneg_mii(sc, PN_FLAG_SCHEDDELAY, 1);
|
||||
} else {
|
||||
if (PN_TXOWN(sc->pn_cdata.pn_tx_head) == PN_UNSENT) {
|
||||
PN_TXOWN(sc->pn_cdata.pn_tx_head) = PN_TXSTAT_OWN;
|
||||
ifp->if_timer = 5;
|
||||
CSR_WRITE_4(sc, PN_TXSTART, 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@ -1588,7 +1636,7 @@ static int pn_encap(sc, c, m_head)
|
||||
|
||||
c->pn_mbuf = m_head;
|
||||
c->pn_lastdesc = frag - 1;
|
||||
PN_TXCTL(c) |= PN_TXCTL_LASTFRAG;
|
||||
PN_TXCTL(c) |= PN_TXCTL_LASTFRAG|PN_TXCTL_FINT;
|
||||
PN_TXNEXT(c) = vtophys(&c->pn_nextdesc->pn_ptr->pn_frag[0]);
|
||||
|
||||
return(0);
|
||||
@ -1649,6 +1697,8 @@ static void pn_start(ifp)
|
||||
if (ifp->if_bpf)
|
||||
bpf_mtap(ifp, cur_tx->pn_mbuf);
|
||||
#endif
|
||||
PN_TXOWN(cur_tx) = PN_TXSTAT_OWN;
|
||||
CSR_WRITE_4(sc, PN_TXSTART, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1657,23 +1707,10 @@ static void pn_start(ifp)
|
||||
if (cur_tx == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Place the request for the upload interrupt
|
||||
* in the last descriptor in the chain. This way, if
|
||||
* we're chaining several packets at once, we'll only
|
||||
* get an interupt once for the whole chain rather than
|
||||
* once for each packet.
|
||||
*/
|
||||
PN_TXCTL(cur_tx) |= PN_TXCTL_FINT;
|
||||
sc->pn_cdata.pn_tx_tail = cur_tx;
|
||||
|
||||
if (sc->pn_cdata.pn_tx_head == NULL) {
|
||||
if (sc->pn_cdata.pn_tx_head == NULL)
|
||||
sc->pn_cdata.pn_tx_head = start_tx;
|
||||
PN_TXOWN(start_tx) = PN_TXSTAT_OWN;
|
||||
CSR_WRITE_4(sc, PN_TXSTART, 0xFFFFFFFF);
|
||||
} else {
|
||||
PN_TXOWN(start_tx) = PN_UNSENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a timeout in case the chip goes out to lunch.
|
||||
|
@ -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_pnreg.h,v 1.17 1999/02/26 07:49:31 wpaul Exp $
|
||||
* $Id: if_pnreg.h,v 1.21 1999/03/27 20:08:53 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -367,8 +367,6 @@ struct pn_txdesc {
|
||||
|
||||
#define PN_TXOWN(x) x->pn_ptr->pn_frag[0].pn_status
|
||||
|
||||
#define PN_UNSENT 0x12344321
|
||||
|
||||
struct pn_list_data {
|
||||
struct pn_desc pn_rx_list[PN_RX_LIST_CNT];
|
||||
struct pn_txdesc pn_tx_list[PN_TX_LIST_CNT];
|
||||
@ -458,7 +456,7 @@ struct pn_softc {
|
||||
#define CSR_WRITE_4(sc, reg, val) \
|
||||
bus_space_write_4(sc->pn_btag, sc->pn_bhandle, reg, val)
|
||||
#define CSR_WRITE_2(sc, reg, val) \
|
||||
bus_space_write_2(sc->pn_btag, sc->pn_bbhandle, reg, val)
|
||||
bus_space_write_2(sc->pn_btag, sc->pn_bhandle, reg, val)
|
||||
#define CSR_WRITE_1(sc, reg, val) \
|
||||
bus_space_write_1(sc->pn_btag, sc->pn_bhandle, reg, val)
|
||||
|
||||
@ -651,3 +649,9 @@ struct pn_softc {
|
||||
#define PHY_BMSR_LINKSTAT 0x0004
|
||||
#define PHY_BMSR_JABBER 0x0002
|
||||
#define PHY_BMSR_EXTENDED 0x0001
|
||||
|
||||
#ifdef __alpha__
|
||||
#undef vtophys
|
||||
#define vtophys(va) (pmap_kextract(((vm_offset_t) (va))) \
|
||||
+ 1*1024*1024*1024)
|
||||
#endif
|
||||
|
@ -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_xl.c,v 1.24 1999/02/11 23:59:29 wpaul Exp $
|
||||
* $Id: if_xl.c,v 1.68 1999/03/27 20:35:14 wpaul Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -107,6 +107,9 @@
|
||||
#include <vm/vm.h> /* for vtophys */
|
||||
#include <vm/pmap.h> /* for vtophys */
|
||||
#include <machine/clock.h> /* for DELAY */
|
||||
#include <machine/bus_memio.h>
|
||||
#include <machine/bus_pio.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <pci/pcireg.h>
|
||||
#include <pci/pcivar.h>
|
||||
@ -147,7 +150,7 @@
|
||||
|
||||
#if !defined(lint)
|
||||
static const char rcsid[] =
|
||||
"$Id: if_xl.c,v 1.24 1999/02/11 23:59:29 wpaul Exp $";
|
||||
"$Id: if_xl.c,v 1.68 1999/03/27 20:35:14 wpaul Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1387,7 +1390,18 @@ xl_attach(config_id, unit)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->iobase = pci_conf_read(config_id, XL_PCI_LOIO) & 0xFFFFFFE0;
|
||||
if (!pci_map_port(config_id, XL_PCI_LOIO,
|
||||
(u_short *)&(sc->xl_bhandle))) {
|
||||
printf ("xl%d: couldn't map port\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
sc->xl_btag = I386_BUS_SPACE_IO;
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
sc->xl_btag = ALPHA_BUS_SPACE_IO;
|
||||
#endif
|
||||
#else
|
||||
if (!(command & PCIM_CMD_MEMEN)) {
|
||||
printf("xl%d: failed to enable memory mapping!\n", unit);
|
||||
@ -1398,7 +1412,13 @@ xl_attach(config_id, unit)
|
||||
printf ("xl%d: couldn't map memory\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
sc->csr = (volatile caddr_t)vbase;
|
||||
sc->xl_bhandle = vbase;
|
||||
#ifdef __i386__
|
||||
sc->xl_btag = I386_BUS_SPACE_MEM;
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
sc->xl_btag = ALPHA_BUS_SPACE_MEM;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Allocate interrupt */
|
||||
@ -1768,6 +1788,11 @@ static int xl_newbuf(sc, c)
|
||||
return(ENOBUFS);
|
||||
}
|
||||
|
||||
#ifdef __alpha__
|
||||
/* Force longword alignment for packet payload to pacify alpha. */
|
||||
m_new->m_data += 2;
|
||||
#endif
|
||||
|
||||
c->xl_mbuf = m_new;
|
||||
c->xl_ptr->xl_status = 0;
|
||||
c->xl_ptr->xl_frag.xl_addr = vtophys(mtod(m_new, caddr_t));
|
||||
|
@ -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_xlreg.h,v 1.19 1998/10/22 15:35:06 wpaul Exp $
|
||||
* $Id: if_xlreg.h,v 1.20 1999/03/27 20:10:10 wpaul Exp $
|
||||
*/
|
||||
|
||||
#define XL_EE_READ 0x0080 /* read, 5 bit address */
|
||||
@ -539,10 +539,8 @@ struct xl_mii_frame {
|
||||
struct xl_softc {
|
||||
struct arpcom arpcom; /* interface info */
|
||||
struct ifmedia ifmedia; /* media info */
|
||||
u_int32_t iobase; /* pointer to PIO space */
|
||||
#ifndef XL_USEIOSPACE
|
||||
volatile caddr_t csr; /* pointer to register map */
|
||||
#endif
|
||||
bus_space_handle_t xl_bhandle;
|
||||
bus_space_tag_t xl_btag;
|
||||
struct xl_type *xl_info; /* 3Com adapter info */
|
||||
struct xl_type *xl_pinfo; /* phy info */
|
||||
u_int8_t xl_unit; /* interface number */
|
||||
@ -586,35 +584,19 @@ struct xl_stats {
|
||||
/*
|
||||
* register space access macros
|
||||
*/
|
||||
#ifdef XL_USEIOSPACE
|
||||
#define CSR_WRITE_4(sc, reg, val) \
|
||||
outl(sc->iobase + (u_int32_t)(reg), val)
|
||||
bus_space_write_4(sc->xl_btag, sc->xl_bhandle, reg, val)
|
||||
#define CSR_WRITE_2(sc, reg, val) \
|
||||
outw(sc->iobase + (u_int32_t)(reg), val)
|
||||
bus_space_write_2(sc->xl_btag, sc->xl_bhandle, reg, val)
|
||||
#define CSR_WRITE_1(sc, reg, val) \
|
||||
outb(sc->iobase + (u_int32_t)(reg), val)
|
||||
bus_space_write_1(sc->xl_btag, sc->xl_bhandle, reg, val)
|
||||
|
||||
#define CSR_READ_4(sc, reg) \
|
||||
inl(sc->iobase + (u_int32_t)(reg))
|
||||
#define CSR_READ_2(sc, reg) \
|
||||
inw(sc->iobase + (u_int32_t)(reg))
|
||||
#define CSR_READ_1(sc, reg) \
|
||||
inb(sc->iobase + (u_int32_t)(reg))
|
||||
#else
|
||||
#define CSR_WRITE_4(sc, reg, val) \
|
||||
((*(u_int32_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int32_t)(val))
|
||||
#define CSR_WRITE_2(sc, reg, val) \
|
||||
((*(u_int16_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int16_t)(val))
|
||||
#define CSR_WRITE_1(sc, reg, val) \
|
||||
((*(u_int8_t*)((sc)->csr + (u_int32_t)(reg))) = (u_int8_t)(val))
|
||||
|
||||
#define CSR_READ_4(sc, reg) \
|
||||
(*(u_int32_t *)((sc)->csr + (u_int32_t)(reg)))
|
||||
#define CSR_READ_2(sc, reg) \
|
||||
(*(u_int16_t *)((sc)->csr + (u_int32_t)(reg)))
|
||||
#define CSR_READ_1(sc, reg) \
|
||||
(*(u_int8_t *)((sc)->csr + (u_int32_t)(reg)))
|
||||
#endif
|
||||
#define CSR_READ_4(sc, reg) \
|
||||
bus_space_read_4(sc->xl_btag, sc->xl_bhandle, reg)
|
||||
#define CSR_READ_2(sc, reg) \
|
||||
bus_space_read_2(sc->xl_btag, sc->xl_bhandle, reg)
|
||||
#define CSR_READ_1(sc, reg) \
|
||||
bus_space_read_1(sc->xl_btag, sc->xl_bhandle, reg)
|
||||
|
||||
#define XL_SEL_WIN(x) \
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_WINSEL | x)
|
||||
@ -822,3 +804,9 @@ struct xl_stats {
|
||||
#define PHY_BMSR_LINKSTAT 0x0004
|
||||
#define PHY_BMSR_JABBER 0x0002
|
||||
#define PHY_BMSR_EXTENDED 0x0001
|
||||
|
||||
#ifdef __alpha__
|
||||
#undef vtophys
|
||||
#define vtophys(va) (pmap_kextract(((vm_offset_t) (va))) \
|
||||
+ 1*1024*1024*1024)
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user