提交 421355de 编写于 作者: D David S. Miller

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

...@@ -3654,6 +3654,7 @@ NETWORKING [GENERAL] ...@@ -3654,6 +3654,7 @@ NETWORKING [GENERAL]
M: "David S. Miller" <davem@davemloft.net> M: "David S. Miller" <davem@davemloft.net>
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
W: http://www.linuxfoundation.org/en/Net W: http://www.linuxfoundation.org/en/Net
W: http://patchwork.ozlabs.org/project/netdev/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
S: Maintained S: Maintained
F: net/ F: net/
...@@ -5635,6 +5636,13 @@ S: Maintained ...@@ -5635,6 +5636,13 @@ S: Maintained
F: drivers/vlynq/vlynq.c F: drivers/vlynq/vlynq.c
F: include/linux/vlynq.h F: include/linux/vlynq.h
VMWARE VMXNET3 ETHERNET DRIVER
M: Shreyas Bhatewara <sbhatewara@vmware.com>
M: VMware, Inc. <pv-drivers@vmware.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/vmxnet3/
VOLTAGE AND CURRENT REGULATOR FRAMEWORK VOLTAGE AND CURRENT REGULATOR FRAMEWORK
M: Liam Girdwood <lrg@slimlogic.co.uk> M: Liam Girdwood <lrg@slimlogic.co.uk>
M: Mark Brown <broonie@opensource.wolfsonmicro.com> M: Mark Brown <broonie@opensource.wolfsonmicro.com>
......
...@@ -3230,4 +3230,12 @@ config VIRTIO_NET ...@@ -3230,4 +3230,12 @@ config VIRTIO_NET
This is the virtual network driver for virtio. It can be used with This is the virtual network driver for virtio. It can be used with
lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
config VMXNET3
tristate "VMware VMXNET3 ethernet driver"
depends on PCI && X86
help
This driver supports VMware's vmxnet3 virtual ethernet NIC.
To compile this driver as a module, choose M here: the
module will be called vmxnet3.
endif # NETDEVICES endif # NETDEVICES
...@@ -30,6 +30,7 @@ obj-$(CONFIG_TEHUTI) += tehuti.o ...@@ -30,6 +30,7 @@ obj-$(CONFIG_TEHUTI) += tehuti.o
obj-$(CONFIG_ENIC) += enic/ obj-$(CONFIG_ENIC) += enic/
obj-$(CONFIG_JME) += jme.o obj-$(CONFIG_JME) += jme.o
obj-$(CONFIG_BE2NET) += benet/ obj-$(CONFIG_BE2NET) += benet/
obj-$(CONFIG_VMXNET3) += vmxnet3/
gianfar_driver-objs := gianfar.o \ gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o \ gianfar_ethtool.o \
......
...@@ -1209,7 +1209,8 @@ static int __devinit ace_init(struct net_device *dev) ...@@ -1209,7 +1209,8 @@ static int __devinit ace_init(struct net_device *dev)
memset(ap->info, 0, sizeof(struct ace_info)); memset(ap->info, 0, sizeof(struct ace_info));
memset(ap->skb, 0, sizeof(struct ace_skb)); memset(ap->skb, 0, sizeof(struct ace_skb));
if (ace_load_firmware(dev)) ecode = ace_load_firmware(dev);
if (ecode)
goto init_error; goto init_error;
ap->fw_running = 0; ap->fw_running = 0;
......
...@@ -330,6 +330,9 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; ...@@ -330,6 +330,9 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
#define EMAC_DM646X_MAC_EOI_C0_RXEN (0x01) #define EMAC_DM646X_MAC_EOI_C0_RXEN (0x01)
#define EMAC_DM646X_MAC_EOI_C0_TXEN (0x02) #define EMAC_DM646X_MAC_EOI_C0_TXEN (0x02)
/* EMAC Stats Clear Mask */
#define EMAC_STATS_CLR_MASK (0xFFFFFFFF)
/** net_buf_obj: EMAC network bufferdata structure /** net_buf_obj: EMAC network bufferdata structure
* *
* EMAC network buffer data structure * EMAC network buffer data structure
...@@ -2544,40 +2547,49 @@ static int emac_dev_stop(struct net_device *ndev) ...@@ -2544,40 +2547,49 @@ static int emac_dev_stop(struct net_device *ndev)
static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
{ {
struct emac_priv *priv = netdev_priv(ndev); struct emac_priv *priv = netdev_priv(ndev);
u32 mac_control;
u32 stats_clear_mask;
/* update emac hardware stats and reset the registers*/ /* update emac hardware stats and reset the registers*/
mac_control = emac_read(EMAC_MACCONTROL);
if (mac_control & EMAC_MACCONTROL_GMIIEN)
stats_clear_mask = EMAC_STATS_CLR_MASK;
else
stats_clear_mask = 0;
priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES); priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
emac_write(EMAC_RXMCASTFRAMES, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_RXMCASTFRAMES, stats_clear_mask);
priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) + priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
emac_read(EMAC_TXSINGLECOLL) + emac_read(EMAC_TXSINGLECOLL) +
emac_read(EMAC_TXMULTICOLL)); emac_read(EMAC_TXMULTICOLL));
emac_write(EMAC_TXCOLLISION, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_TXCOLLISION, stats_clear_mask);
emac_write(EMAC_TXSINGLECOLL, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_TXSINGLECOLL, stats_clear_mask);
emac_write(EMAC_TXMULTICOLL, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_TXMULTICOLL, stats_clear_mask);
priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) + priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
emac_read(EMAC_RXJABBER) + emac_read(EMAC_RXJABBER) +
emac_read(EMAC_RXUNDERSIZED)); emac_read(EMAC_RXUNDERSIZED));
emac_write(EMAC_RXOVERSIZED, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_RXOVERSIZED, stats_clear_mask);
emac_write(EMAC_RXJABBER, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_RXJABBER, stats_clear_mask);
emac_write(EMAC_RXUNDERSIZED, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_RXUNDERSIZED, stats_clear_mask);
priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) + priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
emac_read(EMAC_RXMOFOVERRUNS)); emac_read(EMAC_RXMOFOVERRUNS));
emac_write(EMAC_RXSOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_RXSOFOVERRUNS, stats_clear_mask);
emac_write(EMAC_RXMOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_RXMOFOVERRUNS, stats_clear_mask);
priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS); priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
emac_write(EMAC_RXDMAOVERRUNS, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_RXDMAOVERRUNS, stats_clear_mask);
priv->net_dev_stats.tx_carrier_errors += priv->net_dev_stats.tx_carrier_errors +=
emac_read(EMAC_TXCARRIERSENSE); emac_read(EMAC_TXCARRIERSENSE);
emac_write(EMAC_TXCARRIERSENSE, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_TXCARRIERSENSE, stats_clear_mask);
priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN); priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
emac_write(EMAC_TXUNDERRUN, EMAC_ALL_MULTI_REG_VALUE); emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
return &priv->net_dev_stats; return &priv->net_dev_stats;
} }
......
...@@ -663,7 +663,8 @@ static int ethoc_open(struct net_device *dev) ...@@ -663,7 +663,8 @@ static int ethoc_open(struct net_device *dev)
return ret; return ret;
/* calculate the number of TX/RX buffers, maximum 128 supported */ /* calculate the number of TX/RX buffers, maximum 128 supported */
num_bd = min(128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ); num_bd = min_t(unsigned int,
128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ);
priv->num_tx = max(min_tx, num_bd / 4); priv->num_tx = max(min_tx, num_bd / 4);
priv->num_rx = num_bd - priv->num_tx; priv->num_rx = num_bd - priv->num_tx;
ethoc_write(priv, TX_BD_NUM, priv->num_tx); ethoc_write(priv, TX_BD_NUM, priv->num_tx);
......
...@@ -232,8 +232,11 @@ static int sa1100_irda_startup(struct sa1100_irda *si) ...@@ -232,8 +232,11 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
/* /*
* Ensure that the ports for this device are setup correctly. * Ensure that the ports for this device are setup correctly.
*/ */
if (si->pdata->startup) if (si->pdata->startup) {
si->pdata->startup(si->dev); ret = si->pdata->startup(si->dev);
if (ret)
return ret;
}
/* /*
* Configure PPC for IRDA - we want to drive TXD2 low. * Configure PPC for IRDA - we want to drive TXD2 low.
......
...@@ -119,24 +119,9 @@ static struct ixp2400_msf_parameters enp2611_msf_parameters = ...@@ -119,24 +119,9 @@ static struct ixp2400_msf_parameters enp2611_msf_parameters =
} }
}; };
struct enp2611_ixpdev_priv
{
struct ixpdev_priv ixpdev_priv;
struct net_device_stats stats;
};
static struct net_device *nds[3]; static struct net_device *nds[3];
static struct timer_list link_check_timer; static struct timer_list link_check_timer;
static struct net_device_stats *enp2611_get_stats(struct net_device *dev)
{
struct enp2611_ixpdev_priv *ip = netdev_priv(dev);
pm3386_get_stats(ip->ixpdev_priv.channel, &(ip->stats));
return &(ip->stats);
}
/* @@@ Poll the SFP moddef0 line too. */ /* @@@ Poll the SFP moddef0 line too. */
/* @@@ Try to use the pm3386 DOOL interrupt as well. */ /* @@@ Try to use the pm3386 DOOL interrupt as well. */
static void enp2611_check_link_status(unsigned long __dummy) static void enp2611_check_link_status(unsigned long __dummy)
...@@ -203,14 +188,13 @@ static int __init enp2611_init_module(void) ...@@ -203,14 +188,13 @@ static int __init enp2611_init_module(void)
ports = pm3386_port_count(); ports = pm3386_port_count();
for (i = 0; i < ports; i++) { for (i = 0; i < ports; i++) {
nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv)); nds[i] = ixpdev_alloc(i, sizeof(struct ixpdev_priv));
if (nds[i] == NULL) { if (nds[i] == NULL) {
while (--i >= 0) while (--i >= 0)
free_netdev(nds[i]); free_netdev(nds[i]);
return -ENOMEM; return -ENOMEM;
} }
nds[i]->get_stats = enp2611_get_stats;
pm3386_init_port(i); pm3386_init_port(i);
pm3386_get_mac(i, nds[i]->dev_addr); pm3386_get_mac(i, nds[i]->dev_addr);
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "ixp2400_tx.ucode" #include "ixp2400_tx.ucode"
#include "ixpdev_priv.h" #include "ixpdev_priv.h"
#include "ixpdev.h" #include "ixpdev.h"
#include "pm3386.h"
#define DRV_MODULE_VERSION "0.2" #define DRV_MODULE_VERSION "0.2"
...@@ -270,6 +271,15 @@ static int ixpdev_close(struct net_device *dev) ...@@ -270,6 +271,15 @@ static int ixpdev_close(struct net_device *dev)
return 0; return 0;
} }
static struct net_device_stats *ixpdev_get_stats(struct net_device *dev)
{
struct ixpdev_priv *ip = netdev_priv(dev);
pm3386_get_stats(ip->channel, &(dev->stats));
return &(dev->stats);
}
static const struct net_device_ops ixpdev_netdev_ops = { static const struct net_device_ops ixpdev_netdev_ops = {
.ndo_open = ixpdev_open, .ndo_open = ixpdev_open,
.ndo_stop = ixpdev_close, .ndo_stop = ixpdev_close,
...@@ -277,6 +287,7 @@ static const struct net_device_ops ixpdev_netdev_ops = { ...@@ -277,6 +287,7 @@ static const struct net_device_ops ixpdev_netdev_ops = {
.ndo_change_mtu = eth_change_mtu, .ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr, .ndo_set_mac_address = eth_mac_addr,
.ndo_get_stats = ixpdev_get_stats,
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ixpdev_poll_controller, .ndo_poll_controller = ixpdev_poll_controller,
#endif #endif
......
...@@ -597,7 +597,8 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) ...@@ -597,7 +597,8 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
void __iomem *mem_ptr2 = NULL; void __iomem *mem_ptr2 = NULL;
void __iomem *db_ptr = NULL; void __iomem *db_ptr = NULL;
unsigned long mem_base, mem_len, db_base, db_len = 0, pci_len0 = 0; resource_size_t mem_base, db_base;
unsigned long mem_len, db_len = 0, pci_len0 = 0;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
int pci_func = adapter->ahw.pci_func; int pci_func = adapter->ahw.pci_func;
......
...@@ -251,6 +251,7 @@ static void el3_tx_timeout(struct net_device *dev); ...@@ -251,6 +251,7 @@ static void el3_tx_timeout(struct net_device *dev);
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static const struct ethtool_ops netdev_ethtool_ops; static const struct ethtool_ops netdev_ethtool_ops;
static void set_rx_mode(struct net_device *dev); static void set_rx_mode(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static void tc574_detach(struct pcmcia_device *p_dev); static void tc574_detach(struct pcmcia_device *p_dev);
...@@ -266,7 +267,7 @@ static const struct net_device_ops el3_netdev_ops = { ...@@ -266,7 +267,7 @@ static const struct net_device_ops el3_netdev_ops = {
.ndo_tx_timeout = el3_tx_timeout, .ndo_tx_timeout = el3_tx_timeout,
.ndo_get_stats = el3_get_stats, .ndo_get_stats = el3_get_stats,
.ndo_do_ioctl = el3_ioctl, .ndo_do_ioctl = el3_ioctl,
.ndo_set_multicast_list = set_rx_mode, .ndo_set_multicast_list = set_multicast_list,
.ndo_change_mtu = eth_change_mtu, .ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr, .ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
...@@ -1161,6 +1162,16 @@ static void set_rx_mode(struct net_device *dev) ...@@ -1161,6 +1162,16 @@ static void set_rx_mode(struct net_device *dev)
outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
} }
static void set_multicast_list(struct net_device *dev)
{
struct el3_private *lp = netdev_priv(dev);
unsigned long flags;
spin_lock_irqsave(&lp->window_lock, flags);
set_rx_mode(dev);
spin_unlock_irqrestore(&lp->window_lock, flags);
}
static int el3_close(struct net_device *dev) static int el3_close(struct net_device *dev)
{ {
unsigned int ioaddr = dev->base_addr; unsigned int ioaddr = dev->base_addr;
......
此差异已折叠。
...@@ -62,8 +62,11 @@ static char *devid=NULL; ...@@ -62,8 +62,11 @@ static char *devid=NULL;
static struct usb_eth_dev usb_dev_id[] = { static struct usb_eth_dev usb_dev_id[] = {
#define PEGASUS_DEV(pn, vid, pid, flags) \ #define PEGASUS_DEV(pn, vid, pid, flags) \
{.name = pn, .vendor = vid, .device = pid, .private = flags}, {.name = pn, .vendor = vid, .device = pid, .private = flags},
#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
PEGASUS_DEV(pn, vid, pid, flags)
#include "pegasus.h" #include "pegasus.h"
#undef PEGASUS_DEV #undef PEGASUS_DEV
#undef PEGASUS_DEV_CLASS
{NULL, 0, 0, 0}, {NULL, 0, 0, 0},
{NULL, 0, 0, 0} {NULL, 0, 0, 0}
}; };
...@@ -71,8 +74,18 @@ static struct usb_eth_dev usb_dev_id[] = { ...@@ -71,8 +74,18 @@ static struct usb_eth_dev usb_dev_id[] = {
static struct usb_device_id pegasus_ids[] = { static struct usb_device_id pegasus_ids[] = {
#define PEGASUS_DEV(pn, vid, pid, flags) \ #define PEGASUS_DEV(pn, vid, pid, flags) \
{.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
/*
* The Belkin F8T012xx1 bluetooth adaptor has the same vendor and product
* IDs as the Belkin F5D5050, so we need to teach the pegasus driver to
* ignore adaptors belonging to the "Wireless" class 0xE0. For this one
* case anyway, seeing as the pegasus is for "Wired" adaptors.
*/
#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
{.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS), \
.idVendor = vid, .idProduct = pid, .bDeviceClass = dclass},
#include "pegasus.h" #include "pegasus.h"
#undef PEGASUS_DEV #undef PEGASUS_DEV
#undef PEGASUS_DEV_CLASS
{}, {},
{} {}
}; };
......
...@@ -202,7 +202,11 @@ PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701, ...@@ -202,7 +202,11 @@ PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100, PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, /*
* Distinguish between this Belkin adaptor and the Belkin bluetooth adaptors
* with the same product IDs by checking the device class too.
*/
PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
DEFAULT_GPIO_RESET | PEGASUS_II ) DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
DEFAULT_GPIO_RESET ) DEFAULT_GPIO_RESET )
......
################################################################################
#
# Linux driver for VMware's vmxnet3 ethernet NIC.
#
# Copyright (C) 2007-2009, VMware, Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License and no later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
# NON INFRINGEMENT. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
#
# Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
#
#
################################################################################
#
# Makefile for the VMware vmxnet3 ethernet NIC driver
#
obj-$(CONFIG_VMXNET3) += vmxnet3.o
vmxnet3-objs := vmxnet3_drv.o vmxnet3_ethtool.o
/*
* Linux driver for VMware's vmxnet3 ethernet NIC.
*
* Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2 of the License and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
* Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
*
*/
#ifndef _UPT1_DEFS_H
#define _UPT1_DEFS_H
struct UPT1_TxStats {
u64 TSOPktsTxOK; /* TSO pkts post-segmentation */
u64 TSOBytesTxOK;
u64 ucastPktsTxOK;
u64 ucastBytesTxOK;
u64 mcastPktsTxOK;
u64 mcastBytesTxOK;
u64 bcastPktsTxOK;
u64 bcastBytesTxOK;
u64 pktsTxError;
u64 pktsTxDiscard;
};
struct UPT1_RxStats {
u64 LROPktsRxOK; /* LRO pkts */
u64 LROBytesRxOK; /* bytes from LRO pkts */
/* the following counters are for pkts from the wire, i.e., pre-LRO */
u64 ucastPktsRxOK;
u64 ucastBytesRxOK;
u64 mcastPktsRxOK;
u64 mcastBytesRxOK;
u64 bcastPktsRxOK;
u64 bcastBytesRxOK;
u64 pktsRxOutOfBuf;
u64 pktsRxError;
};
/* interrupt moderation level */
enum {
UPT1_IML_NONE = 0, /* no interrupt moderation */
UPT1_IML_HIGHEST = 7, /* least intr generated */
UPT1_IML_ADAPTIVE = 8, /* adpative intr moderation */
};
/* values for UPT1_RSSConf.hashFunc */
enum {
UPT1_RSS_HASH_TYPE_NONE = 0x0,
UPT1_RSS_HASH_TYPE_IPV4 = 0x01,
UPT1_RSS_HASH_TYPE_TCP_IPV4 = 0x02,
UPT1_RSS_HASH_TYPE_IPV6 = 0x04,
UPT1_RSS_HASH_TYPE_TCP_IPV6 = 0x08,
};
enum {
UPT1_RSS_HASH_FUNC_NONE = 0x0,
UPT1_RSS_HASH_FUNC_TOEPLITZ = 0x01,
};
#define UPT1_RSS_MAX_KEY_SIZE 40
#define UPT1_RSS_MAX_IND_TABLE_SIZE 128
struct UPT1_RSSConf {
u16 hashType;
u16 hashFunc;
u16 hashKeySize;
u16 indTableSize;
u8 hashKey[UPT1_RSS_MAX_KEY_SIZE];
u8 indTable[UPT1_RSS_MAX_IND_TABLE_SIZE];
};
/* features */
enum {
UPT1_F_RXCSUM = 0x0001, /* rx csum verification */
UPT1_F_RSS = 0x0002,
UPT1_F_RXVLAN = 0x0004, /* VLAN tag stripping */
UPT1_F_LRO = 0x0008,
};
#endif
/*
* Linux driver for VMware's vmxnet3 ethernet NIC.
*
* Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2 of the License and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
* Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
*
*/
#ifndef _VMXNET3_DEFS_H_
#define _VMXNET3_DEFS_H_
#include "upt1_defs.h"
/* all registers are 32 bit wide */
/* BAR 1 */
enum {
VMXNET3_REG_VRRS = 0x0, /* Vmxnet3 Revision Report Selection */
VMXNET3_REG_UVRS = 0x8, /* UPT Version Report Selection */
VMXNET3_REG_DSAL = 0x10, /* Driver Shared Address Low */
VMXNET3_REG_DSAH = 0x18, /* Driver Shared Address High */
VMXNET3_REG_CMD = 0x20, /* Command */
VMXNET3_REG_MACL = 0x28, /* MAC Address Low */
VMXNET3_REG_MACH = 0x30, /* MAC Address High */
VMXNET3_REG_ICR = 0x38, /* Interrupt Cause Register */
VMXNET3_REG_ECR = 0x40 /* Event Cause Register */
};
/* BAR 0 */
enum {
VMXNET3_REG_IMR = 0x0, /* Interrupt Mask Register */
VMXNET3_REG_TXPROD = 0x600, /* Tx Producer Index */
VMXNET3_REG_RXPROD = 0x800, /* Rx Producer Index for ring 1 */
VMXNET3_REG_RXPROD2 = 0xA00 /* Rx Producer Index for ring 2 */
};
#define VMXNET3_PT_REG_SIZE 4096 /* BAR 0 */
#define VMXNET3_VD_REG_SIZE 4096 /* BAR 1 */
#define VMXNET3_REG_ALIGN 8 /* All registers are 8-byte aligned. */
#define VMXNET3_REG_ALIGN_MASK 0x7
/* I/O Mapped access to registers */
#define VMXNET3_IO_TYPE_PT 0
#define VMXNET3_IO_TYPE_VD 1
#define VMXNET3_IO_ADDR(type, reg) (((type) << 24) | ((reg) & 0xFFFFFF))
#define VMXNET3_IO_TYPE(addr) ((addr) >> 24)
#define VMXNET3_IO_REG(addr) ((addr) & 0xFFFFFF)
enum {
VMXNET3_CMD_FIRST_SET = 0xCAFE0000,
VMXNET3_CMD_ACTIVATE_DEV = VMXNET3_CMD_FIRST_SET,
VMXNET3_CMD_QUIESCE_DEV,
VMXNET3_CMD_RESET_DEV,
VMXNET3_CMD_UPDATE_RX_MODE,
VMXNET3_CMD_UPDATE_MAC_FILTERS,
VMXNET3_CMD_UPDATE_VLAN_FILTERS,
VMXNET3_CMD_UPDATE_RSSIDT,
VMXNET3_CMD_UPDATE_IML,
VMXNET3_CMD_UPDATE_PMCFG,
VMXNET3_CMD_UPDATE_FEATURE,
VMXNET3_CMD_LOAD_PLUGIN,
VMXNET3_CMD_FIRST_GET = 0xF00D0000,
VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
VMXNET3_CMD_GET_STATS,
VMXNET3_CMD_GET_LINK,
VMXNET3_CMD_GET_PERM_MAC_LO,
VMXNET3_CMD_GET_PERM_MAC_HI,
VMXNET3_CMD_GET_DID_LO,
VMXNET3_CMD_GET_DID_HI,
VMXNET3_CMD_GET_DEV_EXTRA_INFO,
VMXNET3_CMD_GET_CONF_INTR
};
struct Vmxnet3_TxDesc {
u64 addr;
u32 len:14;
u32 gen:1; /* generation bit */
u32 rsvd:1;
u32 dtype:1; /* descriptor type */
u32 ext1:1;
u32 msscof:14; /* MSS, checksum offset, flags */
u32 hlen:10; /* header len */
u32 om:2; /* offload mode */
u32 eop:1; /* End Of Packet */
u32 cq:1; /* completion request */
u32 ext2:1;
u32 ti:1; /* VLAN Tag Insertion */
u32 tci:16; /* Tag to Insert */
};
/* TxDesc.OM values */
#define VMXNET3_OM_NONE 0
#define VMXNET3_OM_CSUM 2
#define VMXNET3_OM_TSO 3
/* fields in TxDesc we access w/o using bit fields */
#define VMXNET3_TXD_EOP_SHIFT 12
#define VMXNET3_TXD_CQ_SHIFT 13
#define VMXNET3_TXD_GEN_SHIFT 14
#define VMXNET3_TXD_CQ (1 << VMXNET3_TXD_CQ_SHIFT)
#define VMXNET3_TXD_EOP (1 << VMXNET3_TXD_EOP_SHIFT)
#define VMXNET3_TXD_GEN (1 << VMXNET3_TXD_GEN_SHIFT)
#define VMXNET3_HDR_COPY_SIZE 128
struct Vmxnet3_TxDataDesc {
u8 data[VMXNET3_HDR_COPY_SIZE];
};
struct Vmxnet3_TxCompDesc {
u32 txdIdx:12; /* Index of the EOP TxDesc */
u32 ext1:20;
u32 ext2;
u32 ext3;
u32 rsvd:24;
u32 type:7; /* completion type */
u32 gen:1; /* generation bit */
};
struct Vmxnet3_RxDesc {
u64 addr;
u32 len:14;
u32 btype:1; /* Buffer Type */
u32 dtype:1; /* Descriptor type */
u32 rsvd:15;
u32 gen:1; /* Generation bit */
u32 ext1;
};
/* values of RXD.BTYPE */
#define VMXNET3_RXD_BTYPE_HEAD 0 /* head only */
#define VMXNET3_RXD_BTYPE_BODY 1 /* body only */
/* fields in RxDesc we access w/o using bit fields */
#define VMXNET3_RXD_BTYPE_SHIFT 14
#define VMXNET3_RXD_GEN_SHIFT 31
struct Vmxnet3_RxCompDesc {
u32 rxdIdx:12; /* Index of the RxDesc */
u32 ext1:2;
u32 eop:1; /* End of Packet */
u32 sop:1; /* Start of Packet */
u32 rqID:10; /* rx queue/ring ID */
u32 rssType:4; /* RSS hash type used */
u32 cnc:1; /* Checksum Not Calculated */
u32 ext2:1;
u32 rssHash; /* RSS hash value */
u32 len:14; /* data length */
u32 err:1; /* Error */
u32 ts:1; /* Tag is stripped */
u32 tci:16; /* Tag stripped */
u32 csum:16;
u32 tuc:1; /* TCP/UDP Checksum Correct */
u32 udp:1; /* UDP packet */
u32 tcp:1; /* TCP packet */
u32 ipc:1; /* IP Checksum Correct */
u32 v6:1; /* IPv6 */
u32 v4:1; /* IPv4 */
u32 frg:1; /* IP Fragment */
u32 fcs:1; /* Frame CRC correct */
u32 type:7; /* completion type */
u32 gen:1; /* generation bit */
};
/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
#define VMXNET3_RCD_TUC_SHIFT 16
#define VMXNET3_RCD_IPC_SHIFT 19
/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.qword[1] */
#define VMXNET3_RCD_TYPE_SHIFT 56
#define VMXNET3_RCD_GEN_SHIFT 63
/* csum OK for TCP/UDP pkts over IP */
#define VMXNET3_RCD_CSUM_OK (1 << VMXNET3_RCD_TUC_SHIFT | \
1 << VMXNET3_RCD_IPC_SHIFT)
/* value of RxCompDesc.rssType */
enum {
VMXNET3_RCD_RSS_TYPE_NONE = 0,
VMXNET3_RCD_RSS_TYPE_IPV4 = 1,
VMXNET3_RCD_RSS_TYPE_TCPIPV4 = 2,
VMXNET3_RCD_RSS_TYPE_IPV6 = 3,
VMXNET3_RCD_RSS_TYPE_TCPIPV6 = 4,
};
/* a union for accessing all cmd/completion descriptors */
union Vmxnet3_GenericDesc {
u64 qword[2];
u32 dword[4];
u16 word[8];
struct Vmxnet3_TxDesc txd;
struct Vmxnet3_RxDesc rxd;
struct Vmxnet3_TxCompDesc tcd;
struct Vmxnet3_RxCompDesc rcd;
};
#define VMXNET3_INIT_GEN 1
/* Max size of a single tx buffer */
#define VMXNET3_MAX_TX_BUF_SIZE (1 << 14)
/* # of tx desc needed for a tx buffer size */
#define VMXNET3_TXD_NEEDED(size) (((size) + VMXNET3_MAX_TX_BUF_SIZE - 1) / \
VMXNET3_MAX_TX_BUF_SIZE)
/* max # of tx descs for a non-tso pkt */
#define VMXNET3_MAX_TXD_PER_PKT 16
/* Max size of a single rx buffer */
#define VMXNET3_MAX_RX_BUF_SIZE ((1 << 14) - 1)
/* Minimum size of a type 0 buffer */
#define VMXNET3_MIN_T0_BUF_SIZE 128
#define VMXNET3_MAX_CSUM_OFFSET 1024
/* Ring base address alignment */
#define VMXNET3_RING_BA_ALIGN 512
#define VMXNET3_RING_BA_MASK (VMXNET3_RING_BA_ALIGN - 1)
/* Ring size must be a multiple of 32 */
#define VMXNET3_RING_SIZE_ALIGN 32
#define VMXNET3_RING_SIZE_MASK (VMXNET3_RING_SIZE_ALIGN - 1)
/* Max ring size */
#define VMXNET3_TX_RING_MAX_SIZE 4096
#define VMXNET3_TC_RING_MAX_SIZE 4096
#define VMXNET3_RX_RING_MAX_SIZE 4096
#define VMXNET3_RC_RING_MAX_SIZE 8192
/* a list of reasons for queue stop */
enum {
VMXNET3_ERR_NOEOP = 0x80000000, /* cannot find the EOP desc of a pkt */
VMXNET3_ERR_TXD_REUSE = 0x80000001, /* reuse TxDesc before tx completion */
VMXNET3_ERR_BIG_PKT = 0x80000002, /* too many TxDesc for a pkt */
VMXNET3_ERR_DESC_NOT_SPT = 0x80000003, /* descriptor type not supported */
VMXNET3_ERR_SMALL_BUF = 0x80000004, /* type 0 buffer too small */
VMXNET3_ERR_STRESS = 0x80000005, /* stress option firing in vmkernel */
VMXNET3_ERR_SWITCH = 0x80000006, /* mode switch failure */
VMXNET3_ERR_TXD_INVALID = 0x80000007, /* invalid TxDesc */
};
/* completion descriptor types */
#define VMXNET3_CDTYPE_TXCOMP 0 /* Tx Completion Descriptor */
#define VMXNET3_CDTYPE_RXCOMP 3 /* Rx Completion Descriptor */
enum {
VMXNET3_GOS_BITS_UNK = 0, /* unknown */
VMXNET3_GOS_BITS_32 = 1,
VMXNET3_GOS_BITS_64 = 2,
};
#define VMXNET3_GOS_TYPE_LINUX 1
struct Vmxnet3_GOSInfo {
u32 gosBits:2; /* 32-bit or 64-bit? */
u32 gosType:4; /* which guest */
u32 gosVer:16; /* gos version */
u32 gosMisc:10; /* other info about gos */
};
struct Vmxnet3_DriverInfo {
u32 version;
struct Vmxnet3_GOSInfo gos;
u32 vmxnet3RevSpt;
u32 uptVerSpt;
};
#define VMXNET3_REV1_MAGIC 0xbabefee1
/*
* QueueDescPA must be 128 bytes aligned. It points to an array of
* Vmxnet3_TxQueueDesc followed by an array of Vmxnet3_RxQueueDesc.
* The number of Vmxnet3_TxQueueDesc/Vmxnet3_RxQueueDesc are specified by
* Vmxnet3_MiscConf.numTxQueues/numRxQueues, respectively.
*/
#define VMXNET3_QUEUE_DESC_ALIGN 128
struct Vmxnet3_MiscConf {
struct Vmxnet3_DriverInfo driverInfo;
u64 uptFeatures;
u64 ddPA; /* driver data PA */
u64 queueDescPA; /* queue descriptor table PA */
u32 ddLen; /* driver data len */
u32 queueDescLen; /* queue desc. table len in bytes */
u32 mtu;
u16 maxNumRxSG;
u8 numTxQueues;
u8 numRxQueues;
u32 reserved[4];
};
struct Vmxnet3_TxQueueConf {
u64 txRingBasePA;
u64 dataRingBasePA;
u64 compRingBasePA;
u64 ddPA; /* driver data */
u64 reserved;
u32 txRingSize; /* # of tx desc */
u32 dataRingSize; /* # of data desc */
u32 compRingSize; /* # of comp desc */
u32 ddLen; /* size of driver data */
u8 intrIdx;
u8 _pad[7];
};
struct Vmxnet3_RxQueueConf {
u64 rxRingBasePA[2];
u64 compRingBasePA;
u64 ddPA; /* driver data */
u64 reserved;
u32 rxRingSize[2]; /* # of rx desc */
u32 compRingSize; /* # of rx comp desc */
u32 ddLen; /* size of driver data */
u8 intrIdx;
u8 _pad[7];
};
enum vmxnet3_intr_mask_mode {
VMXNET3_IMM_AUTO = 0,
VMXNET3_IMM_ACTIVE = 1,
VMXNET3_IMM_LAZY = 2
};
enum vmxnet3_intr_type {
VMXNET3_IT_AUTO = 0,
VMXNET3_IT_INTX = 1,
VMXNET3_IT_MSI = 2,
VMXNET3_IT_MSIX = 3
};
#define VMXNET3_MAX_TX_QUEUES 8
#define VMXNET3_MAX_RX_QUEUES 16
/* addition 1 for events */
#define VMXNET3_MAX_INTRS 25
struct Vmxnet3_IntrConf {
bool autoMask;
u8 numIntrs; /* # of interrupts */
u8 eventIntrIdx;
u8 modLevels[VMXNET3_MAX_INTRS]; /* moderation level for
* each intr */
u32 reserved[3];
};
/* one bit per VLAN ID, the size is in the units of u32 */
#define VMXNET3_VFT_SIZE (4096 / (sizeof(u32) * 8))
struct Vmxnet3_QueueStatus {
bool stopped;
u8 _pad[3];
u32 error;
};
struct Vmxnet3_TxQueueCtrl {
u32 txNumDeferred;
u32 txThreshold;
u64 reserved;
};
struct Vmxnet3_RxQueueCtrl {
bool updateRxProd;
u8 _pad[7];
u64 reserved;
};
enum {
VMXNET3_RXM_UCAST = 0x01, /* unicast only */
VMXNET3_RXM_MCAST = 0x02, /* multicast passing the filters */
VMXNET3_RXM_BCAST = 0x04, /* broadcast only */
VMXNET3_RXM_ALL_MULTI = 0x08, /* all multicast */
VMXNET3_RXM_PROMISC = 0x10 /* promiscuous */
};
struct Vmxnet3_RxFilterConf {
u32 rxMode; /* VMXNET3_RXM_xxx */
u16 mfTableLen; /* size of the multicast filter table */
u16 _pad1;
u64 mfTablePA; /* PA of the multicast filters table */
u32 vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */
};
#define VMXNET3_PM_MAX_FILTERS 6
#define VMXNET3_PM_MAX_PATTERN_SIZE 128
#define VMXNET3_PM_MAX_MASK_SIZE (VMXNET3_PM_MAX_PATTERN_SIZE / 8)
#define VMXNET3_PM_WAKEUP_MAGIC 0x01 /* wake up on magic pkts */
#define VMXNET3_PM_WAKEUP_FILTER 0x02 /* wake up on pkts matching
* filters */
struct Vmxnet3_PM_PktFilter {
u8 maskSize;
u8 patternSize;
u8 mask[VMXNET3_PM_MAX_MASK_SIZE];
u8 pattern[VMXNET3_PM_MAX_PATTERN_SIZE];
u8 pad[6];
};
struct Vmxnet3_PMConf {
u16 wakeUpEvents; /* VMXNET3_PM_WAKEUP_xxx */
u8 numFilters;
u8 pad[5];
struct Vmxnet3_PM_PktFilter filters[VMXNET3_PM_MAX_FILTERS];
};
struct Vmxnet3_VariableLenConfDesc {
u32 confVer;
u32 confLen;
u64 confPA;
};
struct Vmxnet3_TxQueueDesc {
struct Vmxnet3_TxQueueCtrl ctrl;
struct Vmxnet3_TxQueueConf conf;
/* Driver read after a GET command */
struct Vmxnet3_QueueStatus status;
struct UPT1_TxStats stats;
u8 _pad[88]; /* 128 aligned */
};
struct Vmxnet3_RxQueueDesc {
struct Vmxnet3_RxQueueCtrl ctrl;
struct Vmxnet3_RxQueueConf conf;
/* Driver read after a GET commad */
struct Vmxnet3_QueueStatus status;
struct UPT1_RxStats stats;
u8 __pad[88]; /* 128 aligned */
};
struct Vmxnet3_DSDevRead {
/* read-only region for device, read by dev in response to a SET cmd */
struct Vmxnet3_MiscConf misc;
struct Vmxnet3_IntrConf intrConf;
struct Vmxnet3_RxFilterConf rxFilterConf;
struct Vmxnet3_VariableLenConfDesc rssConfDesc;
struct Vmxnet3_VariableLenConfDesc pmConfDesc;
struct Vmxnet3_VariableLenConfDesc pluginConfDesc;
};
/* All structures in DriverShared are padded to multiples of 8 bytes */
struct Vmxnet3_DriverShared {
u32 magic;
/* make devRead start at 64bit boundaries */
u32 pad;
struct Vmxnet3_DSDevRead devRead;
u32 ecr;
u32 reserved[5];
};
#define VMXNET3_ECR_RQERR (1 << 0)
#define VMXNET3_ECR_TQERR (1 << 1)
#define VMXNET3_ECR_LINK (1 << 2)
#define VMXNET3_ECR_DIC (1 << 3)
#define VMXNET3_ECR_DEBUG (1 << 4)
/* flip the gen bit of a ring */
#define VMXNET3_FLIP_RING_GEN(gen) ((gen) = (gen) ^ 0x1)
/* only use this if moving the idx won't affect the gen bit */
#define VMXNET3_INC_RING_IDX_ONLY(idx, ring_size) \
do {\
(idx)++;\
if (unlikely((idx) == (ring_size))) {\
(idx) = 0;\
} \
} while (0)
#define VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid) \
(vfTable[vid >> 5] |= (1 << (vid & 31)))
#define VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid) \
(vfTable[vid >> 5] &= ~(1 << (vid & 31)))
#define VMXNET3_VFTABLE_ENTRY_IS_SET(vfTable, vid) \
((vfTable[vid >> 5] & (1 << (vid & 31))) != 0)
#define VMXNET3_MAX_MTU 9000
#define VMXNET3_MIN_MTU 60
#define VMXNET3_LINK_UP (10000 << 16 | 1) /* 10 Gbps, up */
#define VMXNET3_LINK_DOWN 0
#endif /* _VMXNET3_DEFS_H_ */
此差异已折叠。
此差异已折叠。
/*
* Linux driver for VMware's vmxnet3 ethernet NIC.
*
* Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; version 2 of the License and no later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
* Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
*
*/
#ifndef _VMXNET3_INT_H
#define _VMXNET3_INT_H
#include <linux/types.h>
#include <linux/ethtool.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/ethtool.h>
#include <linux/compiler.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/ioport.h>
#include <linux/highmem.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/uaccess.h>
#include <asm/dma.h>
#include <asm/page.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/in.h>
#include <linux/etherdevice.h>
#include <asm/checksum.h>
#include <linux/if_vlan.h>
#include <linux/if_arp.h>
#include <linux/inetdevice.h>
#include <linux/dst.h>
#include "vmxnet3_defs.h"
#ifdef DEBUG
# define VMXNET3_DRIVER_VERSION_REPORT VMXNET3_DRIVER_VERSION_STRING"-NAPI(debug)"
#else
# define VMXNET3_DRIVER_VERSION_REPORT VMXNET3_DRIVER_VERSION_STRING"-NAPI"
#endif
/*
* Version numbers
*/
#define VMXNET3_DRIVER_VERSION_STRING "1.0.5.0-k"
/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
#define VMXNET3_DRIVER_VERSION_NUM 0x01000500
/*
* Capabilities
*/
enum {
VMNET_CAP_SG = 0x0001, /* Can do scatter-gather transmits. */
VMNET_CAP_IP4_CSUM = 0x0002, /* Can checksum only TCP/UDP over
* IPv4 */
VMNET_CAP_HW_CSUM = 0x0004, /* Can checksum all packets. */
VMNET_CAP_HIGH_DMA = 0x0008, /* Can DMA to high memory. */
VMNET_CAP_TOE = 0x0010, /* Supports TCP/IP offload. */
VMNET_CAP_TSO = 0x0020, /* Supports TCP Segmentation
* offload */
VMNET_CAP_SW_TSO = 0x0040, /* Supports SW TCP Segmentation */
VMNET_CAP_VMXNET_APROM = 0x0080, /* Vmxnet APROM support */
VMNET_CAP_HW_TX_VLAN = 0x0100, /* Can we do VLAN tagging in HW */
VMNET_CAP_HW_RX_VLAN = 0x0200, /* Can we do VLAN untagging in HW */
VMNET_CAP_SW_VLAN = 0x0400, /* VLAN tagging/untagging in SW */
VMNET_CAP_WAKE_PCKT_RCV = 0x0800, /* Can wake on network packet recv? */
VMNET_CAP_ENABLE_INT_INLINE = 0x1000, /* Enable Interrupt Inline */
VMNET_CAP_ENABLE_HEADER_COPY = 0x2000, /* copy header for vmkernel */
VMNET_CAP_TX_CHAIN = 0x4000, /* Guest can use multiple tx entries
* for a pkt */
VMNET_CAP_RX_CHAIN = 0x8000, /* pkt can span multiple rx entries */
VMNET_CAP_LPD = 0x10000, /* large pkt delivery */
VMNET_CAP_BPF = 0x20000, /* BPF Support in VMXNET Virtual HW*/
VMNET_CAP_SG_SPAN_PAGES = 0x40000, /* Scatter-gather can span multiple*/
/* pages transmits */
VMNET_CAP_IP6_CSUM = 0x80000, /* Can do IPv6 csum offload. */
VMNET_CAP_TSO6 = 0x100000, /* TSO seg. offload for IPv6 pkts. */
VMNET_CAP_TSO256k = 0x200000, /* Can do TSO seg offload for */
/* pkts up to 256kB. */
VMNET_CAP_UPT = 0x400000 /* Support UPT */
};
/*
* PCI vendor and device IDs.
*/
#define PCI_VENDOR_ID_VMWARE 0x15AD
#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
#define MAX_ETHERNET_CARDS 10
#define MAX_PCI_PASSTHRU_DEVICE 6
struct vmxnet3_cmd_ring {
union Vmxnet3_GenericDesc *base;
u32 size;
u32 next2fill;
u32 next2comp;
u8 gen;
dma_addr_t basePA;
};
static inline void
vmxnet3_cmd_ring_adv_next2fill(struct vmxnet3_cmd_ring *ring)
{
ring->next2fill++;
if (unlikely(ring->next2fill == ring->size)) {
ring->next2fill = 0;
VMXNET3_FLIP_RING_GEN(ring->gen);
}
}
static inline void
vmxnet3_cmd_ring_adv_next2comp(struct vmxnet3_cmd_ring *ring)
{
VMXNET3_INC_RING_IDX_ONLY(ring->next2comp, ring->size);
}
static inline int
vmxnet3_cmd_ring_desc_avail(struct vmxnet3_cmd_ring *ring)
{
return (ring->next2comp > ring->next2fill ? 0 : ring->size) +
ring->next2comp - ring->next2fill - 1;
}
struct vmxnet3_comp_ring {
union Vmxnet3_GenericDesc *base;
u32 size;
u32 next2proc;
u8 gen;
u8 intr_idx;
dma_addr_t basePA;
};
static inline void
vmxnet3_comp_ring_adv_next2proc(struct vmxnet3_comp_ring *ring)
{
ring->next2proc++;
if (unlikely(ring->next2proc == ring->size)) {
ring->next2proc = 0;
VMXNET3_FLIP_RING_GEN(ring->gen);
}
}
struct vmxnet3_tx_data_ring {
struct Vmxnet3_TxDataDesc *base;
u32 size;
dma_addr_t basePA;
};
enum vmxnet3_buf_map_type {
VMXNET3_MAP_INVALID = 0,
VMXNET3_MAP_NONE,
VMXNET3_MAP_SINGLE,
VMXNET3_MAP_PAGE,
};
struct vmxnet3_tx_buf_info {
u32 map_type;
u16 len;
u16 sop_idx;
dma_addr_t dma_addr;
struct sk_buff *skb;
};
struct vmxnet3_tq_driver_stats {
u64 drop_total; /* # of pkts dropped by the driver, the
* counters below track droppings due to
* different reasons
*/
u64 drop_too_many_frags;
u64 drop_oversized_hdr;
u64 drop_hdr_inspect_err;
u64 drop_tso;
u64 tx_ring_full;
u64 linearized; /* # of pkts linearized */
u64 copy_skb_header; /* # of times we have to copy skb header */
u64 oversized_hdr;
};
struct vmxnet3_tx_ctx {
bool ipv4;
u16 mss;
u32 eth_ip_hdr_size; /* only valid for pkts requesting tso or csum
* offloading
*/
u32 l4_hdr_size; /* only valid if mss != 0 */
u32 copy_size; /* # of bytes copied into the data ring */
union Vmxnet3_GenericDesc *sop_txd;
union Vmxnet3_GenericDesc *eop_txd;
};
struct vmxnet3_tx_queue {
spinlock_t tx_lock;
struct vmxnet3_cmd_ring tx_ring;
struct vmxnet3_tx_buf_info *buf_info;
struct vmxnet3_tx_data_ring data_ring;
struct vmxnet3_comp_ring comp_ring;
struct Vmxnet3_TxQueueCtrl *shared;
struct vmxnet3_tq_driver_stats stats;
bool stopped;
int num_stop; /* # of times the queue is
* stopped */
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
enum vmxnet3_rx_buf_type {
VMXNET3_RX_BUF_NONE = 0,
VMXNET3_RX_BUF_SKB = 1,
VMXNET3_RX_BUF_PAGE = 2
};
struct vmxnet3_rx_buf_info {
enum vmxnet3_rx_buf_type buf_type;
u16 len;
union {
struct sk_buff *skb;
struct page *page;
};
dma_addr_t dma_addr;
};
struct vmxnet3_rx_ctx {
struct sk_buff *skb;
u32 sop_idx;
};
struct vmxnet3_rq_driver_stats {
u64 drop_total;
u64 drop_err;
u64 drop_fcs;
u64 rx_buf_alloc_failure;
};
struct vmxnet3_rx_queue {
struct vmxnet3_cmd_ring rx_ring[2];
struct vmxnet3_comp_ring comp_ring;
struct vmxnet3_rx_ctx rx_ctx;
u32 qid; /* rqID in RCD for buffer from 1st ring */
u32 qid2; /* rqID in RCD for buffer from 2nd ring */
u32 uncommitted[2]; /* # of buffers allocated since last RXPROD
* update */
struct vmxnet3_rx_buf_info *buf_info[2];
struct Vmxnet3_RxQueueCtrl *shared;
struct vmxnet3_rq_driver_stats stats;
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
#define VMXNET3_LINUX_MAX_MSIX_VECT 1
struct vmxnet3_intr {
enum vmxnet3_intr_mask_mode mask_mode;
enum vmxnet3_intr_type type; /* MSI-X, MSI, or INTx? */
u8 num_intrs; /* # of intr vectors */
u8 event_intr_idx; /* idx of the intr vector for event */
u8 mod_levels[VMXNET3_LINUX_MAX_MSIX_VECT]; /* moderation level */
#ifdef CONFIG_PCI_MSI
struct msix_entry msix_entries[VMXNET3_LINUX_MAX_MSIX_VECT];
#endif
};
#define VMXNET3_STATE_BIT_RESETTING 0
#define VMXNET3_STATE_BIT_QUIESCED 1
struct vmxnet3_adapter {
struct vmxnet3_tx_queue tx_queue;
struct vmxnet3_rx_queue rx_queue;
struct napi_struct napi;
struct vlan_group *vlan_grp;
struct vmxnet3_intr intr;
struct Vmxnet3_DriverShared *shared;
struct Vmxnet3_PMConf *pm_conf;
struct Vmxnet3_TxQueueDesc *tqd_start; /* first tx queue desc */
struct Vmxnet3_RxQueueDesc *rqd_start; /* first rx queue desc */
struct net_device *netdev;
struct pci_dev *pdev;
u8 *hw_addr0; /* for BAR 0 */
u8 *hw_addr1; /* for BAR 1 */
/* feature control */
bool rxcsum;
bool lro;
bool jumbo_frame;
/* rx buffer related */
unsigned skb_buf_size;
int rx_buf_per_pkt; /* only apply to the 1st ring */
dma_addr_t shared_pa;
dma_addr_t queue_desc_pa;
/* Wake-on-LAN */
u32 wol;
/* Link speed */
u32 link_speed; /* in mbps */
u64 tx_timeout_count;
struct work_struct work;
unsigned long state; /* VMXNET3_STATE_BIT_xxx */
int dev_number;
};
#define VMXNET3_WRITE_BAR0_REG(adapter, reg, val) \
writel((val), (adapter)->hw_addr0 + (reg))
#define VMXNET3_READ_BAR0_REG(adapter, reg) \
readl((adapter)->hw_addr0 + (reg))
#define VMXNET3_WRITE_BAR1_REG(adapter, reg, val) \
writel((val), (adapter)->hw_addr1 + (reg))
#define VMXNET3_READ_BAR1_REG(adapter, reg) \
readl((adapter)->hw_addr1 + (reg))
#define VMXNET3_WAKE_QUEUE_THRESHOLD(tq) (5)
#define VMXNET3_RX_ALLOC_THRESHOLD(rq, ring_idx, adapter) \
((rq)->rx_ring[ring_idx].size >> 3)
#define VMXNET3_GET_ADDR_LO(dma) ((u32)(dma))
#define VMXNET3_GET_ADDR_HI(dma) ((u32)(((u64)(dma)) >> 32))
/* must be a multiple of VMXNET3_RING_SIZE_ALIGN */
#define VMXNET3_DEF_TX_RING_SIZE 512
#define VMXNET3_DEF_RX_RING_SIZE 256
#define VMXNET3_MAX_ETH_HDR_SIZE 22
#define VMXNET3_MAX_SKB_BUF_SIZE (3*1024)
int
vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter);
int
vmxnet3_activate_dev(struct vmxnet3_adapter *adapter);
void
vmxnet3_force_close(struct vmxnet3_adapter *adapter);
void
vmxnet3_reset_dev(struct vmxnet3_adapter *adapter);
void
vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
struct vmxnet3_adapter *adapter);
void
vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
struct vmxnet3_adapter *adapter);
int
vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size);
extern void vmxnet3_set_ethtool_ops(struct net_device *netdev);
extern struct net_device_stats *vmxnet3_get_stats(struct net_device *netdev);
extern char vmxnet3_driver_name[];
#endif
此差异已折叠。
...@@ -690,7 +690,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -690,7 +690,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
} }
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
local_bh_disable();
ieee80211_rx(dev->wl->hw, skb); ieee80211_rx(dev->wl->hw, skb);
local_bh_enable();
#if B43_DEBUG #if B43_DEBUG
dev->rx_count++; dev->rx_count++;
......
...@@ -3156,8 +3156,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -3156,8 +3156,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
out_pci_disable_device: out_pci_disable_device:
pci_disable_device(pdev); pci_disable_device(pdev);
out_ieee80211_free_hw: out_ieee80211_free_hw:
ieee80211_free_hw(priv->hw);
iwl_free_traffic_mem(priv); iwl_free_traffic_mem(priv);
ieee80211_free_hw(priv->hw);
out: out:
return err; return err;
} }
......
...@@ -4099,8 +4099,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e ...@@ -4099,8 +4099,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev); pci_disable_device(pdev);
out_ieee80211_free_hw: out_ieee80211_free_hw:
ieee80211_free_hw(priv->hw);
iwl_free_traffic_mem(priv); iwl_free_traffic_mem(priv);
ieee80211_free_hw(priv->hw);
out: out:
return err; return err;
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* responses as well as events generated by firmware. * responses as well as events generated by firmware.
*/ */
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/sched.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
......
此差异已折叠。
此差异已折叠。
...@@ -644,6 +644,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, ...@@ -644,6 +644,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
/* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
inet_csk(sk)->icsk_accept_queue.rskq_defer_accept--;
inet_rsk(req)->acked = 1; inet_rsk(req)->acked = 1;
return NULL; return NULL;
} }
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册