Skip site navigation (1)Skip section navigation (2)
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>