From owner-svn-soc-all@freebsd.org Sun Aug 2 16:24:13 2015 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 029739B1E10 for ; Sun, 2 Aug 2015 16:24:13 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E7545C32 for ; Sun, 2 Aug 2015 16:24:12 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id t72GOCgm068543 for ; Sun, 2 Aug 2015 16:24:12 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id t72GOCfi068539 for svn-soc-all@FreeBSD.org; Sun, 2 Aug 2015 16:24:12 GMT (envelope-from iateaca@FreeBSD.org) Date: Sun, 2 Aug 2015 16:24:12 GMT Message-Id: <201508021624.t72GOCfi068539@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r289111 - soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 02 Aug 2015 16:24:13 -0000 Author: iateaca Date: Sun Aug 2 16:24:11 2015 New Revision: 289111 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=289111 Log: handle the received multicast traffic Modified: soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c Modified: soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c ============================================================================== --- soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c Sun Aug 2 14:56:30 2015 (r289110) +++ soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_ne2000.c Sun Aug 2 16:24:11 2015 (r289111) @@ -281,6 +281,9 @@ DPRINTF("Receive Packet: from tap interface of %zd bytes", read_len); + /* clear the Receiver Status Register */ + ne2000_set_reg_by_offset(sc, NE2000_P0_RO, ED_P0_RSR, 0x00); + if (!ne2000_ether_frame_is_valid(sc)) { DPRINTF("Drop the packet since the ether frame did not match"); return 0; @@ -291,6 +294,9 @@ return 0; } + ne2000_set_field_by_offset(sc, NE2000_P0_RO, ED_P0_RSR, + ED_RSR_PRX, ED_RSR_PRX); + size = read_len < ETHER_MIN_FRAME_LEN ? ETHER_MIN_FRAME_LEN : read_len; /* psize is the number of pages used by the frame and ne2000 header */ @@ -313,9 +319,6 @@ DPRINTF("Receive Packet: size: %d psize: %d next_curr: %d index: %d", size, psize, next_curr, index); - ne2000_set_field_by_offset(sc, NE2000_P0_RO, ED_P0_RSR, - 0xff, ED_RSR_PRX); - ed_hdr = (struct ed_ring *)(sc->ram + index); ed_hdr->rsr = ne2000_get_reg_by_offset(sc, NE2000_P0_RO, ED_P0_RSR); ed_hdr->next_packet = next_curr; @@ -424,6 +427,9 @@ static int ne2000_ether_frame_is_valid(struct pci_ne2000_softc *sc) { + uint8_t key = 0; + uint8_t mar_offset = 0; + uint8_t mar_reg = 0; uint8_t rcr = 0; uint8_t broadcast_addr[] = {[0 ... (ETHER_ADDR_LEN - 1)] = 0xff}; @@ -445,8 +451,25 @@ /* is valid if the destination MAC is the broadcast address */ if (rcr & ED_RCR_AB) { - if (memcmp(sc->rcv_buf, broadcast_addr, ETHER_ADDR_LEN) == 0) + if (memcmp(sc->rcv_buf, broadcast_addr, ETHER_ADDR_LEN) == 0) { + ne2000_set_field_by_offset(sc, NE2000_P0_RO, ED_P0_RSR, + ED_RSR_PHY, ED_RSR_PHY); return 1; + } + } + + /* is valid if the destination MAC represents a multicast address group */ + if ((rcr & ED_RCR_AM) && (sc->rcv_buf[0] & 0x01)) { + key = ne2000_ether_crc32_be(sc->rcv_buf, ETHER_ADDR_LEN) >> 26; + + mar_offset = ED_P1_MAR0 + (key >> 3); + mar_reg = ne2000_get_reg_by_offset(sc, NE2000_P1, mar_offset); + + if (mar_reg & (1 << (key & 7))) { + ne2000_set_field_by_offset(sc, NE2000_P0_RO, ED_P0_RSR, + ED_RSR_PHY, ED_RSR_PHY); + return 1; + } } return 0; @@ -837,16 +860,29 @@ ne2000_emul_reg_page1(struct pci_ne2000_softc *sc, uint8_t offset, uint8_t value) { + int err; uint8_t pstart = 0; uint8_t pstop = 0; - if (offset == ED_P1_CR) - return ne2000_emul_reg_page0(sc, offset, value); - else if (offset == ED_P1_CURR) { + switch (offset) { + case ED_P1_CR: + err = ne2000_emul_reg_page0(sc, offset, value); + assert(err == 0); + break; + case ED_P1_PAR0 ... ED_P1_PAR5: + DPRINTF("PAR[%d]: 0x%x", offset - ED_P1_PAR0, value); + break; + case ED_P1_CURR: DPRINTF("Current Page Register: %d", value); pstart = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_PSTART); pstop = ne2000_get_reg_by_offset(sc, NE2000_P0, ED_P0_PSTOP); assert(value >= pstart && value < pstop); + break; + case ED_P1_MAR0 ... ED_P1_MAR7: + DPRINTF("MAR[%d]: 0x%x", offset - ED_P1_MAR0, value); + break; + default: + assert(0); } return 0;