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>