Date: Sun, 2 Aug 2015 16:24:12 GMT From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r289111 - soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve Message-ID: <201508021624.t72GOCfi068539@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508021624.t72GOCfi068539>