Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 07 May 1996 01:56:47 -0700
From:      "Amancio Hasty Jr." <hasty@rah.star-gate.com>
To:        whchoi%cosmos.kaist.ac.kr@nuri.net
Cc:        hackers@freebsd.org
Subject:   Re: multicasting in freebsd 
Message-ID:  <199605070856.BAA00303@rah.star-gate.com>
In-Reply-To: Your message of "Tue, 07 May 1996 17:22:44 -0900." <199605080222.RAA19342@cosmos.kaist.ac.kr> 

next in thread | previous in thread | raw e-mail | index | archive | help

> Hello, Amancio!
> 
> We've just received Matrox clones from Omnimedia, and we're trying
> to replace our multicast station with a PC running freebsd.
> 
> The PC is equipped with a 3C509 card, but the problem we now face is
> that multicasting is not enabled for the ethernet interface.  I
> cannot find anything wrong in the configuration. when i asked
> for help to the freebsd group, someone replied multicasting is 
> not supported on 3c509.  but i don't think his answer makes sense.
> how could (device independent) multicasting will not work on any
> specific ethernet hardware?
> 
> We're running the latest freebsd release 2.1.0.
> 
> Do you have any idea?

Hi,
I have no clue as to why no one has tried to help you perhaps they are
busy discussing dosfsck 8)

The ethernet card needs to be able to recognized multiple ip addresses in
order to efficiently received ip multicast packets.

In the future try to do a little digging on the FreeBSD mailing search list:
http://www.freebsd.org/search.html

It is really easy to use 8)

In my case, I  just stored all the messages and do a database
search with glimpse;however, my freebsd folder got wiped out and I don't
feel like restoring it.

Please, since I noticed that you got several Matrox clone cards , any
multimedia related questions should go to multimedia@freebsd.org where
are you bound to find help 8)

As for ethernet cards, I use SMC 8216/SMC8216C (16 bit)  which FreeBSD has
IP multicast support.


I have no clue as to whether the following patch works or not however
at least it will get you close enough and you may also try checking
out what is Freebsd-current/sys/i386/isa/if_ep.c.


    Regards,
	Amancio

<HTML><HEAD>
<TITLE>Search Results: document</TITLE>
</HEAD>
<pre>From owner-freebsd-hackers  Wed Aug  9 19:09:13 1995
Return-Path: hackers-owner
Received: (from majordom@localhost)
          by freefall.FreeBSD.org (8.6.11/8.6.6) id TAA10479
          for hackers-outgoing; Wed, 9 Aug 1995 19:09:13 -0700
Received: from hq.icb.chel.su (icb-rich-gw.icb.chel.su [193.125.10.34])
          by freefall.FreeBSD.org (8.6.11/8.6.6) with ESMTP id TAA10472
          for <freebsd-hackers@freefall.FreeBSD.org>; Wed, 9 Aug 1995 19:09:03 
-0700
Received: from localhost (babkin@localhost) by hq.icb.chel.su (8.6.5/8.6.5) id 
IAA23568; Thu, 10 Aug 1995 08:11:35 +0600
From: "Serge A. Babkin" <babkin@hq.icb.chel.su>
Message-Id: <199508100211.IAA23568@hq.icb.chel.su>
Subject: Re: Multicast and ep0?
To: kargl@troutmask.apl.washington.edu (Steven G. Kargl)
Date: Thu, 10 Aug 1995 08:11:34 +0600 (GMT+0600)
Cc: freebsd-hackers@freefall.FreeBSD.org
In-Reply-To: <199508100020.RAA00613@troutmask.apl.washington.edu> from "Steven 
G. Kargl" at Aug 9, 95 05:20:04 pm
X-Mailer: ELM [version 2.4 PL23]
Content-Type: text
Content-Length: 13352     
Sender: hackers-owner@FreeBSD.org
Precedence: bulk

> I recall a discussion concerning the addtional of
> multicast support to the ep0 driver (if_ep.c).  I
> searched the mail archive via http://www.freebsd.org, 
> but could not find the multicast patch.
> 
> Does anyone have a patch for multicast support for 
> the ep0 driver?

Yes.

-------------------------------------- cut here --------------------------
*** if_ep.c.205	Thu Jul 27 09:12:42 1995
--- if_ep.c	Thu Jul 27 10:04:46 1995
***************
*** 100,105 ****
--- 98,104 ----
  #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 ****
--- 116,122 ----
  
  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
--- 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
***************
*** 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)
--- 154,160 ----
  
  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)) {
--- 170,180 ----
      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--;
--- 199,260 ----
  	     * 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;
      }
  }
  
--- 294,313 ----
  
  	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:
--- 338,358 ----
  
      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]));
      }
--- 427,433 ----
      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 | IFF_NOTRAILERS;
      ifp->if_init = epinit;
      ifp->if_output = ether_output;
      ifp->if_start = epstart;
--- 454,461 ----
      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.
--- 464,472 ----
  	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
--- 509,515 ----
  #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.
--- 570,581 ----
  
      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);
--- 848,854 ----
  		   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 (input buffer overflow)\n", unit, status);
  #endif
  	    epinit(unit);
  	    splx(x);
***************
*** 1132,1137 ****
--- 1166,1175 ----
      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:
***************
*** 1163,1168 ****
--- 1201,1211 ----
  	}
  	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);
***************
*** 1175,1180 ****
--- 1218,1224 ----
  	}
  
  	/* NOTREACHED */
+ #if 0
  
  	if (ifp->if_flags & IFF_UP && (ifp->if_flags & IFF_RUNNING) == 0)
  	    epinit(ifp->if_unit);
***************
*** 1187,1192 ****
--- 1231,1237 ----
  	    ep_frst(F_PROMISC);
  	    epinit(ifp->if_unit);
  	    }
+ #endif
  
  	break;
  #ifdef notdef
***************
*** 1205,1212 ****
  		} else {
  			ifp->if_mtu = ifr->ifr_mtu;
  		}
! 		break;
! 
        default:
  		error = EINVAL;
      }
--- 1250,1264 ----
  		} 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;
      }
*** if_epreg.h.205	Tue Jul 18 09:29:43 1995
--- if_epreg.h	Wed Jul 26 14:19:14 1995
***************
*** 71,76 ****
--- 70,77 ----
  
  #define         F_ACCESS_32_BITS 0x100
  
+     struct ep_board *epb;
+ 
  #ifdef  EP_LOCAL_STATS
      short tx_underrun;
      short rx_no_first;
***************
*** 80,85 ****
--- 81,97 ----
      short rx_overrunl;
  #endif
  };
+ 
+ struct ep_board {
+ 	int epb_addr;	/* address of this board */
+ 	char epb_used;	/* was this entry already used for configuring ? */
+ 				/* data from EEPROM for later use */
+ 	char epb_isa;	/* flag: this is an ISA card */
+ 	u_short eth_addr[3];	/* Ethernet address */
+ 	u_short prod_id;	/* product ID */
+ 	u_short res_cfg;	/* resource configuration */
+ 	};
+ 
  
  /*
   * Some global constants
-------------------------------------- cut here --------------------------

		Serge Babkin

! (babkin@hq.icb.chel.su)
! Headquarter of Joint Stock Commercial Bank "Chelindbank"
! Chelyabinsk, Russia

</pre></BODY></HTML>









Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199605070856.BAA00303>