From patchwork Tue Nov 9 01:46:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Poirier X-Patchwork-Id: 70486 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id AE44DB7115 for ; Tue, 9 Nov 2010 12:50:03 +1100 (EST) Received: from localhost ([127.0.0.1]:52942 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PFdLV-0006tp-13 for incoming@patchwork.ozlabs.org; Mon, 08 Nov 2010 20:50:01 -0500 Received: from [140.186.70.92] (port=60925 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PFdJP-00060x-Ch for qemu-devel@nongnu.org; Mon, 08 Nov 2010 20:47:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PFdJM-00078Y-H7 for qemu-devel@nongnu.org; Mon, 08 Nov 2010 20:47:49 -0500 Received: from smtp.polymtl.ca ([132.207.4.11]:37571) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PFdJM-00078O-EZ for qemu-devel@nongnu.org; Mon, 08 Nov 2010 20:47:48 -0500 Received: from d1.synalogic.ca (196-81-252-216-dsl.colba.net [216.252.81.196] (may be forged)) by smtp.polymtl.ca (8.14.3/8.14.3) with ESMTP id oA91lHGq010777; Mon, 8 Nov 2010 20:47:46 -0500 From: Benjamin Poirier To: qemu-devel@nongnu.org Date: Mon, 8 Nov 2010 20:46:21 -0500 Message-Id: <1289267181-20613-2-git-send-email-benjamin.poirier@polymtl.ca> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: References: X-Poly-FromMTA: (196-81-252-216-dsl.colba.net [216.252.81.196] (may be forged)) at Tue, 9 Nov 2010 01:47:17 +0000 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Subject: [Qemu-devel] [PATCH v2 2/2] rtl8139: add vlan tag extraction X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add support to the emulated hardware to remove vlan tags in packets going from the network to the guest. Signed-off-by: Benjamin Poirier Cc: Igor V. Kovalenko --- Changes since v1: * moved the debug print statement inside the if block and reworded accordingly. (as suggested by Igor) AFAIK, extraction is optional to get vlans working. The driver requests rx detagging but should not assume that it was done. Under Linux, the mac layer will catch the vlan ethertype. I only added this part for completeness (to emulate the hardware more truthfully..?). hw/rtl8139.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 files changed, 37 insertions(+), 3 deletions(-) diff --git a/hw/rtl8139.c b/hw/rtl8139.c index b599945..7762dbb 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -1024,6 +1024,43 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI); + if (s->CpCmd & CPlusRxVLAN && size >= ETHER_ADDR_LEN * 2 + + VLAN_HDR_LEN && be16_to_cpup((uint16_t *) &buf[ETHER_ADDR_LEN * + 2]) == ETHERTYPE_VLAN) + { + size_t new_size = size - VLAN_HDR_LEN; + + rxdw1 &= ~CP_RX_VLAN_TAG_MASK; + rxdw1 |= CP_RX_TAVA | + le16_to_cpup((uint16_t *)&buf[ETHER_HDR_LEN]); + + if (buf == buf1 || new_size < MIN_BUF_SIZE) + { + /* move the end and pad */ + memmove((uint8_t *)buf + ETHER_ADDR_LEN * 2, buf + + ETHER_ADDR_LEN * 2 + VLAN_HDR_LEN, new_size - + ETHER_ADDR_LEN * 2); + memset((uint8_t *)buf + new_size, 0, MIN_BUF_SIZE - new_size); + size = MIN_BUF_SIZE; + } + else + { + /* move the beginning */ + memmove((uint8_t *)buf + VLAN_HDR_LEN, buf, ETHER_ADDR_LEN * + 2); + buf += VLAN_HDR_LEN; + size = new_size; + } + + DEBUG_PRINT(("RTL8139: C+ Rx mode : extracted vlan tag with tci: " + "%u\n", bswap16(rxdw1 & CP_RX_VLAN_TAG_MASK))); + } + else + { + /* reset VLAN tag flag */ + rxdw1 &= ~CP_RX_TAVA; + } + /* receive/copy to target memory */ cpu_physical_memory_write( rx_addr, buf, size ); @@ -1082,9 +1119,6 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_ rxdw0 &= ~CP_RX_BUFFER_SIZE_MASK; rxdw0 |= (size+4); - /* reset VLAN tag flag */ - rxdw1 &= ~CP_RX_TAVA; - /* update ring data */ val = cpu_to_le32(rxdw0); cpu_physical_memory_write(cplus_rx_ring_desc, (uint8_t *)&val, 4);