Date: Wed, 18 Oct 1995 15:12:12 +0500 (GMT+0500) From: "Serge A. Babkin" <babkin@hq.icb.chel.su> To: gena@NetVision.net.il Cc: wollman@freebsd.org, jkh@time.cdrom.com, current@freebsd.org Subject: Re: 3c509 in -current needs patching Message-ID: <199510181012.PAA15264@hq.icb.chel.su> In-Reply-To: <XFMail.951017101523.gena@NetVision.net.il> from "Gennady Sorokopud" at Oct 17, 95 12:15:38 pm
next in thread | previous in thread | raw e-mail | index | archive | help
> >>
> >> When we are on the subject..can you make if_ep.c support IPX?
> >> (latest ipx patches adds IPX support only to if_ed.c)
> >
This patch is combined from the previos one (that contained a bug, the word
SIOCGIFADDR was written as SIOCSGIFADDR) and the IPX support. The $Id$
string says that the last patch applied was made by Garrett Wollman, so
may be he can review and commit this patch, huh ? Thank you!
Serge Babkin
! (babkin@hq.icb.chel.su)
! Headquarter of Joint Stock Commercial Bank "Chelindbank"
! Chelyabinsk, Russia
------------------------- cut here --------------------------------------
*** /usr/src-cur/sys/i386/isa/if_ep.c Mon Oct 16 17:40:39 1995
--- if_ep.c Wed Oct 18 12:30:37 1995
***************
*** 38,45 ****
*/
/*
- * $Id: if_ep.c,v 1.31 1995/10/13 19:47:44 wollman Exp $
- *
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
* logic changed to use value from EEPROM. Autoconfiguration
--- 38,43 ----
***************
*** 87,92 ****
--- 85,95 ----
#include <netns/ns_if.h>
#endif
+ #ifdef IPX
+ #include <netipx/ipx.h>
+ #include <netipx/ipx_if.h>
+ #endif
+
#if NBPFILTER > 0
#include <net/bpf.h>
#include <net/bpfdesc.h>
***************
*** 100,105 ****
--- 103,109 ----
#include <i386/isa/isa_device.h>
#include <i386/isa/icu.h>
#include <i386/isa/if_epreg.h>
+ #include <i386/isa/elink.h>
static int epprobe __P((struct isa_device *));
static int epattach __P((struct isa_device *));
***************
*** 117,122 ****
--- 121,127 ----
static int send_ID_sequence __P((int));
static int get_eeprom_data __P((int, int));
+ static struct ep_board *ep_look_for_board_at(struct isa_device *);
struct ep_softc ep_softc[NEP];
***************
*** 132,145 ****
};
static struct kern_devconf kdc_ep[NEP] = { {
! 0, 0, 0, /* filled in by dev_attach */
"ep", 0, { MDDT_ISA, 0, "net" },
isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,
! &kdc_isa0, /* parent */
! 0, /* parentdata */
! DC_UNCONFIGURED, /* state */
"3Com 3C509 Ethernet adapter",
! DC_CLS_NETIF /* class */
} };
static inline void
--- 137,150 ----
};
static struct kern_devconf kdc_ep[NEP] = { {
! 0, 0, 0, /* filled in by dev_attach */
"ep", 0, { MDDT_ISA, 0, "net" },
isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,
! &kdc_isa0, /* parent */
! 0, /* parentdata */
! DC_UNCONFIGURED, /* state */
"3Com 3C509 Ethernet adapter",
! DC_CLS_NETIF /* class */
} };
static inline void
***************
*** 154,164 ****
int ep_current_tag = EP_LAST_TAG + 1;
! struct {
! int epb_addr; /* address of this board */
! char epb_used; /* was this entry already used for configuring ? */
! }
! ep_board[EP_MAX_BOARDS + 1];
static int
eeprom_rdy(is)
--- 159,165 ----
int ep_current_tag = EP_LAST_TAG + 1;
! struct ep_board ep_board[EP_MAX_BOARDS + 1];
static int
eeprom_rdy(is)
***************
*** 174,184 ****
return (1);
}
! static int
ep_look_for_board_at(is)
struct isa_device *is;
{
! int data, i, j, io_base, id_port = EP_ID_PORT;
int nisa = 0, neisa = 0;
if (ep_current_tag == (EP_LAST_TAG + 1)) {
--- 175,185 ----
return (1);
}
! static struct ep_board *
ep_look_for_board_at(is)
struct isa_device *is;
{
! int data, i, j, io_base, id_port = ELINK_ID_PORT;
int nisa = 0, neisa = 0;
if (ep_current_tag == (EP_LAST_TAG + 1)) {
***************
*** 203,232 ****
* Once activated, all the registers are mapped in the range
* x000 - x00F, where x is the slot number.
*/
ep_board[neisa].epb_used = 0;
ep_board[neisa++].epb_addr = j * EP_EISA_START;
}
ep_current_tag--;
/* Look for the ISA boards. Init and leave them actived */
outb(id_port, 0xc0); /* Global reset */
DELAY(10000);
for (i = 0; i < EP_MAX_BOARDS; i++) {
outb(id_port, 0);
outb(id_port, 0);
send_ID_sequence(id_port);
data = get_eeprom_data(id_port, EEPROM_MFG_ID);
if (data != MFG_ID)
break;
/* resolve contention using the Ethernet address */
for (j = 0; j < 3; j++)
! data = get_eeprom_data(id_port, j);
ep_board[neisa+nisa].epb_used = 0;
ep_board[neisa+nisa++].epb_addr =
! (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
outb(id_port, ep_current_tag); /* tags board */
outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG);
ep_current_tag--;
--- 204,265 ----
* Once activated, all the registers are mapped in the range
* x000 - x00F, where x is the slot number.
*/
+ ep_board[neisa].epb_isa = 0;
ep_board[neisa].epb_used = 0;
ep_board[neisa++].epb_addr = j * EP_EISA_START;
}
ep_current_tag--;
/* Look for the ISA boards. Init and leave them actived */
+ outb(id_port, 0);
+ outb(id_port, 0);
+
+ #if 0
+ send_ID_sequence(id_port);
+ #else
+ elink_idseq(0xCF);
+ #endif
+
+ #if 0
outb(id_port, 0xc0); /* Global reset */
+ #else
+ elink_reset();
+ #endif
DELAY(10000);
for (i = 0; i < EP_MAX_BOARDS; i++) {
outb(id_port, 0);
outb(id_port, 0);
+ #if 0
send_ID_sequence(id_port);
+ #else
+ elink_idseq(0xCF);
+ #endif
data = get_eeprom_data(id_port, EEPROM_MFG_ID);
if (data != MFG_ID)
break;
/* resolve contention using the Ethernet address */
+
+ for (j = 0; j < 3; j++)
+ get_eeprom_data(id_port, j);
+
+ /* and save this address for later use */
+
for (j = 0; j < 3; j++)
! ep_board[neisa+nisa].eth_addr[j] = get_eeprom_data(id_port, j);
+ ep_board[neisa+nisa].res_cfg =
+ get_eeprom_data(id_port, EEPROM_RESOURCE_CFG);
+
+ ep_board[neisa+nisa].prod_id =
+ get_eeprom_data(id_port, EEPROM_PROD_ID);
+
+ ep_board[neisa].epb_isa = 1;
ep_board[neisa+nisa].epb_used = 0;
ep_board[neisa+nisa++].epb_addr =
! (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
!
outb(id_port, ep_current_tag); /* tags board */
outb(id_port, ACTIVATE_ADAPTER_TO_CONFIG);
ep_current_tag--;
***************
*** 266,283 ****
IS_BASE=ep_board[i].epb_addr;
ep_board[i].epb_used=1;
! return 1;
} else {
for (i=0; ep_board[i].epb_addr && ep_board[i].epb_addr != IS_BASE; i++);
! if( ep_board[i].epb_used || ep_board[i].epb_addr != IS_BASE)
return 0;
if (inw(IS_BASE + EP_W0_EEPROM_COMMAND) & EEPROM_TST_MODE)
printf("ep%d: 3c5x9 at 0x%x in test mode. Erase pencil mark!\n",
is->id_unit, IS_BASE);
ep_board[i].epb_used=1;
! return 1;
}
}
--- 299,318 ----
IS_BASE=ep_board[i].epb_addr;
ep_board[i].epb_used=1;
!
! return &ep_board[i];
} else {
for (i=0; ep_board[i].epb_addr && ep_board[i].epb_addr != IS_BASE; i++);
! if( ep_board[i].epb_used || ep_board[i].epb_addr != IS_BASE)
return 0;
if (inw(IS_BASE + EP_W0_EEPROM_COMMAND) & EEPROM_TST_MODE)
printf("ep%d: 3c5x9 at 0x%x in test mode. Erase pencil mark!\n",
is->id_unit, IS_BASE);
ep_board[i].epb_used=1;
!
! return &ep_board[i];
}
}
***************
*** 308,327 ****
ep_registerdev(is);
! if (!ep_look_for_board_at(is))
return (0);
/*
* The iobase was found and MFG_ID was 0x6d50. PROD_ID should be
* 0x9[0-f]50
*/
GO_WINDOW(0);
! k = get_e(is, EEPROM_PROD_ID);
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff)) {
printf("epprobe: ignoring model %04x\n", k);
return (0);
}
! k = get_e(is, EEPROM_RESOURCE_CFG);
k >>= 12;
/* Now we have two cases again:
--- 343,363 ----
ep_registerdev(is);
! if(( sc->epb=ep_look_for_board_at(is) )==0)
return (0);
/*
* The iobase was found and MFG_ID was 0x6d50. PROD_ID should be
* 0x9[0-f]50
*/
GO_WINDOW(0);
! k = sc->epb->epb_isa ? sc->epb->prod_id : get_e(is, EEPROM_PROD_ID);
if ((k & 0xf0ff) != (PROD_ID & 0xf0ff)) {
printf("epprobe: ignoring model %04x\n", k);
return (0);
}
! k = sc->epb->epb_isa ? sc->epb->res_cfg : get_e(is, EEPROM_RESOURCE_CFG);
!
k >>= 12;
/* Now we have two cases again:
***************
*** 396,402 ****
p = (u_short *) & sc->arpcom.ac_enaddr;
for (i = 0; i < 3; i++) {
GO_WINDOW(0);
! p[i] = htons(get_e(is, i));
GO_WINDOW(2);
outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
}
--- 432,438 ----
p = (u_short *) & sc->arpcom.ac_enaddr;
for (i = 0; i < 3; i++) {
GO_WINDOW(0);
! p[i] = htons( sc->epb->epb_isa ? sc->epb->eth_addr[i] : get_e(is, i) );
GO_WINDOW(2);
outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
}
***************
*** 423,429 ****
ifp->if_unit = is->id_unit;
ifp->if_name = "ep";
ifp->if_mtu = ETHERMTU;
! ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
ifp->if_init = epinit;
ifp->if_output = ether_output;
ifp->if_start = epstart;
--- 459,466 ----
ifp->if_unit = is->id_unit;
ifp->if_name = "ep";
ifp->if_mtu = ETHERMTU;
! ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST |
! IFF_SIMPLEX | IFF_NOTRAILERS;
ifp->if_init = epinit;
ifp->if_output = ether_output;
ifp->if_start = epstart;
***************
*** 432,438 ****
ifp->if_timer=1;
if_attach(ifp);
! kdc_ep[is->id_unit].kdc_state = DC_BUSY;
/*
* Fill the hardware address into ifa_addr if we find an AF_LINK entry.
--- 469,477 ----
ifp->if_timer=1;
if_attach(ifp);
!
! /* device attach does transition from UNCONFIGURED to IDLE state */
! kdc_ep[is->id_unit].kdc_state=DC_IDLE;
/*
* Fill the hardware address into ifa_addr if we find an AF_LINK entry.
***************
*** 475,481 ****
#endif
ep_fset(F_RX_FIRST);
sc->top = sc->mcur = 0;
!
#if NBPFILTER > 0
bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
#endif
--- 514,520 ----
#endif
ep_fset(F_RX_FIRST);
sc->top = sc->mcur = 0;
!
#if NBPFILTER > 0
bpfattach(&sc->bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
#endif
***************
*** 536,547 ****
outw(BASE + EP_COMMAND, SET_INTR_MASK | S_5_INTS);
! if(ifp->if_flags & IFF_PROMISC)
! outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
! FIL_GROUP | FIL_BRDCST | FIL_ALL);
! else
! outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
! FIL_GROUP | FIL_BRDCST);
/*
* S.B.
--- 575,586 ----
outw(BASE + EP_COMMAND, SET_INTR_MASK | S_5_INTS);
! if(ifp->if_flags & IFF_PROMISC)
! outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
! FIL_GROUP | FIL_BRDCST | FIL_ALL);
! else
! outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
! FIL_GROUP | FIL_BRDCST);
/*
* S.B.
***************
*** 814,820 ****
sc->rx_no_first, sc->rx_no_mbuf, sc->rx_bpf_disc, sc->rx_overrunf,
sc->rx_overrunl, sc->tx_underrun);
#else
! printf("ep%d: Status: %x\n", unit, status);
#endif
epinit(unit);
splx(x);
--- 853,865 ----
sc->rx_no_first, sc->rx_no_mbuf, sc->rx_bpf_disc, sc->rx_overrunf,
sc->rx_overrunl, sc->tx_underrun);
#else
!
! #ifdef nightmaremessages
! printf("ep%d: Status: %x (input buffer overflow)\n", unit, status);
! #else
! ++sc->arpcom.ac_if.if_ierrors;
! #endif
!
#endif
epinit(unit);
splx(x);
***************
*** 1129,1139 ****
struct ifreq *ifr = (struct ifreq *) data;
int s, error = 0;
! s = splimp();
switch (cmd) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
--- 1174,1188 ----
struct ifreq *ifr = (struct ifreq *) data;
int s, error = 0;
! s=splimp();
switch (cmd) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
+
+ /* netifs are BUSY when UP */
+ kdc_ep[ifp->if_unit].kdc_state=DC_BUSY;
+
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
***************
*** 1159,1179 ****
break;
}
#endif
default:
epinit(ifp->if_unit);
break;
}
break;
case SIOCGIFADDR:
! {
! struct sockaddr *sa;
!
! sa = (struct sockaddr *) & ifr->ifr_data;
! bcopy((caddr_t) sc->arpcom.ac_enaddr,
(caddr_t) sa->sa_data, ETHER_ADDR_LEN);
}
break;
case SIOCSIFFLAGS:
if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
ifp->if_flags &= ~IFF_RUNNING;
epstop(ifp->if_unit);
--- 1208,1251 ----
break;
}
#endif
+ #ifdef IPX
+ case AF_IPX:
+ {
+ register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
+
+ if (ipx_nullhost(*ina))
+ ina->x_host =
+ *(union ipx_host *) (sc->arpcom.ac_enaddr);
+ else {
+ ifp->if_flags &= ~IFF_RUNNING;
+ bcopy((caddr_t) ina->x_host.c_host,
+ (caddr_t) sc->arpcom.ac_enaddr,
+ sizeof(sc->arpcom.ac_enaddr));
+ }
+ epinit(ifp->if_unit);
+ break;
+ }
+ #endif
default:
epinit(ifp->if_unit);
break;
}
break;
case SIOCGIFADDR:
! {
! struct sockaddr *sa;
!
! sa = (struct sockaddr *) & ifr->ifr_data;
! bcopy((caddr_t) sc->arpcom.ac_enaddr,
(caddr_t) sa->sa_data, ETHER_ADDR_LEN);
}
break;
case SIOCSIFFLAGS:
+ /* UP controls BUSY/IDLE */
+ kdc_ep[ifp->if_unit].kdc_state= ( (ifp->if_flags & IFF_UP)
+ ? DC_BUSY
+ : DC_IDLE );
+
if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
ifp->if_flags &= ~IFF_RUNNING;
epstop(ifp->if_unit);
***************
*** 1186,1191 ****
--- 1258,1264 ----
}
/* NOTREACHED */
+ #if 0
if (ifp->if_flags & IFF_UP && (ifp->if_flags & IFF_RUNNING) == 0)
epinit(ifp->if_unit);
***************
*** 1198,1203 ****
--- 1271,1277 ----
ep_frst(F_PROMISC);
epinit(ifp->if_unit);
}
+ #endif
break;
#ifdef notdef
***************
*** 1216,1223 ****
} else {
ifp->if_mtu = ifr->ifr_mtu;
}
! break;
!
default:
error = EINVAL;
}
--- 1290,1304 ----
} else {
ifp->if_mtu = ifr->ifr_mtu;
}
! break;
! case SIOCADDMULTI:
! case SIOCDELMULTI:
! /* Now this driver has no support for programmable
! * multicast filters. If some day it will gain this
! * support this part of code must be extended.
! */
! error=0;
! break;
default:
error = EINVAL;
}
------------------------- cut here --------------------------------------
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199510181012.PAA15264>
