From owner-freebsd-hackers Mon Mar 27 23:18:10 1995 Return-Path: hackers-owner Received: (from majordom@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id XAA29661 for hackers-outgoing; Mon, 27 Mar 1995 23:18:10 -0800 Received: from hq.icb.chel.su (icb-rich-gw.icb.chel.su [193.125.10.34]) by freefall.cdrom.com (8.6.10/8.6.6) with ESMTP id XAA29543 for ; Mon, 27 Mar 1995 23:15:36 -0800 Received: from localhost (babkin@localhost) by hq.icb.chel.su (8.6.5/8.6.5) id NAA07680; Tue, 28 Mar 1995 13:10:49 -0500 From: "Serge A. Babkin" Message-Id: <199503281810.NAA07680@hq.icb.chel.su> Subject: Improvement of 3C509 (ep) driver To: davidg@Root.COM Date: Tue, 28 Mar 1995 13:10:49 -0500 (GMT-0500) Cc: freebsd-hackers@FreeBSD.org In-Reply-To: <199503270447.UAA04338@corbin.Root.COM> from "David Greenman" at Mar 26, 95 08:47:35 pm X-Mailer: ELM [version 2.4 PL23] Content-Type: text Content-Length: 8331 Sender: hackers-owner@FreeBSD.org Precedence: bulk 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