Date: 27 Nov 2002 11:22:00 -0600 From: Craig Boston <craig@xfoil.gank.org> To: freebsd-current@freebsd.org Subject: Testers needed for if_ex multicast patch Message-ID: <1038417716.59621.30.camel@owen1492.it.oot>
next in thread | raw e-mail | index | archive | help
--=-CDQUCZt+cYpQqSWPpYB9 Content-Type: text/plain Content-Transfer-Encoding: 7bit The attached patch adds multicast support for the ex (Intel EtherExpress 10/PRO 10 ISA and pccard) driver. I ported this from the NetBSD driver so I could do IPv6 on my 486 router at home ;). It also seems that the original ex might not have completely supported promiscuous mode, but that should be functional as well now. I'd appreciate if it some people who have one or more of these cards could test it and make sure it doesn't break anything. If you're using multicast routing or IPv6 and can give it a try in those environments to make sure it works as advertised, that would be even better. It seems to work fine on my cards which are mostly ISA Intel Pro/10s (00:aa:00) and a Pro/10+ (00:a0:c9). The patch should be applied in the sys/dev/ex directory. Please send me reports of any problems, no matter how small, along with your board type and version if available, and the first three MAC address octets. Code improvements are of course welcome also :) I've tried to match the style of the rest of the ex driver. I don't think the driver is quite style(9) compliant, but I wanted to keep the patch as simple as possible. I'll give it a week or two of testing and then submit to Matthew Dodd for his review after code freeze is over. Thanks! Craig Boston --=-CDQUCZt+cYpQqSWPpYB9 Content-Disposition: attachment; filename=ex_current_multicast.patch Content-Type: text/x-patch; name=ex_current_multicast.patch; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Index: if_ex.c =================================================================== RCS file: /home/ncvs/src/sys/dev/ex/if_ex.c,v retrieving revision 1.39 diff -u -r1.39 if_ex.c --- if_ex.c 2002/11/14 23:54:51 1.39 +++ if_ex.c 2002/11/27 16:55:21 @@ -35,6 +35,7 @@ * * Revision history: * + * dd-mmm-yyyy: Multicast support ported from NetBSD's if_iy driver. * 30-Oct-1996: first beta version. Inet and BPF supported, but no multicast. */ @@ -54,6 +55,7 @@ #include <net/if.h> #include <net/if_arp.h> +#include <net/if_dl.h> #include <net/if_media.h> #include <net/ethernet.h> #include <net/bpf.h> @@ -103,6 +105,7 @@ static int ex_get_media (u_int32_t iobase); static void ex_reset (struct ex_softc *); +static void ex_setmulti (struct ex_softc *); static void ex_tx_intr (struct ex_softc *); static void ex_rx_intr (struct ex_softc *); @@ -235,7 +238,7 @@ ifp->if_unit = unit; ifp->if_name = "ex"; ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST /* XXX not done yet. | IFF_MULTICAST */; + ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; ifp->if_output = ether_output; ifp->if_start = ex_start; ifp->if_ioctl = ex_ioctl; @@ -349,6 +352,8 @@ ifp->if_flags &= ~IFF_OACTIVE; DODEBUG(Status, printf("OIDLE init\n");); + ex_setmulti(sc); + /* * Final reset of the board, and enable operation. */ @@ -809,11 +814,9 @@ break; #endif case SIOCADDMULTI: - DODEBUG(Start_End, printf("SIOCADDMULTI");); case SIOCDELMULTI: - DODEBUG(Start_End, printf("SIOCDELMULTI");); - /* XXX Support not done yet. */ - error = EINVAL; + ex_init(sc); + error = 0; break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: @@ -831,6 +834,94 @@ return(error); } +static void +ex_setmulti(struct ex_softc *sc) +{ + struct ifnet *ifp; + struct ifmultiaddr *maddr; + u_int16_t *addr; + int iobase = sc->iobase; + int count; + int timeout, status; + + ifp = &sc->arpcom.ac_if; + maddr = ifp->if_multiaddrs.lh_first; + + for (count = 0; maddr != NULL; maddr = maddr->ifma_link.le_next, count++); + + if ((ifp->if_flags & IFF_PROMISC) || (ifp->if_flags & IFF_ALLMULTI) + || count > 63) { + /* Interface is in promiscuous mode or there are too many + * multicast addresses for the card to handle */ + outb(iobase + CMD_REG, Bank2_Sel); + outb(iobase + REG2, inb(iobase + REG2) | Promisc_Mode); + outb(iobase + REG3, inb(iobase + REG3)); + outb(iobase + CMD_REG, Bank0_Sel); + } + else if ((ifp->if_flags & IFF_MULTICAST) && (count > 0)) { + /* Program multicast addresses plus our MAC address + * into the filter */ + outb(iobase + CMD_REG, Bank2_Sel); + outb(iobase + REG2, inb(iobase + REG2) | Multi_IA); + outb(iobase + REG3, inb(iobase + REG3)); + outb(iobase + CMD_REG, Bank0_Sel); + + /* Borrow space from TX buffer; this should be safe + * as this is only called from ex_init */ + + outw(iobase + HOST_ADDR_REG, sc->tx_lower_limit); + outw(iobase + IO_PORT_REG, MC_Setup_CMD); + outw(iobase + IO_PORT_REG, 0); + outw(iobase + IO_PORT_REG, 0); + outw(iobase + IO_PORT_REG, (count + 1) * 6); + + for (maddr = ifp->if_multiaddrs.lh_first; maddr != NULL; + maddr = maddr->ifma_link.le_next) + { + addr = (u_int16_t*)LLADDR((struct sockaddr_dl *) + maddr->ifma_addr); + outw(iobase + IO_PORT_REG, *addr++); + outw(iobase + IO_PORT_REG, *addr++); + outw(iobase + IO_PORT_REG, *addr++); + } + + /* Program our MAC address as well */ + /* XXX: Is this necessary? The Linux driver does this + * but the NetBSD driver does not */ + addr = (u_int16_t*)(&sc->arpcom.ac_enaddr); + outw(iobase + IO_PORT_REG, *addr++); + outw(iobase + IO_PORT_REG, *addr++); + outw(iobase + IO_PORT_REG, *addr++); + + inw(iobase + IO_PORT_REG); + outw(iobase + XMT_BAR, sc->tx_lower_limit); + outb(iobase + CMD_REG, MC_Setup_CMD); + + sc->tx_head = sc->tx_lower_limit; + sc->tx_tail = sc->tx_head + XMT_HEADER_LEN + (count + 1) * 6; + + for (timeout=0; timeout<100; timeout++) { + DELAY(2); + if ((inb(iobase + STATUS_REG) & Exec_Int) == 0) + continue; + + status = inb(iobase + CMD_REG); + outb(iobase + STATUS_REG, Exec_Int); + break; + } + + sc->tx_head = sc->tx_tail; + } + else + { + /* No multicast or promiscuous mode */ + outb(iobase + CMD_REG, Bank2_Sel); + outb(iobase + REG2, inb(iobase + REG2) & 0xDE); + /* ~(Multi_IA | Promisc_Mode) */ + outb(iobase + REG3, inb(iobase + REG3)); + outb(iobase + CMD_REG, Bank0_Sel); + } +} static void ex_reset(struct ex_softc *sc) Index: if_exreg.h =================================================================== RCS file: /home/ncvs/src/sys/dev/ex/if_exreg.h,v retrieving revision 1.3 diff -u -r1.3 if_exreg.h --- if_exreg.h 2000/05/01 09:05:18 1.3 +++ if_exreg.h 2002/11/27 16:55:21 @@ -119,8 +119,10 @@ #define Disc_Bad_Fr 0x80 #define Tx_Chn_ErStp 0x40 #define Tx_Chn_Int_Md 0x20 +#define Multi_IA 0x20 #define No_SA_Ins 0x10 #define RX_CRC_InMem 0x04 +#define Promisc_Mode 0x01 #define BNC_bit 0x20 #define TPE_bit 0x04 #define I_ADDR_REG0 4 --=-CDQUCZt+cYpQqSWPpYB9-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1038417716.59621.30.camel>