Date: Tue, 28 Mar 1995 13:10:49 -0500 (GMT-0500) From: "Serge A. Babkin" <babkin@hq.icb.chel.su> To: davidg@Root.COM Cc: freebsd-hackers@FreeBSD.org Subject: Improvement of 3C509 (ep) driver Message-ID: <199503281810.NAA07680@hq.icb.chel.su> In-Reply-To: <199503270447.UAA04338@corbin.Root.COM> from "David Greenman" at Mar 26, 95 08:47:35 pm
next in thread | previous in thread | raw e-mail | index | archive | help
Yet another patch for 3C509 driver is here. This one enhances
the autoconfiguration feature. Now you may write something
like this in your conf. file:
device ep0 at isa? port? net irq? vector epintr
Indeed, in my opinion the GENERIC kernel *must* be configured in
this way.
*** 1.5 1995/03/27 11:20:41
--- if_ep.c 1995/03/28 07:00:14
***************
*** 38,48 ****
*/
/*
! * March 27 1995
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
! * logic changed to use value from EEPROM.
* Done by:
* Serge Babkin
* Chelindbank (Chelyabinsk, Russia)
--- 38,49 ----
*/
/*
! * March 28 1995
*
* 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
! * features added.
* Done by:
* Serge Babkin
* Chelindbank (Chelyabinsk, Russia)
***************
*** 122,128 ****
struct isa_driver epdriver = {
epprobe,
epattach,
! "ep"
};
static struct kern_devconf kdc_ep[NEP] = { {
--- 123,130 ----
struct isa_driver epdriver = {
epprobe,
epattach,
! "ep",
! 0
};
static struct kern_devconf kdc_ep[NEP] = { {
***************
*** 147,153 ****
int ep_current_tag = EP_LAST_TAG + 1;
! int ep_board[EP_MAX_BOARDS + 1];
static int
eeprom_rdy(is)
--- 149,159 ----
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)
***************
*** 192,198 ****
* Once activated, all the registers are mapped in the range
* x000 - x00F, where x is the slot number.
*/
! ep_board[neisa++] = j * EP_EISA_START;
}
ep_current_tag--;
--- 198,205 ----
* 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--;
***************
*** 212,249 ****
for (j = 0; j < 3; j++)
data = get_eeprom_data(id_port, j);
! ep_board[neisa+nisa++] =
(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--;
}
! ep_board[neisa+nisa] = 0;
if (neisa) {
printf("%d 3C5x9 board(s) on EISA found at", neisa);
! for (j = 0; ep_board[j]; j++)
! if (ep_board[j] >= EP_EISA_START)
! printf(" 0x%x", ep_board[j]);
printf("\n");
}
if (nisa) {
printf("%d 3C5x9 board(s) on ISA found at", nisa);
! for (j = 0; ep_board[j]; j++)
! if (ep_board[j] < EP_EISA_START)
! printf(" 0x%x", ep_board[j]);
printf("\n");
}
}
! for (i = 0; ep_board[i] && ep_board[i] != IS_BASE; i++);
! if (ep_board[i] == IS_BASE) {
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);
! return (1);
}
- return (0);
}
/*
--- 219,279 ----
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--;
}
! ep_board[neisa+nisa].epb_addr = 0;
if (neisa) {
printf("%d 3C5x9 board(s) on EISA found at", neisa);
! for (j = 0; ep_board[j].epb_addr; j++)
! if (ep_board[j].epb_addr >= EP_EISA_START)
! printf(" 0x%x", ep_board[j].epb_addr);
printf("\n");
}
if (nisa) {
printf("%d 3C5x9 board(s) on ISA found at", nisa);
! for (j = 0; ep_board[j].epb_addr; j++)
! if (ep_board[j].epb_addr < EP_EISA_START)
! printf(" 0x%x", ep_board[j].epb_addr);
printf("\n");
}
}
! /* we have two cases:
! *
! * 1. Device was configured with 'port ?'
! * In this case we search for the first unused card in list
! *
! * 2. Device was configured with 'port xxx'
! * In this case we search for the unused card with that address
! *
! */
!
! if(IS_BASE==-1) { /* port? */
! for (i = 0; ep_board[i].epb_addr && ep_board[i].epb_used; i++);
! if(ep_board[i].epb_addr==0)
! return 0;
!
! 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;
}
}
/*
***************
*** 286,294 ****
k = get_e(is, EEPROM_RESOURCE_CFG);
k >>= 12;
! if (is->id_irq != (1 << ((k == 2) ? 9 : k))) {
! printf("epprobe: interrupt number %d doesn't match\n",is->id_irq);
! return (0);
}
if (BASE >= EP_EISA_START) /* we have an EISA board, we allow 32 bits access */
--- 316,334 ----
k = get_e(is, EEPROM_RESOURCE_CFG);
k >>= 12;
!
! /* Now we have two cases again:
! *
! * 1. Device was configured with 'irq?'
! * In this case we use irq read from the board
! *
! * 2. Device was configured with 'irq xxx'
! * In this case we set up the board to use specified interrupt
! *
! */
!
! if(is->id_irq==0) { /* irq? */
! is->id_irq= 1 << ( (k==2) ? 9 : k );
}
if (BASE >= EP_EISA_START) /* we have an EISA board, we allow 32 bits access */
***************
*** 312,317 ****
--- 352,358 ----
u_short i, j, *p;
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
+ int irq;
/* BASE = IS_BASE; */
sc->ep_io_addr = is->id_iobase;
***************
*** 352,358 ****
GO_WINDOW(2);
outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
}
! printf(" address %s\n", ether_sprintf(sc->arpcom.ac_enaddr));
ifp->if_unit = is->id_unit;
ifp->if_name = "ep";
--- 393,417 ----
GO_WINDOW(2);
outw(BASE + EP_W2_ADDR_0 + (i * 2), ntohs(p[i]));
}
! printf(" address %s", ether_sprintf(sc->arpcom.ac_enaddr));
!
! /*
! * Write IRQ value to board
! */
!
! i=is->id_irq;
! if(i==0) {
! printf(" irq STRANGE\n");
! return 0;
! }
!
! for(irq=0; !(i & 1) && irq<16 ; i>>=1, irq++);
!
! if(irq==9)
! irq=2;
! printf(" irq %d\n",irq);
! GO_WINDOW(0);
! outw(BASE + EP_W0_RESOURCE_CFG, SET_IRQ(irq));
ifp->if_unit = is->id_unit;
ifp->if_name = "ep";
*** 1.4 1995/03/27 11:20:41
--- if_epreg.h 1995/03/28 07:00:32
***************
*** 31,41 ****
*/
/*
! * March 27 1995
*
* Promiscuous mode added and interrupt logic slightly changed
* to reduce the number of adapter failures. Transceiver select
! * logic changed to use value from EEPROM.
* Done by:
* Serge Babkin
* Chelindbank (Chelyabinsk, Russia)
--- 31,42 ----
*/
/*
! * March 28 1995
*
* 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
! * features added.
* Done by:
* Serge Babkin
* Chelindbank (Chelyabinsk, Russia)
***************
*** 340,345 ****
--- 341,352 ----
#define ACF_CONNECTOR_AUI 1
#define ACF_CONNECTOR_BNC 3
+ /* Resource configuration register.
+ * Window 0/Port 08
+ *
+ */
+
+ #define SET_IRQ(i) (((i)<<12) | 0xF00) /* set IRQ i */
/*
* FIFO Registers.
Serge Babkin
! (babkin@hq.icb.chel.su)
! Headquarter of Joint Stock Bank "Chelindbank"
! Chelyabinsk, Russia
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199503281810.NAA07680>
