From patchwork Sat Jun 18 00:09:41 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Greear X-Patchwork-Id: 100884 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 466F9B6FE0 for ; Sat, 18 Jun 2011 10:10:39 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759608Ab1FRAKe (ORCPT ); Fri, 17 Jun 2011 20:10:34 -0400 Received: from mail.candelatech.com ([208.74.158.172]:45562 "EHLO ns3.lanforge.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758042Ab1FRAKd (ORCPT ); Fri, 17 Jun 2011 20:10:33 -0400 Received: from localhost.localdomain (firewall.candelatech.com [70.89.124.249]) by ns3.lanforge.com (8.14.2/8.14.2) with ESMTP id p5I09ji9028318 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 17 Jun 2011 17:09:46 -0700 From: greearb@candelatech.com To: netdev@vger.kernel.org Cc: Ben Greear Subject: [RFC 3/5] e100: Support receiving errored frames. Date: Fri, 17 Jun 2011 17:09:41 -0700 Message-Id: <1308355783-22407-4-git-send-email-greearb@candelatech.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1308355783-22407-1-git-send-email-greearb@candelatech.com> References: <1308355783-22407-1-git-send-email-greearb@candelatech.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ben Greear This can be helpful when sniffing dodgy networks. Signed-off-by: Ben Greear --- :100644 100644 647d8c6... aad303d... M drivers/net/e100.c drivers/net/e100.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 647d8c6..aad303d 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -588,6 +588,7 @@ struct nic { wol_magic = (1 << 3), ich_10h_workaround = (1 << 4), save_rxfcs = (1 << 5), + save_rxerr = (1 << 6), } flags ____cacheline_aligned; enum mac mac; @@ -1126,9 +1127,13 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) config->full_duplex_force = 0x1; /* 1=force, 0=auto */ if (nic->flags & promiscuous || nic->loopback) { + config->promiscuous_mode = 0x1; /* 1=on, 0=off */ + } + + if (nic->flags & save_rxerr) { + config->rx_discard_overruns = 0x1; /* 1=save, 0=discard */ config->rx_save_bad_frames = 0x1; /* 1=save, 0=discard */ config->rx_discard_short_frames = 0x0; /* 1=discard, 0=save */ - config->promiscuous_mode = 0x1; /* 1=on, 0=off */ } if (nic->flags & save_rxfcs) @@ -1983,7 +1988,18 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, skb_put(skb, actual_size); skb->protocol = eth_type_trans(skb, nic->netdev); - if (unlikely(!(rfd_status & cb_ok))) { + if (unlikely(nic->flags & save_rxerr)) { + if (!(rfd_status & cb_ok)) { + skb->pkt_type = PACKET_INVALID; + } else if (actual_size > + ETH_DATA_LEN + VLAN_ETH_HLEN + rxfcs_pad) { + nic->rx_over_length_errors++; + skb->pkt_type = PACKET_INVALID; + } + goto process_skb; + } + + if (unlikely((nic->flags & save_rxerr) && !(rfd_status & cb_ok))) { /* Don't indicate if hardware indicates errors */ dev_kfree_skb_any(skb); } else if (actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN + rxfcs_pad) { @@ -1991,6 +2007,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, nic->rx_over_length_errors++; dev_kfree_skb_any(skb); } else { +process_skb: dev->stats.rx_packets++; dev->stats.rx_bytes += actual_size; netif_receive_skb(skb); @@ -2397,6 +2414,25 @@ static u32 e100_get_save_rxfcs(struct net_device *netdev) return !!(nic->flags & save_rxfcs); } +static int e100_set_save_rxerr(struct net_device *netdev, u32 data) +{ + struct nic *nic = netdev_priv(netdev); + if (data) + nic->flags |= save_rxerr; + else + nic->flags &= ~save_rxerr; + + e100_exec_cb(nic, NULL, e100_configure); + + return 0; +} + +static u32 e100_get_save_rxerr(struct net_device *netdev) +{ + struct nic *nic = netdev_priv(netdev); + return !!(nic->flags & save_rxerr); +} + static void e100_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info) { @@ -2718,6 +2754,8 @@ static const struct ethtool_ops e100_ethtool_ops = { .get_sset_count = e100_get_sset_count, .set_save_rxfcs = e100_set_save_rxfcs, .get_save_rxfcs = e100_get_save_rxfcs, + .set_save_rxerr = e100_set_save_rxerr, + .get_save_rxerr = e100_get_save_rxerr, }; static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)