Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 7 May 1996 22:19:07 +0930 (CST)
From:      Michael Smith <msmith@atrad.adelaide.edu.au>
To:        hasty@rah.star-gate.com (Amancio Hasty Jr.)
Cc:        whchoi%cosmos.kaist.ac.kr@nuri.net, hackers@FreeBSD.org
Subject:   Re: multicasting in freebsd
Message-ID:  <199605071249.WAA22648@genesis.atrad.adelaide.edu.au>
In-Reply-To: <199605070856.BAA00303@rah.star-gate.com> from "Amancio Hasty Jr." at May 7, 96 01:56:47 am

next in thread | previous in thread | raw e-mail | index | archive | help
Amancio Hasty Jr. stands accused of saying:
> > 
> > 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?

Multicasting requires hardware support, or driver-level support using
promiscuous mode (which will eat your CPU)

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

Ethernet cards don't "recognise IP addresses".  Multicast packets are
sent to different _ethernet_ hardware addresses.  If the hardware on your
ethernet card can't be programmed to accept packets to more than one hardware
address, then multicast operation is problematic.

In some cases, it's just that documentation for the hardware on a card
isn't good enough to allow the driver author to put the card into
'multicast mode'.

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

The SMC cards are good candidates for multicast work; they emulate the 
good ol' NS8390, which handles multicast just fine.

> 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;
>   

-- 
]] Mike Smith, Software Engineer        msmith@atrad.adelaide.edu.au    [[
]] Genesis Software                     genesis@atrad.adelaide.edu.au   [[
]] High-speed data acquisition and      (GSM mobile) 0411-222-496       [[
]] realtime instrument control          (ph/fax)  +61-8-267-3039        [[
]] Collector of old Unix hardware.      "Where are your PEZ?" The Tick  [[



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