At long last, we know have support for the 3C589 in a FreeBSD release

using the existing files using the existing PCCARD support.  Now that
this is in place I would like to fixup the PCCARD hooks and remove the
if_zp driver.  At this point, we support everything we used to support
*AND MORE* with the PCCARD code.

Submitted by:	Naoki Hamada <nao@sbl.cl.nec.co.jp> (via the Nomad release)

[ This works on both my 3C589B and 3C589C ]
This commit is contained in:
Nate Williams 1996-06-14 22:11:38 +00:00
parent ee42451e19
commit 333f7d7bb6
4 changed files with 438 additions and 6 deletions

View File

@ -38,7 +38,7 @@
*/
/*
* $Id: if_ep.c,v 1.45 1996/06/12 05:03:38 gpalmer Exp $
* $Id: if_ep.c,v 1.46 1996/06/14 21:28:35 nate Exp $
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
@ -50,6 +50,12 @@
* babkin@hq.icb.chel.su
*/
/*
* Pccard support for 3C589 by:
* HAMADA Naoki
* nao@tom-yam.or.jp
*/
#include "ep.h"
#if NEP > 0
@ -131,7 +137,9 @@ static void epstart __P((struct ifnet *));
static void epstop __P((struct ep_softc *));
static void epwatchdog __P((struct ifnet *));
#if 0
static int send_ID_sequence __P((int));
#endif
static int get_eeprom_data __P((int, int));
static struct ep_softc* ep_softc[NEP];
@ -160,6 +168,171 @@ static struct kern_devconf kdc_isa_ep = {
DC_CLS_NETIF /* class */
};
#include "crd.h"
#if NCRD > 0
#include "apm.h"
#include <sys/select.h>
#include <pccard/card.h>
#include <pccard/driver.h>
#include <pccard/slot.h>
/*
* PC-Card (PCMCIA) specific code.
*/
static int card_intr __P((struct pccard_dev *));
static void ep_unload __P((struct pccard_dev *));
static void ep_suspend __P((struct pccard_dev *));
static int ep_pccard_init __P((struct pccard_dev *, int));
static int ep_pccard_attach __P((struct pccard_dev *));
static struct pccard_drv ep_info = {
"ep",
card_intr,
ep_unload,
ep_suspend,
ep_pccard_init,
0, /* Attributes - presently unused */
&net_imask
};
/* Resume is done by executing ep_pccard_init(dp, 0). */
static void
ep_suspend(dp)
struct pccard_dev *dp;
{
struct ep_softc *sc = ep_softc[dp->isahd.id_unit];
printf("ep%d: suspending\n", dp->isahd.id_unit);
sc->gone = 1;
}
/*
*
*/
static int
ep_pccard_init(dp, first)
struct pccard_dev *dp;
int first;
{
struct isa_device *is = &dp->isahd;
struct ep_softc *sc = ep_softc[is->id_unit];
struct ep_board *epb;
int i;
epb = &ep_board[is->id_unit];
if (sc == 0) {
if ((sc = ep_alloc(is->id_unit, epb)) == 0) {
return (ENXIO);
}
ep_unit++;
ep_isa_registerdev(sc, is);
}
/* get_e() requires these. */
sc->ep_io_addr = is->id_iobase;
sc->unit = is->id_unit;
epb->epb_addr = is->id_iobase;
epb->epb_used = 1;
epb->prod_id = get_e(sc, EEPROM_PROD_ID);
if (epb->prod_id != 0x9058) { /* 3C589's product id */
if (first) {
printf("ep%d: failed to come ready.\n", is->id_unit);
} else {
printf("ep%d: failed to resume.\n", is->id_unit);
}
return (ENXIO);
}
epb->res_cfg = get_e(sc, EEPROM_RESOURCE_CFG);
for (i = 0; i < 3; i++) {
sc->epb->eth_addr[i] = get_e(sc, EEPROM_NODE_ADDR_0 + i);
}
if (first) {
if (ep_pccard_attach(dp) == 0) {
return (ENXIO);
}
sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen;
}
if (!first) {
sc->kdc->kdc_state = DC_IDLE;
sc->gone = 0;
printf("ep%d: resumed.\n", is->id_unit);
epinit(sc);
}
return (0);
}
static int
ep_pccard_attach(dp)
struct pccard_dev *dp;
{
struct isa_device *is = &dp->isahd;
struct ep_softc *sc = ep_softc[is->id_unit];
u_short config;
sc->ep_connectors = 0;
config = inw(IS_BASE + EP_W0_CONFIG_CTRL);
if (config & IS_BNC) {
sc->ep_connectors |= BNC;
}
if (config & IS_UTP) {
sc->ep_connectors |= UTP;
}
if (!(sc->ep_connectors & 7))
printf("no connectors!");
sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
/* ROM size = 0, ROM base = 0 */
/* For now, ignore AUTO SELECT feature of 3C589B and later. */
outw(BASE + EP_W0_ADDRESS_CFG, get_e(sc, EEPROM_ADDR_CFG) & 0xc000);
/* Fake IRQ must be 3 */
outw(BASE + EP_W0_RESOURCE_CFG, (sc->epb->res_cfg & 0x0fff) | 0x3000);
outw(BASE + EP_W0_PRODUCT_ID, sc->epb->prod_id);
ep_attach(sc);
return 1;
}
static void
ep_unload(dp)
struct pccard_dev *dp;
{
struct ep_softc *sc = ep_softc[dp->isahd.id_unit];
if (sc->kdc->kdc_state == DC_UNCONFIGURED) {
printf("ep%d: already unloaded\n", dp->isahd.id_unit);
return;
}
sc->kdc->kdc_state = DC_UNCONFIGURED;
sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
sc->gone = 1;
printf("ep%d: unload\n", dp->isahd.id_unit);
}
/*
* card_intr - Shared interrupt called from
* front end of PC-Card handler.
*/
static int
card_intr(dp)
struct pccard_dev *dp;
{
epintr(dp->isahd.id_unit);
return(1);
}
#endif /* NCRD > 0 */
static void
ep_isa_registerdev(sc, id)
struct ep_softc *sc;
@ -365,6 +538,10 @@ ep_isa_probe(is)
struct ep_board *epb;
u_short k;
#if NCRD > 0
pccard_add_driver(&ep_info);
#endif /* NCRD > 0 */
if(( epb=ep_look_for_board_at(is) )==0)
return (0);
@ -466,6 +643,10 @@ ep_attach(sc)
struct sockaddr_dl *sdl;
u_short *p;
int i;
int attached;
sc->gone = 0;
attached = (ifp->if_softc != 0);
printf("ep%d: ", sc->unit);
/*
@ -508,8 +689,10 @@ ep_attach(sc)
ifp->if_ioctl = epioctl;
ifp->if_watchdog = epwatchdog;
if (!attached) {
if_attach(ifp);
ether_ifattach(ifp);
}
/* device attach does transition from UNCONFIGURED to IDLE state */
sc->kdc->kdc_state=DC_IDLE;
@ -557,7 +740,9 @@ ep_attach(sc)
sc->top = sc->mcur = 0;
#if NBPFILTER > 0
if (!attached) {
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
}
#endif
return 0;
}
@ -572,7 +757,10 @@ epinit(sc)
struct ep_softc *sc;
{
register struct ifnet *ifp = &sc->arpcom.ac_if;
int s, i;
int s, i, j;
if (sc->gone)
return;
/*
if (ifp->if_addrlist == (struct ifaddr *) 0)
@ -736,6 +924,10 @@ epstart(ifp)
struct mbuf *top;
int s, pad;
if (sc->gone) {
return;
}
s = splimp();
if (ifp->if_flags & IFF_OACTIVE) {
splx(s);
@ -850,6 +1042,11 @@ epintr(unit)
int unit;
{
register struct ep_softc *sc = ep_softc[unit];
if (sc->gone) {
return;
}
ep_intr(sc);
}
@ -1349,6 +1546,8 @@ static void
epwatchdog(ifp)
struct ifnet *ifp;
{
struct ep_softc *sc = ifp->if_softc;
/*
printf("ep: watchdog\n");
@ -1356,6 +1555,10 @@ epwatchdog(ifp)
ifp->if_oerrors++;
*/
if (sc->gone) {
return;
}
ifp->if_flags &= ~IFF_OACTIVE;
epstart(ifp);
ep_intr(ifp->if_softc);
@ -1365,6 +1568,10 @@ static void
epstop(sc)
struct ep_softc *sc;
{
if (sc->gone) {
return;
}
outw(BASE + EP_COMMAND, RX_DISABLE);
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
@ -1379,6 +1586,7 @@ epstop(sc)
}
#if 0
static int
send_ID_sequence(port)
int port;
@ -1393,6 +1601,7 @@ send_ID_sequence(port)
}
return (1);
}
#endif
/*

View File

@ -31,7 +31,7 @@
*/
/*
* $Id: if_epreg.h,v 1.12 1996/02/26 01:05:36 gibbs Exp $
* $Id: if_epreg.h,v 1.13 1996/02/28 17:19:04 gibbs Exp $
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
@ -43,6 +43,12 @@
* babkin@hq.icb.chel.su
*/
/*
* Pccard support for 3C589 by:
* HAMADA Naoki
* nao@tom-yam.or.jp
*/
/*
* Ethernet software status per interface.
*/
@ -64,6 +70,7 @@ struct ep_softc {
u_short ep_connectors; /* Connectors on this card. */
u_char ep_connector; /* Configured connector. */
int stat; /* some flags */
int gone; /* adapter is not present (for PCCARD) */
#define F_RX_FIRST 0x1
#define F_WAIT_TRAIL 0x2
#define F_RX_TRAILER 0x4

View File

@ -38,7 +38,7 @@
*/
/*
* $Id: if_ep.c,v 1.45 1996/06/12 05:03:38 gpalmer Exp $
* $Id: if_ep.c,v 1.46 1996/06/14 21:28:35 nate Exp $
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
@ -50,6 +50,12 @@
* babkin@hq.icb.chel.su
*/
/*
* Pccard support for 3C589 by:
* HAMADA Naoki
* nao@tom-yam.or.jp
*/
#include "ep.h"
#if NEP > 0
@ -131,7 +137,9 @@ static void epstart __P((struct ifnet *));
static void epstop __P((struct ep_softc *));
static void epwatchdog __P((struct ifnet *));
#if 0
static int send_ID_sequence __P((int));
#endif
static int get_eeprom_data __P((int, int));
static struct ep_softc* ep_softc[NEP];
@ -160,6 +168,171 @@ static struct kern_devconf kdc_isa_ep = {
DC_CLS_NETIF /* class */
};
#include "crd.h"
#if NCRD > 0
#include "apm.h"
#include <sys/select.h>
#include <pccard/card.h>
#include <pccard/driver.h>
#include <pccard/slot.h>
/*
* PC-Card (PCMCIA) specific code.
*/
static int card_intr __P((struct pccard_dev *));
static void ep_unload __P((struct pccard_dev *));
static void ep_suspend __P((struct pccard_dev *));
static int ep_pccard_init __P((struct pccard_dev *, int));
static int ep_pccard_attach __P((struct pccard_dev *));
static struct pccard_drv ep_info = {
"ep",
card_intr,
ep_unload,
ep_suspend,
ep_pccard_init,
0, /* Attributes - presently unused */
&net_imask
};
/* Resume is done by executing ep_pccard_init(dp, 0). */
static void
ep_suspend(dp)
struct pccard_dev *dp;
{
struct ep_softc *sc = ep_softc[dp->isahd.id_unit];
printf("ep%d: suspending\n", dp->isahd.id_unit);
sc->gone = 1;
}
/*
*
*/
static int
ep_pccard_init(dp, first)
struct pccard_dev *dp;
int first;
{
struct isa_device *is = &dp->isahd;
struct ep_softc *sc = ep_softc[is->id_unit];
struct ep_board *epb;
int i;
epb = &ep_board[is->id_unit];
if (sc == 0) {
if ((sc = ep_alloc(is->id_unit, epb)) == 0) {
return (ENXIO);
}
ep_unit++;
ep_isa_registerdev(sc, is);
}
/* get_e() requires these. */
sc->ep_io_addr = is->id_iobase;
sc->unit = is->id_unit;
epb->epb_addr = is->id_iobase;
epb->epb_used = 1;
epb->prod_id = get_e(sc, EEPROM_PROD_ID);
if (epb->prod_id != 0x9058) { /* 3C589's product id */
if (first) {
printf("ep%d: failed to come ready.\n", is->id_unit);
} else {
printf("ep%d: failed to resume.\n", is->id_unit);
}
return (ENXIO);
}
epb->res_cfg = get_e(sc, EEPROM_RESOURCE_CFG);
for (i = 0; i < 3; i++) {
sc->epb->eth_addr[i] = get_e(sc, EEPROM_NODE_ADDR_0 + i);
}
if (first) {
if (ep_pccard_attach(dp) == 0) {
return (ENXIO);
}
sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen;
}
if (!first) {
sc->kdc->kdc_state = DC_IDLE;
sc->gone = 0;
printf("ep%d: resumed.\n", is->id_unit);
epinit(sc);
}
return (0);
}
static int
ep_pccard_attach(dp)
struct pccard_dev *dp;
{
struct isa_device *is = &dp->isahd;
struct ep_softc *sc = ep_softc[is->id_unit];
u_short config;
sc->ep_connectors = 0;
config = inw(IS_BASE + EP_W0_CONFIG_CTRL);
if (config & IS_BNC) {
sc->ep_connectors |= BNC;
}
if (config & IS_UTP) {
sc->ep_connectors |= UTP;
}
if (!(sc->ep_connectors & 7))
printf("no connectors!");
sc->ep_connector = inw(BASE + EP_W0_ADDRESS_CFG) >> ACF_CONNECTOR_BITS;
/* ROM size = 0, ROM base = 0 */
/* For now, ignore AUTO SELECT feature of 3C589B and later. */
outw(BASE + EP_W0_ADDRESS_CFG, get_e(sc, EEPROM_ADDR_CFG) & 0xc000);
/* Fake IRQ must be 3 */
outw(BASE + EP_W0_RESOURCE_CFG, (sc->epb->res_cfg & 0x0fff) | 0x3000);
outw(BASE + EP_W0_PRODUCT_ID, sc->epb->prod_id);
ep_attach(sc);
return 1;
}
static void
ep_unload(dp)
struct pccard_dev *dp;
{
struct ep_softc *sc = ep_softc[dp->isahd.id_unit];
if (sc->kdc->kdc_state == DC_UNCONFIGURED) {
printf("ep%d: already unloaded\n", dp->isahd.id_unit);
return;
}
sc->kdc->kdc_state = DC_UNCONFIGURED;
sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
sc->gone = 1;
printf("ep%d: unload\n", dp->isahd.id_unit);
}
/*
* card_intr - Shared interrupt called from
* front end of PC-Card handler.
*/
static int
card_intr(dp)
struct pccard_dev *dp;
{
epintr(dp->isahd.id_unit);
return(1);
}
#endif /* NCRD > 0 */
static void
ep_isa_registerdev(sc, id)
struct ep_softc *sc;
@ -365,6 +538,10 @@ ep_isa_probe(is)
struct ep_board *epb;
u_short k;
#if NCRD > 0
pccard_add_driver(&ep_info);
#endif /* NCRD > 0 */
if(( epb=ep_look_for_board_at(is) )==0)
return (0);
@ -466,6 +643,10 @@ ep_attach(sc)
struct sockaddr_dl *sdl;
u_short *p;
int i;
int attached;
sc->gone = 0;
attached = (ifp->if_softc != 0);
printf("ep%d: ", sc->unit);
/*
@ -508,8 +689,10 @@ ep_attach(sc)
ifp->if_ioctl = epioctl;
ifp->if_watchdog = epwatchdog;
if (!attached) {
if_attach(ifp);
ether_ifattach(ifp);
}
/* device attach does transition from UNCONFIGURED to IDLE state */
sc->kdc->kdc_state=DC_IDLE;
@ -557,7 +740,9 @@ ep_attach(sc)
sc->top = sc->mcur = 0;
#if NBPFILTER > 0
if (!attached) {
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
}
#endif
return 0;
}
@ -572,7 +757,10 @@ epinit(sc)
struct ep_softc *sc;
{
register struct ifnet *ifp = &sc->arpcom.ac_if;
int s, i;
int s, i, j;
if (sc->gone)
return;
/*
if (ifp->if_addrlist == (struct ifaddr *) 0)
@ -736,6 +924,10 @@ epstart(ifp)
struct mbuf *top;
int s, pad;
if (sc->gone) {
return;
}
s = splimp();
if (ifp->if_flags & IFF_OACTIVE) {
splx(s);
@ -850,6 +1042,11 @@ epintr(unit)
int unit;
{
register struct ep_softc *sc = ep_softc[unit];
if (sc->gone) {
return;
}
ep_intr(sc);
}
@ -1349,6 +1546,8 @@ static void
epwatchdog(ifp)
struct ifnet *ifp;
{
struct ep_softc *sc = ifp->if_softc;
/*
printf("ep: watchdog\n");
@ -1356,6 +1555,10 @@ epwatchdog(ifp)
ifp->if_oerrors++;
*/
if (sc->gone) {
return;
}
ifp->if_flags &= ~IFF_OACTIVE;
epstart(ifp);
ep_intr(ifp->if_softc);
@ -1365,6 +1568,10 @@ static void
epstop(sc)
struct ep_softc *sc;
{
if (sc->gone) {
return;
}
outw(BASE + EP_COMMAND, RX_DISABLE);
outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
@ -1379,6 +1586,7 @@ epstop(sc)
}
#if 0
static int
send_ID_sequence(port)
int port;
@ -1393,6 +1601,7 @@ send_ID_sequence(port)
}
return (1);
}
#endif
/*

View File

@ -31,7 +31,7 @@
*/
/*
* $Id: if_epreg.h,v 1.12 1996/02/26 01:05:36 gibbs Exp $
* $Id: if_epreg.h,v 1.13 1996/02/28 17:19:04 gibbs Exp $
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
@ -43,6 +43,12 @@
* babkin@hq.icb.chel.su
*/
/*
* Pccard support for 3C589 by:
* HAMADA Naoki
* nao@tom-yam.or.jp
*/
/*
* Ethernet software status per interface.
*/
@ -64,6 +70,7 @@ struct ep_softc {
u_short ep_connectors; /* Connectors on this card. */
u_char ep_connector; /* Configured connector. */
int stat; /* some flags */
int gone; /* adapter is not present (for PCCARD) */
#define F_RX_FIRST 0x1
#define F_WAIT_TRAIL 0x2
#define F_RX_TRAILER 0x4