Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt
index d0aeead..ab1e8d7 100644
--- a/Documentation/networking/stmmac.txt
+++ b/Documentation/networking/stmmac.txt
@@ -111,11 +111,12 @@
int phy_addr;
int interface;
struct stmmac_mdio_bus_data *mdio_bus_data;
- int pbl;
+ struct stmmac_dma_cfg *dma_cfg;
int clk_csr;
int has_gmac;
int enh_desc;
int tx_coe;
+ int rx_coe;
int bugged_jumbo;
int pmt;
int force_sf_dma_mode;
@@ -136,10 +137,12 @@
o pbl: the Programmable Burst Length is maximum number of beats to
be transferred in one DMA transaction.
GMAC also enables the 4xPBL by default.
- o clk_csr: CSR Clock range selection.
+ o clk_csr: fixed CSR Clock range selection.
o has_gmac: uses the GMAC core.
o enh_desc: if sets the MAC will use the enhanced descriptor structure.
o tx_coe: core is able to perform the tx csum in HW.
+ o rx_coe: the supports three check sum offloading engine types:
+ type_1, type_2 (full csum) and no RX coe.
o bugged_jumbo: some HWs are not able to perform the csum in HW for
over-sized frames due to limited buffer sizes.
Setting this flag the csum will be done in SW on
@@ -160,7 +163,7 @@
o custom_cfg: this is a custom configuration that can be passed while
initialising the resources.
-The we have:
+For MDIO bus The we have:
struct stmmac_mdio_bus_data {
int bus_id;
@@ -177,10 +180,28 @@
o irqs: list of IRQs, one per PHY.
o probed_phy_irq: if irqs is NULL, use this for probed PHY.
+
+For DMA engine we have the following internal fields that should be
+tuned according to the HW capabilities.
+
+struct stmmac_dma_cfg {
+ int pbl;
+ int fixed_burst;
+ int burst_len_supported;
+};
+
+Where:
+ o pbl: Programmable Burst Length
+ o fixed_burst: program the DMA to use the fixed burst mode
+ o burst_len: this is the value we put in the register
+ supported values are provided as macros in
+ linux/stmmac.h header file.
+
+---
+
Below an example how the structures above are using on ST platforms.
static struct plat_stmmacenet_data stxYYY_ethernet_platform_data = {
- .pbl = 32,
.has_gmac = 0,
.enh_desc = 0,
.fix_mac_speed = stxYYY_ethernet_fix_mac_speed,
diff --git a/MAINTAINERS b/MAINTAINERS
index 6d05ae2..f7c39b8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3519,12 +3519,6 @@
S: Maintained
F: drivers/char/hw_random/ixp4xx-rng.c
-INTEL IXP2000 ETHERNET DRIVER
-M: Lennert Buytenhek <kernel@wantstofly.org>
-L: netdev@vger.kernel.org
-S: Maintained
-F: drivers/net/ethernet/xscale/ixp2000/
-
INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf)
M: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
M: Jesse Brandeburg <jesse.brandeburg@intel.com>
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h b/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h
index 292d55e..cf03614 100644
--- a/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h
@@ -75,4 +75,7 @@
#define TX_SNAPSHOT_LOCKED (1<<0)
#define RX_SNAPSHOT_LOCKED (1<<1)
+/* The ptp_ixp46x module will set this variable */
+extern int ixp46x_phc_index;
+
#endif
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 8d3a056..533de95 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -397,9 +397,9 @@
rblkcipher.max_keysize = alg->cra_ablkcipher.max_keysize;
rblkcipher.ivsize = alg->cra_ablkcipher.ivsize;
- NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
- sizeof(struct crypto_report_blkcipher), &rblkcipher);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
+ sizeof(struct crypto_report_blkcipher), &rblkcipher))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -478,9 +478,9 @@
rblkcipher.max_keysize = alg->cra_ablkcipher.max_keysize;
rblkcipher.ivsize = alg->cra_ablkcipher.ivsize;
- NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
- sizeof(struct crypto_report_blkcipher), &rblkcipher);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
+ sizeof(struct crypto_report_blkcipher), &rblkcipher))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/crypto/aead.c b/crypto/aead.c
index e4cb351..0b8121e 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -125,9 +125,9 @@
raead.maxauthsize = aead->maxauthsize;
raead.ivsize = aead->ivsize;
- NLA_PUT(skb, CRYPTOCFGA_REPORT_AEAD,
- sizeof(struct crypto_report_aead), &raead);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_AEAD,
+ sizeof(struct crypto_report_aead), &raead))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -210,9 +210,9 @@
raead.maxauthsize = aead->maxauthsize;
raead.ivsize = aead->ivsize;
- NLA_PUT(skb, CRYPTOCFGA_REPORT_AEAD,
- sizeof(struct crypto_report_aead), &raead);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_AEAD,
+ sizeof(struct crypto_report_aead), &raead))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/crypto/ahash.c b/crypto/ahash.c
index 33bc9b6..3887856 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -409,9 +409,9 @@
rhash.blocksize = alg->cra_blocksize;
rhash.digestsize = __crypto_hash_alg_common(alg)->digestsize;
- NLA_PUT(skb, CRYPTOCFGA_REPORT_HASH,
- sizeof(struct crypto_report_hash), &rhash);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_HASH,
+ sizeof(struct crypto_report_hash), &rhash))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index 4dd80c7..a8d85a1 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -508,9 +508,9 @@
rblkcipher.max_keysize = alg->cra_blkcipher.max_keysize;
rblkcipher.ivsize = alg->cra_blkcipher.ivsize;
- NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
- sizeof(struct crypto_report_blkcipher), &rblkcipher);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
+ sizeof(struct crypto_report_blkcipher), &rblkcipher))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index f1ea0a0..5a37ead 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -81,9 +81,9 @@
rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
rcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
- NLA_PUT(skb, CRYPTOCFGA_REPORT_CIPHER,
- sizeof(struct crypto_report_cipher), &rcipher);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_CIPHER,
+ sizeof(struct crypto_report_cipher), &rcipher))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -96,9 +96,9 @@
snprintf(rcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "compression");
- NLA_PUT(skb, CRYPTOCFGA_REPORT_COMPRESS,
- sizeof(struct crypto_report_comp), &rcomp);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
+ sizeof(struct crypto_report_comp), &rcomp))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -117,16 +117,16 @@
ualg->cru_flags = alg->cra_flags;
ualg->cru_refcnt = atomic_read(&alg->cra_refcnt);
- NLA_PUT_U32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority);
-
+ if (nla_put_u32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority))
+ goto nla_put_failure;
if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
struct crypto_report_larval rl;
snprintf(rl.type, CRYPTO_MAX_ALG_NAME, "%s", "larval");
- NLA_PUT(skb, CRYPTOCFGA_REPORT_LARVAL,
- sizeof(struct crypto_report_larval), &rl);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL,
+ sizeof(struct crypto_report_larval), &rl))
+ goto nla_put_failure;
goto out;
}
diff --git a/crypto/pcompress.c b/crypto/pcompress.c
index 2e458e5..04e083f 100644
--- a/crypto/pcompress.c
+++ b/crypto/pcompress.c
@@ -55,9 +55,9 @@
snprintf(rpcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "pcomp");
- NLA_PUT(skb, CRYPTOCFGA_REPORT_COMPRESS,
- sizeof(struct crypto_report_comp), &rpcomp);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS,
+ sizeof(struct crypto_report_comp), &rpcomp))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/crypto/rng.c b/crypto/rng.c
index 64f864f..f3b7894 100644
--- a/crypto/rng.c
+++ b/crypto/rng.c
@@ -69,9 +69,9 @@
rrng.seedsize = alg->cra_rng.seedsize;
- NLA_PUT(skb, CRYPTOCFGA_REPORT_RNG,
- sizeof(struct crypto_report_rng), &rrng);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_RNG,
+ sizeof(struct crypto_report_rng), &rrng))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/crypto/shash.c b/crypto/shash.c
index 21fc12e..32067f4 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -534,9 +534,9 @@
rhash.blocksize = alg->cra_blocksize;
rhash.digestsize = salg->digestsize;
- NLA_PUT(skb, CRYPTOCFGA_REPORT_HASH,
- sizeof(struct crypto_report_hash), &rhash);
-
+ if (nla_put(skb, CRYPTOCFGA_REPORT_HASH,
+ sizeof(struct crypto_report_hash), &rhash))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 75fd691..7d01c2a 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2182,7 +2182,6 @@
default:
PRINTD (DBG_QOS|DBG_VCC, "Bad AAL!");
return -EINVAL;
- break;
}
// TX traffic parameters
@@ -2357,7 +2356,6 @@
default: {
PRINTD (DBG_QOS, "unsupported TX traffic class");
return -EINVAL;
- break;
}
}
}
@@ -2433,7 +2431,6 @@
default: {
PRINTD (DBG_QOS, "unsupported RX traffic class");
return -EINVAL;
- break;
}
}
}
@@ -2581,7 +2578,6 @@
// break;
default:
return -ENOPROTOOPT;
- break;
};
break;
}
@@ -2601,7 +2597,6 @@
// break;
default:
return -ENOPROTOOPT;
- break;
};
break;
}
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 8af25a0..7233c88 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -30,37 +30,6 @@
#include "hyperv_vmbus.h"
-/* #defines */
-
-
-/* Amount of space to write to */
-#define BYTES_AVAIL_TO_WRITE(r, w, z) \
- ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
-
-
-/*
- *
- * hv_get_ringbuffer_availbytes()
- *
- * Get number of bytes available to read and to write to
- * for the specified ring buffer
- */
-static inline void
-hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
- u32 *read, u32 *write)
-{
- u32 read_loc, write_loc;
-
- smp_read_barrier_depends();
-
- /* Capture the read/write indices before they changed */
- read_loc = rbi->ring_buffer->read_index;
- write_loc = rbi->ring_buffer->write_index;
-
- *write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->ring_datasize);
- *read = rbi->ring_datasize - *write;
-}
-
/*
* hv_get_next_write_location()
*
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index e3e470f..59fbd70 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -42,6 +42,7 @@
#include <linux/inetdevice.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <net/route.h>
#include <net/tcp.h>
#include <net/ipv6.h>
@@ -1826,7 +1827,10 @@
route->path_rec->reversible = 1;
route->path_rec->pkey = cpu_to_be16(0xffff);
route->path_rec->mtu_selector = IB_SA_EQ;
- route->path_rec->sl = id_priv->tos >> 5;
+ route->path_rec->sl = netdev_get_prio_tc_map(
+ ndev->priv_flags & IFF_802_1Q_VLAN ?
+ vlan_dev_real_dev(ndev) : ndev,
+ rt_tos2priority(id_priv->tos));
route->path_rec->mtu = iboe_get_mtu(ndev->mtu);
route->path_rec->rate_selector = IB_SA_EQ;
diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c
index 396e293..e497dfbe 100644
--- a/drivers/infiniband/core/netlink.c
+++ b/drivers/infiniband/core/netlink.c
@@ -125,7 +125,8 @@
unsigned char *prev_tail;
prev_tail = skb_tail_pointer(skb);
- NLA_PUT(skb, type, len, data);
+ if (nla_put(skb, type, len, data))
+ goto nla_put_failure;
nlh->nlmsg_len += skb_tail_pointer(skb) - prev_tail;
return 0;
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index c5fe3a3..f03d7a48 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -687,18 +687,19 @@
if (priv->do_get_state)
priv->do_get_state(dev, &state);
- NLA_PUT_U32(skb, IFLA_CAN_STATE, state);
- NLA_PUT(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm);
- NLA_PUT_U32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms);
- NLA_PUT(skb, IFLA_CAN_BITTIMING,
- sizeof(priv->bittiming), &priv->bittiming);
- NLA_PUT(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock);
- if (priv->do_get_berr_counter && !priv->do_get_berr_counter(dev, &bec))
- NLA_PUT(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec);
- if (priv->bittiming_const)
- NLA_PUT(skb, IFLA_CAN_BITTIMING_CONST,
- sizeof(*priv->bittiming_const), priv->bittiming_const);
-
+ if (nla_put_u32(skb, IFLA_CAN_STATE, state) ||
+ nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) ||
+ nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) ||
+ nla_put(skb, IFLA_CAN_BITTIMING,
+ sizeof(priv->bittiming), &priv->bittiming) ||
+ nla_put(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock) ||
+ (priv->do_get_berr_counter &&
+ !priv->do_get_berr_counter(dev, &bec) &&
+ nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) ||
+ (priv->bittiming_const &&
+ nla_put(skb, IFLA_CAN_BITTIMING_CONST,
+ sizeof(*priv->bittiming_const), priv->bittiming_const)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -714,9 +715,9 @@
{
struct can_priv *priv = netdev_priv(dev);
- NLA_PUT(skb, IFLA_INFO_XSTATS,
- sizeof(priv->can_stats), &priv->can_stats);
-
+ if (nla_put(skb, IFLA_INFO_XSTATS,
+ sizeof(priv->can_stats), &priv->can_stats))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
index 11476ca..203ff9d 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -501,6 +501,7 @@
.get_settings = ax_get_settings,
.set_settings = ax_set_settings,
.get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
};
#ifdef CONFIG_AX88796_93CX6
diff --git a/drivers/net/ethernet/8390/etherh.c b/drivers/net/ethernet/8390/etherh.c
index dbefd56..8322c54 100644
--- a/drivers/net/ethernet/8390/etherh.c
+++ b/drivers/net/ethernet/8390/etherh.c
@@ -635,6 +635,7 @@
.get_settings = etherh_get_settings,
.set_settings = etherh_set_settings,
.get_drvinfo = etherh_get_drvinfo,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static const struct net_device_ops etherh_netdev_ops = {
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index c63a64c..a11af5c 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -174,6 +174,7 @@
source "drivers/net/ethernet/toshiba/Kconfig"
source "drivers/net/ethernet/tundra/Kconfig"
source "drivers/net/ethernet/via/Kconfig"
+source "drivers/net/ethernet/wiznet/Kconfig"
source "drivers/net/ethernet/xilinx/Kconfig"
source "drivers/net/ethernet/xircom/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 9676a51..878ad32 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -73,5 +73,6 @@
obj-$(CONFIG_NET_VENDOR_TOSHIBA) += toshiba/
obj-$(CONFIG_NET_VENDOR_TUNDRA) += tundra/
obj-$(CONFIG_NET_VENDOR_VIA) += via/
+obj-$(CONFIG_NET_VENDOR_WIZNET) += wiznet/
obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
index d896816..d920a52 100644
--- a/drivers/net/ethernet/adaptec/starfire.c
+++ b/drivers/net/ethernet/adaptec/starfire.c
@@ -114,15 +114,6 @@
#define DMA_BURST_SIZE 128
#endif
-/* Used to pass the media type, etc.
- Both 'options[]' and 'full_duplex[]' exist for driver interoperability.
- The media type is usually passed in 'options[]'.
- These variables are deprecated, use ethtool instead. -Ion
-*/
-#define MAX_UNITS 8 /* More are supported, limit only on options */
-static int options[MAX_UNITS] = {0, };
-static int full_duplex[MAX_UNITS] = {0, };
-
/* Operational parameters that are set at compile time. */
/* The "native" ring sizes are either 256 or 2048.
@@ -192,8 +183,6 @@
module_param(rx_copybreak, int, 0);
module_param(intr_latency, int, 0);
module_param(small_frames, int, 0);
-module_param_array(options, int, NULL, 0);
-module_param_array(full_duplex, int, NULL, 0);
module_param(enable_hw_cksum, int, 0);
MODULE_PARM_DESC(max_interrupt_work, "Maximum events handled per interrupt");
MODULE_PARM_DESC(mtu, "MTU (all boards)");
@@ -201,8 +190,6 @@
MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
MODULE_PARM_DESC(intr_latency, "Maximum interrupt latency, in microseconds");
MODULE_PARM_DESC(small_frames, "Maximum size of receive frames that bypass interrupt latency (0,64,128,256,512)");
-MODULE_PARM_DESC(options, "Deprecated: Bits 0-3: media type, bit 17: full duplex");
-MODULE_PARM_DESC(full_duplex, "Deprecated: Forced full-duplex setting (0/1)");
MODULE_PARM_DESC(enable_hw_cksum, "Enable/disable hardware cksum support (0/1)");
/*
@@ -657,10 +644,10 @@
static int __devinit starfire_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
+ struct device *d = &pdev->dev;
struct netdev_private *np;
- int i, irq, option, chip_idx = ent->driver_data;
+ int i, irq, chip_idx = ent->driver_data;
struct net_device *dev;
- static int card_idx = -1;
long ioaddr;
void __iomem *base;
int drv_flags, io_size;
@@ -673,15 +660,13 @@
printk(version);
#endif
- card_idx++;
-
if (pci_enable_device (pdev))
return -EIO;
ioaddr = pci_resource_start(pdev, 0);
io_size = pci_resource_len(pdev, 0);
if (!ioaddr || ((pci_resource_flags(pdev, 0) & IORESOURCE_MEM) == 0)) {
- printk(KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx);
+ dev_err(d, "no PCI MEM resources, aborting\n");
return -ENODEV;
}
@@ -694,14 +679,14 @@
irq = pdev->irq;
if (pci_request_regions (pdev, DRV_NAME)) {
- printk(KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx);
+ dev_err(d, "cannot reserve PCI resources, aborting\n");
goto err_out_free_netdev;
}
base = ioremap(ioaddr, io_size);
if (!base) {
- printk(KERN_ERR DRV_NAME " %d: cannot remap %#x @ %#lx, aborting\n",
- card_idx, io_size, ioaddr);
+ dev_err(d, "cannot remap %#x @ %#lx, aborting\n",
+ io_size, ioaddr);
goto err_out_free_res;
}
@@ -753,9 +738,6 @@
/* wait a little longer */
udelay(1000);
- dev->base_addr = (unsigned long)base;
- dev->irq = irq;
-
np = netdev_priv(dev);
np->dev = dev;
np->base = base;
@@ -772,21 +754,6 @@
drv_flags = netdrv_tbl[chip_idx].drv_flags;
- option = card_idx < MAX_UNITS ? options[card_idx] : 0;
- if (dev->mem_start)
- option = dev->mem_start;
-
- /* The lower four bits are the media type. */
- if (option & 0x200)
- np->mii_if.full_duplex = 1;
-
- if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
- np->mii_if.full_duplex = 1;
-
- if (np->mii_if.full_duplex)
- np->mii_if.force_media = 1;
- else
- np->mii_if.force_media = 0;
np->speed100 = 1;
/* timer resolution is 128 * 0.8us */
@@ -909,13 +876,14 @@
const __be32 *fw_rx_data, *fw_tx_data;
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base;
+ const int irq = np->pci_dev->irq;
int i, retval;
size_t tx_size, rx_size;
size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size;
/* Do we ever need to reset the chip??? */
- retval = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
+ retval = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
if (retval)
return retval;
@@ -924,7 +892,7 @@
writel(1, ioaddr + PCIDeviceConfig);
if (debug > 1)
printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
- dev->name, dev->irq);
+ dev->name, irq);
/* Allocate the various queues. */
if (!np->queue_mem) {
@@ -935,7 +903,7 @@
np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size;
np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma);
if (np->queue_mem == NULL) {
- free_irq(dev->irq, dev);
+ free_irq(irq, dev);
return -ENOMEM;
}
@@ -1962,7 +1930,7 @@
}
}
- free_irq(dev->irq, dev);
+ free_irq(np->pci_dev->irq, dev);
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
index ab4daec..f816426 100644
--- a/drivers/net/ethernet/adi/bfin_mac.c
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -548,6 +548,25 @@
return 0;
}
+static int bfin_mac_ethtool_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_SYS_HARDWARE;
+ info->phc_index = -1;
+ info->tx_types =
+ (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON);
+ info->rx_filters =
+ (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
+ return 0;
+}
+
static const struct ethtool_ops bfin_mac_ethtool_ops = {
.get_settings = bfin_mac_ethtool_getsettings,
.set_settings = bfin_mac_ethtool_setsettings,
@@ -555,6 +574,7 @@
.get_drvinfo = bfin_mac_ethtool_getdrvinfo,
.get_wol = bfin_mac_ethtool_getwol,
.set_wol = bfin_mac_ethtool_setwol,
+ .get_ts_info = bfin_mac_ethtool_get_ts_info,
};
/**************************************************************************/
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 1ef0c927..ef5b85b 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2307,8 +2307,7 @@
"Unable to allocate MSI interrupt Error: %d\n",
err);
adapter->have_msi = false;
- } else
- netdev->irq = pdev->irq;
+ }
if (!adapter->have_msi)
flags |= IRQF_SHARED;
@@ -2616,7 +2615,6 @@
SET_NETDEV_DEV(netdev, &pdev->dev);
pci_set_drvdata(pdev, netdev);
- netdev->irq = pdev->irq;
netdev->netdev_ops = &atl1c_netdev_ops;
netdev->watchdog_timeo = AT_TX_WATCHDOG;
atl1c_set_ethtool_ops(netdev);
@@ -2706,7 +2704,6 @@
dev_err(&pdev->dev, "cannot map device registers\n");
goto err_ioremap;
}
- netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
/* init mii data */
adapter->mii.dev = netdev;
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index 93ff2b2..1220e51 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -1883,27 +1883,24 @@
int err = 0;
adapter->have_msi = true;
- err = pci_enable_msi(adapter->pdev);
+ err = pci_enable_msi(pdev);
if (err) {
- netdev_dbg(adapter->netdev,
+ netdev_dbg(netdev,
"Unable to allocate MSI interrupt Error: %d\n", err);
adapter->have_msi = false;
- } else
- netdev->irq = pdev->irq;
-
+ }
if (!adapter->have_msi)
flags |= IRQF_SHARED;
- err = request_irq(adapter->pdev->irq, atl1e_intr, flags,
- netdev->name, netdev);
+ err = request_irq(pdev->irq, atl1e_intr, flags, netdev->name, netdev);
if (err) {
netdev_dbg(adapter->netdev,
"Unable to allocate interrupt Error: %d\n", err);
if (adapter->have_msi)
- pci_disable_msi(adapter->pdev);
+ pci_disable_msi(pdev);
return err;
}
- netdev_dbg(adapter->netdev, "atl1e_request_irq OK\n");
+ netdev_dbg(netdev, "atl1e_request_irq OK\n");
return err;
}
@@ -2233,7 +2230,6 @@
SET_NETDEV_DEV(netdev, &pdev->dev);
pci_set_drvdata(pdev, netdev);
- netdev->irq = pdev->irq;
netdev->netdev_ops = &atl1e_netdev_ops;
netdev->watchdog_timeo = AT_TX_WATCHDOG;
@@ -2319,7 +2315,6 @@
netdev_err(netdev, "cannot map device registers\n");
goto err_ioremap;
}
- netdev->base_addr = (unsigned long)adapter->hw.hw_addr;
/* init mii data */
adapter->mii.dev = netdev;
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 8297e28..36037a6 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -7976,7 +7976,6 @@
bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
{
struct bnx2 *bp;
- unsigned long mem_len;
int rc, i, j;
u32 reg;
u64 dma_mask, persist_dma_mask;
@@ -8036,13 +8035,8 @@
#endif
INIT_WORK(&bp->reset_task, bnx2_reset_task);
- dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
- mem_len = MB_GET_CID_ADDR(TX_TSS_CID + TX_MAX_TSS_RINGS + 1);
- dev->mem_end = dev->mem_start + mem_len;
- dev->irq = pdev->irq;
-
- bp->regview = ioremap_nocache(dev->base_addr, mem_len);
-
+ bp->regview = pci_iomap(pdev, 0, MB_GET_CID_ADDR(TX_TSS_CID +
+ TX_MAX_TSS_RINGS + 1));
if (!bp->regview) {
dev_err(&pdev->dev, "Cannot map register space, aborting\n");
rc = -ENOMEM;
@@ -8346,10 +8340,8 @@
bp->flags &= ~BNX2_FLAG_AER_ENABLED;
}
- if (bp->regview) {
- iounmap(bp->regview);
- bp->regview = NULL;
- }
+ pci_iounmap(pdev, bp->regview);
+ bp->regview = NULL;
err_out_release:
pci_release_regions(pdev);
@@ -8432,7 +8424,7 @@
bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int version_printed = 0;
- struct net_device *dev = NULL;
+ struct net_device *dev;
struct bnx2 *bp;
int rc;
char str[40];
@@ -8442,15 +8434,12 @@
/* dev zeroed in init_etherdev */
dev = alloc_etherdev_mq(sizeof(*bp), TX_MAX_RINGS);
-
if (!dev)
return -ENOMEM;
rc = bnx2_init_board(pdev, dev);
- if (rc < 0) {
- free_netdev(dev);
- return rc;
- }
+ if (rc < 0)
+ goto err_free;
dev->netdev_ops = &bnx2_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
@@ -8480,22 +8469,21 @@
goto error;
}
- netdev_info(dev, "%s (%c%d) %s found at mem %lx, IRQ %d, node addr %pM\n",
- board_info[ent->driver_data].name,
+ netdev_info(dev, "%s (%c%d) %s found at mem %lx, IRQ %d, "
+ "node addr %pM\n", board_info[ent->driver_data].name,
((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
((CHIP_ID(bp) & 0x0ff0) >> 4),
- bnx2_bus_string(bp, str),
- dev->base_addr,
- bp->pdev->irq, dev->dev_addr);
+ bnx2_bus_string(bp, str), (long)pci_resource_start(pdev, 0),
+ pdev->irq, dev->dev_addr);
return 0;
error:
- if (bp->regview)
- iounmap(bp->regview);
+ iounmap(bp->regview);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
+err_free:
free_netdev(dev);
return rc;
}
@@ -8511,8 +8499,7 @@
del_timer_sync(&bp->timer);
cancel_work_sync(&bp->reset_task);
- if (bp->regview)
- iounmap(bp->regview);
+ pci_iounmap(bp->pdev, bp->regview);
kfree(bp->temp_stats_blk);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 2c9ee55..bfa7888 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -23,13 +23,17 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
-#define DRV_MODULE_VERSION "1.72.10-0"
-#define DRV_MODULE_RELDATE "2012/02/20"
+#define DRV_MODULE_VERSION "1.72.17-0"
+#define DRV_MODULE_RELDATE "2012/04/02"
#define BNX2X_BC_VER 0x040200
#if defined(CONFIG_DCB)
#define BCM_DCBNL
#endif
+
+
+#include "bnx2x_hsi.h"
+
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
#include "../cnic_if.h"
@@ -815,6 +819,8 @@
#define CHIP_NUM_57800_MF 0x16a5
#define CHIP_NUM_57810 0x168e
#define CHIP_NUM_57810_MF 0x16ae
+#define CHIP_NUM_57811 0x163d
+#define CHIP_NUM_57811_MF 0x163e
#define CHIP_NUM_57840 0x168d
#define CHIP_NUM_57840_MF 0x16ab
#define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710)
@@ -826,6 +832,8 @@
#define CHIP_IS_57800_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57800_MF)
#define CHIP_IS_57810(bp) (CHIP_NUM(bp) == CHIP_NUM_57810)
#define CHIP_IS_57810_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57810_MF)
+#define CHIP_IS_57811(bp) (CHIP_NUM(bp) == CHIP_NUM_57811)
+#define CHIP_IS_57811_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57811_MF)
#define CHIP_IS_57840(bp) (CHIP_NUM(bp) == CHIP_NUM_57840)
#define CHIP_IS_57840_MF(bp) (CHIP_NUM(bp) == CHIP_NUM_57840_MF)
#define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \
@@ -836,6 +844,8 @@
CHIP_IS_57800_MF(bp) || \
CHIP_IS_57810(bp) || \
CHIP_IS_57810_MF(bp) || \
+ CHIP_IS_57811(bp) || \
+ CHIP_IS_57811_MF(bp) || \
CHIP_IS_57840(bp) || \
CHIP_IS_57840_MF(bp))
#define CHIP_IS_E1x(bp) (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp)))
@@ -1300,6 +1310,7 @@
#define NO_ISCSI_FLAG (1 << 14)
#define NO_FCOE_FLAG (1 << 15)
#define BC_SUPPORTS_PFC_STATS (1 << 17)
+#define USING_SINGLE_MSIX_FLAG (1 << 20)
#define NO_ISCSI(bp) ((bp)->flags & NO_ISCSI_FLAG)
#define NO_ISCSI_OOO(bp) ((bp)->flags & NO_ISCSI_OOO_FLAG)
@@ -1329,8 +1340,8 @@
struct bnx2x_common common;
struct bnx2x_port port;
- struct cmng_struct_per_port cmng;
- u32 vn_weight_sum;
+ struct cmng_init cmng;
+
u32 mf_config[E1HVN_MAX];
u32 mf2_config[E2_FUNC_MAX];
u32 path_has_ovlan; /* E3 */
@@ -1371,7 +1382,6 @@
#define BNX2X_STATE_DIAG 0xe000
#define BNX2X_STATE_ERROR 0xf000
- int multi_mode;
#define BNX2X_MAX_PRIORITY 8
#define BNX2X_MAX_ENTRIES_PER_PRI 16
#define BNX2X_MAX_COS 3
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 4b05481..5a58cff 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -23,7 +23,6 @@
#include <linux/ip.h>
#include <net/ipv6.h>
#include <net/ip6_checksum.h>
-#include <linux/firmware.h>
#include <linux/prefetch.h>
#include "bnx2x_cmn.h"
#include "bnx2x_init.h"
@@ -1212,16 +1211,15 @@
void bnx2x_free_irq(struct bnx2x *bp)
{
- if (bp->flags & USING_MSIX_FLAG)
+ if (bp->flags & USING_MSIX_FLAG &&
+ !(bp->flags & USING_SINGLE_MSIX_FLAG))
bnx2x_free_msix_irqs(bp, BNX2X_NUM_ETH_QUEUES(bp) +
CNIC_PRESENT + 1);
- else if (bp->flags & USING_MSI_FLAG)
- free_irq(bp->pdev->irq, bp->dev);
else
- free_irq(bp->pdev->irq, bp->dev);
+ free_irq(bp->dev->irq, bp->dev);
}
-int bnx2x_enable_msix(struct bnx2x *bp)
+int __devinit bnx2x_enable_msix(struct bnx2x *bp)
{
int msix_vec = 0, i, rc, req_cnt;
@@ -1261,8 +1259,8 @@
rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], rc);
if (rc) {
- BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
- return rc;
+ BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
+ goto no_msix;
}
/*
* decrease number of queues by number of unallocated entries
@@ -1270,18 +1268,34 @@
bp->num_queues -= diff;
BNX2X_DEV_INFO("New queue configuration set: %d\n",
- bp->num_queues);
- } else if (rc) {
- /* fall to INTx if not enough memory */
- if (rc == -ENOMEM)
- bp->flags |= DISABLE_MSI_FLAG;
+ bp->num_queues);
+ } else if (rc > 0) {
+ /* Get by with single vector */
+ rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], 1);
+ if (rc) {
+ BNX2X_DEV_INFO("Single MSI-X is not attainable rc %d\n",
+ rc);
+ goto no_msix;
+ }
+
+ BNX2X_DEV_INFO("Using single MSI-X vector\n");
+ bp->flags |= USING_SINGLE_MSIX_FLAG;
+
+ } else if (rc < 0) {
BNX2X_DEV_INFO("MSI-X is not attainable rc %d\n", rc);
- return rc;
+ goto no_msix;
}
bp->flags |= USING_MSIX_FLAG;
return 0;
+
+no_msix:
+ /* fall to INTx if not enough memory */
+ if (rc == -ENOMEM)
+ bp->flags |= DISABLE_MSI_FLAG;
+
+ return rc;
}
static int bnx2x_req_msix_irqs(struct bnx2x *bp)
@@ -1343,22 +1357,26 @@
static int bnx2x_req_irq(struct bnx2x *bp)
{
unsigned long flags;
- int rc;
+ unsigned int irq;
- if (bp->flags & USING_MSI_FLAG)
+ if (bp->flags & (USING_MSI_FLAG | USING_MSIX_FLAG))
flags = 0;
else
flags = IRQF_SHARED;
- rc = request_irq(bp->pdev->irq, bnx2x_interrupt, flags,
- bp->dev->name, bp->dev);
- return rc;
+ if (bp->flags & USING_MSIX_FLAG)
+ irq = bp->msix_table[0].vector;
+ else
+ irq = bp->pdev->irq;
+
+ return request_irq(irq, bnx2x_interrupt, flags, bp->dev->name, bp->dev);
}
static inline int bnx2x_setup_irqs(struct bnx2x *bp)
{
int rc = 0;
- if (bp->flags & USING_MSIX_FLAG) {
+ if (bp->flags & USING_MSIX_FLAG &&
+ !(bp->flags & USING_SINGLE_MSIX_FLAG)) {
rc = bnx2x_req_msix_irqs(bp);
if (rc)
return rc;
@@ -1371,8 +1389,13 @@
}
if (bp->flags & USING_MSI_FLAG) {
bp->dev->irq = bp->pdev->irq;
- netdev_info(bp->dev, "using MSI IRQ %d\n",
- bp->pdev->irq);
+ netdev_info(bp->dev, "using MSI IRQ %d\n",
+ bp->dev->irq);
+ }
+ if (bp->flags & USING_MSIX_FLAG) {
+ bp->dev->irq = bp->msix_table[0].vector;
+ netdev_info(bp->dev, "using MSIX IRQ %d\n",
+ bp->dev->irq);
}
}
@@ -1437,20 +1460,11 @@
return __skb_tx_hash(dev, skb, BNX2X_NUM_ETH_QUEUES(bp));
}
+
void bnx2x_set_num_queues(struct bnx2x *bp)
{
- switch (bp->multi_mode) {
- case ETH_RSS_MODE_DISABLED:
- bp->num_queues = 1;
- break;
- case ETH_RSS_MODE_REGULAR:
- bp->num_queues = bnx2x_calc_num_queues(bp);
- break;
-
- default:
- bp->num_queues = 1;
- break;
- }
+ /* RSS queues */
+ bp->num_queues = bnx2x_calc_num_queues(bp);
#ifdef BCM_CNIC
/* override in STORAGE SD mode */
@@ -1549,16 +1563,13 @@
u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0};
u8 num_eth_queues = BNX2X_NUM_ETH_QUEUES(bp);
- /*
- * Prepare the inital contents fo the indirection table if RSS is
+ /* Prepare the initial contents fo the indirection table if RSS is
* enabled
*/
- if (bp->multi_mode != ETH_RSS_MODE_DISABLED) {
- for (i = 0; i < sizeof(ind_table); i++)
- ind_table[i] =
- bp->fp->cl_id +
- ethtool_rxfh_indir_default(i, num_eth_queues);
- }
+ for (i = 0; i < sizeof(ind_table); i++)
+ ind_table[i] =
+ bp->fp->cl_id +
+ ethtool_rxfh_indir_default(i, num_eth_queues);
/*
* For 57710 and 57711 SEARCHER configuration (rss_keys) is
@@ -1568,11 +1579,12 @@
* For 57712 and newer on the other hand it's a per-function
* configuration.
*/
- return bnx2x_config_rss_pf(bp, ind_table,
- bp->port.pmf || !CHIP_IS_E1x(bp));
+ return bnx2x_config_rss_eth(bp, ind_table,
+ bp->port.pmf || !CHIP_IS_E1x(bp));
}
-int bnx2x_config_rss_pf(struct bnx2x *bp, u8 *ind_table, bool config_hash)
+int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
+ u8 *ind_table, bool config_hash)
{
struct bnx2x_config_rss_params params = {NULL};
int i;
@@ -1584,52 +1596,29 @@
* bp->multi_mode = ETH_RSS_MODE_DISABLED;
*/
- params.rss_obj = &bp->rss_conf_obj;
+ params.rss_obj = rss_obj;
__set_bit(RAMROD_COMP_WAIT, ¶ms.ramrod_flags);
- /* RSS mode */
- switch (bp->multi_mode) {
- case ETH_RSS_MODE_DISABLED:
- __set_bit(BNX2X_RSS_MODE_DISABLED, ¶ms.rss_flags);
- break;
- case ETH_RSS_MODE_REGULAR:
- __set_bit(BNX2X_RSS_MODE_REGULAR, ¶ms.rss_flags);
- break;
- case ETH_RSS_MODE_VLAN_PRI:
- __set_bit(BNX2X_RSS_MODE_VLAN_PRI, ¶ms.rss_flags);
- break;
- case ETH_RSS_MODE_E1HOV_PRI:
- __set_bit(BNX2X_RSS_MODE_E1HOV_PRI, ¶ms.rss_flags);
- break;
- case ETH_RSS_MODE_IP_DSCP:
- __set_bit(BNX2X_RSS_MODE_IP_DSCP, ¶ms.rss_flags);
- break;
- default:
- BNX2X_ERR("Unknown multi_mode: %d\n", bp->multi_mode);
- return -EINVAL;
- }
+ __set_bit(BNX2X_RSS_MODE_REGULAR, ¶ms.rss_flags);
- /* If RSS is enabled */
- if (bp->multi_mode != ETH_RSS_MODE_DISABLED) {
- /* RSS configuration */
- __set_bit(BNX2X_RSS_IPV4, ¶ms.rss_flags);
- __set_bit(BNX2X_RSS_IPV4_TCP, ¶ms.rss_flags);
- __set_bit(BNX2X_RSS_IPV6, ¶ms.rss_flags);
- __set_bit(BNX2X_RSS_IPV6_TCP, ¶ms.rss_flags);
+ /* RSS configuration */
+ __set_bit(BNX2X_RSS_IPV4, ¶ms.rss_flags);
+ __set_bit(BNX2X_RSS_IPV4_TCP, ¶ms.rss_flags);
+ __set_bit(BNX2X_RSS_IPV6, ¶ms.rss_flags);
+ __set_bit(BNX2X_RSS_IPV6_TCP, ¶ms.rss_flags);
- /* Hash bits */
- params.rss_result_mask = MULTI_MASK;
+ /* Hash bits */
+ params.rss_result_mask = MULTI_MASK;
- memcpy(params.ind_table, ind_table, sizeof(params.ind_table));
+ memcpy(params.ind_table, ind_table, sizeof(params.ind_table));
- if (config_hash) {
- /* RSS keys */
- for (i = 0; i < sizeof(params.rss_key) / 4; i++)
- params.rss_key[i] = random32();
+ if (config_hash) {
+ /* RSS keys */
+ for (i = 0; i < sizeof(params.rss_key) / 4; i++)
+ params.rss_key[i] = random32();
- __set_bit(BNX2X_RSS_SET_SRCH, ¶ms.rss_flags);
- }
+ __set_bit(BNX2X_RSS_SET_SRCH, ¶ms.rss_flags);
}
return bnx2x_config_rss(bp, ¶ms);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 5c27454..2c3a243 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -86,13 +86,15 @@
void bnx2x_send_unload_done(struct bnx2x *bp);
/**
- * bnx2x_config_rss_pf - configure RSS parameters.
+ * bnx2x_config_rss_pf - configure RSS parameters in a PF.
*
* @bp: driver handle
+ * @rss_obj RSS object to use
* @ind_table: indirection table to configure
* @config_hash: re-configure RSS hash keys configuration
*/
-int bnx2x_config_rss_pf(struct bnx2x *bp, u8 *ind_table, bool config_hash);
+int bnx2x_config_rss_pf(struct bnx2x *bp, struct bnx2x_rss_config_obj *rss_obj,
+ u8 *ind_table, bool config_hash);
/**
* bnx2x__init_func_obj - init function object
@@ -485,7 +487,7 @@
* fills msix_table, requests vectors, updates num_queues
* according to number of available vectors.
*/
-int bnx2x_enable_msix(struct bnx2x *bp);
+int __devinit bnx2x_enable_msix(struct bnx2x *bp);
/**
* bnx2x_enable_msi - request msi mode from OS, updated internals accordingly
@@ -843,7 +845,7 @@
{
if (bp->flags & USING_MSIX_FLAG) {
pci_disable_msix(bp->pdev);
- bp->flags &= ~USING_MSIX_FLAG;
+ bp->flags &= ~(USING_MSIX_FLAG | USING_SINGLE_MSIX_FLAG);
} else if (bp->flags & USING_MSI_FLAG) {
pci_disable_msi(bp->pdev);
bp->flags &= ~USING_MSI_FLAG;
@@ -964,6 +966,19 @@
/************************* Init ******************************************/
+/* returns func by VN for current port */
+static inline int func_by_vn(struct bnx2x *bp, int vn)
+{
+ return 2 * vn + BP_PORT(bp);
+}
+
+static inline int bnx2x_config_rss_eth(struct bnx2x *bp, u8 *ind_table,
+ bool config_hash)
+{
+ return bnx2x_config_rss_pf(bp, &bp->rss_conf_obj, ind_table,
+ config_hash);
+}
+
/**
* bnx2x_func_start - init function
*
@@ -1419,15 +1434,32 @@
}
static inline void storm_memset_cmng(struct bnx2x *bp,
- struct cmng_struct_per_port *cmng,
+ struct cmng_init *cmng,
u8 port)
{
+ int vn;
size_t size = sizeof(struct cmng_struct_per_port);
u32 addr = BAR_XSTRORM_INTMEM +
XSTORM_CMNG_PER_PORT_VARS_OFFSET(port);
- __storm_memset_struct(bp, addr, size, (u32 *)cmng);
+ __storm_memset_struct(bp, addr, size, (u32 *)&cmng->port);
+
+ for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) {
+ int func = func_by_vn(bp, vn);
+
+ addr = BAR_XSTRORM_INTMEM +
+ XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(func);
+ size = sizeof(struct rate_shaping_vars_per_vn);
+ __storm_memset_struct(bp, addr, size,
+ (u32 *)&cmng->vnic.vnic_max_rate[vn]);
+
+ addr = BAR_XSTRORM_INTMEM +
+ XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func);
+ size = sizeof(struct fairness_vars_per_vn);
+ __storm_memset_struct(bp, addr, size,
+ (u32 *)&cmng->vnic.vnic_min_rate[vn]);
+ }
}
/**
@@ -1608,11 +1640,6 @@
*/
void bnx2x_get_iscsi_info(struct bnx2x *bp);
#endif
-/* returns func by VN for current port */
-static inline int func_by_vn(struct bnx2x *bp, int vn)
-{
- return 2 * vn + BP_PORT(bp);
-}
/**
* bnx2x_link_sync_notify - send notification to other functions.
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 2cc0a17..3c7d0cc 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -22,13 +22,10 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/crc32.h>
-
-
#include "bnx2x.h"
#include "bnx2x_cmn.h"
#include "bnx2x_dump.h"
#include "bnx2x_init.h"
-#include "bnx2x_sp.h"
/* Note: in the format strings below %s is replaced by the queue-name which is
* either its index or 'fcoe' for the fcoe queue. Make sure the format string
@@ -2396,10 +2393,7 @@
static u32 bnx2x_get_rxfh_indir_size(struct net_device *dev)
{
- struct bnx2x *bp = netdev_priv(dev);
-
- return (bp->multi_mode == ETH_RSS_MODE_DISABLED ?
- 0 : T_ETH_INDIRECTION_TABLE_SIZE);
+ return T_ETH_INDIRECTION_TABLE_SIZE;
}
static int bnx2x_get_rxfh_indir(struct net_device *dev, u32 *indir)
@@ -2445,7 +2439,7 @@
ind_table[i] = indir[i] + bp->fp->cl_id;
}
- return bnx2x_config_rss_pf(bp, ind_table, false);
+ return bnx2x_config_rss_eth(bp, ind_table, false);
}
static const struct ethtool_ops bnx2x_ethtool_ops = {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index dbff591..799272d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -4448,6 +4448,65 @@
struct cmng_flags_per_port flags;
};
+/*
+ * a single rate shaping counter. can be used as protocol or vnic counter
+ */
+struct rate_shaping_counter {
+ u32 quota;
+#if defined(__BIG_ENDIAN)
+ u16 __reserved0;
+ u16 rate;
+#elif defined(__LITTLE_ENDIAN)
+ u16 rate;
+ u16 __reserved0;
+#endif
+};
+
+/*
+ * per-vnic rate shaping variables
+ */
+struct rate_shaping_vars_per_vn {
+ struct rate_shaping_counter vn_counter;
+};
+
+/*
+ * per-vnic fairness variables
+ */
+struct fairness_vars_per_vn {
+ u32 cos_credit_delta[MAX_COS_NUMBER];
+ u32 vn_credit_delta;
+ u32 __reserved0;
+};
+
+/*
+ * cmng port init state
+ */
+struct cmng_vnic {
+ struct rate_shaping_vars_per_vn vnic_max_rate[4];
+ struct fairness_vars_per_vn vnic_min_rate[4];
+};
+
+/*
+ * cmng port init state
+ */
+struct cmng_init {
+ struct cmng_struct_per_port port;
+ struct cmng_vnic vnic;
+};
+
+
+/*
+ * driver parameters for congestion management init, all rates are in Mbps
+ */
+struct cmng_init_input {
+ u32 port_rate;
+ u16 vnic_min_rate[4];
+ u16 vnic_max_rate[4];
+ u16 cos_min_rate[MAX_COS_NUMBER];
+ u16 cos_to_pause_mask[MAX_COS_NUMBER];
+ struct cmng_flags_per_port flags;
+};
+
/*
* Protocol-common command ID for slow path elements
@@ -4763,16 +4822,6 @@
/*
- * per-vnic fairness variables
- */
-struct fairness_vars_per_vn {
- u32 cos_credit_delta[MAX_COS_NUMBER];
- u32 vn_credit_delta;
- u32 __reserved0;
-};
-
-
-/*
* Priority and cos
*/
struct priority_cos {
@@ -5140,29 +5189,6 @@
/*
- * a single rate shaping counter. can be used as protocol or vnic counter
- */
-struct rate_shaping_counter {
- u32 quota;
-#if defined(__BIG_ENDIAN)
- u16 __reserved0;
- u16 rate;
-#elif defined(__LITTLE_ENDIAN)
- u16 rate;
- u16 __reserved0;
-#endif
-};
-
-
-/*
- * per-vnic rate shaping variables
- */
-struct rate_shaping_vars_per_vn {
- struct rate_shaping_counter vn_counter;
-};
-
-
-/*
* The send queue element
*/
struct slow_path_element {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
index 29f5c3c..2b7a2bd 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
@@ -241,7 +241,8 @@
REG_WR(bp, reg_addr, reg_bit_map | q_bit_map);
/* set/clear queue bit in command-queue bit map
- (E2/E3A0 only, valid COS values are 0/1) */
+ * (E2/E3A0 only, valid COS values are 0/1)
+ */
if (!(INIT_MODE_FLAGS(bp) & MODE_E3_B0)) {
reg_addr = BNX2X_Q_CMDQ_REG_ADDR(pf_q_num);
reg_bit_map = REG_RD(bp, reg_addr);
@@ -277,7 +278,215 @@
}
-/* Returns the index of start or end of a specific block stage in ops array*/
+/* congestion managment port init api description
+ * the api works as follows:
+ * the driver should pass the cmng_init_input struct, the port_init function
+ * will prepare the required internal ram structure which will be passed back
+ * to the driver (cmng_init) that will write it into the internal ram.
+ *
+ * IMPORTANT REMARKS:
+ * 1. the cmng_init struct does not represent the contiguous internal ram
+ * structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET
+ * offset in order to write the port sub struct and the
+ * PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other
+ * words - don't use memcpy!).
+ * 2. although the cmng_init struct is filled for the maximal vnic number
+ * possible, the driver should only write the valid vnics into the internal
+ * ram according to the appropriate port mode.
+ */
+#define BITS_TO_BYTES(x) ((x)/8)
+
+/* CMNG constants, as derived from system spec calculations */
+
+/* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */
+#define DEF_MIN_RATE 100
+
+/* resolution of the rate shaping timer - 400 usec */
+#define RS_PERIODIC_TIMEOUT_USEC 400
+
+/* number of bytes in single QM arbitration cycle -
+ * coefficient for calculating the fairness timer
+ */
+#define QM_ARB_BYTES 160000
+
+/* resolution of Min algorithm 1:100 */
+#define MIN_RES 100
+
+/* how many bytes above threshold for
+ * the minimal credit of Min algorithm
+ */
+#define MIN_ABOVE_THRESH 32768
+
+/* Fairness algorithm integration time coefficient -
+ * for calculating the actual Tfair
+ */
+#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
+
+/* Memory of fairness algorithm - 2 cycles */
+#define FAIR_MEM 2
+#define SAFC_TIMEOUT_USEC 52
+
+#define SDM_TICKS 4
+
+
+static inline void bnx2x_init_max(const struct cmng_init_input *input_data,
+ u32 r_param, struct cmng_init *ram_data)
+{
+ u32 vnic;
+ struct cmng_vnic *vdata = &ram_data->vnic;
+ struct cmng_struct_per_port *pdata = &ram_data->port;
+ /* rate shaping per-port variables
+ * 100 micro seconds in SDM ticks = 25
+ * since each tick is 4 microSeconds
+ */
+
+ pdata->rs_vars.rs_periodic_timeout =
+ RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS;
+
+ /* this is the threshold below which no timer arming will occur.
+ * 1.25 coefficient is for the threshold to be a little bigger
+ * then the real time to compensate for timer in-accuracy
+ */
+ pdata->rs_vars.rs_threshold =
+ (5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4;
+
+ /* rate shaping per-vnic variables */
+ for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
+ /* global vnic counter */
+ vdata->vnic_max_rate[vnic].vn_counter.rate =
+ input_data->vnic_max_rate[vnic];
+ /* maximal Mbps for this vnic
+ * the quota in each timer period - number of bytes
+ * transmitted in this period
+ */
+ vdata->vnic_max_rate[vnic].vn_counter.quota =
+ RS_PERIODIC_TIMEOUT_USEC *
+ (u32)vdata->vnic_max_rate[vnic].vn_counter.rate / 8;
+ }
+
+}
+
+static inline void bnx2x_init_min(const struct cmng_init_input *input_data,
+ u32 r_param, struct cmng_init *ram_data)
+{
+ u32 vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair;
+ struct cmng_vnic *vdata = &ram_data->vnic;
+ struct cmng_struct_per_port *pdata = &ram_data->port;
+
+ /* this is the resolution of the fairness timer */
+ fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
+
+ /* fairness per-port variables
+ * for 10G it is 1000usec. for 1G it is 10000usec.
+ */
+ tFair = T_FAIR_COEF / input_data->port_rate;
+
+ /* this is the threshold below which we won't arm the timer anymore */
+ pdata->fair_vars.fair_threshold = QM_ARB_BYTES;
+
+ /* we multiply by 1e3/8 to get bytes/msec. We don't want the credits
+ * to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution)
+ */
+ pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM;
+
+ /* since each tick is 4 microSeconds */
+ pdata->fair_vars.fairness_timeout =
+ fair_periodic_timeout_usec / SDM_TICKS;
+
+ /* calculate sum of weights */
+ vnicWeightSum = 0;
+
+ for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++)
+ vnicWeightSum += input_data->vnic_min_rate[vnic];
+
+ /* global vnic counter */
+ if (vnicWeightSum > 0) {
+ /* fairness per-vnic variables */
+ for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
+ /* this is the credit for each period of the fairness
+ * algorithm - number of bytes in T_FAIR (this vnic
+ * share of the port rate)
+ */
+ vdata->vnic_min_rate[vnic].vn_credit_delta =
+ (u32)input_data->vnic_min_rate[vnic] * 100 *
+ (T_FAIR_COEF / (8 * 100 * vnicWeightSum));
+ if (vdata->vnic_min_rate[vnic].vn_credit_delta <
+ pdata->fair_vars.fair_threshold +
+ MIN_ABOVE_THRESH) {
+ vdata->vnic_min_rate[vnic].vn_credit_delta =
+ pdata->fair_vars.fair_threshold +
+ MIN_ABOVE_THRESH;
+ }
+ }
+ }
+}
+
+static inline void bnx2x_init_fw_wrr(const struct cmng_init_input *input_data,
+ u32 r_param, struct cmng_init *ram_data)
+{
+ u32 vnic, cos;
+ u32 cosWeightSum = 0;
+ struct cmng_vnic *vdata = &ram_data->vnic;
+ struct cmng_struct_per_port *pdata = &ram_data->port;
+
+ for (cos = 0; cos < MAX_COS_NUMBER; cos++)
+ cosWeightSum += input_data->cos_min_rate[cos];
+
+ if (cosWeightSum > 0) {
+
+ for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
+ /* Since cos and vnic shouldn't work together the rate
+ * to divide between the coses is the port rate.
+ */
+ u32 *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta;
+ for (cos = 0; cos < MAX_COS_NUMBER; cos++) {
+ /* this is the credit for each period of
+ * the fairness algorithm - number of bytes
+ * in T_FAIR (this cos share of the vnic rate)
+ */
+ ccd[cos] =
+ (u32)input_data->cos_min_rate[cos] * 100 *
+ (T_FAIR_COEF / (8 * 100 * cosWeightSum));
+ if (ccd[cos] < pdata->fair_vars.fair_threshold
+ + MIN_ABOVE_THRESH) {
+ ccd[cos] =
+ pdata->fair_vars.fair_threshold +
+ MIN_ABOVE_THRESH;
+ }
+ }
+ }
+ }
+}
+
+static inline void bnx2x_init_safc(const struct cmng_init_input *input_data,
+ struct cmng_init *ram_data)
+{
+ /* in microSeconds */
+ ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC;
+}
+
+/* Congestion management port init */
+static inline void bnx2x_init_cmng(const struct cmng_init_input *input_data,
+ struct cmng_init *ram_data)
+{
+ u32 r_param;
+ memset(ram_data, 0, sizeof(struct cmng_init));
+
+ ram_data->port.flags = input_data->flags;
+
+ /* number of bytes transmitted in a rate of 10Gbps
+ * in one usec = 1.25KB.
+ */
+ r_param = BITS_TO_BYTES(input_data->port_rate);
+ bnx2x_init_max(input_data, r_param, ram_data);
+ bnx2x_init_min(input_data, r_param, ram_data);
+ bnx2x_init_fw_wrr(input_data, r_param, ram_data);
+ bnx2x_init_safc(input_data, ram_data);
+}
+
+
+
+/* Returns the index of start or end of a specific block stage in ops array */
#define BLOCK_OPS_IDX(block, stage, end) \
(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
@@ -499,9 +708,7 @@
bnx2x_set_mcp_parity(bp, false);
}
-/**
- * Clear the parity error status registers.
- */
+/* Clear the parity error status registers. */
static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp)
{
int i;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index ad95324..ff882a4 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -138,7 +138,6 @@
-/* */
#define SFP_EEPROM_CON_TYPE_ADDR 0x2
#define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
#define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
@@ -404,8 +403,7 @@
DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n");
- /*
- * mapping between entry priority to client number (0,1,2 -debug and
+ /* mapping between entry priority to client number (0,1,2 -debug and
* management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
* 3bits client num.
* PRI4 | PRI3 | PRI2 | PRI1 | PRI0
@@ -413,8 +411,7 @@
*/
REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
- /*
- * Bitmap of 5bits length. Each bit specifies whether the entry behaves
+ /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
* as strict. Bits 0,1,2 - debug and management entries, 3 -
* COS0 entry, 4 - COS1 entry.
* COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
@@ -425,13 +422,11 @@
REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
/* defines which entries (clients) are subjected to WFQ arbitration */
REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
- /*
- * For strict priority entries defines the number of consecutive
+ /* For strict priority entries defines the number of consecutive
* slots for the highest priority.
*/
REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
- /*
- * mapping between the CREDIT_WEIGHT registers and actual client
+ /* mapping between the CREDIT_WEIGHT registers and actual client
* numbers
*/
REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
@@ -443,8 +438,7 @@
REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
/* ETS mode disable */
REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
- /*
- * If ETS mode is enabled (there is no strict priority) defines a WFQ
+ /* If ETS mode is enabled (there is no strict priority) defines a WFQ
* weight for COS0/COS1.
*/
REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
@@ -471,10 +465,9 @@
min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
} else
min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
- /**
- * If the link isn't up (static configuration for example ) The
- * link will be according to 20GBPS.
- */
+ /* If the link isn't up (static configuration for example ) The
+ * link will be according to 20GBPS.
+ */
return min_w_val;
}
/******************************************************************************
@@ -538,8 +531,7 @@
struct bnx2x *bp = params->bp;
const u8 port = params->port;
const u32 min_w_val = bnx2x_ets_get_min_w_val_nig(vars);
- /**
- * mapping between entry priority to client number (0,1,2 -debug and
+ /* Mapping between entry priority to client number (0,1,2 -debug and
* management clients, 3 - COS0 client, 4 - COS1, ... 8 -
* COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
* reset value or init tool
@@ -551,18 +543,14 @@
REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
}
- /**
- * For strict priority entries defines the number of consecutive
- * slots for the highest priority.
- */
- /* TODO_ETS - Should be done by reset value or init tool */
+ /* For strict priority entries defines the number of consecutive
+ * slots for the highest priority.
+ */
REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
- /**
- * mapping between the CREDIT_WEIGHT registers and actual client
+ /* Mapping between the CREDIT_WEIGHT registers and actual client
* numbers
*/
- /* TODO_ETS - Should be done by reset value or init tool */
if (port) {
/*Port 1 has 6 COS*/
REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
@@ -574,8 +562,7 @@
REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
}
- /**
- * Bitmap of 5bits length. Each bit specifies whether the entry behaves
+ /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
* as strict. Bits 0,1,2 - debug and management entries, 3 -
* COS0 entry, 4 - COS1 entry.
* COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
@@ -590,13 +577,12 @@
REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
- /**
- * Please notice the register address are note continuous and a
- * for here is note appropriate.In 2 port mode port0 only COS0-5
- * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
- * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
- * are never used for WFQ
- */
+ /* Please notice the register address are note continuous and a
+ * for here is note appropriate.In 2 port mode port0 only COS0-5
+ * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
+ * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
+ * are never used for WFQ
+ */
REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
@@ -633,10 +619,9 @@
u32 base_upper_bound = 0;
u8 max_cos = 0;
u8 i = 0;
- /**
- * In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
- * port mode port1 has COS0-2 that can be used for WFQ.
- */
+ /* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
+ * port mode port1 has COS0-2 that can be used for WFQ.
+ */
if (!port) {
base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
@@ -666,8 +651,7 @@
u32 base_weight = 0;
u8 max_cos = 0;
- /**
- * mapping between entry priority to client number 0 - COS0
+ /* Mapping between entry priority to client number 0 - COS0
* client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
* TODO_ETS - Should be done by reset value or init tool
*/
@@ -695,10 +679,9 @@
REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
- /**
- * In 2 port mode port0 has COS0-5 that can be used for WFQ.
- * In 4 port mode port1 has COS0-2 that can be used for WFQ.
- */
+ /* In 2 port mode port0 has COS0-5 that can be used for WFQ.
+ * In 4 port mode port1 has COS0-2 that can be used for WFQ.
+ */
if (!port) {
base_weight = PBF_REG_COS0_WEIGHT_P0;
max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
@@ -738,7 +721,7 @@
/******************************************************************************
* Description:
* Disable will return basicly the values to init values.
-*.
+*
******************************************************************************/
int bnx2x_ets_disabled(struct link_params *params,
struct link_vars *vars)
@@ -867,7 +850,7 @@
/******************************************************************************
* Description:
* Calculate the total BW.A value of 0 isn't legal.
-*.
+*
******************************************************************************/
static int bnx2x_ets_e3b0_get_total_bw(
const struct link_params *params,
@@ -879,7 +862,6 @@
u8 is_bw_cos_exist = 0;
*total_bw = 0 ;
-
/* Calculate total BW requested */
for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
if (ets_params->cos[cos_idx].state == bnx2x_cos_state_bw) {
@@ -887,10 +869,9 @@
if (!ets_params->cos[cos_idx].params.bw_params.bw) {
DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW"
"was set to 0\n");
- /*
- * This is to prevent a state when ramrods
+ /* This is to prevent a state when ramrods
* can't be sent
- */
+ */
ets_params->cos[cos_idx].params.bw_params.bw
= 1;
}
@@ -908,8 +889,7 @@
}
DP(NETIF_MSG_LINK,
"bnx2x_ets_E3B0_config total BW should be 100\n");
- /*
- * We can handle a case whre the BW isn't 100 this can happen
+ /* We can handle a case whre the BW isn't 100 this can happen
* if the TC are joined.
*/
}
@@ -919,7 +899,7 @@
/******************************************************************************
* Description:
* Invalidate all the sp_pri_to_cos.
-*.
+*
******************************************************************************/
static void bnx2x_ets_e3b0_sp_pri_to_cos_init(u8 *sp_pri_to_cos)
{
@@ -931,7 +911,7 @@
* Description:
* Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
* according to sp_pri_to_cos.
-*.
+*
******************************************************************************/
static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
u8 *sp_pri_to_cos, const u8 pri,
@@ -964,7 +944,7 @@
* Description:
* Returns the correct value according to COS and priority in
* the sp_pri_cli register.
-*.
+*
******************************************************************************/
static u64 bnx2x_e3b0_sp_get_pri_cli_reg(const u8 cos, const u8 cos_offset,
const u8 pri_set,
@@ -981,7 +961,7 @@
* Description:
* Returns the correct value according to COS and priority in the
* sp_pri_cli register for NIG.
-*.
+*
******************************************************************************/
static u64 bnx2x_e3b0_sp_get_pri_cli_reg_nig(const u8 cos, const u8 pri_set)
{
@@ -997,7 +977,7 @@
* Description:
* Returns the correct value according to COS and priority in the
* sp_pri_cli register for PBF.
-*.
+*
******************************************************************************/
static u64 bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos, const u8 pri_set)
{
@@ -1013,7 +993,7 @@
* Description:
* Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
* according to sp_pri_to_cos.(which COS has higher priority)
-*.
+*
******************************************************************************/
static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params,
u8 *sp_pri_to_cos)
@@ -1149,8 +1129,7 @@
return -EINVAL;
}
- /*
- * Upper bound is set according to current link speed (min_w_val
+ /* Upper bound is set according to current link speed (min_w_val
* should be the same for upper bound and COS credit val).
*/
bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
@@ -1160,8 +1139,7 @@
for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) {
cos_bw_bitmap |= (1 << cos_entry);
- /*
- * The function also sets the BW in HW(not the mappin
+ /* The function also sets the BW in HW(not the mappin
* yet)
*/
bnx2x_status = bnx2x_ets_e3b0_set_cos_bw(
@@ -1217,14 +1195,12 @@
/* ETS disabled configuration */
struct bnx2x *bp = params->bp;
DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
- /*
- * defines which entries (clients) are subjected to WFQ arbitration
+ /* Defines which entries (clients) are subjected to WFQ arbitration
* COS0 0x8
* COS1 0x10
*/
REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
- /*
- * mapping between the ARB_CREDIT_WEIGHT registers and actual
+ /* Mapping between the ARB_CREDIT_WEIGHT registers and actual
* client numbers (WEIGHT_0 does not actually have to represent
* client 0)
* PRI4 | PRI3 | PRI2 | PRI1 | PRI0
@@ -1242,8 +1218,7 @@
/* Defines the number of consecutive slots for the strict priority */
REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
- /*
- * Bitmap of 5bits length. Each bit specifies whether the entry behaves
+ /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
* as strict. Bits 0,1,2 - debug and management entries, 3 - COS0
* entry, 4 - COS1 entry.
* COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
@@ -1298,8 +1273,7 @@
u32 val = 0;
DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
- /*
- * Bitmap of 5bits length. Each bit specifies whether the entry behaves
+ /* Bitmap of 5bits length. Each bit specifies whether the entry behaves
* as strict. Bits 0,1,2 - debug and management entries,
* 3 - COS0 entry, 4 - COS1 entry.
* COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
@@ -1307,8 +1281,7 @@
* MCP and debug are strict
*/
REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
- /*
- * For strict priority entries defines the number of consecutive slots
+ /* For strict priority entries defines the number of consecutive slots
* for the highest priority.
*/
REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
@@ -1320,8 +1293,7 @@
/* Defines the number of consecutive slots for the strict priority */
REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
- /*
- * mapping between entry priority to client number (0,1,2 -debug and
+ /* Mapping between entry priority to client number (0,1,2 -debug and
* management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
* 3bits client num.
* PRI4 | PRI3 | PRI2 | PRI1 | PRI0
@@ -1356,15 +1328,12 @@
if (!(params->feature_config_flags &
FEATURE_CONFIG_PFC_ENABLED)) {
- /*
- * RX flow control - Process pause frame in receive direction
+ /* RX flow control - Process pause frame in receive direction
*/
if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
- /*
- * TX flow control - Send pause packet when buffer is full
- */
+ /* TX flow control - Send pause packet when buffer is full */
if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
} else {/* PFC support */
@@ -1457,8 +1426,7 @@
static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port)
{
u32 mode, emac_base;
- /**
- * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
+ /* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
* (a value of 49==0x31) and make sure that the AUTO poll is off
*/
@@ -1578,15 +1546,6 @@
DP(NETIF_MSG_LINK, "enabling UMAC\n");
- /**
- * This register determines on which events the MAC will assert
- * error on the i/f to the NIG along w/ EOP.
- */
-
- /**
- * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK +
- * params->port*0x14, 0xfffff.
- */
/* This register opens the gate for the UMAC despite its name */
REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
@@ -1649,8 +1608,7 @@
val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
- /*
- * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
+ /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
* length used by the MAC receive logic to check frames.
*/
REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
@@ -1666,8 +1624,7 @@
struct bnx2x *bp = params->bp;
u32 is_port4mode = bnx2x_is_4_port_mode(bp);
- /*
- * In 4-port mode, need to set the mode only once, so if XMAC is
+ /* In 4-port mode, need to set the mode only once, so if XMAC is
* already out of reset, it means the mode has already been set,
* and it must not* reset the XMAC again, since it controls both
* ports of the path
@@ -1691,13 +1648,13 @@
if (is_port4mode) {
DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
- /* Set the number of ports on the system side to up to 2 */
+ /* Set the number of ports on the system side to up to 2 */
REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
/* Set the number of ports on the Warp Core to 10G */
REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
} else {
- /* Set the number of ports on the system side to 1 */
+ /* Set the number of ports on the system side to 1 */
REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
if (max_speed == SPEED_10000) {
DP(NETIF_MSG_LINK,
@@ -1729,8 +1686,7 @@
if (REG_RD(bp, MISC_REG_RESET_REG_2) &
MISC_REGISTERS_RESET_REG_2_XMAC) {
- /*
- * Send an indication to change the state in the NIG back to XON
+ /* Send an indication to change the state in the NIG back to XON
* Clearing this bit enables the next set of this bit to get
* rising edge
*/
@@ -1755,13 +1711,11 @@
bnx2x_xmac_init(params, vars->line_speed);
- /*
- * This register determines on which events the MAC will assert
+ /* This register determines on which events the MAC will assert
* error on the i/f to the NIG along w/ EOP.
*/
- /*
- * This register tells the NIG whether to send traffic to UMAC
+ /* This register tells the NIG whether to send traffic to UMAC
* or XMAC
*/
REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
@@ -1863,8 +1817,7 @@
val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
- /*
- * Setting this bit causes MAC control frames (except for pause
+ /* Setting this bit causes MAC control frames (except for pause
* frames) to be passed on for processing. This setting has no
* affect on the operation of the pause frames. This bit effects
* all packets regardless of RX Parser packet sorting logic.
@@ -1963,8 +1916,7 @@
struct link_vars *vars,
u8 is_lb)
{
- /*
- * Set rx control: Strip CRC and enable BigMAC to relay
+ /* Set rx control: Strip CRC and enable BigMAC to relay
* control packets to the system as well
*/
u32 wb_data[2];
@@ -2016,8 +1968,7 @@
REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
- /*
- * Set Time (based unit is 512 bit time) between automatic
+ /* Set Time (based unit is 512 bit time) between automatic
* re-sending of PP packets amd enable automatic re-send of
* Per-Priroity Packet as long as pp_gen is asserted and
* pp_disable is low.
@@ -2086,7 +2037,7 @@
config_val->default_class1.full_xon = 0;
if (CHIP_IS_E2(bp)) {
- /* class0 defaults */
+ /* Class0 defaults */
config_val->default_class0.pause_xoff =
DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR;
config_val->default_class0.pause_xon =
@@ -2095,7 +2046,7 @@
DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR;
config_val->default_class0.full_xon =
DEFAULT0_E2_BRB_MAC_FULL_XON_THR;
- /* pause able*/
+ /* Pause able*/
config_val->pauseable_th.pause_xoff =
PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
config_val->pauseable_th.pause_xon =
@@ -2114,7 +2065,7 @@
config_val->non_pauseable_th.full_xon =
PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
} else if (CHIP_IS_E3A0(bp)) {
- /* class0 defaults */
+ /* Class0 defaults */
config_val->default_class0.pause_xoff =
DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR;
config_val->default_class0.pause_xon =
@@ -2123,7 +2074,7 @@
DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR;
config_val->default_class0.full_xon =
DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR;
- /* pause able */
+ /* Pause able */
config_val->pauseable_th.pause_xoff =
PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
config_val->pauseable_th.pause_xon =
@@ -2142,7 +2093,7 @@
config_val->non_pauseable_th.full_xon =
PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
} else if (CHIP_IS_E3B0(bp)) {
- /* class0 defaults */
+ /* Class0 defaults */
config_val->default_class0.pause_xoff =
DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR;
config_val->default_class0.pause_xon =
@@ -2305,27 +2256,23 @@
reg_th_config = &config_val.non_pauseable_th;
} else
reg_th_config = &config_val.default_class0;
- /*
- * The number of free blocks below which the pause signal to class 0
+ /* The number of free blocks below which the pause signal to class 0
* of MAC #n is asserted. n=0,1
*/
REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
reg_th_config->pause_xoff);
- /*
- * The number of free blocks above which the pause signal to class 0
+ /* The number of free blocks above which the pause signal to class 0
* of MAC #n is de-asserted. n=0,1
*/
REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
- /*
- * The number of free blocks below which the full signal to class 0
+ /* The number of free blocks below which the full signal to class 0
* of MAC #n is asserted. n=0,1
*/
REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
- /*
- * The number of free blocks above which the full signal to class 0
+ /* The number of free blocks above which the full signal to class 0
* of MAC #n is de-asserted. n=0,1
*/
REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
@@ -2339,30 +2286,26 @@
reg_th_config = &config_val.non_pauseable_th;
} else
reg_th_config = &config_val.default_class1;
- /*
- * The number of free blocks below which the pause signal to
+ /* The number of free blocks below which the pause signal to
* class 1 of MAC #n is asserted. n=0,1
*/
REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
reg_th_config->pause_xoff);
- /*
- * The number of free blocks above which the pause signal to
+ /* The number of free blocks above which the pause signal to
* class 1 of MAC #n is de-asserted. n=0,1
*/
REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
reg_th_config->pause_xon);
- /*
- * The number of free blocks below which the full signal to
+ /* The number of free blocks below which the full signal to
* class 1 of MAC #n is asserted. n=0,1
*/
REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
reg_th_config->full_xoff);
- /*
- * The number of free blocks above which the full signal to
+ /* The number of free blocks above which the full signal to
* class 1 of MAC #n is de-asserted. n=0,1
*/
REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
@@ -2379,49 +2322,41 @@
REG_WR(bp, BRB1_REG_PER_CLASS_GUARANTY_MODE,
e3b0_val.per_class_guaranty_mode);
- /*
- * The hysteresis on the guarantied buffer space for the Lb
+ /* The hysteresis on the guarantied buffer space for the Lb
* port before signaling XON.
*/
REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST,
e3b0_val.lb_guarantied_hyst);
- /*
- * The number of free blocks below which the full signal to the
+ /* The number of free blocks below which the full signal to the
* LB port is asserted.
*/
REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
e3b0_val.full_lb_xoff_th);
- /*
- * The number of free blocks above which the full signal to the
+ /* The number of free blocks above which the full signal to the
* LB port is de-asserted.
*/
REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
e3b0_val.full_lb_xon_threshold);
- /*
- * The number of blocks guarantied for the MAC #n port. n=0,1
+ /* The number of blocks guarantied for the MAC #n port. n=0,1
*/
- /* The number of blocks guarantied for the LB port.*/
+ /* The number of blocks guarantied for the LB port. */
REG_WR(bp, BRB1_REG_LB_GUARANTIED,
e3b0_val.lb_guarantied);
- /*
- * The number of blocks guarantied for the MAC #n port.
- */
+ /* The number of blocks guarantied for the MAC #n port. */
REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
2 * e3b0_val.mac_0_class_t_guarantied);
REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
2 * e3b0_val.mac_1_class_t_guarantied);
- /*
- * The number of blocks guarantied for class #t in MAC0. t=0,1
+ /* The number of blocks guarantied for class #t in MAC0. t=0,1
*/
REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
e3b0_val.mac_0_class_t_guarantied);
REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
e3b0_val.mac_0_class_t_guarantied);
- /*
- * The hysteresis on the guarantied buffer space for class in
+ /* The hysteresis on the guarantied buffer space for class in
* MAC0. t=0,1
*/
REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
@@ -2429,15 +2364,13 @@
REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
e3b0_val.mac_0_class_t_guarantied_hyst);
- /*
- * The number of blocks guarantied for class #t in MAC1.t=0,1
+ /* The number of blocks guarantied for class #t in MAC1.t=0,1
*/
REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
e3b0_val.mac_1_class_t_guarantied);
REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
e3b0_val.mac_1_class_t_guarantied);
- /*
- * The hysteresis on the guarantied buffer space for class #t
+ /* The hysteresis on the guarantied buffer space for class #t
* in MAC1. t=0,1
*/
REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
@@ -2520,15 +2453,13 @@
FEATURE_CONFIG_PFC_ENABLED;
DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
- /*
- * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
+ /* When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
* MAC control frames (that are not pause packets)
* will be forwarded to the XCM.
*/
xcm_mask = REG_RD(bp, port ? NIG_REG_LLH1_XCM_MASK :
NIG_REG_LLH0_XCM_MASK);
- /*
- * nig params will override non PFC params, since it's possible to
+ /* NIG params will override non PFC params, since it's possible to
* do transition from PFC to SAFC
*/
if (set_pfc) {
@@ -2548,7 +2479,7 @@
llfc_out_en = nig_params->llfc_out_en;
llfc_enable = nig_params->llfc_enable;
pause_enable = nig_params->pause_enable;
- } else /*defaul non PFC mode - PAUSE */
+ } else /* Default non PFC mode - PAUSE */
pause_enable = 1;
xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
@@ -2608,8 +2539,7 @@
struct link_vars *vars,
struct bnx2x_nig_brb_pfc_port_params *pfc_params)
{
- /*
- * The PFC and pause are orthogonal to one another, meaning when
+ /* The PFC and pause are orthogonal to one another, meaning when
* PFC is enabled, the pause are disabled, and when PFC is
* disabled, pause are set according to the pause result.
*/
@@ -3148,7 +3078,6 @@
EMAC_MDIO_STATUS_10MB);
/* address */
-
tmp = ((phy->addr << 21) | (devad << 16) | reg |
EMAC_MDIO_COMM_COMMAND_ADDRESS |
EMAC_MDIO_COMM_START_BUSY);
@@ -3337,8 +3266,7 @@
u8 devad, u16 reg, u16 *ret_val)
{
u8 phy_index;
- /*
- * Probe for the phy according to the given phy_addr, and execute
+ /* Probe for the phy according to the given phy_addr, and execute
* the read request on it
*/
for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
@@ -3355,8 +3283,7 @@
u8 devad, u16 reg, u16 val)
{
u8 phy_index;
- /*
- * Probe for the phy according to the given phy_addr, and execute
+ /* Probe for the phy according to the given phy_addr, and execute
* the write request on it
*/
for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
@@ -3382,7 +3309,7 @@
if (bnx2x_is_4_port_mode(bp)) {
u32 port_swap, port_swap_ovr;
- /*figure out path swap value */
+ /* Figure out path swap value */
path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
if (path_swap_ovr & 0x1)
path_swap = (path_swap_ovr & 0x2);
@@ -3392,7 +3319,7 @@
if (path_swap)
path = path ^ 1;
- /*figure out port swap value */
+ /* Figure out port swap value */
port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
if (port_swap_ovr & 0x1)
port_swap = (port_swap_ovr & 0x2);
@@ -3405,7 +3332,7 @@
lane = (port<<1) + path;
} else { /* two port mode - no port swap */
- /*figure out path swap value */
+ /* Figure out path swap value */
path_swap_ovr =
REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
if (path_swap_ovr & 0x1) {
@@ -3437,8 +3364,7 @@
if (USES_WARPCORE(bp)) {
aer_val = bnx2x_get_warpcore_lane(phy, params);
- /*
- * In Dual-lane mode, two lanes are joined together,
+ /* In Dual-lane mode, two lanes are joined together,
* so in order to configure them, the AER broadcast method is
* used here.
* 0x200 is the broadcast address for lanes 0,1
@@ -3518,8 +3444,7 @@
{
struct bnx2x *bp = params->bp;
*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
- /**
- * resolve pause mode and advertisement Please refer to Table
+ /* Resolve pause mode and advertisement Please refer to Table
* 28B-3 of the 802.3ab-1999 spec
*/
@@ -3642,6 +3567,7 @@
vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
if (pause_result & (1<<1))
vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
+
}
static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
@@ -3698,6 +3624,7 @@
bnx2x_pause_resolve(vars, pause_result);
}
+
static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
struct link_params *params,
struct link_vars *vars)
@@ -3819,9 +3746,7 @@
/* Advertise pause */
bnx2x_ext_phy_set_pause(params, phy, vars);
-
- /*
- * Set KR Autoneg Work-Around flag for Warpcore version older than D108
+ /* Set KR Autoneg Work-Around flag for Warpcore version older than D108
*/
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_UC_INFO_B1_VERSION, &val16);
@@ -3829,7 +3754,6 @@
DP(NETIF_MSG_LINK, "Enable AN KR work-around\n");
vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
}
-
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_DIGITAL5_MISC7, &val16);
@@ -3903,7 +3827,7 @@
bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
- /*Enable encoded forced speed */
+ /* Enable encoded forced speed */
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
@@ -4265,8 +4189,7 @@
PORT_HW_CFG_E3_MOD_ABS_MASK) >>
PORT_HW_CFG_E3_MOD_ABS_SHIFT;
- /*
- * Should not happen. This function called upon interrupt
+ /* Should not happen. This function called upon interrupt
* triggered by GPIO ( since EPIO can only generate interrupts
* to MCP).
* So if this function was called and none of the GPIOs was set,
@@ -4366,7 +4289,7 @@
"link up, rx_tx_asic_rst 0x%x\n",
vars->rx_tx_asic_rst);
} else {
- /*reset the lane to see if link comes up.*/
+ /* Reset the lane to see if link comes up.*/
bnx2x_warpcore_reset_lane(bp, phy, 1);
bnx2x_warpcore_reset_lane(bp, phy, 0);
@@ -4387,7 +4310,6 @@
} /*params->rx_tx_asic_rst*/
}
-
static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
struct link_params *params,
struct link_vars *vars)
@@ -4545,7 +4467,7 @@
/* Update those 1-copy registers */
CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
MDIO_AER_BLOCK_AER_REG, 0);
- /* Enable 1G MDIO (1-copy) */
+ /* Enable 1G MDIO (1-copy) */
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
&val16);
@@ -4624,43 +4546,43 @@
vars->duplex = DUPLEX_FULL;
switch (vars->link_status &
LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
- case LINK_10THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_10TFD:
- vars->line_speed = SPEED_10;
- break;
+ case LINK_10THD:
+ vars->duplex = DUPLEX_HALF;
+ /* Fall thru */
+ case LINK_10TFD:
+ vars->line_speed = SPEED_10;
+ break;
- case LINK_100TXHD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_100T4:
- case LINK_100TXFD:
- vars->line_speed = SPEED_100;
- break;
+ case LINK_100TXHD:
+ vars->duplex = DUPLEX_HALF;
+ /* Fall thru */
+ case LINK_100T4:
+ case LINK_100TXFD:
+ vars->line_speed = SPEED_100;
+ break;
- case LINK_1000THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_1000TFD:
- vars->line_speed = SPEED_1000;
- break;
+ case LINK_1000THD:
+ vars->duplex = DUPLEX_HALF;
+ /* Fall thru */
+ case LINK_1000TFD:
+ vars->line_speed = SPEED_1000;
+ break;
- case LINK_2500THD:
- vars->duplex = DUPLEX_HALF;
- /* fall thru */
- case LINK_2500TFD:
- vars->line_speed = SPEED_2500;
- break;
+ case LINK_2500THD:
+ vars->duplex = DUPLEX_HALF;
+ /* Fall thru */
+ case LINK_2500TFD:
+ vars->line_speed = SPEED_2500;
+ break;
- case LINK_10GTFD:
- vars->line_speed = SPEED_10000;
- break;
- case LINK_20GTFD:
- vars->line_speed = SPEED_20000;
- break;
- default:
- break;
+ case LINK_10GTFD:
+ vars->line_speed = SPEED_10000;
+ break;
+ case LINK_20GTFD:
+ vars->line_speed = SPEED_20000;
+ break;
+ default:
+ break;
}
vars->flow_ctrl = 0;
if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
@@ -4835,9 +4757,8 @@
struct bnx2x_phy *phy)
{
struct bnx2x *bp = params->bp;
- /*
- * Each two bits represents a lane number:
- * No swap is 0123 => 0x1b no need to enable the swap
+ /* Each two bits represents a lane number:
+ * No swap is 0123 => 0x1b no need to enable the swap
*/
u16 rx_lane_swap, tx_lane_swap;
@@ -5051,8 +4972,7 @@
MDIO_REG_BANK_COMBO_IEEE0,
MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
- /*
- * program speed
+ /* Program speed
* - needed only if the speed is greater than 1G (2.5G or 10G)
*/
CL22_RD_OVER_CL45(bp, phy,
@@ -5087,8 +5007,6 @@
struct bnx2x *bp = params->bp;
u16 val = 0;
- /* configure the 48 bits for BAM AN */
-
/* set extended capabilities */
if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
val |= MDIO_OVER_1G_UP1_2_5G;
@@ -5234,11 +5152,8 @@
}
}
-
-/*
- * link management
+/* Link management
*/
-
static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
struct link_params *params)
{
@@ -5383,8 +5298,7 @@
"ustat_val(0x8371) = 0x%x\n", ustat_val);
return;
}
- /*
- * Step 3: Check CL37 Message Pages received to indicate LP
+ /* Step 3: Check CL37 Message Pages received to indicate LP
* supports only CL37
*/
CL22_RD_OVER_CL45(bp, phy,
@@ -5401,8 +5315,7 @@
cl37_fsm_received);
return;
}
- /*
- * The combined cl37/cl73 fsm state information indicating that
+ /* The combined cl37/cl73 fsm state information indicating that
* we are connected to a device which does not support cl73, but
* does support cl37 BAM. In this case we disable cl73 and
* restart cl37 auto-neg
@@ -5973,8 +5886,7 @@
{
u32 latch_status = 0;
- /*
- * Disable the MI INT ( external phy int ) by writing 1 to the
+ /* Disable the MI INT ( external phy int ) by writing 1 to the
* status register. Link down indication is high-active-signal,
* so in this case we need to write the status to clear the XOR
*/
@@ -6009,8 +5921,7 @@
struct bnx2x *bp = params->bp;
u8 port = params->port;
u32 mask;
- /*
- * First reset all status we assume only one line will be
+ /* First reset all status we assume only one line will be
* change at a time
*/
bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
@@ -6024,8 +5935,7 @@
if (is_10g_plus)
mask = NIG_STATUS_XGXS0_LINK10G;
else if (params->switch_cfg == SWITCH_CFG_10G) {
- /*
- * Disable the link interrupt by writing 1 to
+ /* Disable the link interrupt by writing 1 to
* the relevant lane in the status register
*/
u32 ser_lane =
@@ -6227,8 +6137,7 @@
break;
case LED_MODE_OPER:
- /*
- * For all other phys, OPER mode is same as ON, so in case
+ /* For all other phys, OPER mode is same as ON, so in case
* link is down, do nothing
*/
if (!vars->link_up)
@@ -6239,9 +6148,7 @@
(params->phy[EXT_PHY1].type ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
CHIP_IS_E2(bp) && params->num_phys == 2) {
- /*
- * This is a work-around for E2+8727 Configurations
- */
+ /* This is a work-around for E2+8727 Configurations */
if (mode == LED_MODE_ON ||
speed == SPEED_10000){
REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
@@ -6250,8 +6157,7 @@
tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
EMAC_WR(bp, EMAC_REG_EMAC_LED,
(tmp | EMAC_LED_OVERRIDE));
- /*
- * return here without enabling traffic
+ /* Return here without enabling traffic
* LED blink and setting rate in ON mode.
* In oper mode, enabling LED blink
* and setting rate is needed.
@@ -6260,8 +6166,7 @@
return rc;
}
} else if (SINGLE_MEDIA_DIRECT(params)) {
- /*
- * This is a work-around for HW issue found when link
+ /* This is a work-around for HW issue found when link
* is up in CL73
*/
if ((!CHIP_IS_E3(bp)) ||
@@ -6310,10 +6215,7 @@
(speed == SPEED_1000) ||
(speed == SPEED_100) ||
(speed == SPEED_10))) {
- /*
- * On Everest 1 Ax chip versions for speeds less than
- * 10G LED scheme is different
- */
+ /* For speeds less than 10G LED scheme is different */
REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
+ port*4, 1);
REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
@@ -6333,8 +6235,7 @@
}
-/*
- * This function comes to reflect the actual link state read DIRECTLY from the
+/* This function comes to reflect the actual link state read DIRECTLY from the
* HW
*/
int bnx2x_test_link(struct link_params *params, struct link_vars *vars,
@@ -6422,16 +6323,14 @@
int rc = 0;
u8 phy_index, non_ext_phy;
struct bnx2x *bp = params->bp;
- /*
- * In case of external phy existence, the line speed would be the
+ /* In case of external phy existence, the line speed would be the
* line speed linked up by the external phy. In case it is direct
* only, then the line_speed during initialization will be
* equal to the req_line_speed
*/
vars->line_speed = params->phy[INT_PHY].req_line_speed;
- /*
- * Initialize the internal phy in case this is a direct board
+ /* Initialize the internal phy in case this is a direct board
* (no external phys), or this board has external phy which requires
* to first.
*/
@@ -6463,8 +6362,7 @@
} else {
for (phy_index = EXT_PHY1; phy_index < params->num_phys;
phy_index++) {
- /*
- * No need to initialize second phy in case of first
+ /* No need to initialize second phy in case of first
* phy only selection. In case of second phy, we do
* need to initialize the first phy, since they are
* connected.
@@ -6492,7 +6390,6 @@
NIG_STATUS_XGXS0_LINK_STATUS |
NIG_STATUS_SERDES0_LINK_STATUS |
NIG_MASK_MI_INT));
- bnx2x_update_mng(params, vars->link_status);
return rc;
}
@@ -6577,7 +6474,7 @@
u8 link_10g)
{
struct bnx2x *bp = params->bp;
- u8 port = params->port;
+ u8 phy_idx, port = params->port;
int rc = 0;
vars->link_status |= (LINK_STATUS_LINK_UP |
@@ -6641,11 +6538,18 @@
/* update shared memory */
bnx2x_update_mng(params, vars->link_status);
+
+ /* Check remote fault */
+ for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
+ if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
+ bnx2x_check_half_open_conn(params, vars, 0);
+ break;
+ }
+ }
msleep(20);
return rc;
}
-/*
- * The bnx2x_link_update function should be called upon link
+/* The bnx2x_link_update function should be called upon link
* interrupt.
* Link is considered up as follows:
* - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
@@ -6702,8 +6606,7 @@
if (!CHIP_IS_E3(bp))
REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
- /*
- * Step 1:
+ /* Step 1:
* Check external link change only for external phys, and apply
* priority selection between them in case the link on both phys
* is up. Note that instead of the common vars, a temporary
@@ -6734,23 +6637,20 @@
switch (bnx2x_phy_selection(params)) {
case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
- /*
- * In this option, the first PHY makes sure to pass the
+ /* In this option, the first PHY makes sure to pass the
* traffic through itself only.
* Its not clear how to reset the link on the second phy
*/
active_external_phy = EXT_PHY1;
break;
case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
- /*
- * In this option, the first PHY makes sure to pass the
+ /* In this option, the first PHY makes sure to pass the
* traffic through the second PHY.
*/
active_external_phy = EXT_PHY2;
break;
default:
- /*
- * Link indication on both PHYs with the following cases
+ /* Link indication on both PHYs with the following cases
* is invalid:
* - FIRST_PHY means that second phy wasn't initialized,
* hence its link is expected to be down
@@ -6767,8 +6667,7 @@
}
}
prev_line_speed = vars->line_speed;
- /*
- * Step 2:
+ /* Step 2:
* Read the status of the internal phy. In case of
* DIRECT_SINGLE_MEDIA board, this link is the external link,
* otherwise this is the link between the 577xx and the first
@@ -6778,8 +6677,7 @@
params->phy[INT_PHY].read_status(
¶ms->phy[INT_PHY],
params, vars);
- /*
- * The INT_PHY flow control reside in the vars. This include the
+ /* The INT_PHY flow control reside in the vars. This include the
* case where the speed or flow control are not set to AUTO.
* Otherwise, the active external phy flow control result is set
* to the vars. The ext_phy_line_speed is needed to check if the
@@ -6788,14 +6686,12 @@
*/
if (active_external_phy > INT_PHY) {
vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
- /*
- * Link speed is taken from the XGXS. AN and FC result from
+ /* Link speed is taken from the XGXS. AN and FC result from
* the external phy.
*/
vars->link_status |= phy_vars[active_external_phy].link_status;
- /*
- * if active_external_phy is first PHY and link is up - disable
+ /* if active_external_phy is first PHY and link is up - disable
* disable TX on second external PHY
*/
if (active_external_phy == EXT_PHY1) {
@@ -6832,8 +6728,7 @@
DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
" ext_phy_line_speed = %d\n", vars->flow_ctrl,
vars->link_status, ext_phy_line_speed);
- /*
- * Upon link speed change set the NIG into drain mode. Comes to
+ /* Upon link speed change set the NIG into drain mode. Comes to
* deals with possible FIFO glitch due to clk change when speed
* is decreased without link down indicator
*/
@@ -6858,8 +6753,7 @@
bnx2x_link_int_ack(params, vars, link_10g_plus);
- /*
- * In case external phy link is up, and internal link is down
+ /* In case external phy link is up, and internal link is down
* (not initialized yet probably after link initialization, it
* needs to be initialized.
* Note that after link down-up as result of cable plug, the xgxs
@@ -6887,8 +6781,7 @@
vars);
}
}
- /*
- * Link is up only if both local phy and external phy (in case of
+ /* Link is up only if both local phy and external phy (in case of
* non-direct board) are up and no fault detected on active PHY.
*/
vars->link_up = (vars->phy_link_up &&
@@ -7120,8 +7013,7 @@
}
/* XAUI workaround in 8073 A0: */
- /*
- * After loading the boot ROM and restarting Autoneg, poll
+ /* After loading the boot ROM and restarting Autoneg, poll
* Dev1, Reg $C820:
*/
@@ -7130,8 +7022,7 @@
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
&val);
- /*
- * If bit [14] = 0 or bit [13] = 0, continue on with
+ /* If bit [14] = 0 or bit [13] = 0, continue on with
* system initialization (XAUI work-around not required, as
* these bits indicate 2.5G or 1G link up).
*/
@@ -7140,8 +7031,7 @@
return 0;
} else if (!(val & (1<<15))) {
DP(NETIF_MSG_LINK, "bit 15 went off\n");
- /*
- * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
+ /* If bit 15 is 0, then poll Dev1, Reg $C841 until it's
* MSB (bit15) goes to 1 (indicating that the XAUI
* workaround has completed), then continue on with
* system initialization.
@@ -7291,8 +7181,7 @@
val = (1<<7);
} else if (phy->req_line_speed == SPEED_2500) {
val = (1<<5);
- /*
- * Note that 2.5G works only when used with 1G
+ /* Note that 2.5G works only when used with 1G
* advertisement
*/
} else
@@ -7343,8 +7232,7 @@
/* Add support for CL37 (passive mode) III */
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
- /*
- * The SNR will improve about 2db by changing BW and FEE main
+ /* The SNR will improve about 2db by changing BW and FEE main
* tap. Rest commands are executed after link is up
* Change FFE main cursor to 5 in EDC register
*/
@@ -7431,8 +7319,7 @@
link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
- /*
- * The SNR will improve about 2dbby changing the BW and FEE main
+ /* The SNR will improve about 2dbby changing the BW and FEE main
* tap. The 1st write to change FFE main tap is set before
* restart AN. Change PLL Bandwidth in EDC register
*/
@@ -7479,8 +7366,7 @@
bnx2x_cl45_read(bp, phy,
MDIO_XS_DEVAD,
MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
- /*
- * Set bit 3 to invert Rx in 1G mode and clear this bit
+ /* Set bit 3 to invert Rx in 1G mode and clear this bit
* when it`s in 10G mode.
*/
if (vars->line_speed == SPEED_1000) {
@@ -7602,8 +7488,7 @@
u8 pmd_dis)
{
struct bnx2x *bp = params->bp;
- /*
- * Disable transmitter only for bootcodes which can enable it afterwards
+ /* Disable transmitter only for bootcodes which can enable it afterwards
* (for D3 link)
*/
if (pmd_dis) {
@@ -7780,9 +7665,6 @@
u32 data_array[4];
u16 addr32;
struct bnx2x *bp = params->bp;
- /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:"
- " addr %d, cnt %d\n",
- addr, byte_cnt);*/
if (byte_cnt > 16) {
DP(NETIF_MSG_LINK,
"Reading from eeprom is limited to 16 bytes\n");
@@ -7847,8 +7729,7 @@
MDIO_PMA_DEVAD,
MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
0x8002);
- /*
- * Wait appropriate time for two-wire command to finish before
+ /* Wait appropriate time for two-wire command to finish before
* polling the status register
*/
msleep(1);
@@ -7941,8 +7822,7 @@
{
u8 copper_module_type;
phy->media_type = ETH_PHY_DA_TWINAX;
- /*
- * Check if its active cable (includes SFP+ module)
+ /* Check if its active cable (includes SFP+ module)
* of passive cable
*/
if (bnx2x_read_sfp_module_eeprom(phy,
@@ -8019,8 +7899,7 @@
DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
return 0;
}
-/*
- * This function read the relevant field from the module (SFP+), and verify it
+/* This function read the relevant field from the module (SFP+), and verify it
* is compliant with this board
*/
static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
@@ -8102,8 +7981,7 @@
u8 val;
struct bnx2x *bp = params->bp;
u16 timeout;
- /*
- * Initialization time after hot-plug may take up to 300ms for
+ /* Initialization time after hot-plug may take up to 300ms for
* some phys type ( e.g. JDSU )
*/
@@ -8125,8 +8003,7 @@
u8 is_power_up) {
/* Make sure GPIOs are not using for LED mode */
u16 val;
- /*
- * In the GPIO register, bit 4 is use to determine if the GPIOs are
+ /* In the GPIO register, bit 4 is use to determine if the GPIOs are
* operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
* output
* Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
@@ -8142,8 +8019,7 @@
if (is_power_up)
val = (1<<4);
else
- /*
- * Set GPIO control to OUTPUT, and set the power bit
+ /* Set GPIO control to OUTPUT, and set the power bit
* to according to the is_power_up
*/
val = (1<<1);
@@ -8177,8 +8053,7 @@
DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
- /*
- * Changing to LRM mode takes quite few seconds. So do it only
+ /* Changing to LRM mode takes quite few seconds. So do it only
* if current mode is limiting (default is LRM)
*/
if (cur_limiting_mode != EDC_MODE_LIMITING)
@@ -8313,8 +8188,7 @@
struct bnx2x *bp = params->bp;
DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode);
if (CHIP_IS_E3(bp)) {
- /*
- * Low ==> if SFP+ module is supported otherwise
+ /* Low ==> if SFP+ module is supported otherwise
* High ==> if SFP+ module is not on the approved vendor list
*/
bnx2x_set_e3_module_fault_led(params, gpio_mode);
@@ -8339,8 +8213,7 @@
return;
DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
power, pin_cfg);
- /*
- * Low ==> corresponding SFP+ module is powered
+ /* Low ==> corresponding SFP+ module is powered
* high ==> the SFP+ module is powered down
*/
bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
@@ -8474,14 +8347,12 @@
bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
}
- /*
- * Check and set limiting mode / LRM mode on 8726. On 8727 it
+ /* Check and set limiting mode / LRM mode on 8726. On 8727 it
* is done automatically
*/
bnx2x_set_limiting_mode(params, phy, edc_mode);
- /*
- * Enable transmit for this module if the module is approved, or
+ /* Enable transmit for this module if the module is approved, or
* if unapproved modules should also enable the Tx laser
*/
if (rc == 0 ||
@@ -8536,8 +8407,7 @@
bnx2x_set_gpio_int(bp, gpio_num,
MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
gpio_port);
- /*
- * Module was plugged out.
+ /* Module was plugged out.
* Disable transmit for this module
*/
phy->media_type = ETH_PHY_NOT_PRESENT;
@@ -8607,8 +8477,7 @@
DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
" link_status 0x%x\n", rx_sd, pcs_status, val2);
- /*
- * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
+ /* Link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
* are set, or if the autoneg bit 1 is set
*/
link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
@@ -8722,8 +8591,7 @@
}
bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
- /*
- * If TX Laser is controlled by GPIO_0, do not let PHY go into low
+ /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
* power mode, if TX Laser is disabled
*/
@@ -8833,8 +8701,7 @@
bnx2x_8726_external_rom_boot(phy, params);
- /*
- * Need to call module detected on initialization since the module
+ /* Need to call module detected on initialization since the module
* detection triggered by actual module insertion might occur before
* driver is loaded, and when driver is loaded, it reset all
* registers, including the transmitter
@@ -8871,8 +8738,7 @@
MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
bnx2x_cl45_write(bp, phy,
MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
- /*
- * Enable RX-ALARM control to receive interrupt for 1G speed
+ /* Enable RX-ALARM control to receive interrupt for 1G speed
* change
*/
bnx2x_cl45_write(bp, phy,
@@ -8973,8 +8839,7 @@
struct link_params *params) {
u32 swap_val, swap_override;
u8 port;
- /*
- * The PHY reset is controlled by GPIO 1. Fake the port number
+ /* The PHY reset is controlled by GPIO 1. Fake the port number
* to cancel the swap done in set_gpio()
*/
struct bnx2x *bp = params->bp;
@@ -9012,14 +8877,12 @@
bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, lasi_ctrl_val);
- /*
- * Initially configure MOD_ABS to interrupt when module is
+ /* Initially configure MOD_ABS to interrupt when module is
* presence( bit 8)
*/
bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
- /*
- * Set EDC off by setting OPTXLOS signal input to low (bit 9).
+ /* Set EDC off by setting OPTXLOS signal input to low (bit 9).
* When the EDC is off it locks onto a reference clock and avoids
* becoming 'lost'
*/
@@ -9040,8 +8903,7 @@
if (phy->flags & FLAGS_NOC)
val |= (3<<5);
- /*
- * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
+ /* Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
* status which reflect SFP+ module over-current
*/
if (!(phy->flags & FLAGS_NOC))
@@ -9067,8 +8929,7 @@
bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
- /*
- * Power down the XAUI until link is up in case of dual-media
+ /* Power down the XAUI until link is up in case of dual-media
* and 1G
*/
if (DUAL_MEDIA(params)) {
@@ -9093,8 +8954,7 @@
bnx2x_cl45_write(bp, phy,
MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
} else {
- /*
- * Since the 8727 has only single reset pin, need to set the 10G
+ /* Since the 8727 has only single reset pin, need to set the 10G
* registers although it is default
*/
bnx2x_cl45_write(bp, phy,
@@ -9109,8 +8969,7 @@
0x0008);
}
- /*
- * Set 2-wire transfer rate of SFP+ module EEPROM
+ /* Set 2-wire transfer rate of SFP+ module EEPROM
* to 100Khz since some DACs(direct attached cables) do
* not work at 400Khz.
*/
@@ -9133,8 +8992,7 @@
phy->tx_preemphasis[1]);
}
- /*
- * If TX Laser is controlled by GPIO_0, do not let PHY go into low
+ /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
* power mode, if TX Laser is disabled
*/
tx_en_mode = REG_RD(bp, params->shmem_base +
@@ -9180,8 +9038,7 @@
DP(NETIF_MSG_LINK,
"MOD_ABS indication show module is absent\n");
phy->media_type = ETH_PHY_NOT_PRESENT;
- /*
- * 1. Set mod_abs to detect next module
+ /* 1. Set mod_abs to detect next module
* presence event
* 2. Set EDC off by setting OPTXLOS signal input to low
* (bit 9).
@@ -9195,8 +9052,7 @@
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
- /*
- * Clear RX alarm since it stays up as long as
+ /* Clear RX alarm since it stays up as long as
* the mod_abs wasn't changed
*/
bnx2x_cl45_read(bp, phy,
@@ -9207,8 +9063,7 @@
/* Module is present */
DP(NETIF_MSG_LINK,
"MOD_ABS indication show module is present\n");
- /*
- * First disable transmitter, and if the module is ok, the
+ /* First disable transmitter, and if the module is ok, the
* module_detection will enable it
* 1. Set mod_abs to detect next module absent event ( bit 8)
* 2. Restore the default polarity of the OPRXLOS signal and
@@ -9222,8 +9077,7 @@
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
- /*
- * Clear RX alarm since it stays up as long as the mod_abs
+ /* Clear RX alarm since it stays up as long as the mod_abs
* wasn't changed. This is need to be done before calling the
* module detection, otherwise it will clear* the link update
* alarm
@@ -9284,8 +9138,7 @@
bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
- /*
- * If a module is present and there is need to check
+ /* If a module is present and there is need to check
* for over current
*/
if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
@@ -9350,8 +9203,7 @@
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
- /*
- * Bits 0..2 --> speed detected,
+ /* Bits 0..2 --> speed detected,
* Bits 13..15--> link is down
*/
if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
@@ -9394,8 +9246,7 @@
bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_8727_PCS_GP, &val1);
- /*
- * In case of dual-media board and 1G, power up the XAUI side,
+ /* In case of dual-media board and 1G, power up the XAUI side,
* otherwise power it down. For 10G it is done automatically
*/
if (link_up)
@@ -9561,8 +9412,7 @@
/* Save spirom version */
bnx2x_save_848xx_spirom_version(phy, bp, params->port);
}
- /*
- * This phy uses the NIG latch mechanism since link indication
+ /* This phy uses the NIG latch mechanism since link indication
* arrives through its LED4 and not via its LASI signal, so we
* get steady signal instead of clear on read
*/
@@ -9667,8 +9517,7 @@
if (phy->req_duplex == DUPLEX_FULL)
autoneg_val |= (1<<8);
- /*
- * Always write this if this is not 84833.
+ /* Always write this if this is not 84833.
* For 84833, write it only when it's a forced speed.
*/
if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
@@ -9916,8 +9765,7 @@
/* Wait for GPHY to come out of reset */
msleep(50);
if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
- /*
- * BCM84823 requires that XGXS links up first @ 10G for normal
+ /* BCM84823 requires that XGXS links up first @ 10G for normal
* behavior.
*/
u16 temp;
@@ -10393,8 +10241,7 @@
break;
}
- /*
- * This is a workaround for E3+84833 until autoneg
+ /* This is a workaround for E3+84833 until autoneg
* restart is fixed in f/w
*/
if (CHIP_IS_E3(bp)) {
@@ -10418,8 +10265,7 @@
DP(NETIF_MSG_LINK, "54618SE cfg init\n");
usleep_range(1000, 1000);
- /*
- * This works with E3 only, no need to check the chip
+ /* This works with E3 only, no need to check the chip
* before determining the port.
*/
port = params->port;
@@ -10441,7 +10287,7 @@
MDIO_PMA_REG_CTRL, 0x8000);
bnx2x_wait_reset_complete(bp, phy, params);
- /*wait for GPHY to reset */
+ /* Wait for GPHY to reset */
msleep(50);
/* Configure LED4: set to INTR (0x6). */
@@ -10647,13 +10493,11 @@
u32 cfg_pin;
u8 port;
- /*
- * In case of no EPIO routed to reset the GPHY, put it
+ /* In case of no EPIO routed to reset the GPHY, put it
* in low power mode.
*/
bnx2x_cl22_write(bp, phy, MDIO_PMA_REG_CTRL, 0x800);
- /*
- * This works with E3 only, no need to check the chip
+ /* This works with E3 only, no need to check the chip
* before determining the port.
*/
port = params->port;
@@ -10762,7 +10606,7 @@
bnx2x_ext_phy_resolve_fc(phy, params, vars);
if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
- /* report LP advertised speeds */
+ /* Report LP advertised speeds */
bnx2x_cl22_read(bp, phy, 0x5, &val);
if (val & (1<<5))
@@ -10827,8 +10671,7 @@
/* This register opens the gate for the UMAC despite its name */
REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
- /*
- * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
+ /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
* length used by the MAC receive logic to check frames.
*/
REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
@@ -11101,22 +10944,23 @@
.type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
.addr = 0xff,
.def_md_devad = 0,
- .flags = FLAGS_HW_LOCK_REQUIRED,
+ .flags = (FLAGS_HW_LOCK_REQUIRED |
+ FLAGS_TX_ERROR_CHECK),
.rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.mdio_ctrl = 0,
.supported = (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_1000baseT_Full |
- SUPPORTED_10000baseT_Full |
- SUPPORTED_20000baseKR2_Full |
- SUPPORTED_20000baseMLD2_Full |
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
- SUPPORTED_Pause |
- SUPPORTED_Asym_Pause),
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_20000baseKR2_Full |
+ SUPPORTED_20000baseMLD2_Full |
+ SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause),
.media_type = ETH_PHY_UNSPECIFIED,
.ver_addr = 0,
.req_flow_ctrl = 0,
@@ -11258,7 +11102,8 @@
.addr = 0xff,
.def_md_devad = 0,
.flags = (FLAGS_HW_LOCK_REQUIRED |
- FLAGS_INIT_XGXS_FIRST),
+ FLAGS_INIT_XGXS_FIRST |
+ FLAGS_TX_ERROR_CHECK),
.rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.mdio_ctrl = 0,
@@ -11289,7 +11134,8 @@
.type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
.addr = 0xff,
.def_md_devad = 0,
- .flags = FLAGS_FAN_FAILURE_DET_REQ,
+ .flags = (FLAGS_FAN_FAILURE_DET_REQ |
+ FLAGS_TX_ERROR_CHECK),
.rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.mdio_ctrl = 0,
@@ -11354,8 +11200,9 @@
.type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
.addr = 0xff,
.def_md_devad = 0,
- .flags = FLAGS_FAN_FAILURE_DET_REQ |
- FLAGS_REARM_LATCH_SIGNAL,
+ .flags = (FLAGS_FAN_FAILURE_DET_REQ |
+ FLAGS_REARM_LATCH_SIGNAL |
+ FLAGS_TX_ERROR_CHECK),
.rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.mdio_ctrl = 0,
@@ -11390,8 +11237,9 @@
.type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
.addr = 0xff,
.def_md_devad = 0,
- .flags = FLAGS_FAN_FAILURE_DET_REQ |
- FLAGS_REARM_LATCH_SIGNAL,
+ .flags = (FLAGS_FAN_FAILURE_DET_REQ |
+ FLAGS_REARM_LATCH_SIGNAL |
+ FLAGS_TX_ERROR_CHECK),
.rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
.mdio_ctrl = 0,
@@ -11466,9 +11314,8 @@
/* Get the 4 lanes xgxs config rx and tx */
u32 rx = 0, tx = 0, i;
for (i = 0; i < 2; i++) {
- /*
- * INT_PHY and EXT_PHY1 share the same value location in the
- * shmem. When num_phys is greater than 1, than this value
+ /* INT_PHY and EXT_PHY1 share the same value location in
+ * the shmem. When num_phys is greater than 1, than this value
* applies only to EXT_PHY1
*/
if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
@@ -11546,8 +11393,7 @@
offsetof(struct shmem_region, dev_info.
port_hw_config[port].default_cfg)) &
PORT_HW_CFG_NET_SERDES_IF_MASK);
- /*
- * Set the appropriate supported and flags indications per
+ /* Set the appropriate supported and flags indications per
* interface type of the chip
*/
switch (serdes_net_if) {
@@ -11605,8 +11451,7 @@
break;
}
- /*
- * Enable MDC/MDIO work-around for E3 A0 since free running MDC
+ /* Enable MDC/MDIO work-around for E3 A0 since free running MDC
* was not set as expected. For B0, ECO will be enabled so there
* won't be an issue there
*/
@@ -11719,8 +11564,7 @@
phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
- /*
- * The shmem address of the phy version is located on different
+ /* The shmem address of the phy version is located on different
* structures. In case this structure is too old, do not set
* the address
*/
@@ -11754,8 +11598,7 @@
if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
(phy->ver_addr)) {
- /*
- * Remove 100Mb link supported for BCM84833 when phy fw
+ /* Remove 100Mb link supported for BCM84833 when phy fw
* version lower than or equal to 1.39
*/
u32 raw_ver = REG_RD(bp, phy->ver_addr);
@@ -11765,8 +11608,7 @@
SUPPORTED_100baseT_Full);
}
- /*
- * In case mdc/mdio_access of the external phy is different than the
+ /* In case mdc/mdio_access of the external phy is different than the
* mdc/mdio access of the XGXS, a HW lock must be taken in each access
* to prevent one port interfere with another port's CL45 operations.
*/
@@ -11936,13 +11778,16 @@
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
break;
+ if (params->feature_config_flags &
+ FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET)
+ phy->flags &= ~FLAGS_TX_ERROR_CHECK;
+
sync_offset = params->shmem_base +
offsetof(struct shmem_region,
dev_info.port_hw_config[params->port].media_type);
media_types = REG_RD(bp, sync_offset);
- /*
- * Update media type for non-PMF sync only for the first time
+ /* Update media type for non-PMF sync only for the first time
* In case the media type changes afterwards, it will be updated
* using the update_status function
*/
@@ -12016,8 +11861,7 @@
vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
vars->mac_type = MAC_TYPE_XMAC;
vars->phy_flags = PHY_XGXS_FLAG;
- /*
- * Set WC to loopback mode since link is required to provide clock
+ /* Set WC to loopback mode since link is required to provide clock
* to the XMAC in 20G mode
*/
bnx2x_set_aer_mmd(params, ¶ms->phy[0]);
@@ -12162,6 +12006,7 @@
bnx2x_link_int_enable(params);
break;
}
+ bnx2x_update_mng(params, vars->link_status);
return 0;
}
@@ -12302,7 +12147,8 @@
NIG_MASK_MI_INT));
/* Need to take the phy out of low power mode in order
- to write to access its registers */
+ * to write to access its registers
+ */
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
MISC_REGISTERS_GPIO_OUTPUT_HIGH,
port);
@@ -12350,8 +12196,7 @@
(val | 1<<10));
}
- /*
- * Toggle Transmitter: Power down and then up with 600ms delay
+ /* Toggle Transmitter: Power down and then up with 600ms delay
* between
*/
msleep(600);
@@ -12494,8 +12339,7 @@
reset_gpio = MISC_REGISTERS_GPIO_1;
port = 1;
- /*
- * Retrieve the reset gpio/port which control the reset.
+ /* Retrieve the reset gpio/port which control the reset.
* Default is GPIO1, PORT1
*/
bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
@@ -12670,8 +12514,7 @@
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
- /*
- * GPIO1 affects both ports, so there's need to pull
+ /* GPIO1 affects both ports, so there's need to pull
* it for single port alone
*/
rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
@@ -12679,8 +12522,7 @@
phy_index, chip_id);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
- /*
- * GPIO3's are linked, and so both need to be toggled
+ /* GPIO3's are linked, and so both need to be toggled
* to obtain required 2us pulse.
*/
rc = bnx2x_84833_common_init_phy(bp, shmem_base_path,
@@ -12779,7 +12621,8 @@
}
static void bnx2x_analyze_link_error(struct link_params *params,
- struct link_vars *vars, u32 lss_status)
+ struct link_vars *vars, u32 lss_status,
+ u8 notify)
{
struct bnx2x *bp = params->bp;
/* Compare new value with previous value */
@@ -12793,8 +12636,7 @@
DP(NETIF_MSG_LINK, "Link changed:%x %x->%x\n", vars->link_up,
half_open_conn, lss_status);
- /*
- * a. Update shmem->link_status accordingly
+ /* a. Update shmem->link_status accordingly
* b. Update link_vars->link_up
*/
if (lss_status) {
@@ -12802,8 +12644,10 @@
vars->link_status &= ~LINK_STATUS_LINK_UP;
vars->link_up = 0;
vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
- /*
- * Set LED mode to off since the PHY doesn't know about these
+
+ /* activate nig drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 1);
+ /* Set LED mode to off since the PHY doesn't know about these
* errors
*/
led_mode = LED_MODE_OFF;
@@ -12813,7 +12657,11 @@
vars->link_up = 1;
vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
led_mode = LED_MODE_OPER;
+
+ /* Clear nig drain */
+ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
}
+ bnx2x_sync_link(params, vars);
/* Update the LED according to the link state */
bnx2x_set_led(params, vars, led_mode, SPEED_10000);
@@ -12822,7 +12670,8 @@
/* C. Trigger General Attention */
vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT;
- bnx2x_notify_link_changed(bp);
+ if (notify)
+ bnx2x_notify_link_changed(bp);
}
/******************************************************************************
@@ -12834,22 +12683,23 @@
* a fault, for example, due to break in the TX side of fiber.
*
******************************************************************************/
-static void bnx2x_check_half_open_conn(struct link_params *params,
- struct link_vars *vars)
+int bnx2x_check_half_open_conn(struct link_params *params,
+ struct link_vars *vars,
+ u8 notify)
{
struct bnx2x *bp = params->bp;
u32 lss_status = 0;
u32 mac_base;
/* In case link status is physically up @ 10G do */
- if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
- return;
+ if (((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) ||
+ (REG_RD(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4)))
+ return 0;
if (CHIP_IS_E3(bp) &&
(REG_RD(bp, MISC_REG_RESET_REG_2) &
(MISC_REGISTERS_RESET_REG_2_XMAC))) {
/* Check E3 XMAC */
- /*
- * Note that link speed cannot be queried here, since it may be
+ /* Note that link speed cannot be queried here, since it may be
* zero while link is down. In case UMAC is active, LSS will
* simply not be set
*/
@@ -12863,7 +12713,7 @@
if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS))
lss_status = 1;
- bnx2x_analyze_link_error(params, vars, lss_status);
+ bnx2x_analyze_link_error(params, vars, lss_status, notify);
} else if (REG_RD(bp, MISC_REG_RESET_REG_2) &
(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
/* Check E1X / E2 BMAC */
@@ -12880,18 +12730,21 @@
REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2);
lss_status = (wb_data[0] > 0);
- bnx2x_analyze_link_error(params, vars, lss_status);
+ bnx2x_analyze_link_error(params, vars, lss_status, notify);
}
+ return 0;
}
void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
{
- struct bnx2x *bp = params->bp;
u16 phy_idx;
+ struct bnx2x *bp = params->bp;
for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
bnx2x_set_aer_mmd(params, ¶ms->phy[phy_idx]);
- bnx2x_check_half_open_conn(params, vars);
+ if (bnx2x_check_half_open_conn(params, vars, 1) !=
+ 0)
+ DP(NETIF_MSG_LINK, "Fault detection failed\n");
break;
}
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
index 763535e..00f26d3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
@@ -256,6 +256,7 @@
#define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3)
#define FEATURE_CONFIG_AUTOGREEEN_ENABLED (1<<9)
#define FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED (1<<10)
+#define FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET (1<<11)
/* Will be populated during common init */
struct bnx2x_phy phy[MAX_PHYS];
@@ -495,4 +496,6 @@
void bnx2x_period_func(struct link_params *params, struct link_vars *vars);
+int bnx2x_check_half_open_conn(struct link_params *params,
+ struct link_vars *vars, u8 notify);
#endif /* BNX2X_LINK_H */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index e077d25..1da25d7 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -39,7 +39,6 @@
#include <linux/time.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
-#include <linux/if.h>
#include <linux/if_vlan.h>
#include <net/ip.h>
#include <net/ipv6.h>
@@ -93,15 +92,11 @@
MODULE_FIRMWARE(FW_FILE_NAME_E1H);
MODULE_FIRMWARE(FW_FILE_NAME_E2);
-static int multi_mode = 1;
-module_param(multi_mode, int, 0);
-MODULE_PARM_DESC(multi_mode, " Multi queue mode "
- "(0 Disable; 1 Enable (default))");
int num_queues;
module_param(num_queues, int, 0);
-MODULE_PARM_DESC(num_queues, " Number of queues for multi_mode=1"
- " (default is as a number of CPUs)");
+MODULE_PARM_DESC(num_queues,
+ " Set number of queues (default is as a number of CPUs)");
static int disable_tpa;
module_param(disable_tpa, int, 0);
@@ -141,7 +136,9 @@
BCM57810,
BCM57810_MF,
BCM57840,
- BCM57840_MF
+ BCM57840_MF,
+ BCM57811,
+ BCM57811_MF
};
/* indexed by board_type, above */
@@ -158,8 +155,9 @@
{ "Broadcom NetXtreme II BCM57810 10 Gigabit Ethernet" },
{ "Broadcom NetXtreme II BCM57810 10 Gigabit Ethernet Multi Function" },
{ "Broadcom NetXtreme II BCM57840 10/20 Gigabit Ethernet" },
- { "Broadcom NetXtreme II BCM57840 10/20 Gigabit "
- "Ethernet Multi Function"}
+ { "Broadcom NetXtreme II BCM57840 10/20 Gigabit Ethernet Multi Function"},
+ { "Broadcom NetXtreme II BCM57811 10 Gigabit Ethernet"},
+ { "Broadcom NetXtreme II BCM57811 10 Gigabit Ethernet Multi Function"},
};
#ifndef PCI_DEVICE_ID_NX2_57710
@@ -195,6 +193,12 @@
#ifndef PCI_DEVICE_ID_NX2_57840_MF
#define PCI_DEVICE_ID_NX2_57840_MF CHIP_NUM_57840_MF
#endif
+#ifndef PCI_DEVICE_ID_NX2_57811
+#define PCI_DEVICE_ID_NX2_57811 CHIP_NUM_57811
+#endif
+#ifndef PCI_DEVICE_ID_NX2_57811_MF
+#define PCI_DEVICE_ID_NX2_57811_MF CHIP_NUM_57811_MF
+#endif
static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = {
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 },
@@ -207,6 +211,8 @@
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57810_MF), BCM57810_MF },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840), BCM57840 },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_MF), BCM57840_MF },
+ { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57811), BCM57811 },
+ { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57811_MF), BCM57811_MF },
{ 0 }
};
@@ -309,67 +315,6 @@
#define DMAE_DP_DST_PCI "pci dst_addr [%x:%08x]"
#define DMAE_DP_DST_NONE "dst_addr [none]"
-static void bnx2x_dp_dmae(struct bnx2x *bp, struct dmae_command *dmae,
- int msglvl)
-{
- u32 src_type = dmae->opcode & DMAE_COMMAND_SRC;
-
- switch (dmae->opcode & DMAE_COMMAND_DST) {
- case DMAE_CMD_DST_PCI:
- if (src_type == DMAE_CMD_SRC_PCI)
- DP(msglvl, "DMAE: opcode 0x%08x\n"
- "src [%x:%08x], len [%d*4], dst [%x:%08x]\n"
- "comp_addr [%x:%08x], comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
- dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo,
- dmae->comp_addr_hi, dmae->comp_addr_lo,
- dmae->comp_val);
- else
- DP(msglvl, "DMAE: opcode 0x%08x\n"
- "src [%08x], len [%d*4], dst [%x:%08x]\n"
- "comp_addr [%x:%08x], comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_lo >> 2,
- dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo,
- dmae->comp_addr_hi, dmae->comp_addr_lo,
- dmae->comp_val);
- break;
- case DMAE_CMD_DST_GRC:
- if (src_type == DMAE_CMD_SRC_PCI)
- DP(msglvl, "DMAE: opcode 0x%08x\n"
- "src [%x:%08x], len [%d*4], dst_addr [%08x]\n"
- "comp_addr [%x:%08x], comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
- dmae->len, dmae->dst_addr_lo >> 2,
- dmae->comp_addr_hi, dmae->comp_addr_lo,
- dmae->comp_val);
- else
- DP(msglvl, "DMAE: opcode 0x%08x\n"
- "src [%08x], len [%d*4], dst [%08x]\n"
- "comp_addr [%x:%08x], comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_lo >> 2,
- dmae->len, dmae->dst_addr_lo >> 2,
- dmae->comp_addr_hi, dmae->comp_addr_lo,
- dmae->comp_val);
- break;
- default:
- if (src_type == DMAE_CMD_SRC_PCI)
- DP(msglvl, "DMAE: opcode 0x%08x\n"
- "src_addr [%x:%08x] len [%d * 4] dst_addr [none]\n"
- "comp_addr [%x:%08x] comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
- dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo,
- dmae->comp_val);
- else
- DP(msglvl, "DMAE: opcode 0x%08x\n"
- "src_addr [%08x] len [%d * 4] dst_addr [none]\n"
- "comp_addr [%x:%08x] comp_val 0x%08x\n",
- dmae->opcode, dmae->src_addr_lo >> 2,
- dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo,
- dmae->comp_val);
- break;
- }
-
-}
/* copy command into DMAE command memory and set DMAE command go */
void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx)
@@ -506,8 +451,6 @@
dmae.dst_addr_hi = 0;
dmae.len = len32;
- bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF);
-
/* issue the command and wait for completion */
bnx2x_issue_dmae_with_comp(bp, &dmae);
}
@@ -540,8 +483,6 @@
dmae.dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
dmae.len = len32;
- bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF);
-
/* issue the command and wait for completion */
bnx2x_issue_dmae_with_comp(bp, &dmae);
}
@@ -562,27 +503,6 @@
bnx2x_write_dmae(bp, phys_addr + offset, addr + offset, len);
}
-/* used only for slowpath so not inlined */
-static void bnx2x_wb_wr(struct bnx2x *bp, int reg, u32 val_hi, u32 val_lo)
-{
- u32 wb_write[2];
-
- wb_write[0] = val_hi;
- wb_write[1] = val_lo;
- REG_WR_DMAE(bp, reg, wb_write, 2);
-}
-
-#ifdef USE_WB_RD
-static u64 bnx2x_wb_rd(struct bnx2x *bp, int reg)
-{
- u32 wb_data[2];
-
- REG_RD_DMAE(bp, reg, wb_data, 2);
-
- return HILO_U64(wb_data[0], wb_data[1]);
-}
-#endif
-
static int bnx2x_mc_assert(struct bnx2x *bp)
{
char last_idx;
@@ -1425,8 +1345,9 @@
static void bnx2x_igu_int_enable(struct bnx2x *bp)
{
u32 val;
- int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
- int msi = (bp->flags & USING_MSI_FLAG) ? 1 : 0;
+ bool msix = (bp->flags & USING_MSIX_FLAG) ? true : false;
+ bool single_msix = (bp->flags & USING_SINGLE_MSIX_FLAG) ? true : false;
+ bool msi = (bp->flags & USING_MSI_FLAG) ? true : false;
val = REG_RD(bp, IGU_REG_PF_CONFIGURATION);
@@ -1436,6 +1357,9 @@
val |= (IGU_PF_CONF_FUNC_EN |
IGU_PF_CONF_MSI_MSIX_EN |
IGU_PF_CONF_ATTN_BIT_EN);
+
+ if (single_msix)
+ val |= IGU_PF_CONF_SINGLE_ISR_EN;
} else if (msi) {
val &= ~IGU_PF_CONF_INT_LINE_EN;
val |= (IGU_PF_CONF_FUNC_EN |
@@ -1455,6 +1379,9 @@
REG_WR(bp, IGU_REG_PF_CONFIGURATION, val);
+ if (val & IGU_PF_CONF_INT_LINE_EN)
+ pci_intx(bp->pdev, true);
+
barrier();
/* init leading/trailing edge */
@@ -2229,40 +2156,6 @@
return rc;
}
-static void bnx2x_init_port_minmax(struct bnx2x *bp)
-{
- u32 r_param = bp->link_vars.line_speed / 8;
- u32 fair_periodic_timeout_usec;
- u32 t_fair;
-
- memset(&(bp->cmng.rs_vars), 0,
- sizeof(struct rate_shaping_vars_per_port));
- memset(&(bp->cmng.fair_vars), 0, sizeof(struct fairness_vars_per_port));
-
- /* 100 usec in SDM ticks = 25 since each tick is 4 usec */
- bp->cmng.rs_vars.rs_periodic_timeout = RS_PERIODIC_TIMEOUT_USEC / 4;
-
- /* this is the threshold below which no timer arming will occur
- 1.25 coefficient is for the threshold to be a little bigger
- than the real time, to compensate for timer in-accuracy */
- bp->cmng.rs_vars.rs_threshold =
- (RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
-
- /* resolution of fairness timer */
- fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
- /* for 10G it is 1000usec. for 1G it is 10000usec. */
- t_fair = T_FAIR_COEF / bp->link_vars.line_speed;
-
- /* this is the threshold below which we won't arm the timer anymore */
- bp->cmng.fair_vars.fair_threshold = QM_ARB_BYTES;
-
- /* we multiply by 1e3/8 to get bytes/msec.
- We don't want the credits to pass a credit
- of the t_fair*FAIR_MEM (algorithm resolution) */
- bp->cmng.fair_vars.upper_bound = r_param * t_fair * FAIR_MEM;
- /* since each tick is 4 usec */
- bp->cmng.fair_vars.fairness_timeout = fair_periodic_timeout_usec / 4;
-}
/* Calculates the sum of vn_min_rates.
It's needed for further normalizing of the min_rates.
@@ -2273,12 +2166,12 @@
In the later case fainess algorithm should be deactivated.
If not all min_rates are zero then those that are zeroes will be set to 1.
*/
-static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
+static void bnx2x_calc_vn_min(struct bnx2x *bp,
+ struct cmng_init_input *input)
{
int all_zero = 1;
int vn;
- bp->vn_weight_sum = 0;
for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++) {
u32 vn_cfg = bp->mf_config[vn];
u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
@@ -2286,106 +2179,56 @@
/* Skip hidden vns */
if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
- continue;
-
+ vn_min_rate = 0;
/* If min rate is zero - set it to 1 */
- if (!vn_min_rate)
+ else if (!vn_min_rate)
vn_min_rate = DEF_MIN_RATE;
else
all_zero = 0;
- bp->vn_weight_sum += vn_min_rate;
+ input->vnic_min_rate[vn] = vn_min_rate;
}
/* if ETS or all min rates are zeros - disable fairness */
if (BNX2X_IS_ETS_ENABLED(bp)) {
- bp->cmng.flags.cmng_enables &=
+ input->flags.cmng_enables &=
~CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
DP(NETIF_MSG_IFUP, "Fairness will be disabled due to ETS\n");
} else if (all_zero) {
- bp->cmng.flags.cmng_enables &=
+ input->flags.cmng_enables &=
~CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
- DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
- " fairness will be disabled\n");
+ DP(NETIF_MSG_IFUP,
+ "All MIN values are zeroes fairness will be disabled\n");
} else
- bp->cmng.flags.cmng_enables |=
+ input->flags.cmng_enables |=
CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
}
-static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn)
+static void bnx2x_calc_vn_max(struct bnx2x *bp, int vn,
+ struct cmng_init_input *input)
{
- struct rate_shaping_vars_per_vn m_rs_vn;
- struct fairness_vars_per_vn m_fair_vn;
+ u16 vn_max_rate;
u32 vn_cfg = bp->mf_config[vn];
- int func = func_by_vn(bp, vn);
- u16 vn_min_rate, vn_max_rate;
- int i;
- /* If function is hidden - set min and max to zeroes */
- if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE) {
- vn_min_rate = 0;
+ if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
vn_max_rate = 0;
-
- } else {
+ else {
u32 maxCfg = bnx2x_extract_max_cfg(bp, vn_cfg);
- vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
- FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
- /* If fairness is enabled (not all min rates are zeroes) and
- if current min rate is zero - set it to 1.
- This is a requirement of the algorithm. */
- if (bp->vn_weight_sum && (vn_min_rate == 0))
- vn_min_rate = DEF_MIN_RATE;
-
- if (IS_MF_SI(bp))
+ if (IS_MF_SI(bp)) {
/* maxCfg in percents of linkspeed */
vn_max_rate = (bp->link_vars.line_speed * maxCfg) / 100;
- else
+ } else /* SD modes */
/* maxCfg is absolute in 100Mb units */
vn_max_rate = maxCfg * 100;
}
- DP(NETIF_MSG_IFUP,
- "func %d: vn_min_rate %d vn_max_rate %d vn_weight_sum %d\n",
- func, vn_min_rate, vn_max_rate, bp->vn_weight_sum);
+ DP(NETIF_MSG_IFUP, "vn %d: vn_max_rate %d\n", vn, vn_max_rate);
- memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
- memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn));
-
- /* global vn counter - maximal Mbps for this vn */
- m_rs_vn.vn_counter.rate = vn_max_rate;
-
- /* quota - number of bytes transmitted in this period */
- m_rs_vn.vn_counter.quota =
- (vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8;
-
- if (bp->vn_weight_sum) {
- /* credit for each period of the fairness algorithm:
- number of bytes in T_FAIR (the vn share the port rate).
- vn_weight_sum should not be larger than 10000, thus
- T_FAIR_COEF / (8 * vn_weight_sum) will always be greater
- than zero */
- m_fair_vn.vn_credit_delta =
- max_t(u32, (vn_min_rate * (T_FAIR_COEF /
- (8 * bp->vn_weight_sum))),
- (bp->cmng.fair_vars.fair_threshold +
- MIN_ABOVE_THRESH));
- DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta %d\n",
- m_fair_vn.vn_credit_delta);
- }
-
- /* Store it to internal memory */
- for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(func) + i * 4,
- ((u32 *)(&m_rs_vn))[i]);
-
- for (i = 0; i < sizeof(struct fairness_vars_per_vn)/4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + i * 4,
- ((u32 *)(&m_fair_vn))[i]);
+ input->vnic_max_rate[vn] = vn_max_rate;
}
+
static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp)
{
if (CHIP_REV_IS_SLOW(bp))
@@ -2427,34 +2270,31 @@
static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type)
{
+ struct cmng_init_input input;
+ memset(&input, 0, sizeof(struct cmng_init_input));
+
+ input.port_rate = bp->link_vars.line_speed;
if (cmng_type == CMNG_FNS_MINMAX) {
int vn;
- /* clear cmng_enables */
- bp->cmng.flags.cmng_enables = 0;
-
/* read mf conf from shmem */
if (read_cfg)
bnx2x_read_mf_cfg(bp);
- /* Init rate shaping and fairness contexts */
- bnx2x_init_port_minmax(bp);
-
/* vn_weight_sum and enable fairness if not 0 */
- bnx2x_calc_vn_weight_sum(bp);
+ bnx2x_calc_vn_min(bp, &input);
/* calculate and set min-max rate for each vn */
if (bp->port.pmf)
for (vn = VN_0; vn < BP_MAX_VN_NUM(bp); vn++)
- bnx2x_init_vn_minmax(bp, vn);
+ bnx2x_calc_vn_max(bp, vn, &input);
/* always enable rate shaping and fairness */
- bp->cmng.flags.cmng_enables |=
+ input.flags.cmng_enables |=
CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
- if (!bp->vn_weight_sum)
- DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
- " fairness will be disabled\n");
+
+ bnx2x_init_cmng(&input, &bp->cmng);
return;
}
@@ -6640,13 +6480,16 @@
static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr)
{
int reg;
+ u32 wb_write[2];
if (CHIP_IS_E1(bp))
reg = PXP2_REG_RQ_ONCHIP_AT + index*8;
else
reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8;
- bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr));
+ wb_write[0] = ONCHIP_ADDR1(addr);
+ wb_write[1] = ONCHIP_ADDR2(addr);
+ REG_WR_DMAE(bp, reg, wb_write, 2);
}
static inline void bnx2x_igu_clear_sb(struct bnx2x *bp, u8 idu_sb_id)
@@ -7230,7 +7073,7 @@
BNX2X_DEV_INFO("set number of queues to 1\n");
break;
default:
- /* Set number of queues according to bp->multi_mode value */
+ /* Set number of queues for MSI-X mode */
bnx2x_set_num_queues(bp);
BNX2X_DEV_INFO("set number of queues to %d\n", bp->num_queues);
@@ -7239,15 +7082,17 @@
* so try to enable MSI-X with the requested number of fp's
* and fallback to MSI or legacy INTx with one fp
*/
- if (bnx2x_enable_msix(bp)) {
- /* failed to enable MSI-X */
- BNX2X_DEV_INFO("Failed to enable MSI-X (%d), set number of queues to %d\n",
+ if (bnx2x_enable_msix(bp) ||
+ bp->flags & USING_SINGLE_MSIX_FLAG) {
+ /* failed to enable multiple MSI-X */
+ BNX2X_DEV_INFO("Failed to enable multiple MSI-X (%d), set number of queues to %d\n",
bp->num_queues, 1 + NON_ETH_CONTEXT_USE);
bp->num_queues = 1 + NON_ETH_CONTEXT_USE;
/* Try to enable MSI */
- if (!(bp->flags & DISABLE_MSI_FLAG))
+ if (!(bp->flags & USING_SINGLE_MSIX_FLAG) &&
+ !(bp->flags & DISABLE_MSI_FLAG))
bnx2x_enable_msi(bp);
}
break;
@@ -9201,6 +9046,17 @@
id |= (val & 0xf);
bp->common.chip_id = id;
+ /* force 57811 according to MISC register */
+ if (REG_RD(bp, MISC_REG_CHIP_TYPE) & MISC_REG_CHIP_TYPE_57811_MASK) {
+ if (CHIP_IS_57810(bp))
+ bp->common.chip_id = (CHIP_NUM_57811 << 16) |
+ (bp->common.chip_id & 0x0000FFFF);
+ else if (CHIP_IS_57810_MF(bp))
+ bp->common.chip_id = (CHIP_NUM_57811_MF << 16) |
+ (bp->common.chip_id & 0x0000FFFF);
+ bp->common.chip_id |= 0x1;
+ }
+
/* Set doorbell size */
bp->db_size = (1 << BNX2X_DB_SHIFT);
@@ -10384,8 +10240,6 @@
if (BP_NOMCP(bp) && (func == 0))
dev_err(&bp->pdev->dev, "MCP disabled, must load devices in order!\n");
- bp->multi_mode = multi_mode;
-
bp->disable_tpa = disable_tpa;
#ifdef BCM_CNIC
@@ -11325,6 +11179,8 @@
case BCM57810_MF:
case BCM57840:
case BCM57840_MF:
+ case BCM57811:
+ case BCM57811_MF:
max_cos_est = BNX2X_MULTI_TX_COS_E3B0;
break;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index c25803b..bbd3874 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -1483,6 +1483,11 @@
starts at 0x0 for the A0 tape-out and increments by one for each
all-layer tape-out. */
#define MISC_REG_CHIP_REV 0xa40c
+/* [R 14] otp_misc_do[100:0] spare bits collection: 13:11-
+ * otp_misc_do[100:98]; 10:7 - otp_misc_do[87:84]; 6:3 - otp_misc_do[75:72];
+ * 2:1 - otp_misc_do[51:50]; 0 - otp_misc_do[1]. */
+#define MISC_REG_CHIP_TYPE 0xac60
+#define MISC_REG_CHIP_TYPE_57811_MASK (1<<1)
/* [RW 32] The following driver registers(1...16) represent 16 drivers and
32 clients. Each client can be controlled by one driver only. One in each
bit represent that this driver control the appropriate client (Ex: bit 5
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index 5135733..553b987 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -4090,12 +4090,6 @@
rss_mode = ETH_RSS_MODE_DISABLED;
else if (test_bit(BNX2X_RSS_MODE_REGULAR, &p->rss_flags))
rss_mode = ETH_RSS_MODE_REGULAR;
- else if (test_bit(BNX2X_RSS_MODE_VLAN_PRI, &p->rss_flags))
- rss_mode = ETH_RSS_MODE_VLAN_PRI;
- else if (test_bit(BNX2X_RSS_MODE_E1HOV_PRI, &p->rss_flags))
- rss_mode = ETH_RSS_MODE_E1HOV_PRI;
- else if (test_bit(BNX2X_RSS_MODE_IP_DSCP, &p->rss_flags))
- rss_mode = ETH_RSS_MODE_IP_DSCP;
data->rss_mode = rss_mode;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
index 61a7670..dee2f37 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
@@ -685,9 +685,6 @@
/* RSS_MODE bits are mutually exclusive */
BNX2X_RSS_MODE_DISABLED,
BNX2X_RSS_MODE_REGULAR,
- BNX2X_RSS_MODE_VLAN_PRI,
- BNX2X_RSS_MODE_E1HOV_PRI,
- BNX2X_RSS_MODE_IP_DSCP,
BNX2X_RSS_SET_SRCH, /* Setup searcher, E1x specific flag */
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 062ac33..0c3e7c7 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -12234,6 +12234,7 @@
.get_rxfh_indir_size = tg3_get_rxfh_indir_size,
.get_rxfh_indir = tg3_get_rxfh_indir,
.set_rxfh_indir = tg3_set_rxfh_indir,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev,
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
index 77977d7..0b640fa 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
@@ -70,7 +70,6 @@
static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc);
static void bfa_ioc_mbox_flush(struct bfa_ioc *ioc);
static void bfa_ioc_recover(struct bfa_ioc *ioc);
-static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc);
static void bfa_ioc_event_notify(struct bfa_ioc *, enum bfa_ioc_event);
static void bfa_ioc_disable_comp(struct bfa_ioc *ioc);
static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc);
@@ -346,8 +345,6 @@
switch (event) {
case IOC_E_FWRSP_GETATTR:
del_timer(&ioc->ioc_timer);
- bfa_ioc_check_attr_wwns(ioc);
- bfa_ioc_hb_monitor(ioc);
bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
break;
@@ -380,6 +377,7 @@
{
ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED);
+ bfa_ioc_hb_monitor(ioc);
}
static void
@@ -1207,27 +1205,62 @@
writel(1, sem_reg);
}
+/* Clear fwver hdr */
+static void
+bfa_ioc_fwver_clear(struct bfa_ioc *ioc)
+{
+ u32 pgnum, pgoff, loff = 0;
+ int i;
+
+ pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
+ pgoff = PSS_SMEM_PGOFF(loff);
+ writel(pgnum, ioc->ioc_regs.host_page_num_fn);
+
+ for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32)); i++) {
+ writel(0, ioc->ioc_regs.smem_page_start + loff);
+ loff += sizeof(u32);
+ }
+}
+
+
static void
bfa_ioc_hw_sem_init(struct bfa_ioc *ioc)
{
struct bfi_ioc_image_hdr fwhdr;
- u32 fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+ u32 fwstate, r32;
- if (fwstate == BFI_IOC_UNINIT)
+ /* Spin on init semaphore to serialize. */
+ r32 = readl(ioc->ioc_regs.ioc_init_sem_reg);
+ while (r32 & 0x1) {
+ udelay(20);
+ r32 = readl(ioc->ioc_regs.ioc_init_sem_reg);
+ }
+
+ fwstate = readl(ioc->ioc_regs.ioc_fwstate);
+ if (fwstate == BFI_IOC_UNINIT) {
+ writel(1, ioc->ioc_regs.ioc_init_sem_reg);
return;
+ }
bfa_nw_ioc_fwver_get(ioc, &fwhdr);
- if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL)
+ if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) {
+ writel(1, ioc->ioc_regs.ioc_init_sem_reg);
return;
+ }
+ bfa_ioc_fwver_clear(ioc);
writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+ writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
/*
* Try to lock and then unlock the semaphore.
*/
readl(ioc->ioc_regs.ioc_sem_reg);
writel(1, ioc->ioc_regs.ioc_sem_reg);
+
+ /* Unlock init semaphore */
+ writel(1, ioc->ioc_regs.ioc_init_sem_reg);
}
static void
@@ -1585,11 +1618,6 @@
u32 i;
u32 asicmode;
- /**
- * Initialize LMEM first before code download
- */
- bfa_ioc_lmem_init(ioc);
-
fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno);
pgnum = bfa_ioc_smem_pgnum(ioc, loff);
@@ -1914,6 +1942,10 @@
bfa_ioc_pll_init_asic(ioc);
ioc->pllinit = true;
+
+ /* Initialize LMEM */
+ bfa_ioc_lmem_init(ioc);
+
/*
* release semaphore.
*/
@@ -2513,13 +2545,6 @@
bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
}
-static void
-bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc)
-{
- if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL)
- return;
-}
-
/**
* @dg hal_iocpf_pvt BFA IOC PF private functions
* @{
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c
index 348479b..b6b036a 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc_ct.c
@@ -199,9 +199,9 @@
* Host to LPU mailbox message addresses
*/
static const struct {
- u32 hfn_mbox;
- u32 lpu_mbox;
- u32 hfn_pgn;
+ u32 hfn_mbox;
+ u32 lpu_mbox;
+ u32 hfn_pgn;
} ct_fnreg[] = {
{ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
{ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
@@ -803,17 +803,72 @@
}
#define CT2_NFC_MAX_DELAY 1000
+#define CT2_NFC_VER_VALID 0x143
+#define BFA_IOC_PLL_POLL 1000000
+
+static bool
+bfa_ioc_ct2_nfc_halted(void __iomem *rb)
+{
+ volatile u32 r32;
+
+ r32 = readl(rb + CT2_NFC_CSR_SET_REG);
+ if (r32 & __NFC_CONTROLLER_HALTED)
+ return true;
+
+ return false;
+}
+
+static void
+bfa_ioc_ct2_nfc_resume(void __iomem *rb)
+{
+ volatile u32 r32;
+ int i;
+
+ writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_CLR_REG);
+ for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
+ r32 = readl(rb + CT2_NFC_CSR_SET_REG);
+ if (!(r32 & __NFC_CONTROLLER_HALTED))
+ return;
+ udelay(1000);
+ }
+ BUG_ON(1);
+}
+
static enum bfa_status
bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode asic_mode)
{
volatile u32 wgn, r32;
- int i;
+ u32 nfc_ver, i;
- /*
- * Initialize PLL if not already done by NFC
- */
wgn = readl(rb + CT2_WGN_STATUS);
- if (!(wgn & __GLBL_PF_VF_CFG_RDY)) {
+
+ nfc_ver = readl(rb + CT2_RSC_GPR15_REG);
+
+ if ((wgn == (__A2T_AHB_LOAD | __WGN_READY)) &&
+ (nfc_ver >= CT2_NFC_VER_VALID)) {
+ if (bfa_ioc_ct2_nfc_halted(rb))
+ bfa_ioc_ct2_nfc_resume(rb);
+ writel(__RESET_AND_START_SCLK_LCLK_PLLS,
+ rb + CT2_CSI_FW_CTL_SET_REG);
+
+ for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+ r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
+ if (r32 & __RESET_AND_START_SCLK_LCLK_PLLS)
+ break;
+ }
+ BUG_ON(!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS));
+
+ for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+ r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
+ if (!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS))
+ break;
+ }
+ BUG_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
+ udelay(1000);
+
+ r32 = readl(rb + CT2_CSI_FW_CTL_REG);
+ BUG_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
+ } else {
writel(__HALT_NFC_CONTROLLER, (rb + CT2_NFC_CSR_SET_REG));
for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
r32 = readl(rb + CT2_NFC_CSR_SET_REG);
@@ -821,53 +876,48 @@
break;
udelay(1000);
}
+
+ bfa_ioc_ct2_mac_reset(rb);
+ bfa_ioc_ct2_sclk_init(rb);
+ bfa_ioc_ct2_lclk_init(rb);
+
+ /* release soft reset on s_clk & l_clk */
+ r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
+ writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
+ rb + CT2_APP_PLL_SCLK_CTL_REG);
+ r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
+ writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
+ rb + CT2_APP_PLL_LCLK_CTL_REG);
+ }
+
+ /* Announce flash device presence, if flash was corrupted. */
+ if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
+ r32 = readl((rb + PSS_GPIO_OUT_REG));
+ writel(r32 & ~1, rb + PSS_GPIO_OUT_REG);
+ r32 = readl((rb + PSS_GPIO_OE_REG));
+ writel(r32 | 1, rb + PSS_GPIO_OE_REG);
}
/*
* Mask the interrupts and clear any
* pending interrupts left by BIOS/EFI
*/
-
writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK));
writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK));
- r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
- if (r32 == 1) {
- writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT));
- readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
- }
- r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
- if (r32 == 1) {
- writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT));
- readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
- }
-
- bfa_ioc_ct2_mac_reset(rb);
- bfa_ioc_ct2_sclk_init(rb);
- bfa_ioc_ct2_lclk_init(rb);
-
- /*
- * release soft reset on s_clk & l_clk
- */
- r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
- writel((r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET),
- (rb + CT2_APP_PLL_SCLK_CTL_REG));
-
- /*
- * release soft reset on s_clk & l_clk
- */
- r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
- writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
- (rb + CT2_APP_PLL_LCLK_CTL_REG));
-
- /*
- * Announce flash device presence, if flash was corrupted.
- */
- if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
- r32 = readl((rb + PSS_GPIO_OUT_REG));
- writel((r32 & ~1), (rb + PSS_GPIO_OUT_REG));
- r32 = readl((rb + PSS_GPIO_OE_REG));
- writel((r32 | 1), (rb + PSS_GPIO_OE_REG));
+ /* For first time initialization, no need to clear interrupts */
+ r32 = readl(rb + HOST_SEM5_REG);
+ if (r32 & 0x1) {
+ r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
+ if (r32 == 1) {
+ writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT));
+ readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
+ }
+ r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
+ if (r32 == 1) {
+ writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT));
+ readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
+ }
}
bfa_ioc_ct2_mem_init(rb);
diff --git a/drivers/net/ethernet/brocade/bna/bfi_reg.h b/drivers/net/ethernet/brocade/bna/bfi_reg.h
index efacff3..0e094fe 100644
--- a/drivers/net/ethernet/brocade/bna/bfi_reg.h
+++ b/drivers/net/ethernet/brocade/bna/bfi_reg.h
@@ -339,10 +339,16 @@
#define __A2T_AHB_LOAD 0x00000800
#define __WGN_READY 0x00000400
#define __GLBL_PF_VF_CFG_RDY 0x00000200
+#define CT2_NFC_CSR_CLR_REG 0x00027420
#define CT2_NFC_CSR_SET_REG 0x00027424
#define __HALT_NFC_CONTROLLER 0x00000002
#define __NFC_CONTROLLER_HALTED 0x00001000
+#define CT2_RSC_GPR15_REG 0x0002765c
+#define CT2_CSI_FW_CTL_REG 0x00027080
+#define __RESET_AND_START_SCLK_LCLK_PLLS 0x00010000
+#define CT2_CSI_FW_CTL_SET_REG 0x00027088
+
#define CT2_CSI_MAC0_CONTROL_REG 0x000270d0
#define __CSI_MAC_RESET 0x00000010
#define __CSI_MAC_AHB_RESET 0x00000008
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index ff78f77..25c4e7f 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -80,8 +80,6 @@
(sizeof(struct bnad_skb_unmap) * ((_depth) - 1)); \
} while (0)
-#define BNAD_TXRX_SYNC_MDELAY 250 /* 250 msecs */
-
static void
bnad_add_to_list(struct bnad *bnad)
{
@@ -103,7 +101,7 @@
* Reinitialize completions in CQ, once Rx is taken down
*/
static void
-bnad_cq_cmpl_init(struct bnad *bnad, struct bna_ccb *ccb)
+bnad_cq_cleanup(struct bnad *bnad, struct bna_ccb *ccb)
{
struct bna_cq_entry *cmpl, *next_cmpl;
unsigned int wi_range, wis = 0, ccb_prod = 0;
@@ -141,7 +139,8 @@
for (j = 0; j < frag; j++) {
dma_unmap_page(pdev, dma_unmap_addr(&array[index], dma_addr),
- skb_frag_size(&skb_shinfo(skb)->frags[j]), DMA_TO_DEVICE);
+ skb_frag_size(&skb_shinfo(skb)->frags[j]),
+ DMA_TO_DEVICE);
dma_unmap_addr_set(&array[index], dma_addr, 0);
BNA_QE_INDX_ADD(index, 1, depth);
}
@@ -155,7 +154,7 @@
* so DMA unmap & freeing is fine.
*/
static void
-bnad_free_all_txbufs(struct bnad *bnad,
+bnad_txq_cleanup(struct bnad *bnad,
struct bna_tcb *tcb)
{
u32 unmap_cons;
@@ -183,13 +182,12 @@
/* Data Path Handlers */
/*
- * bnad_free_txbufs : Frees the Tx bufs on Tx completion
+ * bnad_txcmpl_process : Frees the Tx bufs on Tx completion
* Can be called in a) Interrupt context
* b) Sending context
- * c) Tasklet context
*/
static u32
-bnad_free_txbufs(struct bnad *bnad,
+bnad_txcmpl_process(struct bnad *bnad,
struct bna_tcb *tcb)
{
u32 unmap_cons, sent_packets = 0, sent_bytes = 0;
@@ -198,13 +196,7 @@
struct bnad_skb_unmap *unmap_array;
struct sk_buff *skb;
- /*
- * Just return if TX is stopped. This check is useful
- * when bnad_free_txbufs() runs out of a tasklet scheduled
- * before bnad_cb_tx_cleanup() cleared BNAD_TXQ_TX_STARTED bit
- * but this routine runs actually after the cleanup has been
- * executed.
- */
+ /* Just return if TX is stopped */
if (!test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
return 0;
@@ -243,57 +235,8 @@
return sent_packets;
}
-/* Tx Free Tasklet function */
-/* Frees for all the tcb's in all the Tx's */
-/*
- * Scheduled from sending context, so that
- * the fat Tx lock is not held for too long
- * in the sending context.
- */
-static void
-bnad_tx_free_tasklet(unsigned long bnad_ptr)
-{
- struct bnad *bnad = (struct bnad *)bnad_ptr;
- struct bna_tcb *tcb;
- u32 acked = 0;
- int i, j;
-
- for (i = 0; i < bnad->num_tx; i++) {
- for (j = 0; j < bnad->num_txq_per_tx; j++) {
- tcb = bnad->tx_info[i].tcb[j];
- if (!tcb)
- continue;
- if (((u16) (*tcb->hw_consumer_index) !=
- tcb->consumer_index) &&
- (!test_and_set_bit(BNAD_TXQ_FREE_SENT,
- &tcb->flags))) {
- acked = bnad_free_txbufs(bnad, tcb);
- if (likely(test_bit(BNAD_TXQ_TX_STARTED,
- &tcb->flags)))
- bna_ib_ack(tcb->i_dbell, acked);
- smp_mb__before_clear_bit();
- clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
- }
- if (unlikely(!test_bit(BNAD_TXQ_TX_STARTED,
- &tcb->flags)))
- continue;
- if (netif_queue_stopped(bnad->netdev)) {
- if (acked && netif_carrier_ok(bnad->netdev) &&
- BNA_QE_FREE_CNT(tcb, tcb->q_depth) >=
- BNAD_NETIF_WAKE_THRESHOLD) {
- netif_wake_queue(bnad->netdev);
- /* TODO */
- /* Counters for individual TxQs? */
- BNAD_UPDATE_CTR(bnad,
- netif_queue_wakeup);
- }
- }
- }
- }
-}
-
static u32
-bnad_tx(struct bnad *bnad, struct bna_tcb *tcb)
+bnad_tx_complete(struct bnad *bnad, struct bna_tcb *tcb)
{
struct net_device *netdev = bnad->netdev;
u32 sent = 0;
@@ -301,7 +244,7 @@
if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
return 0;
- sent = bnad_free_txbufs(bnad, tcb);
+ sent = bnad_txcmpl_process(bnad, tcb);
if (sent) {
if (netif_queue_stopped(netdev) &&
netif_carrier_ok(netdev) &&
@@ -330,13 +273,13 @@
struct bna_tcb *tcb = (struct bna_tcb *)data;
struct bnad *bnad = tcb->bnad;
- bnad_tx(bnad, tcb);
+ bnad_tx_complete(bnad, tcb);
return IRQ_HANDLED;
}
static void
-bnad_reset_rcb(struct bnad *bnad, struct bna_rcb *rcb)
+bnad_rcb_cleanup(struct bnad *bnad, struct bna_rcb *rcb)
{
struct bnad_unmap_q *unmap_q = rcb->unmap_q;
@@ -348,7 +291,7 @@
}
static void
-bnad_free_all_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
+bnad_rxq_cleanup(struct bnad *bnad, struct bna_rcb *rcb)
{
struct bnad_unmap_q *unmap_q;
struct bnad_skb_unmap *unmap_array;
@@ -369,11 +312,11 @@
DMA_FROM_DEVICE);
dev_kfree_skb(skb);
}
- bnad_reset_rcb(bnad, rcb);
+ bnad_rcb_cleanup(bnad, rcb);
}
static void
-bnad_alloc_n_post_rxbufs(struct bnad *bnad, struct bna_rcb *rcb)
+bnad_rxq_post(struct bnad *bnad, struct bna_rcb *rcb)
{
u16 to_alloc, alloced, unmap_prod, wi_range;
struct bnad_unmap_q *unmap_q = rcb->unmap_q;
@@ -434,14 +377,14 @@
if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
>> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
- bnad_alloc_n_post_rxbufs(bnad, rcb);
+ bnad_rxq_post(bnad, rcb);
smp_mb__before_clear_bit();
clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
}
}
static u32
-bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget)
+bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget)
{
struct bna_cq_entry *cmpl, *next_cmpl;
struct bna_rcb *rcb = NULL;
@@ -453,12 +396,8 @@
struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate;
struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl);
- set_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
-
- if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)) {
- clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
+ if (!test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))
return 0;
- }
prefetch(bnad->netdev);
BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl,
@@ -533,9 +472,8 @@
if (skb->ip_summed == CHECKSUM_UNNECESSARY)
napi_gro_receive(&rx_ctrl->napi, skb);
- else {
+ else
netif_receive_skb(skb);
- }
next:
cmpl->valid = 0;
@@ -646,7 +584,7 @@
for (j = 0; j < bnad->num_txq_per_tx; j++) {
tcb = bnad->tx_info[i].tcb[j];
if (tcb && test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
- bnad_tx(bnad, bnad->tx_info[i].tcb[j]);
+ bnad_tx_complete(bnad, bnad->tx_info[i].tcb[j]);
}
}
/* Rx processing */
@@ -839,20 +777,9 @@
{
struct bnad_tx_info *tx_info =
(struct bnad_tx_info *)tcb->txq->tx->priv;
- struct bnad_unmap_q *unmap_q = tcb->unmap_q;
-
- while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
- cpu_relax();
-
- bnad_free_all_txbufs(bnad, tcb);
-
- unmap_q->producer_index = 0;
- unmap_q->consumer_index = 0;
-
- smp_mb__before_clear_bit();
- clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
tx_info->tcb[tcb->id] = NULL;
+ tcb->priv = NULL;
}
static void
@@ -866,12 +793,6 @@
}
static void
-bnad_cb_rcb_destroy(struct bnad *bnad, struct bna_rcb *rcb)
-{
- bnad_free_all_rxbufs(bnad, rcb);
-}
-
-static void
bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb)
{
struct bnad_rx_info *rx_info =
@@ -916,7 +837,6 @@
{
struct bnad_tx_info *tx_info = (struct bnad_tx_info *)tx->priv;
struct bna_tcb *tcb;
- struct bnad_unmap_q *unmap_q;
u32 txq_id;
int i;
@@ -926,23 +846,9 @@
continue;
txq_id = tcb->id;
- unmap_q = tcb->unmap_q;
-
- if (test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags))
- continue;
-
- while (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags))
- cpu_relax();
-
- bnad_free_all_txbufs(bnad, tcb);
-
- unmap_q->producer_index = 0;
- unmap_q->consumer_index = 0;
-
- smp_mb__before_clear_bit();
- clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
-
+ BUG_ON(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags));
set_bit(BNAD_TXQ_TX_STARTED, &tcb->flags);
+ BUG_ON(*(tcb->hw_consumer_index) != 0);
if (netif_carrier_ok(bnad->netdev)) {
printk(KERN_INFO "bna: %s %d TXQ_STARTED\n",
@@ -963,6 +869,54 @@
}
}
+/*
+ * Free all TxQs buffers and then notify TX_E_CLEANUP_DONE to Tx fsm.
+ */
+static void
+bnad_tx_cleanup(struct delayed_work *work)
+{
+ struct bnad_tx_info *tx_info =
+ container_of(work, struct bnad_tx_info, tx_cleanup_work);
+ struct bnad *bnad = NULL;
+ struct bnad_unmap_q *unmap_q;
+ struct bna_tcb *tcb;
+ unsigned long flags;
+ uint32_t i, pending = 0;
+
+ for (i = 0; i < BNAD_MAX_TXQ_PER_TX; i++) {
+ tcb = tx_info->tcb[i];
+ if (!tcb)
+ continue;
+
+ bnad = tcb->bnad;
+
+ if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
+ pending++;
+ continue;
+ }
+
+ bnad_txq_cleanup(bnad, tcb);
+
+ unmap_q = tcb->unmap_q;
+ unmap_q->producer_index = 0;
+ unmap_q->consumer_index = 0;
+
+ smp_mb__before_clear_bit();
+ clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags);
+ }
+
+ if (pending) {
+ queue_delayed_work(bnad->work_q, &tx_info->tx_cleanup_work,
+ msecs_to_jiffies(1));
+ return;
+ }
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_tx_cleanup_complete(tx_info->tx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
+
static void
bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx)
{
@@ -976,8 +930,7 @@
continue;
}
- mdelay(BNAD_TXRX_SYNC_MDELAY);
- bna_tx_cleanup_complete(tx);
+ queue_delayed_work(bnad->work_q, &tx_info->tx_cleanup_work, 0);
}
static void
@@ -1001,6 +954,44 @@
}
}
+/*
+ * Free all RxQs buffers and then notify RX_E_CLEANUP_DONE to Rx fsm.
+ */
+static void
+bnad_rx_cleanup(void *work)
+{
+ struct bnad_rx_info *rx_info =
+ container_of(work, struct bnad_rx_info, rx_cleanup_work);
+ struct bnad_rx_ctrl *rx_ctrl;
+ struct bnad *bnad = NULL;
+ unsigned long flags;
+ uint32_t i;
+
+ for (i = 0; i < BNAD_MAX_RXP_PER_RX; i++) {
+ rx_ctrl = &rx_info->rx_ctrl[i];
+
+ if (!rx_ctrl->ccb)
+ continue;
+
+ bnad = rx_ctrl->ccb->bnad;
+
+ /*
+ * Wait till the poll handler has exited
+ * and nothing can be scheduled anymore
+ */
+ napi_disable(&rx_ctrl->napi);
+
+ bnad_cq_cleanup(bnad, rx_ctrl->ccb);
+ bnad_rxq_cleanup(bnad, rx_ctrl->ccb->rcb[0]);
+ if (rx_ctrl->ccb->rcb[1])
+ bnad_rxq_cleanup(bnad, rx_ctrl->ccb->rcb[1]);
+ }
+
+ spin_lock_irqsave(&bnad->bna_lock, flags);
+ bna_rx_cleanup_complete(rx_info->rx);
+ spin_unlock_irqrestore(&bnad->bna_lock, flags);
+}
+
static void
bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_rx *rx)
{
@@ -1009,8 +1000,6 @@
struct bnad_rx_ctrl *rx_ctrl;
int i;
- mdelay(BNAD_TXRX_SYNC_MDELAY);
-
for (i = 0; i < BNAD_MAX_RXP_PER_RX; i++) {
rx_ctrl = &rx_info->rx_ctrl[i];
ccb = rx_ctrl->ccb;
@@ -1021,12 +1010,9 @@
if (ccb->rcb[1])
clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags);
-
- while (test_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags))
- cpu_relax();
}
- bna_rx_cleanup_complete(rx);
+ queue_work(bnad->work_q, &rx_info->rx_cleanup_work);
}
static void
@@ -1046,13 +1032,12 @@
if (!ccb)
continue;
- bnad_cq_cmpl_init(bnad, ccb);
+ napi_enable(&rx_ctrl->napi);
for (j = 0; j < BNAD_MAX_RXQ_PER_RXP; j++) {
rcb = ccb->rcb[j];
if (!rcb)
continue;
- bnad_free_all_rxbufs(bnad, rcb);
set_bit(BNAD_RXQ_STARTED, &rcb->flags);
set_bit(BNAD_RXQ_POST_OK, &rcb->flags);
@@ -1063,7 +1048,7 @@
if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) {
if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth)
>> BNAD_RXQ_REFILL_THRESHOLD_SHIFT)
- bnad_alloc_n_post_rxbufs(bnad, rcb);
+ bnad_rxq_post(bnad, rcb);
smp_mb__before_clear_bit();
clear_bit(BNAD_RXQ_REFILL, &rcb->flags);
}
@@ -1687,7 +1672,7 @@
if (!netif_carrier_ok(bnad->netdev))
goto poll_exit;
- rcvd = bnad_poll_cq(bnad, rx_ctrl->ccb, budget);
+ rcvd = bnad_cq_process(bnad, rx_ctrl->ccb, budget);
if (rcvd >= budget)
return rcvd;
@@ -1704,7 +1689,7 @@
#define BNAD_NAPI_POLL_QUOTA 64
static void
-bnad_napi_init(struct bnad *bnad, u32 rx_id)
+bnad_napi_add(struct bnad *bnad, u32 rx_id)
{
struct bnad_rx_ctrl *rx_ctrl;
int i;
@@ -1718,34 +1703,18 @@
}
static void
-bnad_napi_enable(struct bnad *bnad, u32 rx_id)
-{
- struct bnad_rx_ctrl *rx_ctrl;
- int i;
-
- /* Initialize & enable NAPI */
- for (i = 0; i < bnad->num_rxp_per_rx; i++) {
- rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i];
-
- napi_enable(&rx_ctrl->napi);
- }
-}
-
-static void
-bnad_napi_disable(struct bnad *bnad, u32 rx_id)
+bnad_napi_delete(struct bnad *bnad, u32 rx_id)
{
int i;
/* First disable and then clean up */
- for (i = 0; i < bnad->num_rxp_per_rx; i++) {
- napi_disable(&bnad->rx_info[rx_id].rx_ctrl[i].napi);
+ for (i = 0; i < bnad->num_rxp_per_rx; i++)
netif_napi_del(&bnad->rx_info[rx_id].rx_ctrl[i].napi);
- }
}
/* Should be held with conf_lock held */
void
-bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
+bnad_destroy_tx(struct bnad *bnad, u32 tx_id)
{
struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id];
struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0];
@@ -1764,9 +1733,6 @@
bnad_tx_msix_unregister(bnad, tx_info,
bnad->num_txq_per_tx);
- if (0 == tx_id)
- tasklet_kill(&bnad->tx_free_tasklet);
-
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_tx_destroy(tx_info->tx);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -1832,6 +1798,9 @@
goto err_return;
tx_info->tx = tx;
+ INIT_DELAYED_WORK(&tx_info->tx_cleanup_work,
+ (work_func_t)bnad_tx_cleanup);
+
/* Register ISR for the Tx object */
if (intr_info->intr_type == BNA_INTR_T_MSIX) {
err = bnad_tx_msix_register(bnad, tx_info,
@@ -1896,7 +1865,7 @@
/* Called with mutex_lock(&bnad->conf_mutex) held */
void
-bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
+bnad_destroy_rx(struct bnad *bnad, u32 rx_id)
{
struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
@@ -1928,7 +1897,7 @@
if (rx_info->rx_ctrl[0].ccb->intr_type == BNA_INTR_T_MSIX)
bnad_rx_msix_unregister(bnad, rx_info, rx_config->num_paths);
- bnad_napi_disable(bnad, rx_id);
+ bnad_napi_delete(bnad, rx_id);
spin_lock_irqsave(&bnad->bna_lock, flags);
bna_rx_destroy(rx_info->rx);
@@ -1952,7 +1921,7 @@
struct bna_rx_config *rx_config = &bnad->rx_config[rx_id];
static const struct bna_rx_event_cbfn rx_cbfn = {
.rcb_setup_cbfn = bnad_cb_rcb_setup,
- .rcb_destroy_cbfn = bnad_cb_rcb_destroy,
+ .rcb_destroy_cbfn = NULL,
.ccb_setup_cbfn = bnad_cb_ccb_setup,
.ccb_destroy_cbfn = bnad_cb_ccb_destroy,
.rx_stall_cbfn = bnad_cb_rx_stall,
@@ -1998,11 +1967,14 @@
rx_info->rx = rx;
spin_unlock_irqrestore(&bnad->bna_lock, flags);
+ INIT_WORK(&rx_info->rx_cleanup_work,
+ (work_func_t)(bnad_rx_cleanup));
+
/*
* Init NAPI, so that state is set to NAPI_STATE_SCHED,
* so that IRQ handler cannot schedule NAPI at this point.
*/
- bnad_napi_init(bnad, rx_id);
+ bnad_napi_add(bnad, rx_id);
/* Register ISR for the Rx object */
if (intr_info->intr_type == BNA_INTR_T_MSIX) {
@@ -2028,13 +2000,10 @@
bna_rx_enable(rx);
spin_unlock_irqrestore(&bnad->bna_lock, flags);
- /* Enable scheduling of NAPI */
- bnad_napi_enable(bnad, rx_id);
-
return 0;
err_return:
- bnad_cleanup_rx(bnad, rx_id);
+ bnad_destroy_rx(bnad, rx_id);
return err;
}
@@ -2519,7 +2488,7 @@
return 0;
cleanup_tx:
- bnad_cleanup_tx(bnad, 0);
+ bnad_destroy_tx(bnad, 0);
err_return:
mutex_unlock(&bnad->conf_mutex);
@@ -2546,8 +2515,8 @@
wait_for_completion(&bnad->bnad_completions.enet_comp);
- bnad_cleanup_tx(bnad, 0);
- bnad_cleanup_rx(bnad, 0);
+ bnad_destroy_tx(bnad, 0);
+ bnad_destroy_rx(bnad, 0);
/* Synchronize mailbox IRQ */
bnad_mbox_irq_sync(bnad);
@@ -2620,7 +2589,7 @@
if ((u16) (*tcb->hw_consumer_index) !=
tcb->consumer_index &&
!test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) {
- acked = bnad_free_txbufs(bnad, tcb);
+ acked = bnad_txcmpl_process(bnad, tcb);
if (likely(test_bit(BNAD_TXQ_TX_STARTED, &tcb->flags)))
bna_ib_ack(tcb->i_dbell, acked);
smp_mb__before_clear_bit();
@@ -2843,9 +2812,6 @@
bna_txq_prod_indx_doorbell(tcb);
smp_mb();
- if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index)
- tasklet_schedule(&bnad->tx_free_tasklet);
-
return NETDEV_TX_OK;
}
@@ -3127,8 +3093,8 @@
/*
* 1. Initialize the bnad structure
* 2. Setup netdev pointer in pci_dev
- * 3. Initialze Tx free tasklet
- * 4. Initialize no. of TxQ & CQs & MSIX vectors
+ * 3. Initialize no. of TxQ & CQs & MSIX vectors
+ * 4. Initialize work queue.
*/
static int
bnad_init(struct bnad *bnad,
@@ -3171,8 +3137,11 @@
bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO;
bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO;
- tasklet_init(&bnad->tx_free_tasklet, bnad_tx_free_tasklet,
- (unsigned long)bnad);
+ sprintf(bnad->wq_name, "%s_wq_%d", BNAD_NAME, bnad->id);
+ bnad->work_q = create_singlethread_workqueue(bnad->wq_name);
+
+ if (!bnad->work_q)
+ return -ENOMEM;
return 0;
}
@@ -3185,6 +3154,12 @@
static void
bnad_uninit(struct bnad *bnad)
{
+ if (bnad->work_q) {
+ flush_workqueue(bnad->work_q);
+ destroy_workqueue(bnad->work_q);
+ bnad->work_q = NULL;
+ }
+
if (bnad->bar0)
iounmap(bnad->bar0);
pci_set_drvdata(bnad->pcidev, NULL);
@@ -3304,7 +3279,6 @@
/*
* Initialize bnad structure
* Setup relation between pci_dev & netdev
- * Init Tx free tasklet
*/
err = bnad_init(bnad, pdev, netdev);
if (err)
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index 55824d9..72742be 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -71,7 +71,7 @@
#define BNAD_NAME "bna"
#define BNAD_NAME_LEN 64
-#define BNAD_VERSION "3.0.2.2"
+#define BNAD_VERSION "3.0.23.0"
#define BNAD_MAILBOX_MSIX_INDEX 0
#define BNAD_MAILBOX_MSIX_VECTORS 1
@@ -210,6 +210,7 @@
struct bna_tx *tx; /* 1:1 between tx_info & tx */
struct bna_tcb *tcb[BNAD_MAX_TXQ_PER_TX];
u32 tx_id;
+ struct delayed_work tx_cleanup_work;
} ____cacheline_aligned;
struct bnad_rx_info {
@@ -217,6 +218,7 @@
struct bnad_rx_ctrl rx_ctrl[BNAD_MAX_RXP_PER_RX];
u32 rx_id;
+ struct work_struct rx_cleanup_work;
} ____cacheline_aligned;
/* Unmap queues for Tx / Rx cleanup */
@@ -318,7 +320,7 @@
/* Burnt in MAC address */
mac_t perm_addr;
- struct tasklet_struct tx_free_tasklet;
+ struct workqueue_struct *work_q;
/* Statistics */
struct bnad_stats stats;
@@ -328,6 +330,7 @@
char adapter_name[BNAD_NAME_LEN];
char port_name[BNAD_NAME_LEN];
char mbox_irq_name[BNAD_NAME_LEN];
+ char wq_name[BNAD_NAME_LEN];
/* debugfs specific data */
char *regdata;
@@ -370,8 +373,8 @@
extern int bnad_setup_rx(struct bnad *bnad, u32 rx_id);
extern int bnad_setup_tx(struct bnad *bnad, u32 tx_id);
-extern void bnad_cleanup_tx(struct bnad *bnad, u32 tx_id);
-extern void bnad_cleanup_rx(struct bnad *bnad, u32 rx_id);
+extern void bnad_destroy_tx(struct bnad *bnad, u32 tx_id);
+extern void bnad_destroy_rx(struct bnad *bnad, u32 rx_id);
/* Timer start/stop protos */
extern void bnad_dim_timer_start(struct bnad *bnad);
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index ab753d7..40e1e84 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -464,7 +464,7 @@
for (i = 0; i < bnad->num_rx; i++) {
if (!bnad->rx_info[i].rx)
continue;
- bnad_cleanup_rx(bnad, i);
+ bnad_destroy_rx(bnad, i);
current_err = bnad_setup_rx(bnad, i);
if (current_err && !err)
err = current_err;
@@ -492,7 +492,7 @@
for (i = 0; i < bnad->num_tx; i++) {
if (!bnad->tx_info[i].tx)
continue;
- bnad_cleanup_tx(bnad, i);
+ bnad_destroy_tx(bnad, i);
current_err = bnad_setup_tx(bnad, i);
if (current_err && !err)
err = current_err;
@@ -539,7 +539,7 @@
}
static void
-bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string)
+bnad_get_strings(struct net_device *netdev, u32 stringset, u8 *string)
{
struct bnad *bnad = netdev_priv(netdev);
int i, j, q_num;
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index c4834c2..1466bc4 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -1213,6 +1213,7 @@
.set_settings = macb_set_settings,
.get_drvinfo = macb_get_drvinfo,
.get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 77b4e87..d7ac6c1 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1193,18 +1193,16 @@
if (err)
return err;
- NLA_PUT_U16(skb, IFLA_PORT_REQUEST, pp->request);
- NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
- if (pp->set & ENIC_SET_NAME)
- NLA_PUT(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX,
- pp->name);
- if (pp->set & ENIC_SET_INSTANCE)
- NLA_PUT(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX,
- pp->instance_uuid);
- if (pp->set & ENIC_SET_HOST)
- NLA_PUT(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX,
- pp->host_uuid);
-
+ if (nla_put_u16(skb, IFLA_PORT_REQUEST, pp->request) ||
+ nla_put_u16(skb, IFLA_PORT_RESPONSE, response) ||
+ ((pp->set & ENIC_SET_NAME) &&
+ nla_put(skb, IFLA_PORT_PROFILE, PORT_PROFILE_MAX, pp->name)) ||
+ ((pp->set & ENIC_SET_INSTANCE) &&
+ nla_put(skb, IFLA_PORT_INSTANCE_UUID, PORT_UUID_MAX,
+ pp->instance_uuid)) ||
+ ((pp->set & ENIC_SET_HOST) &&
+ nla_put(skb, IFLA_PORT_HOST_UUID, PORT_UUID_MAX, pp->host_uuid)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c
index 68f1c39..61cc093 100644
--- a/drivers/net/ethernet/dec/tulip/de2104x.c
+++ b/drivers/net/ethernet/dec/tulip/de2104x.c
@@ -1380,6 +1380,7 @@
static int de_open (struct net_device *dev)
{
struct de_private *de = netdev_priv(dev);
+ const int irq = de->pdev->irq;
int rc;
netif_dbg(de, ifup, dev, "enabling interface\n");
@@ -1394,10 +1395,9 @@
dw32(IntrMask, 0);
- rc = request_irq(dev->irq, de_interrupt, IRQF_SHARED, dev->name, dev);
+ rc = request_irq(irq, de_interrupt, IRQF_SHARED, dev->name, dev);
if (rc) {
- netdev_err(dev, "IRQ %d request failure, err=%d\n",
- dev->irq, rc);
+ netdev_err(dev, "IRQ %d request failure, err=%d\n", irq, rc);
goto err_out_free;
}
@@ -1413,7 +1413,7 @@
return 0;
err_out_free_irq:
- free_irq(dev->irq, dev);
+ free_irq(irq, dev);
err_out_free:
de_free_rings(de);
return rc;
@@ -1434,7 +1434,7 @@
netif_carrier_off(dev);
spin_unlock_irqrestore(&de->lock, flags);
- free_irq(dev->irq, dev);
+ free_irq(de->pdev->irq, dev);
de_free_rings(de);
de_adapter_sleep(de);
@@ -1444,6 +1444,7 @@
static void de_tx_timeout (struct net_device *dev)
{
struct de_private *de = netdev_priv(dev);
+ const int irq = de->pdev->irq;
netdev_dbg(dev, "NIC status %08x mode %08x sia %08x desc %u/%u/%u\n",
dr32(MacStatus), dr32(MacMode), dr32(SIAStatus),
@@ -1451,7 +1452,7 @@
del_timer_sync(&de->media_timer);
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock_irq(&de->lock);
de_stop_hw(de);
@@ -1459,12 +1460,12 @@
netif_carrier_off(dev);
spin_unlock_irq(&de->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
/* Update the error counts. */
__de_get_stats(de);
- synchronize_irq(dev->irq);
+ synchronize_irq(irq);
de_clean_rings(de);
de_init_rings(de);
@@ -2024,8 +2025,6 @@
goto err_out_res;
}
- dev->irq = pdev->irq;
-
/* obtain and check validity of PCI I/O address */
pciaddr = pci_resource_start(pdev, 1);
if (!pciaddr) {
@@ -2050,7 +2049,6 @@
pciaddr, pci_name(pdev));
goto err_out_res;
}
- dev->base_addr = (unsigned long) regs;
de->regs = regs;
de_adapter_wake(de);
@@ -2078,11 +2076,9 @@
goto err_out_iomap;
/* print info about board and interface just registered */
- netdev_info(dev, "%s at 0x%lx, %pM, IRQ %d\n",
+ netdev_info(dev, "%s at %p, %pM, IRQ %d\n",
de->de21040 ? "21040" : "21041",
- dev->base_addr,
- dev->dev_addr,
- dev->irq);
+ regs, dev->dev_addr, pdev->irq);
pci_set_drvdata(pdev, dev);
@@ -2130,9 +2126,11 @@
rtnl_lock();
if (netif_running (dev)) {
+ const int irq = pdev->irq;
+
del_timer_sync(&de->media_timer);
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock_irq(&de->lock);
de_stop_hw(de);
@@ -2141,12 +2139,12 @@
netif_carrier_off(dev);
spin_unlock_irq(&de->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
/* Update the error counts. */
__de_get_stats(de);
- synchronize_irq(dev->irq);
+ synchronize_irq(irq);
de_clean_rings(de);
de_adapter_sleep(de);
diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c
index 1eccf494..0ef5b68 100644
--- a/drivers/net/ethernet/dec/tulip/dmfe.c
+++ b/drivers/net/ethernet/dec/tulip/dmfe.c
@@ -150,6 +150,12 @@
#define DMFE_TX_TIMEOUT ((3*HZ)/2) /* tx packet time-out time 1.5 s" */
#define DMFE_TX_KICK (HZ/2) /* tx packet Kick-out time 0.5 s" */
+#define dw32(reg, val) iowrite32(val, ioaddr + (reg))
+#define dw16(reg, val) iowrite16(val, ioaddr + (reg))
+#define dr32(reg) ioread32(ioaddr + (reg))
+#define dr16(reg) ioread16(ioaddr + (reg))
+#define dr8(reg) ioread8(ioaddr + (reg))
+
#define DMFE_DBUG(dbug_now, msg, value) \
do { \
if (dmfe_debug || (dbug_now)) \
@@ -178,14 +184,6 @@
#define SROM_V41_CODE 0x14
-#define SROM_CLK_WRITE(data, ioaddr) \
- outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \
- udelay(5); \
- outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr); \
- udelay(5); \
- outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \
- udelay(5);
-
#define __CHK_IO_SIZE(pci_id, dev_rev) \
(( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x30) ) ? \
DM9102A_IO_SIZE: DM9102_IO_SIZE)
@@ -213,11 +211,11 @@
struct dmfe_board_info {
u32 chip_id; /* Chip vendor/Device ID */
u8 chip_revision; /* Chip revision */
- struct DEVICE *next_dev; /* next device */
+ struct net_device *next_dev; /* next device */
struct pci_dev *pdev; /* PCI device */
spinlock_t lock;
- long ioaddr; /* I/O base address */
+ void __iomem *ioaddr; /* I/O base address */
u32 cr0_data;
u32 cr5_data;
u32 cr6_data;
@@ -320,20 +318,20 @@
static int dmfe_stop(struct DEVICE *);
static void dmfe_set_filter_mode(struct DEVICE *);
static const struct ethtool_ops netdev_ethtool_ops;
-static u16 read_srom_word(long ,int);
+static u16 read_srom_word(void __iomem *, int);
static irqreturn_t dmfe_interrupt(int , void *);
#ifdef CONFIG_NET_POLL_CONTROLLER
static void poll_dmfe (struct net_device *dev);
#endif
-static void dmfe_descriptor_init(struct net_device *, unsigned long);
+static void dmfe_descriptor_init(struct net_device *);
static void allocate_rx_buffer(struct net_device *);
-static void update_cr6(u32, unsigned long);
+static void update_cr6(u32, void __iomem *);
static void send_filter_frame(struct DEVICE *);
static void dm9132_id_table(struct DEVICE *);
-static u16 phy_read(unsigned long, u8, u8, u32);
-static void phy_write(unsigned long, u8, u8, u16, u32);
-static void phy_write_1bit(unsigned long, u32);
-static u16 phy_read_1bit(unsigned long);
+static u16 phy_read(void __iomem *, u8, u8, u32);
+static void phy_write(void __iomem *, u8, u8, u16, u32);
+static void phy_write_1bit(void __iomem *, u32);
+static u16 phy_read_1bit(void __iomem *);
static u8 dmfe_sense_speed(struct dmfe_board_info *);
static void dmfe_process_mode(struct dmfe_board_info *);
static void dmfe_timer(unsigned long);
@@ -462,14 +460,16 @@
db->buf_pool_dma_start = db->buf_pool_dma_ptr;
db->chip_id = ent->driver_data;
- db->ioaddr = pci_resource_start(pdev, 0);
+ /* IO type range. */
+ db->ioaddr = pci_iomap(pdev, 0, 0);
+ if (!db->ioaddr)
+ goto err_out_free_buf;
+
db->chip_revision = pdev->revision;
db->wol_mode = 0;
db->pdev = pdev;
- dev->base_addr = db->ioaddr;
- dev->irq = pdev->irq;
pci_set_drvdata(pdev, dev);
dev->netdev_ops = &netdev_ops;
dev->ethtool_ops = &netdev_ethtool_ops;
@@ -484,9 +484,10 @@
db->chip_type = 0;
/* read 64 word srom data */
- for (i = 0; i < 64; i++)
+ for (i = 0; i < 64; i++) {
((__le16 *) db->srom)[i] =
cpu_to_le16(read_srom_word(db->ioaddr, i));
+ }
/* Set Node address */
for (i = 0; i < 6; i++)
@@ -494,16 +495,18 @@
err = register_netdev (dev);
if (err)
- goto err_out_free_buf;
+ goto err_out_unmap;
dev_info(&dev->dev, "Davicom DM%04lx at pci%s, %pM, irq %d\n",
ent->driver_data >> 16,
- pci_name(pdev), dev->dev_addr, dev->irq);
+ pci_name(pdev), dev->dev_addr, pdev->irq);
pci_set_master(pdev);
return 0;
+err_out_unmap:
+ pci_iounmap(pdev, db->ioaddr);
err_out_free_buf:
pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
db->buf_pool_ptr, db->buf_pool_dma_ptr);
@@ -532,7 +535,7 @@
if (dev) {
unregister_netdev(dev);
-
+ pci_iounmap(db->pdev, db->ioaddr);
pci_free_consistent(db->pdev, sizeof(struct tx_desc) *
DESC_ALL_CNT + 0x20, db->desc_pool_ptr,
db->desc_pool_dma_ptr);
@@ -555,13 +558,13 @@
static int dmfe_open(struct DEVICE *dev)
{
- int ret;
struct dmfe_board_info *db = netdev_priv(dev);
+ const int irq = db->pdev->irq;
+ int ret;
DMFE_DBUG(0, "dmfe_open", 0);
- ret = request_irq(dev->irq, dmfe_interrupt,
- IRQF_SHARED, dev->name, dev);
+ ret = request_irq(irq, dmfe_interrupt, IRQF_SHARED, dev->name, dev);
if (ret)
return ret;
@@ -615,14 +618,14 @@
static void dmfe_init_dm910x(struct DEVICE *dev)
{
struct dmfe_board_info *db = netdev_priv(dev);
- unsigned long ioaddr = db->ioaddr;
+ void __iomem *ioaddr = db->ioaddr;
DMFE_DBUG(0, "dmfe_init_dm910x()", 0);
/* Reset DM910x MAC controller */
- outl(DM910X_RESET, ioaddr + DCR0); /* RESET MAC */
+ dw32(DCR0, DM910X_RESET); /* RESET MAC */
udelay(100);
- outl(db->cr0_data, ioaddr + DCR0);
+ dw32(DCR0, db->cr0_data);
udelay(5);
/* Phy addr : DM910(A)2/DM9132/9801, phy address = 1 */
@@ -633,12 +636,12 @@
db->media_mode = dmfe_media_mode;
/* RESET Phyxcer Chip by GPR port bit 7 */
- outl(0x180, ioaddr + DCR12); /* Let bit 7 output port */
+ dw32(DCR12, 0x180); /* Let bit 7 output port */
if (db->chip_id == PCI_DM9009_ID) {
- outl(0x80, ioaddr + DCR12); /* Issue RESET signal */
+ dw32(DCR12, 0x80); /* Issue RESET signal */
mdelay(300); /* Delay 300 ms */
}
- outl(0x0, ioaddr + DCR12); /* Clear RESET signal */
+ dw32(DCR12, 0x0); /* Clear RESET signal */
/* Process Phyxcer Media Mode */
if ( !(db->media_mode & 0x10) ) /* Force 1M mode */
@@ -649,7 +652,7 @@
db->op_mode = db->media_mode; /* Force Mode */
/* Initialize Transmit/Receive decriptor and CR3/4 */
- dmfe_descriptor_init(dev, ioaddr);
+ dmfe_descriptor_init(dev);
/* Init CR6 to program DM910x operation */
update_cr6(db->cr6_data, ioaddr);
@@ -662,10 +665,10 @@
/* Init CR7, interrupt active bit */
db->cr7_data = CR7_DEFAULT;
- outl(db->cr7_data, ioaddr + DCR7);
+ dw32(DCR7, db->cr7_data);
/* Init CR15, Tx jabber and Rx watchdog timer */
- outl(db->cr15_data, ioaddr + DCR15);
+ dw32(DCR15, db->cr15_data);
/* Enable DM910X Tx/Rx function */
db->cr6_data |= CR6_RXSC | CR6_TXSC | 0x40000;
@@ -682,6 +685,7 @@
struct DEVICE *dev)
{
struct dmfe_board_info *db = netdev_priv(dev);
+ void __iomem *ioaddr = db->ioaddr;
struct tx_desc *txptr;
unsigned long flags;
@@ -707,7 +711,7 @@
}
/* Disable NIC interrupt */
- outl(0, dev->base_addr + DCR7);
+ dw32(DCR7, 0);
/* transmit this packet */
txptr = db->tx_insert_ptr;
@@ -721,11 +725,11 @@
if ( (!db->tx_queue_cnt) && (db->tx_packet_cnt < TX_MAX_SEND_CNT) ) {
txptr->tdes0 = cpu_to_le32(0x80000000); /* Set owner bit */
db->tx_packet_cnt++; /* Ready to send */
- outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
+ dw32(DCR1, 0x1); /* Issue Tx polling */
dev->trans_start = jiffies; /* saved time stamp */
} else {
db->tx_queue_cnt++; /* queue TX packet */
- outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
+ dw32(DCR1, 0x1); /* Issue Tx polling */
}
/* Tx resource check */
@@ -734,7 +738,7 @@
/* Restore CR7 to enable interrupt */
spin_unlock_irqrestore(&db->lock, flags);
- outl(db->cr7_data, dev->base_addr + DCR7);
+ dw32(DCR7, db->cr7_data);
/* free this SKB */
dev_kfree_skb(skb);
@@ -751,7 +755,7 @@
static int dmfe_stop(struct DEVICE *dev)
{
struct dmfe_board_info *db = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = db->ioaddr;
DMFE_DBUG(0, "dmfe_stop", 0);
@@ -762,12 +766,12 @@
del_timer_sync(&db->timer);
/* Reset & stop DM910X board */
- outl(DM910X_RESET, ioaddr + DCR0);
+ dw32(DCR0, DM910X_RESET);
udelay(5);
- phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
+ phy_write(ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
/* free interrupt */
- free_irq(dev->irq, dev);
+ free_irq(db->pdev->irq, dev);
/* free allocated rx buffer */
dmfe_free_rxbuffer(db);
@@ -794,7 +798,7 @@
{
struct DEVICE *dev = dev_id;
struct dmfe_board_info *db = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = db->ioaddr;
unsigned long flags;
DMFE_DBUG(0, "dmfe_interrupt()", 0);
@@ -802,15 +806,15 @@
spin_lock_irqsave(&db->lock, flags);
/* Got DM910X status */
- db->cr5_data = inl(ioaddr + DCR5);
- outl(db->cr5_data, ioaddr + DCR5);
+ db->cr5_data = dr32(DCR5);
+ dw32(DCR5, db->cr5_data);
if ( !(db->cr5_data & 0xc1) ) {
spin_unlock_irqrestore(&db->lock, flags);
return IRQ_HANDLED;
}
/* Disable all interrupt in CR7 to solve the interrupt edge problem */
- outl(0, ioaddr + DCR7);
+ dw32(DCR7, 0);
/* Check system status */
if (db->cr5_data & 0x2000) {
@@ -838,11 +842,11 @@
if (db->dm910x_chk_mode & 0x2) {
db->dm910x_chk_mode = 0x4;
db->cr6_data |= 0x100;
- update_cr6(db->cr6_data, db->ioaddr);
+ update_cr6(db->cr6_data, ioaddr);
}
/* Restore CR7 to enable interrupt mask */
- outl(db->cr7_data, ioaddr + DCR7);
+ dw32(DCR7, db->cr7_data);
spin_unlock_irqrestore(&db->lock, flags);
return IRQ_HANDLED;
@@ -858,11 +862,14 @@
static void poll_dmfe (struct net_device *dev)
{
+ struct dmfe_board_info *db = netdev_priv(dev);
+ const int irq = db->pdev->irq;
+
/* disable_irq here is not very nice, but with the lockless
interrupt handler we have no other choice. */
- disable_irq(dev->irq);
- dmfe_interrupt (dev->irq, dev);
- enable_irq(dev->irq);
+ disable_irq(irq);
+ dmfe_interrupt (irq, dev);
+ enable_irq(irq);
}
#endif
@@ -873,7 +880,7 @@
static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db)
{
struct tx_desc *txptr;
- unsigned long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = db->ioaddr;
u32 tdes0;
txptr = db->tx_remove_ptr;
@@ -897,7 +904,7 @@
db->tx_fifo_underrun++;
if ( !(db->cr6_data & CR6_SFT) ) {
db->cr6_data = db->cr6_data | CR6_SFT;
- update_cr6(db->cr6_data, db->ioaddr);
+ update_cr6(db->cr6_data, ioaddr);
}
}
if (tdes0 & 0x0100)
@@ -924,7 +931,7 @@
txptr->tdes0 = cpu_to_le32(0x80000000); /* Set owner bit */
db->tx_packet_cnt++; /* Ready to send */
db->tx_queue_cnt--;
- outl(0x1, ioaddr + DCR1); /* Issue Tx polling */
+ dw32(DCR1, 0x1); /* Issue Tx polling */
dev->trans_start = jiffies; /* saved time stamp */
}
@@ -1087,12 +1094,7 @@
strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- if (np->pdev)
- strlcpy(info->bus_info, pci_name(np->pdev),
- sizeof(info->bus_info));
- else
- sprintf(info->bus_info, "EISA 0x%lx %d",
- dev->base_addr, dev->irq);
+ strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info));
}
static int dmfe_ethtool_set_wol(struct net_device *dev,
@@ -1132,10 +1134,11 @@
static void dmfe_timer(unsigned long data)
{
+ struct net_device *dev = (struct net_device *)data;
+ struct dmfe_board_info *db = netdev_priv(dev);
+ void __iomem *ioaddr = db->ioaddr;
u32 tmp_cr8;
unsigned char tmp_cr12;
- struct DEVICE *dev = (struct DEVICE *) data;
- struct dmfe_board_info *db = netdev_priv(dev);
unsigned long flags;
int link_ok, link_ok_phy;
@@ -1148,11 +1151,10 @@
db->first_in_callback = 1;
if (db->chip_type && (db->chip_id==PCI_DM9102_ID)) {
db->cr6_data &= ~0x40000;
- update_cr6(db->cr6_data, db->ioaddr);
- phy_write(db->ioaddr,
- db->phy_addr, 0, 0x1000, db->chip_id);
+ update_cr6(db->cr6_data, ioaddr);
+ phy_write(ioaddr, db->phy_addr, 0, 0x1000, db->chip_id);
db->cr6_data |= 0x40000;
- update_cr6(db->cr6_data, db->ioaddr);
+ update_cr6(db->cr6_data, ioaddr);
db->timer.expires = DMFE_TIMER_WUT + HZ * 2;
add_timer(&db->timer);
spin_unlock_irqrestore(&db->lock, flags);
@@ -1167,7 +1169,7 @@
db->dm910x_chk_mode = 0x4;
/* Dynamic reset DM910X : system error or transmit time-out */
- tmp_cr8 = inl(db->ioaddr + DCR8);
+ tmp_cr8 = dr32(DCR8);
if ( (db->interval_rx_cnt==0) && (tmp_cr8) ) {
db->reset_cr8++;
db->wait_reset = 1;
@@ -1177,7 +1179,7 @@
/* TX polling kick monitor */
if ( db->tx_packet_cnt &&
time_after(jiffies, dev_trans_start(dev) + DMFE_TX_KICK) ) {
- outl(0x1, dev->base_addr + DCR1); /* Tx polling again */
+ dw32(DCR1, 0x1); /* Tx polling again */
/* TX Timeout */
if (time_after(jiffies, dev_trans_start(dev) + DMFE_TX_TIMEOUT) ) {
@@ -1200,9 +1202,9 @@
/* Link status check, Dynamic media type change */
if (db->chip_id == PCI_DM9132_ID)
- tmp_cr12 = inb(db->ioaddr + DCR9 + 3); /* DM9132 */
+ tmp_cr12 = dr8(DCR9 + 3); /* DM9132 */
else
- tmp_cr12 = inb(db->ioaddr + DCR12); /* DM9102/DM9102A */
+ tmp_cr12 = dr8(DCR12); /* DM9102/DM9102A */
if ( ((db->chip_id == PCI_DM9102_ID) &&
(db->chip_revision == 0x30)) ||
@@ -1251,7 +1253,7 @@
/* 10/100M link failed, used 1M Home-Net */
db->cr6_data|=0x00040000; /* bit18=1, MII */
db->cr6_data&=~0x00000200; /* bit9=0, HD mode */
- update_cr6(db->cr6_data, db->ioaddr);
+ update_cr6(db->cr6_data, ioaddr);
}
} else if (!netif_carrier_ok(dev)) {
@@ -1288,17 +1290,18 @@
* Re-initialize DM910X board
*/
-static void dmfe_dynamic_reset(struct DEVICE *dev)
+static void dmfe_dynamic_reset(struct net_device *dev)
{
struct dmfe_board_info *db = netdev_priv(dev);
+ void __iomem *ioaddr = db->ioaddr;
DMFE_DBUG(0, "dmfe_dynamic_reset()", 0);
/* Sopt MAC controller */
db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); /* Disable Tx/Rx */
- update_cr6(db->cr6_data, dev->base_addr);
- outl(0, dev->base_addr + DCR7); /* Disable Interrupt */
- outl(inl(dev->base_addr + DCR5), dev->base_addr + DCR5);
+ update_cr6(db->cr6_data, ioaddr);
+ dw32(DCR7, 0); /* Disable Interrupt */
+ dw32(DCR5, dr32(DCR5));
/* Disable upper layer interface */
netif_stop_queue(dev);
@@ -1364,9 +1367,10 @@
* Using Chain structure, and allocate Tx/Rx buffer
*/
-static void dmfe_descriptor_init(struct net_device *dev, unsigned long ioaddr)
+static void dmfe_descriptor_init(struct net_device *dev)
{
struct dmfe_board_info *db = netdev_priv(dev);
+ void __iomem *ioaddr = db->ioaddr;
struct tx_desc *tmp_tx;
struct rx_desc *tmp_rx;
unsigned char *tmp_buf;
@@ -1379,7 +1383,7 @@
/* tx descriptor start pointer */
db->tx_insert_ptr = db->first_tx_desc;
db->tx_remove_ptr = db->first_tx_desc;
- outl(db->first_tx_desc_dma, ioaddr + DCR4); /* TX DESC address */
+ dw32(DCR4, db->first_tx_desc_dma); /* TX DESC address */
/* rx descriptor start pointer */
db->first_rx_desc = (void *)db->first_tx_desc +
@@ -1389,7 +1393,7 @@
sizeof(struct tx_desc) * TX_DESC_CNT;
db->rx_insert_ptr = db->first_rx_desc;
db->rx_ready_ptr = db->first_rx_desc;
- outl(db->first_rx_desc_dma, ioaddr + DCR3); /* RX DESC address */
+ dw32(DCR3, db->first_rx_desc_dma); /* RX DESC address */
/* Init Transmit chain */
tmp_buf = db->buf_pool_start;
@@ -1431,14 +1435,14 @@
* Firstly stop DM910X , then written value and start
*/
-static void update_cr6(u32 cr6_data, unsigned long ioaddr)
+static void update_cr6(u32 cr6_data, void __iomem *ioaddr)
{
u32 cr6_tmp;
cr6_tmp = cr6_data & ~0x2002; /* stop Tx/Rx */
- outl(cr6_tmp, ioaddr + DCR6);
+ dw32(DCR6, cr6_tmp);
udelay(5);
- outl(cr6_data, ioaddr + DCR6);
+ dw32(DCR6, cr6_data);
udelay(5);
}
@@ -1448,24 +1452,19 @@
* This setup frame initialize DM910X address filter mode
*/
-static void dm9132_id_table(struct DEVICE *dev)
+static void dm9132_id_table(struct net_device *dev)
{
+ struct dmfe_board_info *db = netdev_priv(dev);
+ void __iomem *ioaddr = db->ioaddr + 0xc0;
+ u16 *addrptr = (u16 *)dev->dev_addr;
struct netdev_hw_addr *ha;
- u16 * addrptr;
- unsigned long ioaddr = dev->base_addr+0xc0; /* ID Table */
- u32 hash_val;
u16 i, hash_table[4];
- DMFE_DBUG(0, "dm9132_id_table()", 0);
-
/* Node address */
- addrptr = (u16 *) dev->dev_addr;
- outw(addrptr[0], ioaddr);
- ioaddr += 4;
- outw(addrptr[1], ioaddr);
- ioaddr += 4;
- outw(addrptr[2], ioaddr);
- ioaddr += 4;
+ for (i = 0; i < 3; i++) {
+ dw16(0, addrptr[i]);
+ ioaddr += 4;
+ }
/* Clear Hash Table */
memset(hash_table, 0, sizeof(hash_table));
@@ -1475,13 +1474,14 @@
/* the multicast address in Hash Table : 64 bits */
netdev_for_each_mc_addr(ha, dev) {
- hash_val = cal_CRC((char *) ha->addr, 6, 0) & 0x3f;
+ u32 hash_val = cal_CRC((char *)ha->addr, 6, 0) & 0x3f;
+
hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
}
/* Write the hash table to MAC MD table */
for (i = 0; i < 4; i++, ioaddr += 4)
- outw(hash_table[i], ioaddr);
+ dw16(0, hash_table[i]);
}
@@ -1490,7 +1490,7 @@
* This setup frame initialize DM910X address filter mode
*/
-static void send_filter_frame(struct DEVICE *dev)
+static void send_filter_frame(struct net_device *dev)
{
struct dmfe_board_info *db = netdev_priv(dev);
struct netdev_hw_addr *ha;
@@ -1535,12 +1535,14 @@
/* Resource Check and Send the setup packet */
if (!db->tx_packet_cnt) {
+ void __iomem *ioaddr = db->ioaddr;
+
/* Resource Empty */
db->tx_packet_cnt++;
txptr->tdes0 = cpu_to_le32(0x80000000);
- update_cr6(db->cr6_data | 0x2000, dev->base_addr);
- outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
- update_cr6(db->cr6_data, dev->base_addr);
+ update_cr6(db->cr6_data | 0x2000, ioaddr);
+ dw32(DCR1, 0x1); /* Issue Tx polling */
+ update_cr6(db->cr6_data, ioaddr);
dev->trans_start = jiffies;
} else
db->tx_queue_cnt++; /* Put in TX queue */
@@ -1575,43 +1577,55 @@
db->rx_insert_ptr = rxptr;
}
+static void srom_clk_write(void __iomem *ioaddr, u32 data)
+{
+ static const u32 cmd[] = {
+ CR9_SROM_READ | CR9_SRCS,
+ CR9_SROM_READ | CR9_SRCS | CR9_SRCLK,
+ CR9_SROM_READ | CR9_SRCS
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cmd); i++) {
+ dw32(DCR9, data | cmd[i]);
+ udelay(5);
+ }
+}
/*
* Read one word data from the serial ROM
*/
-
-static u16 read_srom_word(long ioaddr, int offset)
+static u16 read_srom_word(void __iomem *ioaddr, int offset)
{
+ u16 srom_data;
int i;
- u16 srom_data = 0;
- long cr9_ioaddr = ioaddr + DCR9;
- outl(CR9_SROM_READ, cr9_ioaddr);
- outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+ dw32(DCR9, CR9_SROM_READ);
+ dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
/* Send the Read Command 110b */
- SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
- SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
- SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr);
+ srom_clk_write(ioaddr, SROM_DATA_1);
+ srom_clk_write(ioaddr, SROM_DATA_1);
+ srom_clk_write(ioaddr, SROM_DATA_0);
/* Send the offset */
for (i = 5; i >= 0; i--) {
srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;
- SROM_CLK_WRITE(srom_data, cr9_ioaddr);
+ srom_clk_write(ioaddr, srom_data);
}
- outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+ dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
for (i = 16; i > 0; i--) {
- outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr);
+ dw32(DCR9, CR9_SROM_READ | CR9_SRCS | CR9_SRCLK);
udelay(5);
srom_data = (srom_data << 1) |
- ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0);
- outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+ ((dr32(DCR9) & CR9_CRDOUT) ? 1 : 0);
+ dw32(DCR9, CR9_SROM_READ | CR9_SRCS);
udelay(5);
}
- outl(CR9_SROM_READ, cr9_ioaddr);
+ dw32(DCR9, CR9_SROM_READ);
return srom_data;
}
@@ -1620,13 +1634,14 @@
* Auto sense the media mode
*/
-static u8 dmfe_sense_speed(struct dmfe_board_info * db)
+static u8 dmfe_sense_speed(struct dmfe_board_info *db)
{
+ void __iomem *ioaddr = db->ioaddr;
u8 ErrFlag = 0;
u16 phy_mode;
/* CR6 bit18=0, select 10/100M */
- update_cr6( (db->cr6_data & ~0x40000), db->ioaddr);
+ update_cr6(db->cr6_data & ~0x40000, ioaddr);
phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
@@ -1665,11 +1680,12 @@
static void dmfe_set_phyxcer(struct dmfe_board_info *db)
{
+ void __iomem *ioaddr = db->ioaddr;
u16 phy_reg;
/* Select 10/100M phyxcer */
db->cr6_data &= ~0x40000;
- update_cr6(db->cr6_data, db->ioaddr);
+ update_cr6(db->cr6_data, ioaddr);
/* DM9009 Chip: Phyxcer reg18 bit12=0 */
if (db->chip_id == PCI_DM9009_ID) {
@@ -1765,18 +1781,15 @@
* Write a word to Phy register
*/
-static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset,
+static void phy_write(void __iomem *ioaddr, u8 phy_addr, u8 offset,
u16 phy_data, u32 chip_id)
{
u16 i;
- unsigned long ioaddr;
if (chip_id == PCI_DM9132_ID) {
- ioaddr = iobase + 0x80 + offset * 4;
- outw(phy_data, ioaddr);
+ dw16(0x80 + offset * 4, phy_data);
} else {
/* DM9102/DM9102A Chip */
- ioaddr = iobase + DCR9;
/* Send 33 synchronization clock to Phy controller */
for (i = 0; i < 35; i++)
@@ -1816,19 +1829,16 @@
* Read a word data from phy register
*/
-static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id)
+static u16 phy_read(void __iomem *ioaddr, u8 phy_addr, u8 offset, u32 chip_id)
{
int i;
u16 phy_data;
- unsigned long ioaddr;
if (chip_id == PCI_DM9132_ID) {
/* DM9132 Chip */
- ioaddr = iobase + 0x80 + offset * 4;
- phy_data = inw(ioaddr);
+ phy_data = dr16(0x80 + offset * 4);
} else {
/* DM9102/DM9102A Chip */
- ioaddr = iobase + DCR9;
/* Send 33 synchronization clock to Phy controller */
for (i = 0; i < 35; i++)
@@ -1870,13 +1880,13 @@
* Write one bit data to Phy Controller
*/
-static void phy_write_1bit(unsigned long ioaddr, u32 phy_data)
+static void phy_write_1bit(void __iomem *ioaddr, u32 phy_data)
{
- outl(phy_data, ioaddr); /* MII Clock Low */
+ dw32(DCR9, phy_data); /* MII Clock Low */
udelay(1);
- outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */
+ dw32(DCR9, phy_data | MDCLKH); /* MII Clock High */
udelay(1);
- outl(phy_data, ioaddr); /* MII Clock Low */
+ dw32(DCR9, phy_data); /* MII Clock Low */
udelay(1);
}
@@ -1885,14 +1895,14 @@
* Read one bit phy data from PHY controller
*/
-static u16 phy_read_1bit(unsigned long ioaddr)
+static u16 phy_read_1bit(void __iomem *ioaddr)
{
u16 phy_data;
- outl(0x50000, ioaddr);
+ dw32(DCR9, 0x50000);
udelay(1);
- phy_data = ( inl(ioaddr) >> 19 ) & 0x1;
- outl(0x40000, ioaddr);
+ phy_data = (dr32(DCR9) >> 19) & 0x1;
+ dw32(DCR9, 0x40000);
udelay(1);
return phy_data;
@@ -1978,7 +1988,7 @@
/* Check DM9801 or DM9802 present or not */
db->HPNA_present = 0;
- update_cr6(db->cr6_data|0x40000, db->ioaddr);
+ update_cr6(db->cr6_data | 0x40000, db->ioaddr);
tmp_reg = phy_read(db->ioaddr, db->phy_addr, 3, db->chip_id);
if ( ( tmp_reg & 0xfff0 ) == 0xb900 ) {
/* DM9801 or DM9802 present */
@@ -2095,6 +2105,7 @@
{
struct net_device *dev = pci_get_drvdata(pci_dev);
struct dmfe_board_info *db = netdev_priv(dev);
+ void __iomem *ioaddr = db->ioaddr;
u32 tmp;
/* Disable upper layer interface */
@@ -2102,11 +2113,11 @@
/* Disable Tx/Rx */
db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);
- update_cr6(db->cr6_data, dev->base_addr);
+ update_cr6(db->cr6_data, ioaddr);
/* Disable Interrupt */
- outl(0, dev->base_addr + DCR7);
- outl(inl (dev->base_addr + DCR5), dev->base_addr + DCR5);
+ dw32(DCR7, 0);
+ dw32(DCR5, dr32(DCR5));
/* Fre RX buffers */
dmfe_free_rxbuffer(db);
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index fea3641..c4f37ac 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -328,7 +328,7 @@
udelay(100);
if (tulip_debug > 1)
- netdev_dbg(dev, "tulip_up(), irq==%d\n", dev->irq);
+ netdev_dbg(dev, "tulip_up(), irq==%d\n", tp->pdev->irq);
iowrite32(tp->rx_ring_dma, ioaddr + CSR3);
iowrite32(tp->tx_ring_dma, ioaddr + CSR4);
@@ -515,11 +515,13 @@
static int
tulip_open(struct net_device *dev)
{
+ struct tulip_private *tp = netdev_priv(dev);
int retval;
tulip_init_ring (dev);
- retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev);
+ retval = request_irq(tp->pdev->irq, tulip_interrupt, IRQF_SHARED,
+ dev->name, dev);
if (retval)
goto free_ring;
@@ -841,7 +843,7 @@
netdev_dbg(dev, "Shutting down ethercard, status was %02x\n",
ioread32 (ioaddr + CSR5));
- free_irq (dev->irq, dev);
+ free_irq (tp->pdev->irq, dev);
tulip_free_ring (dev);
@@ -1489,8 +1491,6 @@
INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task);
- dev->base_addr = (unsigned long)ioaddr;
-
#ifdef CONFIG_TULIP_MWI
if (!force_csr0 && (tp->flags & HAS_PCI_MWI))
tulip_mwi_config (pdev, dev);
@@ -1650,7 +1650,6 @@
for (i = 0; i < 6; i++)
last_phys_addr[i] = dev->dev_addr[i];
last_irq = irq;
- dev->irq = irq;
/* The lower four bits are the media type. */
if (board_idx >= 0 && board_idx < MAX_UNITS) {
@@ -1858,7 +1857,8 @@
tulip_down(dev);
netif_device_detach(dev);
- free_irq(dev->irq, dev);
+ /* FIXME: it needlessly adds an error path. */
+ free_irq(tp->pdev->irq, dev);
save_state:
pci_save_state(pdev);
@@ -1900,7 +1900,9 @@
return retval;
}
- if ((retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
+ retval = request_irq(pdev->irq, tulip_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (retval) {
pr_err("request_irq failed in resume\n");
return retval;
}
@@ -1960,11 +1962,14 @@
static void poll_tulip (struct net_device *dev)
{
+ struct tulip_private *tp = netdev_priv(dev);
+ const int irq = tp->pdev->irq;
+
/* disable_irq here is not very nice, but with the lockless
interrupt handler we have no other choice. */
- disable_irq(dev->irq);
- tulip_interrupt (dev->irq, dev);
- enable_irq(dev->irq);
+ disable_irq(irq);
+ tulip_interrupt (irq, dev);
+ enable_irq(irq);
}
#endif
diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c
index fc4001f..75d45f8 100644
--- a/drivers/net/ethernet/dec/tulip/uli526x.c
+++ b/drivers/net/ethernet/dec/tulip/uli526x.c
@@ -42,6 +42,8 @@
#include <asm/dma.h>
#include <asm/uaccess.h>
+#define uw32(reg, val) iowrite32(val, ioaddr + (reg))
+#define ur32(reg) ioread32(ioaddr + (reg))
/* Board/System/Debug information/definition ---------------- */
#define PCI_ULI5261_ID 0x526110B9 /* ULi M5261 ID*/
@@ -110,14 +112,6 @@
#define SROM_V41_CODE 0x14
-#define SROM_CLK_WRITE(data, ioaddr) \
- outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \
- udelay(5); \
- outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr); \
- udelay(5); \
- outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \
- udelay(5);
-
/* Structure/enum declaration ------------------------------- */
struct tx_desc {
__le32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
@@ -132,12 +126,15 @@
} __attribute__(( aligned(32) ));
struct uli526x_board_info {
- u32 chip_id; /* Chip vendor/Device ID */
+ struct uli_phy_ops {
+ void (*write)(struct uli526x_board_info *, u8, u8, u16);
+ u16 (*read)(struct uli526x_board_info *, u8, u8);
+ } phy;
struct net_device *next_dev; /* next device */
struct pci_dev *pdev; /* PCI device */
spinlock_t lock;
- long ioaddr; /* I/O base address */
+ void __iomem *ioaddr; /* I/O base address */
u32 cr0_data;
u32 cr5_data;
u32 cr6_data;
@@ -227,21 +224,21 @@
static int uli526x_stop(struct net_device *);
static void uli526x_set_filter_mode(struct net_device *);
static const struct ethtool_ops netdev_ethtool_ops;
-static u16 read_srom_word(long, int);
+static u16 read_srom_word(struct uli526x_board_info *, int);
static irqreturn_t uli526x_interrupt(int, void *);
#ifdef CONFIG_NET_POLL_CONTROLLER
static void uli526x_poll(struct net_device *dev);
#endif
-static void uli526x_descriptor_init(struct net_device *, unsigned long);
+static void uli526x_descriptor_init(struct net_device *, void __iomem *);
static void allocate_rx_buffer(struct net_device *);
-static void update_cr6(u32, unsigned long);
+static void update_cr6(u32, void __iomem *);
static void send_filter_frame(struct net_device *, int);
-static u16 phy_read(unsigned long, u8, u8, u32);
-static u16 phy_readby_cr10(unsigned long, u8, u8);
-static void phy_write(unsigned long, u8, u8, u16, u32);
-static void phy_writeby_cr10(unsigned long, u8, u8, u16);
-static void phy_write_1bit(unsigned long, u32, u32);
-static u16 phy_read_1bit(unsigned long, u32);
+static u16 phy_readby_cr9(struct uli526x_board_info *, u8, u8);
+static u16 phy_readby_cr10(struct uli526x_board_info *, u8, u8);
+static void phy_writeby_cr9(struct uli526x_board_info *, u8, u8, u16);
+static void phy_writeby_cr10(struct uli526x_board_info *, u8, u8, u16);
+static void phy_write_1bit(struct uli526x_board_info *db, u32);
+static u16 phy_read_1bit(struct uli526x_board_info *db);
static u8 uli526x_sense_speed(struct uli526x_board_info *);
static void uli526x_process_mode(struct uli526x_board_info *);
static void uli526x_timer(unsigned long);
@@ -253,6 +250,18 @@
static void uli526x_init(struct net_device *);
static void uli526x_set_phyxcer(struct uli526x_board_info *);
+static void srom_clk_write(struct uli526x_board_info *db, u32 data)
+{
+ void __iomem *ioaddr = db->ioaddr;
+
+ uw32(DCR9, data | CR9_SROM_READ | CR9_SRCS);
+ udelay(5);
+ uw32(DCR9, data | CR9_SROM_READ | CR9_SRCS | CR9_SRCLK);
+ udelay(5);
+ uw32(DCR9, data | CR9_SROM_READ | CR9_SRCS);
+ udelay(5);
+}
+
/* ULI526X network board routine ---------------------------- */
static const struct net_device_ops netdev_ops = {
@@ -277,6 +286,7 @@
{
struct uli526x_board_info *db; /* board information structure */
struct net_device *dev;
+ void __iomem *ioaddr;
int i, err;
ULI526X_DBUG(0, "uli526x_init_one()", 0);
@@ -313,9 +323,9 @@
goto err_out_disable;
}
- if (pci_request_regions(pdev, DRV_NAME)) {
+ err = pci_request_regions(pdev, DRV_NAME);
+ if (err < 0) {
pr_err("Failed to request PCI regions\n");
- err = -ENODEV;
goto err_out_disable;
}
@@ -323,32 +333,41 @@
db = netdev_priv(dev);
/* Allocate Tx/Rx descriptor memory */
+ err = -ENOMEM;
+
db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr);
- if(db->desc_pool_ptr == NULL)
- {
- err = -ENOMEM;
- goto err_out_nomem;
- }
+ if (!db->desc_pool_ptr)
+ goto err_out_release;
+
db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, &db->buf_pool_dma_ptr);
- if(db->buf_pool_ptr == NULL)
- {
- err = -ENOMEM;
- goto err_out_nomem;
- }
+ if (!db->buf_pool_ptr)
+ goto err_out_free_tx_desc;
db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
db->first_tx_desc_dma = db->desc_pool_dma_ptr;
db->buf_pool_start = db->buf_pool_ptr;
db->buf_pool_dma_start = db->buf_pool_dma_ptr;
- db->chip_id = ent->driver_data;
- db->ioaddr = pci_resource_start(pdev, 0);
+ switch (ent->driver_data) {
+ case PCI_ULI5263_ID:
+ db->phy.write = phy_writeby_cr10;
+ db->phy.read = phy_readby_cr10;
+ break;
+ default:
+ db->phy.write = phy_writeby_cr9;
+ db->phy.read = phy_readby_cr9;
+ break;
+ }
+ /* IO region. */
+ ioaddr = pci_iomap(pdev, 0, 0);
+ if (!ioaddr)
+ goto err_out_free_tx_buf;
+
+ db->ioaddr = ioaddr;
db->pdev = pdev;
db->init = 1;
- dev->base_addr = db->ioaddr;
- dev->irq = pdev->irq;
pci_set_drvdata(pdev, dev);
/* Register some necessary functions */
@@ -360,24 +379,24 @@
/* read 64 word srom data */
for (i = 0; i < 64; i++)
- ((__le16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db->ioaddr, i));
+ ((__le16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db, i));
/* Set Node address */
if(((u16 *) db->srom)[0] == 0xffff || ((u16 *) db->srom)[0] == 0) /* SROM absent, so read MAC address from ID Table */
{
- outl(0x10000, db->ioaddr + DCR0); //Diagnosis mode
- outl(0x1c0, db->ioaddr + DCR13); //Reset dianostic pointer port
- outl(0, db->ioaddr + DCR14); //Clear reset port
- outl(0x10, db->ioaddr + DCR14); //Reset ID Table pointer
- outl(0, db->ioaddr + DCR14); //Clear reset port
- outl(0, db->ioaddr + DCR13); //Clear CR13
- outl(0x1b0, db->ioaddr + DCR13); //Select ID Table access port
+ uw32(DCR0, 0x10000); //Diagnosis mode
+ uw32(DCR13, 0x1c0); //Reset dianostic pointer port
+ uw32(DCR14, 0); //Clear reset port
+ uw32(DCR14, 0x10); //Reset ID Table pointer
+ uw32(DCR14, 0); //Clear reset port
+ uw32(DCR13, 0); //Clear CR13
+ uw32(DCR13, 0x1b0); //Select ID Table access port
//Read MAC address from CR14
for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inl(db->ioaddr + DCR14);
+ dev->dev_addr[i] = ur32(DCR14);
//Read end
- outl(0, db->ioaddr + DCR13); //Clear CR13
- outl(0, db->ioaddr + DCR0); //Clear CR0
+ uw32(DCR13, 0); //Clear CR13
+ uw32(DCR0, 0); //Clear CR0
udelay(10);
}
else /*Exist SROM*/
@@ -387,26 +406,26 @@
}
err = register_netdev (dev);
if (err)
- goto err_out_res;
+ goto err_out_unmap;
netdev_info(dev, "ULi M%04lx at pci%s, %pM, irq %d\n",
ent->driver_data >> 16, pci_name(pdev),
- dev->dev_addr, dev->irq);
+ dev->dev_addr, pdev->irq);
pci_set_master(pdev);
return 0;
-err_out_res:
+err_out_unmap:
+ pci_iounmap(pdev, db->ioaddr);
+err_out_free_tx_buf:
+ pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
+ db->buf_pool_ptr, db->buf_pool_dma_ptr);
+err_out_free_tx_desc:
+ pci_free_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
+ db->desc_pool_ptr, db->desc_pool_dma_ptr);
+err_out_release:
pci_release_regions(pdev);
-err_out_nomem:
- if(db->desc_pool_ptr)
- pci_free_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
- db->desc_pool_ptr, db->desc_pool_dma_ptr);
-
- if(db->buf_pool_ptr != NULL)
- pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
- db->buf_pool_ptr, db->buf_pool_dma_ptr);
err_out_disable:
pci_disable_device(pdev);
err_out_free:
@@ -422,19 +441,17 @@
struct net_device *dev = pci_get_drvdata(pdev);
struct uli526x_board_info *db = netdev_priv(dev);
- ULI526X_DBUG(0, "uli526x_remove_one()", 0);
-
+ unregister_netdev(dev);
+ pci_iounmap(pdev, db->ioaddr);
pci_free_consistent(db->pdev, sizeof(struct tx_desc) *
DESC_ALL_CNT + 0x20, db->desc_pool_ptr,
db->desc_pool_dma_ptr);
pci_free_consistent(db->pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
db->buf_pool_ptr, db->buf_pool_dma_ptr);
- unregister_netdev(dev);
pci_release_regions(pdev);
- free_netdev(dev); /* free board information */
- pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
- ULI526X_DBUG(0, "uli526x_remove_one() exit", 0);
+ pci_set_drvdata(pdev, NULL);
+ free_netdev(dev);
}
@@ -468,7 +485,8 @@
/* Initialize ULI526X board */
uli526x_init(dev);
- ret = request_irq(dev->irq, uli526x_interrupt, IRQF_SHARED, dev->name, dev);
+ ret = request_irq(db->pdev->irq, uli526x_interrupt, IRQF_SHARED,
+ dev->name, dev);
if (ret)
return ret;
@@ -496,57 +514,57 @@
static void uli526x_init(struct net_device *dev)
{
struct uli526x_board_info *db = netdev_priv(dev);
- unsigned long ioaddr = db->ioaddr;
+ struct uli_phy_ops *phy = &db->phy;
+ void __iomem *ioaddr = db->ioaddr;
u8 phy_tmp;
u8 timeout;
- u16 phy_value;
u16 phy_reg_reset;
ULI526X_DBUG(0, "uli526x_init()", 0);
/* Reset M526x MAC controller */
- outl(ULI526X_RESET, ioaddr + DCR0); /* RESET MAC */
+ uw32(DCR0, ULI526X_RESET); /* RESET MAC */
udelay(100);
- outl(db->cr0_data, ioaddr + DCR0);
+ uw32(DCR0, db->cr0_data);
udelay(5);
/* Phy addr : In some boards,M5261/M5263 phy address != 1 */
db->phy_addr = 1;
- for(phy_tmp=0;phy_tmp<32;phy_tmp++)
- {
- phy_value=phy_read(db->ioaddr,phy_tmp,3,db->chip_id);//peer add
- if(phy_value != 0xffff&&phy_value!=0)
- {
+ for (phy_tmp = 0; phy_tmp < 32; phy_tmp++) {
+ u16 phy_value;
+
+ phy_value = phy->read(db, phy_tmp, 3); //peer add
+ if (phy_value != 0xffff && phy_value != 0) {
db->phy_addr = phy_tmp;
break;
}
}
- if(phy_tmp == 32)
+
+ if (phy_tmp == 32)
pr_warn("Can not find the phy address!!!\n");
/* Parser SROM and media mode */
db->media_mode = uli526x_media_mode;
/* phyxcer capability setting */
- phy_reg_reset = phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id);
+ phy_reg_reset = phy->read(db, db->phy_addr, 0);
phy_reg_reset = (phy_reg_reset | 0x8000);
- phy_write(db->ioaddr, db->phy_addr, 0, phy_reg_reset, db->chip_id);
+ phy->write(db, db->phy_addr, 0, phy_reg_reset);
/* See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management
* functions") or phy data sheet for details on phy reset
*/
udelay(500);
timeout = 10;
- while (timeout-- &&
- phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id) & 0x8000)
- udelay(100);
+ while (timeout-- && phy->read(db, db->phy_addr, 0) & 0x8000)
+ udelay(100);
/* Process Phyxcer Media Mode */
uli526x_set_phyxcer(db);
/* Media Mode Process */
if ( !(db->media_mode & ULI526X_AUTO) )
- db->op_mode = db->media_mode; /* Force Mode */
+ db->op_mode = db->media_mode; /* Force Mode */
/* Initialize Transmit/Receive decriptor and CR3/4 */
uli526x_descriptor_init(dev, ioaddr);
@@ -559,10 +577,10 @@
/* Init CR7, interrupt active bit */
db->cr7_data = CR7_DEFAULT;
- outl(db->cr7_data, ioaddr + DCR7);
+ uw32(DCR7, db->cr7_data);
/* Init CR15, Tx jabber and Rx watchdog timer */
- outl(db->cr15_data, ioaddr + DCR15);
+ uw32(DCR15, db->cr15_data);
/* Enable ULI526X Tx/Rx function */
db->cr6_data |= CR6_RXSC | CR6_TXSC;
@@ -579,6 +597,7 @@
struct net_device *dev)
{
struct uli526x_board_info *db = netdev_priv(dev);
+ void __iomem *ioaddr = db->ioaddr;
struct tx_desc *txptr;
unsigned long flags;
@@ -604,7 +623,7 @@
}
/* Disable NIC interrupt */
- outl(0, dev->base_addr + DCR7);
+ uw32(DCR7, 0);
/* transmit this packet */
txptr = db->tx_insert_ptr;
@@ -615,10 +634,10 @@
db->tx_insert_ptr = txptr->next_tx_desc;
/* Transmit Packet Process */
- if ( (db->tx_packet_cnt < TX_DESC_CNT) ) {
+ if (db->tx_packet_cnt < TX_DESC_CNT) {
txptr->tdes0 = cpu_to_le32(0x80000000); /* Set owner bit */
db->tx_packet_cnt++; /* Ready to send */
- outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
+ uw32(DCR1, 0x1); /* Issue Tx polling */
dev->trans_start = jiffies; /* saved time stamp */
}
@@ -628,7 +647,7 @@
/* Restore CR7 to enable interrupt */
spin_unlock_irqrestore(&db->lock, flags);
- outl(db->cr7_data, dev->base_addr + DCR7);
+ uw32(DCR7, db->cr7_data);
/* free this SKB */
dev_kfree_skb(skb);
@@ -645,9 +664,7 @@
static int uli526x_stop(struct net_device *dev)
{
struct uli526x_board_info *db = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
-
- ULI526X_DBUG(0, "uli526x_stop", 0);
+ void __iomem *ioaddr = db->ioaddr;
/* disable system */
netif_stop_queue(dev);
@@ -656,12 +673,12 @@
del_timer_sync(&db->timer);
/* Reset & stop ULI526X board */
- outl(ULI526X_RESET, ioaddr + DCR0);
+ uw32(DCR0, ULI526X_RESET);
udelay(5);
- phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
+ db->phy.write(db, db->phy_addr, 0, 0x8000);
/* free interrupt */
- free_irq(dev->irq, dev);
+ free_irq(db->pdev->irq, dev);
/* free allocated rx buffer */
uli526x_free_rxbuffer(db);
@@ -679,18 +696,18 @@
{
struct net_device *dev = dev_id;
struct uli526x_board_info *db = netdev_priv(dev);
- unsigned long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = db->ioaddr;
unsigned long flags;
spin_lock_irqsave(&db->lock, flags);
- outl(0, ioaddr + DCR7);
+ uw32(DCR7, 0);
/* Got ULI526X status */
- db->cr5_data = inl(ioaddr + DCR5);
- outl(db->cr5_data, ioaddr + DCR5);
+ db->cr5_data = ur32(DCR5);
+ uw32(DCR5, db->cr5_data);
if ( !(db->cr5_data & 0x180c1) ) {
/* Restore CR7 to enable interrupt mask */
- outl(db->cr7_data, ioaddr + DCR7);
+ uw32(DCR7, db->cr7_data);
spin_unlock_irqrestore(&db->lock, flags);
return IRQ_HANDLED;
}
@@ -718,7 +735,7 @@
uli526x_free_tx_pkt(dev, db);
/* Restore CR7 to enable interrupt mask */
- outl(db->cr7_data, ioaddr + DCR7);
+ uw32(DCR7, db->cr7_data);
spin_unlock_irqrestore(&db->lock, flags);
return IRQ_HANDLED;
@@ -727,8 +744,10 @@
#ifdef CONFIG_NET_POLL_CONTROLLER
static void uli526x_poll(struct net_device *dev)
{
+ struct uli526x_board_info *db = netdev_priv(dev);
+
/* ISR grabs the irqsave lock, so this should be safe */
- uli526x_interrupt(dev->irq, dev);
+ uli526x_interrupt(db->pdev->irq, dev);
}
#endif
@@ -962,12 +981,7 @@
strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- if (np->pdev)
- strlcpy(info->bus_info, pci_name(np->pdev),
- sizeof(info->bus_info));
- else
- sprintf(info->bus_info, "EISA 0x%lx %d",
- dev->base_addr, dev->irq);
+ strlcpy(info->bus_info, pci_name(np->pdev), sizeof(info->bus_info));
}
static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) {
@@ -1007,18 +1021,20 @@
static void uli526x_timer(unsigned long data)
{
- u32 tmp_cr8;
- unsigned char tmp_cr12=0;
struct net_device *dev = (struct net_device *) data;
struct uli526x_board_info *db = netdev_priv(dev);
+ struct uli_phy_ops *phy = &db->phy;
+ void __iomem *ioaddr = db->ioaddr;
unsigned long flags;
+ u8 tmp_cr12 = 0;
+ u32 tmp_cr8;
//ULI526X_DBUG(0, "uli526x_timer()", 0);
spin_lock_irqsave(&db->lock, flags);
/* Dynamic reset ULI526X : system error or transmit time-out */
- tmp_cr8 = inl(db->ioaddr + DCR8);
+ tmp_cr8 = ur32(DCR8);
if ( (db->interval_rx_cnt==0) && (tmp_cr8) ) {
db->reset_cr8++;
db->wait_reset = 1;
@@ -1028,7 +1044,7 @@
/* TX polling kick monitor */
if ( db->tx_packet_cnt &&
time_after(jiffies, dev_trans_start(dev) + ULI526X_TX_KICK) ) {
- outl(0x1, dev->base_addr + DCR1); // Tx polling again
+ uw32(DCR1, 0x1); // Tx polling again
// TX Timeout
if ( time_after(jiffies, dev_trans_start(dev) + ULI526X_TX_TIMEOUT) ) {
@@ -1049,7 +1065,7 @@
}
/* Link status check, Dynamic media type change */
- if((phy_read(db->ioaddr, db->phy_addr, 5, db->chip_id) & 0x01e0)!=0)
+ if ((phy->read(db, db->phy_addr, 5) & 0x01e0)!=0)
tmp_cr12 = 3;
if ( !(tmp_cr12 & 0x3) && !db->link_failed ) {
@@ -1062,7 +1078,7 @@
/* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */
/* AUTO don't need */
if ( !(db->media_mode & 0x8) )
- phy_write(db->ioaddr, db->phy_addr, 0, 0x1000, db->chip_id);
+ phy->write(db, db->phy_addr, 0, 0x1000);
/* AUTO mode, if INT phyxcer link failed, select EXT device */
if (db->media_mode & ULI526X_AUTO) {
@@ -1119,12 +1135,13 @@
static void uli526x_reset_prepare(struct net_device *dev)
{
struct uli526x_board_info *db = netdev_priv(dev);
+ void __iomem *ioaddr = db->ioaddr;
/* Sopt MAC controller */
db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); /* Disable Tx/Rx */
- update_cr6(db->cr6_data, dev->base_addr);
- outl(0, dev->base_addr + DCR7); /* Disable Interrupt */
- outl(inl(dev->base_addr + DCR5), dev->base_addr + DCR5);
+ update_cr6(db->cr6_data, ioaddr);
+ uw32(DCR7, 0); /* Disable Interrupt */
+ uw32(DCR5, ur32(DCR5));
/* Disable upper layer interface */
netif_stop_queue(dev);
@@ -1289,7 +1306,7 @@
* Using Chain structure, and allocate Tx/Rx buffer
*/
-static void uli526x_descriptor_init(struct net_device *dev, unsigned long ioaddr)
+static void uli526x_descriptor_init(struct net_device *dev, void __iomem *ioaddr)
{
struct uli526x_board_info *db = netdev_priv(dev);
struct tx_desc *tmp_tx;
@@ -1304,14 +1321,14 @@
/* tx descriptor start pointer */
db->tx_insert_ptr = db->first_tx_desc;
db->tx_remove_ptr = db->first_tx_desc;
- outl(db->first_tx_desc_dma, ioaddr + DCR4); /* TX DESC address */
+ uw32(DCR4, db->first_tx_desc_dma); /* TX DESC address */
/* rx descriptor start pointer */
db->first_rx_desc = (void *)db->first_tx_desc + sizeof(struct tx_desc) * TX_DESC_CNT;
db->first_rx_desc_dma = db->first_tx_desc_dma + sizeof(struct tx_desc) * TX_DESC_CNT;
db->rx_insert_ptr = db->first_rx_desc;
db->rx_ready_ptr = db->first_rx_desc;
- outl(db->first_rx_desc_dma, ioaddr + DCR3); /* RX DESC address */
+ uw32(DCR3, db->first_rx_desc_dma); /* RX DESC address */
/* Init Transmit chain */
tmp_buf = db->buf_pool_start;
@@ -1352,11 +1369,9 @@
* Update CR6 value
* Firstly stop ULI526X, then written value and start
*/
-
-static void update_cr6(u32 cr6_data, unsigned long ioaddr)
+static void update_cr6(u32 cr6_data, void __iomem *ioaddr)
{
-
- outl(cr6_data, ioaddr + DCR6);
+ uw32(DCR6, cr6_data);
udelay(5);
}
@@ -1375,6 +1390,7 @@
static void send_filter_frame(struct net_device *dev, int mc_cnt)
{
struct uli526x_board_info *db = netdev_priv(dev);
+ void __iomem *ioaddr = db->ioaddr;
struct netdev_hw_addr *ha;
struct tx_desc *txptr;
u16 * addrptr;
@@ -1420,9 +1436,9 @@
/* Resource Empty */
db->tx_packet_cnt++;
txptr->tdes0 = cpu_to_le32(0x80000000);
- update_cr6(db->cr6_data | 0x2000, dev->base_addr);
- outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */
- update_cr6(db->cr6_data, dev->base_addr);
+ update_cr6(db->cr6_data | 0x2000, ioaddr);
+ uw32(DCR1, 0x1); /* Issue Tx polling */
+ update_cr6(db->cr6_data, ioaddr);
dev->trans_start = jiffies;
} else
netdev_err(dev, "No Tx resource - Send_filter_frame!\n");
@@ -1465,37 +1481,38 @@
* Read one word data from the serial ROM
*/
-static u16 read_srom_word(long ioaddr, int offset)
+static u16 read_srom_word(struct uli526x_board_info *db, int offset)
{
- int i;
+ void __iomem *ioaddr = db->ioaddr;
u16 srom_data = 0;
- long cr9_ioaddr = ioaddr + DCR9;
+ int i;
- outl(CR9_SROM_READ, cr9_ioaddr);
- outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+ uw32(DCR9, CR9_SROM_READ);
+ uw32(DCR9, CR9_SROM_READ | CR9_SRCS);
/* Send the Read Command 110b */
- SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
- SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
- SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr);
+ srom_clk_write(db, SROM_DATA_1);
+ srom_clk_write(db, SROM_DATA_1);
+ srom_clk_write(db, SROM_DATA_0);
/* Send the offset */
for (i = 5; i >= 0; i--) {
srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;
- SROM_CLK_WRITE(srom_data, cr9_ioaddr);
+ srom_clk_write(db, srom_data);
}
- outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+ uw32(DCR9, CR9_SROM_READ | CR9_SRCS);
for (i = 16; i > 0; i--) {
- outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr);
+ uw32(DCR9, CR9_SROM_READ | CR9_SRCS | CR9_SRCLK);
udelay(5);
- srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0);
- outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+ srom_data = (srom_data << 1) |
+ ((ur32(DCR9) & CR9_CRDOUT) ? 1 : 0);
+ uw32(DCR9, CR9_SROM_READ | CR9_SRCS);
udelay(5);
}
- outl(CR9_SROM_READ, cr9_ioaddr);
+ uw32(DCR9, CR9_SROM_READ);
return srom_data;
}
@@ -1506,15 +1523,16 @@
static u8 uli526x_sense_speed(struct uli526x_board_info * db)
{
+ struct uli_phy_ops *phy = &db->phy;
u8 ErrFlag = 0;
u16 phy_mode;
- phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
- phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
+ phy_mode = phy->read(db, db->phy_addr, 1);
+ phy_mode = phy->read(db, db->phy_addr, 1);
if ( (phy_mode & 0x24) == 0x24 ) {
- phy_mode = ((phy_read(db->ioaddr, db->phy_addr, 5, db->chip_id) & 0x01e0)<<7);
+ phy_mode = ((phy->read(db, db->phy_addr, 5) & 0x01e0)<<7);
if(phy_mode&0x8000)
phy_mode = 0x8000;
else if(phy_mode&0x4000)
@@ -1549,10 +1567,11 @@
static void uli526x_set_phyxcer(struct uli526x_board_info *db)
{
+ struct uli_phy_ops *phy = &db->phy;
u16 phy_reg;
/* Phyxcer capability setting */
- phy_reg = phy_read(db->ioaddr, db->phy_addr, 4, db->chip_id) & ~0x01e0;
+ phy_reg = phy->read(db, db->phy_addr, 4) & ~0x01e0;
if (db->media_mode & ULI526X_AUTO) {
/* AUTO Mode */
@@ -1573,10 +1592,10 @@
phy_reg|=db->PHY_reg4;
db->media_mode|=ULI526X_AUTO;
}
- phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id);
+ phy->write(db, db->phy_addr, 4, phy_reg);
/* Restart Auto-Negotiation */
- phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id);
+ phy->write(db, db->phy_addr, 0, 0x1200);
udelay(50);
}
@@ -1590,6 +1609,7 @@
static void uli526x_process_mode(struct uli526x_board_info *db)
{
+ struct uli_phy_ops *phy = &db->phy;
u16 phy_reg;
/* Full Duplex Mode Check */
@@ -1601,10 +1621,10 @@
update_cr6(db->cr6_data, db->ioaddr);
/* 10/100M phyxcer force mode need */
- if ( !(db->media_mode & 0x8)) {
+ if (!(db->media_mode & 0x8)) {
/* Forece Mode */
- phy_reg = phy_read(db->ioaddr, db->phy_addr, 6, db->chip_id);
- if ( !(phy_reg & 0x1) ) {
+ phy_reg = phy->read(db, db->phy_addr, 6);
+ if (!(phy_reg & 0x1)) {
/* parter without N-Way capability */
phy_reg = 0x0;
switch(db->op_mode) {
@@ -1613,148 +1633,126 @@
case ULI526X_100MHF: phy_reg = 0x2000; break;
case ULI526X_100MFD: phy_reg = 0x2100; break;
}
- phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id);
+ phy->write(db, db->phy_addr, 0, phy_reg);
}
}
}
-/*
- * Write a word to Phy register
- */
-
-static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data, u32 chip_id)
+/* M5261/M5263 Chip */
+static void phy_writeby_cr9(struct uli526x_board_info *db, u8 phy_addr,
+ u8 offset, u16 phy_data)
{
u16 i;
- unsigned long ioaddr;
-
- if(chip_id == PCI_ULI5263_ID)
- {
- phy_writeby_cr10(iobase, phy_addr, offset, phy_data);
- return;
- }
- /* M5261/M5263 Chip */
- ioaddr = iobase + DCR9;
/* Send 33 synchronization clock to Phy controller */
for (i = 0; i < 35; i++)
- phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+ phy_write_1bit(db, PHY_DATA_1);
/* Send start command(01) to Phy */
- phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
- phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+ phy_write_1bit(db, PHY_DATA_0);
+ phy_write_1bit(db, PHY_DATA_1);
/* Send write command(01) to Phy */
- phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
- phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+ phy_write_1bit(db, PHY_DATA_0);
+ phy_write_1bit(db, PHY_DATA_1);
/* Send Phy address */
for (i = 0x10; i > 0; i = i >> 1)
- phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
+ phy_write_1bit(db, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0);
/* Send register address */
for (i = 0x10; i > 0; i = i >> 1)
- phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
+ phy_write_1bit(db, offset & i ? PHY_DATA_1 : PHY_DATA_0);
/* written trasnition */
- phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
- phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+ phy_write_1bit(db, PHY_DATA_1);
+ phy_write_1bit(db, PHY_DATA_0);
/* Write a word data to PHY controller */
- for ( i = 0x8000; i > 0; i >>= 1)
- phy_write_1bit(ioaddr, phy_data & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
-
+ for (i = 0x8000; i > 0; i >>= 1)
+ phy_write_1bit(db, phy_data & i ? PHY_DATA_1 : PHY_DATA_0);
}
-
-/*
- * Read a word data from phy register
- */
-
-static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id)
+static u16 phy_readby_cr9(struct uli526x_board_info *db, u8 phy_addr, u8 offset)
{
- int i;
u16 phy_data;
- unsigned long ioaddr;
-
- if(chip_id == PCI_ULI5263_ID)
- return phy_readby_cr10(iobase, phy_addr, offset);
- /* M5261/M5263 Chip */
- ioaddr = iobase + DCR9;
+ int i;
/* Send 33 synchronization clock to Phy controller */
for (i = 0; i < 35; i++)
- phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+ phy_write_1bit(db, PHY_DATA_1);
/* Send start command(01) to Phy */
- phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
- phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+ phy_write_1bit(db, PHY_DATA_0);
+ phy_write_1bit(db, PHY_DATA_1);
/* Send read command(10) to Phy */
- phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
- phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+ phy_write_1bit(db, PHY_DATA_1);
+ phy_write_1bit(db, PHY_DATA_0);
/* Send Phy address */
for (i = 0x10; i > 0; i = i >> 1)
- phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
+ phy_write_1bit(db, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0);
/* Send register address */
for (i = 0x10; i > 0; i = i >> 1)
- phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0, chip_id);
+ phy_write_1bit(db, offset & i ? PHY_DATA_1 : PHY_DATA_0);
/* Skip transition state */
- phy_read_1bit(ioaddr, chip_id);
+ phy_read_1bit(db);
/* read 16bit data */
for (phy_data = 0, i = 0; i < 16; i++) {
phy_data <<= 1;
- phy_data |= phy_read_1bit(ioaddr, chip_id);
+ phy_data |= phy_read_1bit(db);
}
return phy_data;
}
-static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset)
+static u16 phy_readby_cr10(struct uli526x_board_info *db, u8 phy_addr,
+ u8 offset)
{
- unsigned long ioaddr,cr10_value;
+ void __iomem *ioaddr = db->ioaddr;
+ u32 cr10_value = phy_addr;
- ioaddr = iobase + DCR10;
- cr10_value = phy_addr;
- cr10_value = (cr10_value<<5) + offset;
- cr10_value = (cr10_value<<16) + 0x08000000;
- outl(cr10_value,ioaddr);
+ cr10_value = (cr10_value << 5) + offset;
+ cr10_value = (cr10_value << 16) + 0x08000000;
+ uw32(DCR10, cr10_value);
udelay(1);
- while(1)
- {
- cr10_value = inl(ioaddr);
- if(cr10_value&0x10000000)
+ while (1) {
+ cr10_value = ur32(DCR10);
+ if (cr10_value & 0x10000000)
break;
}
return cr10_value & 0x0ffff;
}
-static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data)
+static void phy_writeby_cr10(struct uli526x_board_info *db, u8 phy_addr,
+ u8 offset, u16 phy_data)
{
- unsigned long ioaddr,cr10_value;
+ void __iomem *ioaddr = db->ioaddr;
+ u32 cr10_value = phy_addr;
- ioaddr = iobase + DCR10;
- cr10_value = phy_addr;
- cr10_value = (cr10_value<<5) + offset;
- cr10_value = (cr10_value<<16) + 0x04000000 + phy_data;
- outl(cr10_value,ioaddr);
+ cr10_value = (cr10_value << 5) + offset;
+ cr10_value = (cr10_value << 16) + 0x04000000 + phy_data;
+ uw32(DCR10, cr10_value);
udelay(1);
}
/*
* Write one bit data to Phy Controller
*/
-static void phy_write_1bit(unsigned long ioaddr, u32 phy_data, u32 chip_id)
+static void phy_write_1bit(struct uli526x_board_info *db, u32 data)
{
- outl(phy_data , ioaddr); /* MII Clock Low */
+ void __iomem *ioaddr = db->ioaddr;
+
+ uw32(DCR9, data); /* MII Clock Low */
udelay(1);
- outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */
+ uw32(DCR9, data | MDCLKH); /* MII Clock High */
udelay(1);
- outl(phy_data , ioaddr); /* MII Clock Low */
+ uw32(DCR9, data); /* MII Clock Low */
udelay(1);
}
@@ -1763,14 +1761,15 @@
* Read one bit phy data from PHY controller
*/
-static u16 phy_read_1bit(unsigned long ioaddr, u32 chip_id)
+static u16 phy_read_1bit(struct uli526x_board_info *db)
{
+ void __iomem *ioaddr = db->ioaddr;
u16 phy_data;
- outl(0x50000 , ioaddr);
+ uw32(DCR9, 0x50000);
udelay(1);
- phy_data = ( inl(ioaddr) >> 19 ) & 0x1;
- outl(0x40000 , ioaddr);
+ phy_data = (ur32(DCR9) >> 19) & 0x1;
+ uw32(DCR9, 0x40000);
udelay(1);
return phy_data;
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c
index 2ac6fff..4d1ffca 100644
--- a/drivers/net/ethernet/dec/tulip/winbond-840.c
+++ b/drivers/net/ethernet/dec/tulip/winbond-840.c
@@ -400,9 +400,6 @@
No hold time required! */
iowrite32(0x00000001, ioaddr + PCIBusCfg);
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
-
np = netdev_priv(dev);
np->pci_dev = pdev;
np->chip_id = chip_idx;
@@ -635,17 +632,18 @@
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base_addr;
+ const int irq = np->pci_dev->irq;
int i;
iowrite32(0x00000001, ioaddr + PCIBusCfg); /* Reset */
netif_device_detach(dev);
- i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
+ i = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
if (i)
goto out_err;
if (debug > 1)
- netdev_dbg(dev, "w89c840_open() irq %d\n", dev->irq);
+ netdev_dbg(dev, "w89c840_open() irq %d\n", irq);
if((i=alloc_ringdesc(dev)))
goto out_err;
@@ -932,6 +930,7 @@
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base_addr;
+ const int irq = np->pci_dev->irq;
dev_warn(&dev->dev, "Transmit timed out, status %08x, resetting...\n",
ioread32(ioaddr + IntrStatus));
@@ -951,7 +950,7 @@
np->cur_tx, np->dirty_tx, np->tx_full, np->tx_q_bytes);
printk(KERN_DEBUG "Tx Descriptor addr %xh\n", ioread32(ioaddr+0x4C));
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock_irq(&np->lock);
/*
* Under high load dirty_tx and the internal tx descriptor pointer
@@ -966,7 +965,7 @@
init_rxtx_rings(dev);
init_registers(dev);
spin_unlock_irq(&np->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
netif_wake_queue(dev);
dev->trans_start = jiffies; /* prevent tx timeout */
@@ -1500,7 +1499,7 @@
iowrite32(0x0000, ioaddr + IntrEnable);
spin_unlock_irq(&np->lock);
- free_irq(dev->irq, dev);
+ free_irq(np->pci_dev->irq, dev);
wmb();
netif_device_attach(dev);
@@ -1589,7 +1588,7 @@
iowrite32(0, ioaddr + IntrEnable);
spin_unlock_irq(&np->lock);
- synchronize_irq(dev->irq);
+ synchronize_irq(np->pci_dev->irq);
netif_tx_disable(dev);
np->stats.rx_missed_errors += ioread32(ioaddr + RxMissed) & 0xffff;
diff --git a/drivers/net/ethernet/dec/tulip/xircom_cb.c b/drivers/net/ethernet/dec/tulip/xircom_cb.c
index fdb329f..138bf83 100644
--- a/drivers/net/ethernet/dec/tulip/xircom_cb.c
+++ b/drivers/net/ethernet/dec/tulip/xircom_cb.c
@@ -41,7 +41,9 @@
MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>");
MODULE_LICENSE("GPL");
-
+#define xw32(reg, val) iowrite32(val, ioaddr + (reg))
+#define xr32(reg) ioread32(ioaddr + (reg))
+#define xr8(reg) ioread8(ioaddr + (reg))
/* IO registers on the card, offsets */
#define CSR0 0x00
@@ -83,7 +85,7 @@
struct sk_buff *tx_skb[4];
- unsigned long io_port;
+ void __iomem *ioaddr;
int open;
/* transmit_used is the rotating counter that indicates which transmit
@@ -137,7 +139,7 @@
static DEFINE_PCI_DEVICE_TABLE(xircom_pci_table) = {
- {0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID,},
+ { PCI_VDEVICE(XIRCOM, 0x0003), },
{0,},
};
MODULE_DEVICE_TABLE(pci, xircom_pci_table);
@@ -146,9 +148,7 @@
.name = "xircom_cb",
.id_table = xircom_pci_table,
.probe = xircom_probe,
- .remove = xircom_remove,
- .suspend =NULL,
- .resume =NULL
+ .remove = __devexit_p(xircom_remove),
};
@@ -192,15 +192,18 @@
*/
static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
+ struct device *d = &pdev->dev;
struct net_device *dev = NULL;
struct xircom_private *private;
unsigned long flags;
unsigned short tmp16;
+ int rc;
/* First do the PCI initialisation */
- if (pci_enable_device(pdev))
- return -ENODEV;
+ rc = pci_enable_device(pdev);
+ if (rc < 0)
+ goto out;
/* disable all powermanagement */
pci_write_config_dword(pdev, PCI_POWERMGMT, 0x0000);
@@ -211,11 +214,13 @@
pci_read_config_word (pdev,PCI_STATUS, &tmp16);
pci_write_config_word (pdev, PCI_STATUS,tmp16);
- if (!request_region(pci_resource_start(pdev, 0), 128, "xircom_cb")) {
+ rc = pci_request_regions(pdev, "xircom_cb");
+ if (rc < 0) {
pr_err("%s: failed to allocate io-region\n", __func__);
- return -ENODEV;
+ goto err_disable;
}
+ rc = -ENOMEM;
/*
Before changing the hardware, allocate the memory.
This way, we can fail gracefully if not enough memory
@@ -223,17 +228,21 @@
*/
dev = alloc_etherdev(sizeof(struct xircom_private));
if (!dev)
- goto device_fail;
+ goto err_release;
private = netdev_priv(dev);
/* Allocate the send/receive buffers */
- private->rx_buffer = pci_alloc_consistent(pdev,8192,&private->rx_dma_handle);
+ private->rx_buffer = dma_alloc_coherent(d, 8192,
+ &private->rx_dma_handle,
+ GFP_KERNEL);
if (private->rx_buffer == NULL) {
pr_err("%s: no memory for rx buffer\n", __func__);
goto rx_buf_fail;
}
- private->tx_buffer = pci_alloc_consistent(pdev,8192,&private->tx_dma_handle);
+ private->tx_buffer = dma_alloc_coherent(d, 8192,
+ &private->tx_dma_handle,
+ GFP_KERNEL);
if (private->tx_buffer == NULL) {
pr_err("%s: no memory for tx buffer\n", __func__);
goto tx_buf_fail;
@@ -244,10 +253,13 @@
private->dev = dev;
private->pdev = pdev;
- private->io_port = pci_resource_start(pdev, 0);
+
+ /* IO range. */
+ private->ioaddr = pci_iomap(pdev, 0, 0);
+ if (!private->ioaddr)
+ goto reg_fail;
+
spin_lock_init(&private->lock);
- dev->irq = pdev->irq;
- dev->base_addr = private->io_port;
initialize_card(private);
read_mac_address(private);
@@ -256,9 +268,10 @@
dev->netdev_ops = &netdev_ops;
pci_set_drvdata(pdev, dev);
- if (register_netdev(dev)) {
+ rc = register_netdev(dev);
+ if (rc < 0) {
pr_err("%s: netdevice registration failed\n", __func__);
- goto reg_fail;
+ goto err_unmap;
}
netdev_info(dev, "Xircom cardbus revision %i at irq %i\n",
@@ -273,17 +286,23 @@
spin_unlock_irqrestore(&private->lock,flags);
trigger_receive(private);
+out:
+ return rc;
- return 0;
-
+err_unmap:
+ pci_iounmap(pdev, private->ioaddr);
reg_fail:
- kfree(private->tx_buffer);
+ pci_set_drvdata(pdev, NULL);
+ dma_free_coherent(d, 8192, private->tx_buffer, private->tx_dma_handle);
tx_buf_fail:
- kfree(private->rx_buffer);
+ dma_free_coherent(d, 8192, private->rx_buffer, private->rx_dma_handle);
rx_buf_fail:
free_netdev(dev);
-device_fail:
- return -ENODEV;
+err_release:
+ pci_release_regions(pdev);
+err_disable:
+ pci_disable_device(pdev);
+ goto out;
}
@@ -297,25 +316,28 @@
{
struct net_device *dev = pci_get_drvdata(pdev);
struct xircom_private *card = netdev_priv(dev);
+ struct device *d = &pdev->dev;
- pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle);
- pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle);
-
- release_region(dev->base_addr, 128);
unregister_netdev(dev);
- free_netdev(dev);
+ pci_iounmap(pdev, card->ioaddr);
pci_set_drvdata(pdev, NULL);
+ dma_free_coherent(d, 8192, card->tx_buffer, card->tx_dma_handle);
+ dma_free_coherent(d, 8192, card->rx_buffer, card->rx_dma_handle);
+ free_netdev(dev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
}
static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
{
struct net_device *dev = (struct net_device *) dev_instance;
struct xircom_private *card = netdev_priv(dev);
+ void __iomem *ioaddr = card->ioaddr;
unsigned int status;
int i;
spin_lock(&card->lock);
- status = inl(card->io_port+CSR5);
+ status = xr32(CSR5);
#if defined DEBUG && DEBUG > 1
print_binary(status);
@@ -345,7 +367,7 @@
/* Clear all remaining interrupts */
status |= 0xffffffff; /* FIXME: make this clear only the
real existing bits */
- outl(status,card->io_port+CSR5);
+ xw32(CSR5, status);
for (i=0;i<NUMDESCRIPTORS;i++)
@@ -423,11 +445,11 @@
static int xircom_open(struct net_device *dev)
{
struct xircom_private *xp = netdev_priv(dev);
+ const int irq = xp->pdev->irq;
int retval;
- netdev_info(dev, "xircom cardbus adaptor found, using irq %i\n",
- dev->irq);
- retval = request_irq(dev->irq, xircom_interrupt, IRQF_SHARED, dev->name, dev);
+ netdev_info(dev, "xircom cardbus adaptor found, using irq %i\n", irq);
+ retval = request_irq(irq, xircom_interrupt, IRQF_SHARED, dev->name, dev);
if (retval)
return retval;
@@ -459,7 +481,7 @@
spin_unlock_irqrestore(&card->lock,flags);
card->open = 0;
- free_irq(dev->irq,dev);
+ free_irq(card->pdev->irq, dev);
return 0;
@@ -469,35 +491,39 @@
#ifdef CONFIG_NET_POLL_CONTROLLER
static void xircom_poll_controller(struct net_device *dev)
{
- disable_irq(dev->irq);
- xircom_interrupt(dev->irq, dev);
- enable_irq(dev->irq);
+ struct xircom_private *xp = netdev_priv(dev);
+ const int irq = xp->pdev->irq;
+
+ disable_irq(irq);
+ xircom_interrupt(irq, dev);
+ enable_irq(irq);
}
#endif
static void initialize_card(struct xircom_private *card)
{
- unsigned int val;
+ void __iomem *ioaddr = card->ioaddr;
unsigned long flags;
+ u32 val;
spin_lock_irqsave(&card->lock, flags);
/* First: reset the card */
- val = inl(card->io_port + CSR0);
+ val = xr32(CSR0);
val |= 0x01; /* Software reset */
- outl(val, card->io_port + CSR0);
+ xw32(CSR0, val);
udelay(100); /* give the card some time to reset */
- val = inl(card->io_port + CSR0);
+ val = xr32(CSR0);
val &= ~0x01; /* disable Software reset */
- outl(val, card->io_port + CSR0);
+ xw32(CSR0, val);
val = 0; /* Value 0x00 is a safe and conservative value
for the PCI configuration settings */
- outl(val, card->io_port + CSR0);
+ xw32(CSR0, val);
disable_all_interrupts(card);
@@ -515,10 +541,9 @@
*/
static void trigger_transmit(struct xircom_private *card)
{
- unsigned int val;
+ void __iomem *ioaddr = card->ioaddr;
- val = 0;
- outl(val, card->io_port + CSR1);
+ xw32(CSR1, 0);
}
/*
@@ -530,10 +555,9 @@
*/
static void trigger_receive(struct xircom_private *card)
{
- unsigned int val;
+ void __iomem *ioaddr = card->ioaddr;
- val = 0;
- outl(val, card->io_port + CSR2);
+ xw32(CSR2, 0);
}
/*
@@ -542,6 +566,7 @@
*/
static void setup_descriptors(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
u32 address;
int i;
@@ -571,7 +596,7 @@
wmb();
/* Write the receive descriptor ring address to the card */
address = card->rx_dma_handle;
- outl(address, card->io_port + CSR3); /* Receive descr list address */
+ xw32(CSR3, address); /* Receive descr list address */
/* transmit descriptors */
@@ -596,7 +621,7 @@
wmb();
/* wite the transmit descriptor ring to the card */
address = card->tx_dma_handle;
- outl(address, card->io_port + CSR4); /* xmit descr list address */
+ xw32(CSR4, address); /* xmit descr list address */
}
/*
@@ -605,11 +630,12 @@
*/
static void remove_descriptors(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
val = 0;
- outl(val, card->io_port + CSR3); /* Receive descriptor address */
- outl(val, card->io_port + CSR4); /* Send descriptor address */
+ xw32(CSR3, val); /* Receive descriptor address */
+ xw32(CSR4, val); /* Send descriptor address */
}
/*
@@ -620,17 +646,17 @@
*/
static int link_status_changed(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
- val = inl(card->io_port + CSR5); /* Status register */
-
- if ((val & (1 << 27)) == 0) /* no change */
+ val = xr32(CSR5); /* Status register */
+ if (!(val & (1 << 27))) /* no change */
return 0;
/* clear the event by writing a 1 to the bit in the
status register. */
val = (1 << 27);
- outl(val, card->io_port + CSR5);
+ xw32(CSR5, val);
return 1;
}
@@ -642,11 +668,9 @@
*/
static int transmit_active(struct xircom_private *card)
{
- unsigned int val;
+ void __iomem *ioaddr = card->ioaddr;
- val = inl(card->io_port + CSR5); /* Status register */
-
- if ((val & (7 << 20)) == 0) /* transmitter disabled */
+ if (!(xr32(CSR5) & (7 << 20))) /* transmitter disabled */
return 0;
return 1;
@@ -658,11 +682,9 @@
*/
static int receive_active(struct xircom_private *card)
{
- unsigned int val;
+ void __iomem *ioaddr = card->ioaddr;
- val = inl(card->io_port + CSR5); /* Status register */
-
- if ((val & (7 << 17)) == 0) /* receiver disabled */
+ if (!(xr32(CSR5) & (7 << 17))) /* receiver disabled */
return 0;
return 1;
@@ -680,10 +702,11 @@
*/
static void activate_receiver(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
int counter;
- val = inl(card->io_port + CSR6); /* Operation mode */
+ val = xr32(CSR6); /* Operation mode */
/* If the "active" bit is set and the receiver is already
active, no need to do the expensive thing */
@@ -692,7 +715,7 @@
val = val & ~2; /* disable the receiver */
- outl(val, card->io_port + CSR6);
+ xw32(CSR6, val);
counter = 10;
while (counter > 0) {
@@ -706,9 +729,9 @@
}
/* enable the receiver */
- val = inl(card->io_port + CSR6); /* Operation mode */
- val = val | 2; /* enable the receiver */
- outl(val, card->io_port + CSR6);
+ val = xr32(CSR6); /* Operation mode */
+ val = val | 2; /* enable the receiver */
+ xw32(CSR6, val);
/* now wait for the card to activate again */
counter = 10;
@@ -733,12 +756,13 @@
*/
static void deactivate_receiver(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
int counter;
- val = inl(card->io_port + CSR6); /* Operation mode */
- val = val & ~2; /* disable the receiver */
- outl(val, card->io_port + CSR6);
+ val = xr32(CSR6); /* Operation mode */
+ val = val & ~2; /* disable the receiver */
+ xw32(CSR6, val);
counter = 10;
while (counter > 0) {
@@ -765,10 +789,11 @@
*/
static void activate_transmitter(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
int counter;
- val = inl(card->io_port + CSR6); /* Operation mode */
+ val = xr32(CSR6); /* Operation mode */
/* If the "active" bit is set and the receiver is already
active, no need to do the expensive thing */
@@ -776,7 +801,7 @@
return;
val = val & ~(1 << 13); /* disable the transmitter */
- outl(val, card->io_port + CSR6);
+ xw32(CSR6, val);
counter = 10;
while (counter > 0) {
@@ -791,9 +816,9 @@
}
/* enable the transmitter */
- val = inl(card->io_port + CSR6); /* Operation mode */
+ val = xr32(CSR6); /* Operation mode */
val = val | (1 << 13); /* enable the transmitter */
- outl(val, card->io_port + CSR6);
+ xw32(CSR6, val);
/* now wait for the card to activate again */
counter = 10;
@@ -818,12 +843,13 @@
*/
static void deactivate_transmitter(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
int counter;
- val = inl(card->io_port + CSR6); /* Operation mode */
+ val = xr32(CSR6); /* Operation mode */
val = val & ~2; /* disable the transmitter */
- outl(val, card->io_port + CSR6);
+ xw32(CSR6, val);
counter = 20;
while (counter > 0) {
@@ -846,11 +872,12 @@
*/
static void enable_transmit_interrupt(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
- val = inl(card->io_port + CSR7); /* Interrupt enable register */
- val |= 1; /* enable the transmit interrupt */
- outl(val, card->io_port + CSR7);
+ val = xr32(CSR7); /* Interrupt enable register */
+ val |= 1; /* enable the transmit interrupt */
+ xw32(CSR7, val);
}
@@ -861,11 +888,12 @@
*/
static void enable_receive_interrupt(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
- val = inl(card->io_port + CSR7); /* Interrupt enable register */
- val = val | (1 << 6); /* enable the receive interrupt */
- outl(val, card->io_port + CSR7);
+ val = xr32(CSR7); /* Interrupt enable register */
+ val = val | (1 << 6); /* enable the receive interrupt */
+ xw32(CSR7, val);
}
/*
@@ -875,11 +903,12 @@
*/
static void enable_link_interrupt(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
- val = inl(card->io_port + CSR7); /* Interrupt enable register */
- val = val | (1 << 27); /* enable the link status chage interrupt */
- outl(val, card->io_port + CSR7);
+ val = xr32(CSR7); /* Interrupt enable register */
+ val = val | (1 << 27); /* enable the link status chage interrupt */
+ xw32(CSR7, val);
}
@@ -891,10 +920,9 @@
*/
static void disable_all_interrupts(struct xircom_private *card)
{
- unsigned int val;
+ void __iomem *ioaddr = card->ioaddr;
- val = 0; /* disable all interrupts */
- outl(val, card->io_port + CSR7);
+ xw32(CSR7, 0);
}
/*
@@ -904,9 +932,10 @@
*/
static void enable_common_interrupts(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
- val = inl(card->io_port + CSR7); /* Interrupt enable register */
+ val = xr32(CSR7); /* Interrupt enable register */
val |= (1<<16); /* Normal Interrupt Summary */
val |= (1<<15); /* Abnormal Interrupt Summary */
val |= (1<<13); /* Fatal bus error */
@@ -915,7 +944,7 @@
val |= (1<<5); /* Transmit Underflow */
val |= (1<<2); /* Transmit Buffer Unavailable */
val |= (1<<1); /* Transmit Process Stopped */
- outl(val, card->io_port + CSR7);
+ xw32(CSR7, val);
}
/*
@@ -925,11 +954,12 @@
*/
static int enable_promisc(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned int val;
- val = inl(card->io_port + CSR6);
+ val = xr32(CSR6);
val = val | (1 << 6);
- outl(val, card->io_port + CSR6);
+ xw32(CSR6, val);
return 1;
}
@@ -944,13 +974,16 @@
*/
static int link_status(struct xircom_private *card)
{
- unsigned int val;
+ void __iomem *ioaddr = card->ioaddr;
+ u8 val;
- val = inb(card->io_port + CSR12);
+ val = xr8(CSR12);
- if (!(val&(1<<2))) /* bit 2 is 0 for 10mbit link, 1 for not an 10mbit link */
+ /* bit 2 is 0 for 10mbit link, 1 for not an 10mbit link */
+ if (!(val & (1 << 2)))
return 10;
- if (!(val&(1<<1))) /* bit 1 is 0 for 100mbit link, 1 for not an 100mbit link */
+ /* bit 1 is 0 for 100mbit link, 1 for not an 100mbit link */
+ if (!(val & (1 << 1)))
return 100;
/* If we get here -> no link at all */
@@ -969,29 +1002,31 @@
*/
static void read_mac_address(struct xircom_private *card)
{
- unsigned char j, tuple, link, data_id, data_count;
+ void __iomem *ioaddr = card->ioaddr;
unsigned long flags;
+ u8 link;
int i;
spin_lock_irqsave(&card->lock, flags);
- outl(1 << 12, card->io_port + CSR9); /* enable boot rom access */
+ xw32(CSR9, 1 << 12); /* enable boot rom access */
for (i = 0x100; i < 0x1f7; i += link + 2) {
- outl(i, card->io_port + CSR10);
- tuple = inl(card->io_port + CSR9) & 0xff;
- outl(i + 1, card->io_port + CSR10);
- link = inl(card->io_port + CSR9) & 0xff;
- outl(i + 2, card->io_port + CSR10);
- data_id = inl(card->io_port + CSR9) & 0xff;
- outl(i + 3, card->io_port + CSR10);
- data_count = inl(card->io_port + CSR9) & 0xff;
+ u8 tuple, data_id, data_count;
+
+ xw32(CSR10, i);
+ tuple = xr32(CSR9);
+ xw32(CSR10, i + 1);
+ link = xr32(CSR9);
+ xw32(CSR10, i + 2);
+ data_id = xr32(CSR9);
+ xw32(CSR10, i + 3);
+ data_count = xr32(CSR9);
if ((tuple == 0x22) && (data_id == 0x04) && (data_count == 0x06)) {
- /*
- * This is it. We have the data we want.
- */
+ int j;
+
for (j = 0; j < 6; j++) {
- outl(i + j + 4, card->io_port + CSR10);
- card->dev->dev_addr[j] = inl(card->io_port + CSR9) & 0xff;
+ xw32(CSR10, i + j + 4);
+ card->dev->dev_addr[j] = xr32(CSR9) & 0xff;
}
break;
} else if (link == 0) {
@@ -1010,6 +1045,7 @@
*/
static void transceiver_voodoo(struct xircom_private *card)
{
+ void __iomem *ioaddr = card->ioaddr;
unsigned long flags;
/* disable all powermanagement */
@@ -1019,14 +1055,14 @@
spin_lock_irqsave(&card->lock, flags);
- outl(0x0008, card->io_port + CSR15);
- udelay(25);
- outl(0xa8050000, card->io_port + CSR15);
- udelay(25);
- outl(0xa00f0000, card->io_port + CSR15);
- udelay(25);
+ xw32(CSR15, 0x0008);
+ udelay(25);
+ xw32(CSR15, 0xa8050000);
+ udelay(25);
+ xw32(CSR15, 0xa00f0000);
+ udelay(25);
- spin_unlock_irqrestore(&card->lock, flags);
+ spin_unlock_irqrestore(&card->lock, flags);
netif_start_queue(card->dev);
}
diff --git a/drivers/net/ethernet/dlink/dl2k.c b/drivers/net/ethernet/dlink/dl2k.c
index b2dc2c8..ef4499d 100644
--- a/drivers/net/ethernet/dlink/dl2k.c
+++ b/drivers/net/ethernet/dlink/dl2k.c
@@ -16,6 +16,13 @@
#include "dl2k.h"
#include <linux/dma-mapping.h>
+#define dw32(reg, val) iowrite32(val, ioaddr + (reg))
+#define dw16(reg, val) iowrite16(val, ioaddr + (reg))
+#define dw8(reg, val) iowrite8(val, ioaddr + (reg))
+#define dr32(reg) ioread32(ioaddr + (reg))
+#define dr16(reg) ioread16(ioaddr + (reg))
+#define dr8(reg) ioread8(ioaddr + (reg))
+
static char version[] __devinitdata =
KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n";
#define MAX_UNITS 8
@@ -49,8 +56,13 @@
/* Enable the default interrupts */
#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxDMAComplete| \
UpdateStats | LinkEvent)
-#define EnableInt() \
-writew(DEFAULT_INTR, ioaddr + IntEnable)
+
+static void dl2k_enable_int(struct netdev_private *np)
+{
+ void __iomem *ioaddr = np->ioaddr;
+
+ dw16(IntEnable, DEFAULT_INTR);
+}
static const int max_intrloop = 50;
static const int multicast_filter_limit = 0x40;
@@ -73,7 +85,7 @@
static int rio_close (struct net_device *dev);
static int find_miiphy (struct net_device *dev);
static int parse_eeprom (struct net_device *dev);
-static int read_eeprom (long ioaddr, int eep_addr);
+static int read_eeprom (struct netdev_private *, int eep_addr);
static int mii_wait_link (struct net_device *dev, int wait);
static int mii_set_media (struct net_device *dev);
static int mii_get_media (struct net_device *dev);
@@ -106,7 +118,7 @@
static int card_idx;
int chip_idx = ent->driver_data;
int err, irq;
- long ioaddr;
+ void __iomem *ioaddr;
static int version_printed;
void *ring_space;
dma_addr_t ring_dma;
@@ -124,26 +136,29 @@
goto err_out_disable;
pci_set_master (pdev);
+
+ err = -ENOMEM;
+
dev = alloc_etherdev (sizeof (*np));
- if (!dev) {
- err = -ENOMEM;
+ if (!dev)
goto err_out_res;
- }
SET_NETDEV_DEV(dev, &pdev->dev);
-#ifdef MEM_MAPPING
- ioaddr = pci_resource_start (pdev, 1);
- ioaddr = (long) ioremap (ioaddr, RIO_IO_SIZE);
- if (!ioaddr) {
- err = -ENOMEM;
- goto err_out_dev;
- }
-#else
- ioaddr = pci_resource_start (pdev, 0);
-#endif
- dev->base_addr = ioaddr;
- dev->irq = irq;
np = netdev_priv(dev);
+
+ /* IO registers range. */
+ ioaddr = pci_iomap(pdev, 0, 0);
+ if (!ioaddr)
+ goto err_out_dev;
+ np->eeprom_addr = ioaddr;
+
+#ifdef MEM_MAPPING
+ /* MM registers range. */
+ ioaddr = pci_iomap(pdev, 1, 0);
+ if (!ioaddr)
+ goto err_out_iounmap;
+#endif
+ np->ioaddr = ioaddr;
np->chip_id = chip_idx;
np->pdev = pdev;
spin_lock_init (&np->tx_lock);
@@ -239,7 +254,7 @@
goto err_out_unmap_rx;
/* Fiber device? */
- np->phy_media = (readw(ioaddr + ASICCtrl) & PhyMedia) ? 1 : 0;
+ np->phy_media = (dr16(ASICCtrl) & PhyMedia) ? 1 : 0;
np->link_status = 0;
/* Set media and reset PHY */
if (np->phy_media) {
@@ -276,22 +291,20 @@
printk(KERN_INFO "vlan(id):\t%d\n", np->vlan);
return 0;
- err_out_unmap_rx:
+err_out_unmap_rx:
pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
- err_out_unmap_tx:
+err_out_unmap_tx:
pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
- err_out_iounmap:
+err_out_iounmap:
#ifdef MEM_MAPPING
- iounmap ((void *) ioaddr);
-
- err_out_dev:
+ pci_iounmap(pdev, np->ioaddr);
#endif
+ pci_iounmap(pdev, np->eeprom_addr);
+err_out_dev:
free_netdev (dev);
-
- err_out_res:
+err_out_res:
pci_release_regions (pdev);
-
- err_out_disable:
+err_out_disable:
pci_disable_device (pdev);
return err;
}
@@ -299,11 +312,9 @@
static int
find_miiphy (struct net_device *dev)
{
+ struct netdev_private *np = netdev_priv(dev);
int i, phy_found = 0;
- struct netdev_private *np;
- long ioaddr;
np = netdev_priv(dev);
- ioaddr = dev->base_addr;
np->phy_addr = 1;
for (i = 31; i >= 0; i--) {
@@ -323,26 +334,19 @@
static int
parse_eeprom (struct net_device *dev)
{
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
int i, j;
- long ioaddr = dev->base_addr;
u8 sromdata[256];
u8 *psib;
u32 crc;
PSROM_t psrom = (PSROM_t) sromdata;
- struct netdev_private *np = netdev_priv(dev);
int cid, next;
-#ifdef MEM_MAPPING
- ioaddr = pci_resource_start (np->pdev, 0);
-#endif
- /* Read eeprom */
- for (i = 0; i < 128; i++) {
- ((__le16 *) sromdata)[i] = cpu_to_le16(read_eeprom (ioaddr, i));
- }
-#ifdef MEM_MAPPING
- ioaddr = dev->base_addr;
-#endif
+ for (i = 0; i < 128; i++)
+ ((__le16 *) sromdata)[i] = cpu_to_le16(read_eeprom(np, i));
+
if (np->pdev->vendor == PCI_VENDOR_ID_DLINK) { /* D-Link Only */
/* Check CRC */
crc = ~ether_crc_le (256 - 4, sromdata);
@@ -378,8 +382,7 @@
return 0;
case 2: /* Duplex Polarity */
np->duplex_polarity = psib[i];
- writeb (readb (ioaddr + PhyCtrl) | psib[i],
- ioaddr + PhyCtrl);
+ dw8(PhyCtrl, dr8(PhyCtrl) | psib[i]);
break;
case 3: /* Wake Polarity */
np->wake_polarity = psib[i];
@@ -407,59 +410,57 @@
rio_open (struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = np->ioaddr;
+ const int irq = np->pdev->irq;
int i;
u16 macctrl;
- i = request_irq (dev->irq, rio_interrupt, IRQF_SHARED, dev->name, dev);
+ i = request_irq(irq, rio_interrupt, IRQF_SHARED, dev->name, dev);
if (i)
return i;
/* Reset all logic functions */
- writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
- ioaddr + ASICCtrl + 2);
+ dw16(ASICCtrl + 2,
+ GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset);
mdelay(10);
/* DebugCtrl bit 4, 5, 9 must set */
- writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);
+ dw32(DebugCtrl, dr32(DebugCtrl) | 0x0230);
/* Jumbo frame */
if (np->jumbo != 0)
- writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);
+ dw16(MaxFrameSize, MAX_JUMBO+14);
alloc_list (dev);
/* Get station address */
for (i = 0; i < 6; i++)
- writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
+ dw8(StationAddr0 + i, dev->dev_addr[i]);
set_multicast (dev);
if (np->coalesce) {
- writel (np->rx_coalesce | np->rx_timeout << 16,
- ioaddr + RxDMAIntCtrl);
+ dw32(RxDMAIntCtrl, np->rx_coalesce | np->rx_timeout << 16);
}
/* Set RIO to poll every N*320nsec. */
- writeb (0x20, ioaddr + RxDMAPollPeriod);
- writeb (0xff, ioaddr + TxDMAPollPeriod);
- writeb (0x30, ioaddr + RxDMABurstThresh);
- writeb (0x30, ioaddr + RxDMAUrgentThresh);
- writel (0x0007ffff, ioaddr + RmonStatMask);
+ dw8(RxDMAPollPeriod, 0x20);
+ dw8(TxDMAPollPeriod, 0xff);
+ dw8(RxDMABurstThresh, 0x30);
+ dw8(RxDMAUrgentThresh, 0x30);
+ dw32(RmonStatMask, 0x0007ffff);
/* clear statistics */
clear_stats (dev);
/* VLAN supported */
if (np->vlan) {
/* priority field in RxDMAIntCtrl */
- writel (readl(ioaddr + RxDMAIntCtrl) | 0x7 << 10,
- ioaddr + RxDMAIntCtrl);
+ dw32(RxDMAIntCtrl, dr32(RxDMAIntCtrl) | 0x7 << 10);
/* VLANId */
- writew (np->vlan, ioaddr + VLANId);
+ dw16(VLANId, np->vlan);
/* Length/Type should be 0x8100 */
- writel (0x8100 << 16 | np->vlan, ioaddr + VLANTag);
+ dw32(VLANTag, 0x8100 << 16 | np->vlan);
/* Enable AutoVLANuntagging, but disable AutoVLANtagging.
VLAN information tagged by TFC' VID, CFI fields. */
- writel (readl (ioaddr + MACCtrl) | AutoVLANuntagging,
- ioaddr + MACCtrl);
+ dw32(MACCtrl, dr32(MACCtrl) | AutoVLANuntagging);
}
init_timer (&np->timer);
@@ -469,20 +470,18 @@
add_timer (&np->timer);
/* Start Tx/Rx */
- writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable,
- ioaddr + MACCtrl);
+ dw32(MACCtrl, dr32(MACCtrl) | StatsEnable | RxEnable | TxEnable);
macctrl = 0;
macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
macctrl |= (np->full_duplex) ? DuplexSelect : 0;
macctrl |= (np->tx_flow) ? TxFlowControlEnable : 0;
macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
- writew(macctrl, ioaddr + MACCtrl);
+ dw16(MACCtrl, macctrl);
netif_start_queue (dev);
- /* Enable default interrupts */
- EnableInt ();
+ dl2k_enable_int(np);
return 0;
}
@@ -533,10 +532,11 @@
static void
rio_tx_timeout (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
- dev->name, readl (ioaddr + TxStatus));
+ dev->name, dr32(TxStatus));
rio_free_tx(dev, 0);
dev->if_port = 0;
dev->trans_start = jiffies; /* prevent tx timeout */
@@ -547,6 +547,7 @@
alloc_list (struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
int i;
np->cur_rx = np->cur_tx = 0;
@@ -594,24 +595,23 @@
}
/* Set RFDListPtr */
- writel (np->rx_ring_dma, dev->base_addr + RFDListPtr0);
- writel (0, dev->base_addr + RFDListPtr1);
+ dw32(RFDListPtr0, np->rx_ring_dma);
+ dw32(RFDListPtr1, 0);
}
static netdev_tx_t
start_xmit (struct sk_buff *skb, struct net_device *dev)
{
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
struct netdev_desc *txdesc;
unsigned entry;
- u32 ioaddr;
u64 tfc_vlan_tag = 0;
if (np->link_status == 0) { /* Link Down */
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
- ioaddr = dev->base_addr;
entry = np->cur_tx % TX_RING_SIZE;
np->tx_skbuff[entry] = skb;
txdesc = &np->tx_ring[entry];
@@ -646,9 +646,9 @@
(1 << FragCountShift));
/* TxDMAPollNow */
- writel (readl (ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
+ dw32(DMACtrl, dr32(DMACtrl) | 0x00001000);
/* Schedule ISR */
- writel(10000, ioaddr + CountDown);
+ dw32(CountDown, 10000);
np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
< TX_QUEUE_LEN - 1 && np->speed != 10) {
@@ -658,10 +658,10 @@
}
/* The first TFDListPtr */
- if (readl (dev->base_addr + TFDListPtr0) == 0) {
- writel (np->tx_ring_dma + entry * sizeof (struct netdev_desc),
- dev->base_addr + TFDListPtr0);
- writel (0, dev->base_addr + TFDListPtr1);
+ if (!dr32(TFDListPtr0)) {
+ dw32(TFDListPtr0, np->tx_ring_dma +
+ entry * sizeof (struct netdev_desc));
+ dw32(TFDListPtr1, 0);
}
return NETDEV_TX_OK;
@@ -671,17 +671,15 @@
rio_interrupt (int irq, void *dev_instance)
{
struct net_device *dev = dev_instance;
- struct netdev_private *np;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
unsigned int_status;
- long ioaddr;
int cnt = max_intrloop;
int handled = 0;
- ioaddr = dev->base_addr;
- np = netdev_priv(dev);
while (1) {
- int_status = readw (ioaddr + IntStatus);
- writew (int_status, ioaddr + IntStatus);
+ int_status = dr16(IntStatus);
+ dw16(IntStatus, int_status);
int_status &= DEFAULT_INTR;
if (int_status == 0 || --cnt < 0)
break;
@@ -692,7 +690,7 @@
/* TxDMAComplete interrupt */
if ((int_status & (TxDMAComplete|IntRequested))) {
int tx_status;
- tx_status = readl (ioaddr + TxStatus);
+ tx_status = dr32(TxStatus);
if (tx_status & 0x01)
tx_error (dev, tx_status);
/* Free used tx skbuffs */
@@ -705,7 +703,7 @@
rio_error (dev, int_status);
}
if (np->cur_tx != np->old_tx)
- writel (100, ioaddr + CountDown);
+ dw32(CountDown, 100);
return IRQ_RETVAL(handled);
}
@@ -765,13 +763,11 @@
static void
tx_error (struct net_device *dev, int tx_status)
{
- struct netdev_private *np;
- long ioaddr = dev->base_addr;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
int frame_id;
int i;
- np = netdev_priv(dev);
-
frame_id = (tx_status & 0xffff0000);
printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n",
dev->name, tx_status, frame_id);
@@ -779,23 +775,21 @@
/* Ttransmit Underrun */
if (tx_status & 0x10) {
np->stats.tx_fifo_errors++;
- writew (readw (ioaddr + TxStartThresh) + 0x10,
- ioaddr + TxStartThresh);
+ dw16(TxStartThresh, dr16(TxStartThresh) + 0x10);
/* Transmit Underrun need to set TxReset, DMARest, FIFOReset */
- writew (TxReset | DMAReset | FIFOReset | NetworkReset,
- ioaddr + ASICCtrl + 2);
+ dw16(ASICCtrl + 2,
+ TxReset | DMAReset | FIFOReset | NetworkReset);
/* Wait for ResetBusy bit clear */
for (i = 50; i > 0; i--) {
- if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
+ if (!(dr16(ASICCtrl + 2) & ResetBusy))
break;
mdelay (1);
}
rio_free_tx (dev, 1);
/* Reset TFDListPtr */
- writel (np->tx_ring_dma +
- np->old_tx * sizeof (struct netdev_desc),
- dev->base_addr + TFDListPtr0);
- writel (0, dev->base_addr + TFDListPtr1);
+ dw32(TFDListPtr0, np->tx_ring_dma +
+ np->old_tx * sizeof (struct netdev_desc));
+ dw32(TFDListPtr1, 0);
/* Let TxStartThresh stay default value */
}
@@ -803,10 +797,10 @@
if (tx_status & 0x04) {
np->stats.tx_fifo_errors++;
/* TxReset and clear FIFO */
- writew (TxReset | FIFOReset, ioaddr + ASICCtrl + 2);
+ dw16(ASICCtrl + 2, TxReset | FIFOReset);
/* Wait reset done */
for (i = 50; i > 0; i--) {
- if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
+ if (!(dr16(ASICCtrl + 2) & ResetBusy))
break;
mdelay (1);
}
@@ -821,7 +815,7 @@
np->stats.collisions++;
#endif
/* Restart the Tx */
- writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl);
+ dw32(MACCtrl, dr16(MACCtrl) | TxEnable);
}
static int
@@ -931,8 +925,8 @@
static void
rio_error (struct net_device *dev, int int_status)
{
- long ioaddr = dev->base_addr;
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
u16 macctrl;
/* Link change event */
@@ -954,7 +948,7 @@
TxFlowControlEnable : 0;
macctrl |= (np->rx_flow) ?
RxFlowControlEnable : 0;
- writew(macctrl, ioaddr + MACCtrl);
+ dw16(MACCtrl, macctrl);
np->link_status = 1;
netif_carrier_on(dev);
} else {
@@ -974,7 +968,7 @@
if (int_status & HostError) {
printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
dev->name, int_status);
- writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
+ dw16(ASICCtrl + 2, GlobalReset | HostReset);
mdelay (500);
}
}
@@ -982,8 +976,8 @@
static struct net_device_stats *
get_stats (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
#ifdef MEM_MAPPING
int i;
#endif
@@ -992,106 +986,107 @@
/* All statistics registers need to be acknowledged,
else statistic overflow could cause problems */
- np->stats.rx_packets += readl (ioaddr + FramesRcvOk);
- np->stats.tx_packets += readl (ioaddr + FramesXmtOk);
- np->stats.rx_bytes += readl (ioaddr + OctetRcvOk);
- np->stats.tx_bytes += readl (ioaddr + OctetXmtOk);
+ np->stats.rx_packets += dr32(FramesRcvOk);
+ np->stats.tx_packets += dr32(FramesXmtOk);
+ np->stats.rx_bytes += dr32(OctetRcvOk);
+ np->stats.tx_bytes += dr32(OctetXmtOk);
- np->stats.multicast = readl (ioaddr + McstFramesRcvdOk);
- np->stats.collisions += readl (ioaddr + SingleColFrames)
- + readl (ioaddr + MultiColFrames);
+ np->stats.multicast = dr32(McstFramesRcvdOk);
+ np->stats.collisions += dr32(SingleColFrames)
+ + dr32(MultiColFrames);
/* detailed tx errors */
- stat_reg = readw (ioaddr + FramesAbortXSColls);
+ stat_reg = dr16(FramesAbortXSColls);
np->stats.tx_aborted_errors += stat_reg;
np->stats.tx_errors += stat_reg;
- stat_reg = readw (ioaddr + CarrierSenseErrors);
+ stat_reg = dr16(CarrierSenseErrors);
np->stats.tx_carrier_errors += stat_reg;
np->stats.tx_errors += stat_reg;
/* Clear all other statistic register. */
- readl (ioaddr + McstOctetXmtOk);
- readw (ioaddr + BcstFramesXmtdOk);
- readl (ioaddr + McstFramesXmtdOk);
- readw (ioaddr + BcstFramesRcvdOk);
- readw (ioaddr + MacControlFramesRcvd);
- readw (ioaddr + FrameTooLongErrors);
- readw (ioaddr + InRangeLengthErrors);
- readw (ioaddr + FramesCheckSeqErrors);
- readw (ioaddr + FramesLostRxErrors);
- readl (ioaddr + McstOctetXmtOk);
- readl (ioaddr + BcstOctetXmtOk);
- readl (ioaddr + McstFramesXmtdOk);
- readl (ioaddr + FramesWDeferredXmt);
- readl (ioaddr + LateCollisions);
- readw (ioaddr + BcstFramesXmtdOk);
- readw (ioaddr + MacControlFramesXmtd);
- readw (ioaddr + FramesWEXDeferal);
+ dr32(McstOctetXmtOk);
+ dr16(BcstFramesXmtdOk);
+ dr32(McstFramesXmtdOk);
+ dr16(BcstFramesRcvdOk);
+ dr16(MacControlFramesRcvd);
+ dr16(FrameTooLongErrors);
+ dr16(InRangeLengthErrors);
+ dr16(FramesCheckSeqErrors);
+ dr16(FramesLostRxErrors);
+ dr32(McstOctetXmtOk);
+ dr32(BcstOctetXmtOk);
+ dr32(McstFramesXmtdOk);
+ dr32(FramesWDeferredXmt);
+ dr32(LateCollisions);
+ dr16(BcstFramesXmtdOk);
+ dr16(MacControlFramesXmtd);
+ dr16(FramesWEXDeferal);
#ifdef MEM_MAPPING
for (i = 0x100; i <= 0x150; i += 4)
- readl (ioaddr + i);
+ dr32(i);
#endif
- readw (ioaddr + TxJumboFrames);
- readw (ioaddr + RxJumboFrames);
- readw (ioaddr + TCPCheckSumErrors);
- readw (ioaddr + UDPCheckSumErrors);
- readw (ioaddr + IPCheckSumErrors);
+ dr16(TxJumboFrames);
+ dr16(RxJumboFrames);
+ dr16(TCPCheckSumErrors);
+ dr16(UDPCheckSumErrors);
+ dr16(IPCheckSumErrors);
return &np->stats;
}
static int
clear_stats (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
#ifdef MEM_MAPPING
int i;
#endif
/* All statistics registers need to be acknowledged,
else statistic overflow could cause problems */
- readl (ioaddr + FramesRcvOk);
- readl (ioaddr + FramesXmtOk);
- readl (ioaddr + OctetRcvOk);
- readl (ioaddr + OctetXmtOk);
+ dr32(FramesRcvOk);
+ dr32(FramesXmtOk);
+ dr32(OctetRcvOk);
+ dr32(OctetXmtOk);
- readl (ioaddr + McstFramesRcvdOk);
- readl (ioaddr + SingleColFrames);
- readl (ioaddr + MultiColFrames);
- readl (ioaddr + LateCollisions);
+ dr32(McstFramesRcvdOk);
+ dr32(SingleColFrames);
+ dr32(MultiColFrames);
+ dr32(LateCollisions);
/* detailed rx errors */
- readw (ioaddr + FrameTooLongErrors);
- readw (ioaddr + InRangeLengthErrors);
- readw (ioaddr + FramesCheckSeqErrors);
- readw (ioaddr + FramesLostRxErrors);
+ dr16(FrameTooLongErrors);
+ dr16(InRangeLengthErrors);
+ dr16(FramesCheckSeqErrors);
+ dr16(FramesLostRxErrors);
/* detailed tx errors */
- readw (ioaddr + FramesAbortXSColls);
- readw (ioaddr + CarrierSenseErrors);
+ dr16(FramesAbortXSColls);
+ dr16(CarrierSenseErrors);
/* Clear all other statistic register. */
- readl (ioaddr + McstOctetXmtOk);
- readw (ioaddr + BcstFramesXmtdOk);
- readl (ioaddr + McstFramesXmtdOk);
- readw (ioaddr + BcstFramesRcvdOk);
- readw (ioaddr + MacControlFramesRcvd);
- readl (ioaddr + McstOctetXmtOk);
- readl (ioaddr + BcstOctetXmtOk);
- readl (ioaddr + McstFramesXmtdOk);
- readl (ioaddr + FramesWDeferredXmt);
- readw (ioaddr + BcstFramesXmtdOk);
- readw (ioaddr + MacControlFramesXmtd);
- readw (ioaddr + FramesWEXDeferal);
+ dr32(McstOctetXmtOk);
+ dr16(BcstFramesXmtdOk);
+ dr32(McstFramesXmtdOk);
+ dr16(BcstFramesRcvdOk);
+ dr16(MacControlFramesRcvd);
+ dr32(McstOctetXmtOk);
+ dr32(BcstOctetXmtOk);
+ dr32(McstFramesXmtdOk);
+ dr32(FramesWDeferredXmt);
+ dr16(BcstFramesXmtdOk);
+ dr16(MacControlFramesXmtd);
+ dr16(FramesWEXDeferal);
#ifdef MEM_MAPPING
for (i = 0x100; i <= 0x150; i += 4)
- readl (ioaddr + i);
+ dr32(i);
#endif
- readw (ioaddr + TxJumboFrames);
- readw (ioaddr + RxJumboFrames);
- readw (ioaddr + TCPCheckSumErrors);
- readw (ioaddr + UDPCheckSumErrors);
- readw (ioaddr + IPCheckSumErrors);
+ dr16(TxJumboFrames);
+ dr16(RxJumboFrames);
+ dr16(TCPCheckSumErrors);
+ dr16(UDPCheckSumErrors);
+ dr16(IPCheckSumErrors);
return 0;
}
@@ -1114,10 +1109,10 @@
static void
set_multicast (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
u32 hash_table[2];
u16 rx_mode = 0;
- struct netdev_private *np = netdev_priv(dev);
hash_table[0] = hash_table[1] = 0;
/* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
@@ -1153,9 +1148,9 @@
rx_mode |= ReceiveVLANMatch;
}
- writel (hash_table[0], ioaddr + HashTable0);
- writel (hash_table[1], ioaddr + HashTable1);
- writew (rx_mode, ioaddr + ReceiveMode);
+ dw32(HashTable0, hash_table[0]);
+ dw32(HashTable1, hash_table[1]);
+ dw16(ReceiveMode, rx_mode);
}
static void rio_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
@@ -1318,15 +1313,15 @@
#define EEP_BUSY 0x8000
/* Read the EEPROM word */
/* We use I/O instruction to read/write eeprom to avoid fail on some machines */
-static int
-read_eeprom (long ioaddr, int eep_addr)
+static int read_eeprom(struct netdev_private *np, int eep_addr)
{
+ void __iomem *ioaddr = np->eeprom_addr;
int i = 1000;
- outw (EEP_READ | (eep_addr & 0xff), ioaddr + EepromCtrl);
+
+ dw16(EepromCtrl, EEP_READ | (eep_addr & 0xff));
while (i-- > 0) {
- if (!(inw (ioaddr + EepromCtrl) & EEP_BUSY)) {
- return inw (ioaddr + EepromData);
- }
+ if (!(dr16(EepromCtrl) & EEP_BUSY))
+ return dr16(EepromData);
}
return 0;
}
@@ -1336,38 +1331,40 @@
MII_DUPLEX = 0x08,
};
-#define mii_delay() readb(ioaddr)
+#define mii_delay() dr8(PhyCtrl)
static void
mii_sendbit (struct net_device *dev, u32 data)
{
- long ioaddr = dev->base_addr + PhyCtrl;
- data = (data) ? MII_DATA1 : 0;
- data |= MII_WRITE;
- data |= (readb (ioaddr) & 0xf8) | MII_WRITE;
- writeb (data, ioaddr);
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
+
+ data = ((data) ? MII_DATA1 : 0) | (dr8(PhyCtrl) & 0xf8) | MII_WRITE;
+ dw8(PhyCtrl, data);
mii_delay ();
- writeb (data | MII_CLK, ioaddr);
+ dw8(PhyCtrl, data | MII_CLK);
mii_delay ();
}
static int
mii_getbit (struct net_device *dev)
{
- long ioaddr = dev->base_addr + PhyCtrl;
+ struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
u8 data;
- data = (readb (ioaddr) & 0xf8) | MII_READ;
- writeb (data, ioaddr);
+ data = (dr8(PhyCtrl) & 0xf8) | MII_READ;
+ dw8(PhyCtrl, data);
mii_delay ();
- writeb (data | MII_CLK, ioaddr);
+ dw8(PhyCtrl, data | MII_CLK);
mii_delay ();
- return ((readb (ioaddr) >> 1) & 1);
+ return (dr8(PhyCtrl) >> 1) & 1;
}
static void
mii_send_bits (struct net_device *dev, u32 data, int len)
{
int i;
+
for (i = len - 1; i >= 0; i--) {
mii_sendbit (dev, data & (1 << i));
}
@@ -1721,28 +1718,29 @@
static int
rio_close (struct net_device *dev)
{
- long ioaddr = dev->base_addr;
struct netdev_private *np = netdev_priv(dev);
+ void __iomem *ioaddr = np->ioaddr;
+
+ struct pci_dev *pdev = np->pdev;
struct sk_buff *skb;
int i;
netif_stop_queue (dev);
/* Disable interrupts */
- writew (0, ioaddr + IntEnable);
+ dw16(IntEnable, 0);
/* Stop Tx and Rx logics */
- writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
+ dw32(MACCtrl, TxDisable | RxDisable | StatsDisable);
- free_irq (dev->irq, dev);
+ free_irq(pdev->irq, dev);
del_timer_sync (&np->timer);
/* Free all the skbuffs in the queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
skb = np->rx_skbuff[i];
if (skb) {
- pci_unmap_single(np->pdev,
- desc_to_dma(&np->rx_ring[i]),
+ pci_unmap_single(pdev, desc_to_dma(&np->rx_ring[i]),
skb->len, PCI_DMA_FROMDEVICE);
dev_kfree_skb (skb);
np->rx_skbuff[i] = NULL;
@@ -1753,8 +1751,7 @@
for (i = 0; i < TX_RING_SIZE; i++) {
skb = np->tx_skbuff[i];
if (skb) {
- pci_unmap_single(np->pdev,
- desc_to_dma(&np->tx_ring[i]),
+ pci_unmap_single(pdev, desc_to_dma(&np->tx_ring[i]),
skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb (skb);
np->tx_skbuff[i] = NULL;
@@ -1778,8 +1775,9 @@
pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring,
np->tx_ring_dma);
#ifdef MEM_MAPPING
- iounmap ((char *) (dev->base_addr));
+ pci_iounmap(pdev, np->ioaddr);
#endif
+ pci_iounmap(pdev, np->eeprom_addr);
free_netdev (dev);
pci_release_regions (pdev);
pci_disable_device (pdev);
diff --git a/drivers/net/ethernet/dlink/dl2k.h b/drivers/net/ethernet/dlink/dl2k.h
index ba0adca..40ba6e0 100644
--- a/drivers/net/ethernet/dlink/dl2k.h
+++ b/drivers/net/ethernet/dlink/dl2k.h
@@ -42,23 +42,6 @@
#define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct netdev_desc)
#define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct netdev_desc)
-/* This driver was written to use PCI memory space, however x86-oriented
- hardware often uses I/O space accesses. */
-#ifndef MEM_MAPPING
-#undef readb
-#undef readw
-#undef readl
-#undef writeb
-#undef writew
-#undef writel
-#define readb inb
-#define readw inw
-#define readl inl
-#define writeb outb
-#define writew outw
-#define writel outl
-#endif
-
/* Offsets to the device registers.
Unlike software-only systems, device drivers interact with complex hardware.
It's not useful to define symbolic names for every register bit in the
@@ -391,6 +374,8 @@
dma_addr_t tx_ring_dma;
dma_addr_t rx_ring_dma;
struct pci_dev *pdev;
+ void __iomem *ioaddr;
+ void __iomem *eeprom_addr;
spinlock_t tx_lock;
spinlock_t rx_lock;
struct net_device_stats stats;
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
index d783f4f..d7bb52a 100644
--- a/drivers/net/ethernet/dlink/sundance.c
+++ b/drivers/net/ethernet/dlink/sundance.c
@@ -522,9 +522,6 @@
cpu_to_le16(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
-
np = netdev_priv(dev);
np->base = ioaddr;
np->pci_dev = pdev;
@@ -828,18 +825,19 @@
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->base;
+ const int irq = np->pci_dev->irq;
unsigned long flags;
int i;
/* Do we need to reset the chip??? */
- i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
+ i = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
if (i)
return i;
if (netif_msg_ifup(np))
- printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
- dev->name, dev->irq);
+ printk(KERN_DEBUG "%s: netdev_open() irq %d\n", dev->name, irq);
+
init_ring(dev);
iowrite32(np->rx_ring_dma, ioaddr + RxListPtr);
@@ -1814,7 +1812,7 @@
}
#endif /* __i386__ debugging only */
- free_irq(dev->irq, dev);
+ free_irq(np->pci_dev->irq, dev);
del_timer_sync(&np->timer);
diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c
index b276469..290b26f 100644
--- a/drivers/net/ethernet/dnet.c
+++ b/drivers/net/ethernet/dnet.c
@@ -815,6 +815,7 @@
.set_settings = dnet_set_settings,
.get_drvinfo = dnet_get_drvinfo,
.get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static const struct net_device_ops dnet_netdev_ops = {
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c
index 1637b98..9d71c9c 100644
--- a/drivers/net/ethernet/fealnx.c
+++ b/drivers/net/ethernet/fealnx.c
@@ -545,9 +545,6 @@
/* Reset the chip to erase previous misconfiguration. */
iowrite32(0x00000001, ioaddr + BCR);
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
-
/* Make certain the descriptor lists are aligned. */
np = netdev_priv(dev);
np->mem = ioaddr;
@@ -832,11 +829,13 @@
{
struct netdev_private *np = netdev_priv(dev);
void __iomem *ioaddr = np->mem;
- int i;
+ const int irq = np->pci_dev->irq;
+ int rc, i;
iowrite32(0x00000001, ioaddr + BCR); /* Reset */
- if (request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev))
+ rc = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
+ if (rc)
return -EAGAIN;
for (i = 0; i < 3; i++)
@@ -924,8 +923,7 @@
np->reset_timer.data = (unsigned long) dev;
np->reset_timer.function = reset_timer;
np->reset_timer_armed = 0;
-
- return 0;
+ return rc;
}
@@ -1910,7 +1908,7 @@
del_timer_sync(&np->timer);
del_timer_sync(&np->reset_timer);
- free_irq(dev->irq, dev);
+ free_irq(np->pci_dev->irq, dev);
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index a12b3f5..7fa0227 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -1161,6 +1161,7 @@
.set_settings = fec_enet_set_settings,
.get_drvinfo = fec_enet_get_drvinfo,
.get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.c b/drivers/net/ethernet/freescale/fec_mpc52xx.c
index 7b34d8c..97f947b 100644
--- a/drivers/net/ethernet/freescale/fec_mpc52xx.c
+++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c
@@ -811,6 +811,7 @@
.get_link = ethtool_op_get_link,
.get_msglevel = mpc52xx_fec_get_msglevel,
.set_msglevel = mpc52xx_fec_set_msglevel,
+ .get_ts_info = ethtool_op_get_ts_info,
};
diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index e4e6cd2..2b7633f 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -963,6 +963,7 @@
.get_msglevel = fs_get_msglevel,
.set_msglevel = fs_set_msglevel,
.get_regs = fs_get_regs,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index 4c9f8d4..2136c7f 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -1210,4 +1210,7 @@
struct gfar_filer_entry fe[MAX_FILER_CACHE_IDX + 20];
};
+/* The gianfar_ptp module will set this variable */
+extern int gfar_phc_index;
+
#endif /* __GIANFAR_H */
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 8d74efd..8a02557 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/net_tstamp.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
@@ -1739,6 +1740,34 @@
return ret;
}
+int gfar_phc_index = -1;
+
+static int gfar_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+
+ if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)) {
+ info->so_timestamping =
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE;
+ info->phc_index = -1;
+ return 0;
+ }
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->phc_index = gfar_phc_index;
+ info->tx_types =
+ (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON);
+ info->rx_filters =
+ (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_ALL);
+ return 0;
+}
+
const struct ethtool_ops gfar_ethtool_ops = {
.get_settings = gfar_gsettings,
.set_settings = gfar_ssettings,
@@ -1761,4 +1790,5 @@
#endif
.set_rxnfc = gfar_set_nfc,
.get_rxnfc = gfar_get_nfc,
+ .get_ts_info = gfar_get_ts_info,
};
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c
index 5fd620b..c08e5d4 100644
--- a/drivers/net/ethernet/freescale/gianfar_ptp.c
+++ b/drivers/net/ethernet/freescale/gianfar_ptp.c
@@ -515,6 +515,7 @@
err = PTR_ERR(etsects->clock);
goto no_clock;
}
+ gfar_phc_clock = ptp_clock_index(etsects->clock);
dev_set_drvdata(&dev->dev, etsects);
@@ -538,6 +539,7 @@
gfar_write(&etsects->regs->tmr_temask, 0);
gfar_write(&etsects->regs->tmr_ctrl, 0);
+ gfar_phc_clock = -1;
ptp_clock_unregister(etsects->clock);
iounmap(etsects->regs);
release_resource(etsects->rsrc);
diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
index a97257f..37b0353 100644
--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
+++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
@@ -415,6 +415,7 @@
.get_ethtool_stats = uec_get_ethtool_stats,
.get_wol = uec_get_wol,
.set_wol = uec_set_wol,
+ .get_ts_info = ethtool_op_get_ts_info,
};
void uec_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
index 7621316..74215c0 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -7,7 +7,7 @@
default y
depends on PCI || PCI_MSI || ISA || ISA_DMA_API || ARM || \
ARCH_ACORN || MCA || MCA_LEGACY || SNI_RM || SUN3 || \
- GSC || BVME6000 || MVME16x || ARCH_ENP2611 || \
+ GSC || BVME6000 || MVME16x || \
(ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR) || \
EXPERIMENTAL
---help---
@@ -120,6 +120,17 @@
driver. DCA is a method for warming the CPU cache before data
is used, with the intent of lessening the impact of cache misses.
+config IGB_PTP
+ bool "PTP Hardware Clock (PHC)"
+ default y
+ depends on IGB && PTP_1588_CLOCK
+ ---help---
+ Say Y here if you want to use PTP Hardware Clock (PHC) in the
+ driver. Only the basic clock operations have been implemented.
+
+ Every timestamp and clock read operations must consult the
+ overflow counter to form a correct time value.
+
config IGBVF
tristate "Intel(R) 82576 Virtual Function Ethernet support"
depends on PCI
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index 4348b6f..3d712f2 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -827,9 +827,10 @@
if (changed & NETIF_F_HW_VLAN_RX)
e1000_vlan_mode(netdev, features);
- if (!(changed & NETIF_F_RXCSUM))
+ if (!(changed & (NETIF_F_RXCSUM | NETIF_F_RXALL)))
return 0;
+ netdev->features = features;
adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
if (netif_running(netdev))
@@ -1074,6 +1075,7 @@
netdev->features |= netdev->hw_features;
netdev->hw_features |= NETIF_F_RXCSUM;
+ netdev->hw_features |= NETIF_F_RXALL;
netdev->hw_features |= NETIF_F_RXFCS;
if (pci_using_dac) {
@@ -1841,6 +1843,22 @@
break;
}
+ /* This is useful for sniffing bad packets. */
+ if (adapter->netdev->features & NETIF_F_RXALL) {
+ /* UPE and MPE will be handled by normal PROMISC logic
+ * in e1000e_set_rx_mode */
+ rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
+ E1000_RCTL_BAM | /* RX All Bcast Pkts */
+ E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
+
+ rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
+ E1000_RCTL_DPF | /* Allow filtered pause */
+ E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
+ /* Do not mess with E1000_CTRL_VME, it affects transmit as well,
+ * and that breaks VLANs.
+ */
+ }
+
ew32(RCTL, rctl);
}
@@ -4057,6 +4075,8 @@
irq_flags);
length--;
} else {
+ if (netdev->features & NETIF_F_RXALL)
+ goto process_skb;
/* recycle both page and skb */
buffer_info->skb = skb;
/* an error means any chain goes out the window
@@ -4069,6 +4089,7 @@
}
#define rxtop rx_ring->rx_skb_top
+process_skb:
if (!(status & E1000_RXD_STAT_EOP)) {
/* this descriptor is only the beginning (or middle) */
if (!rxtop) {
@@ -4276,12 +4297,15 @@
flags);
length--;
} else {
+ if (netdev->features & NETIF_F_RXALL)
+ goto process_skb;
/* recycle */
buffer_info->skb = skb;
goto next_desc;
}
}
+process_skb:
total_rx_bytes += (length - 4); /* don't count FCS */
total_rx_packets++;
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index db35dd5..6302b10 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -403,15 +403,15 @@
regs_buff[1] = er32(STATUS);
regs_buff[2] = er32(RCTL);
- regs_buff[3] = er32(RDLEN);
- regs_buff[4] = er32(RDH);
- regs_buff[5] = er32(RDT);
+ regs_buff[3] = er32(RDLEN(0));
+ regs_buff[4] = er32(RDH(0));
+ regs_buff[5] = er32(RDT(0));
regs_buff[6] = er32(RDTR);
regs_buff[7] = er32(TCTL);
- regs_buff[8] = er32(TDLEN);
- regs_buff[9] = er32(TDH);
- regs_buff[10] = er32(TDT);
+ regs_buff[8] = er32(TDLEN(0));
+ regs_buff[9] = er32(TDH(0));
+ regs_buff[10] = er32(TDT(0));
regs_buff[11] = er32(TIDV);
regs_buff[12] = adapter->hw.phy.type; /* PHY type (IGP=1, M88=0) */
@@ -813,15 +813,15 @@
}
REG_PATTERN_TEST(E1000_RDTR, 0x0000FFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(E1000_RDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(E1000_RDLEN, 0x000FFF80, 0x000FFFFF);
- REG_PATTERN_TEST(E1000_RDH, 0x0000FFFF, 0x0000FFFF);
- REG_PATTERN_TEST(E1000_RDT, 0x0000FFFF, 0x0000FFFF);
+ REG_PATTERN_TEST(E1000_RDBAH(0), 0xFFFFFFFF, 0xFFFFFFFF);
+ REG_PATTERN_TEST(E1000_RDLEN(0), 0x000FFF80, 0x000FFFFF);
+ REG_PATTERN_TEST(E1000_RDH(0), 0x0000FFFF, 0x0000FFFF);
+ REG_PATTERN_TEST(E1000_RDT(0), 0x0000FFFF, 0x0000FFFF);
REG_PATTERN_TEST(E1000_FCRTH, 0x0000FFF8, 0x0000FFF8);
REG_PATTERN_TEST(E1000_FCTTV, 0x0000FFFF, 0x0000FFFF);
REG_PATTERN_TEST(E1000_TIPG, 0x3FFFFFFF, 0x3FFFFFFF);
- REG_PATTERN_TEST(E1000_TDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(E1000_TDLEN, 0x000FFF80, 0x000FFFFF);
+ REG_PATTERN_TEST(E1000_TDBAH(0), 0xFFFFFFFF, 0xFFFFFFFF);
+ REG_PATTERN_TEST(E1000_TDLEN(0), 0x000FFF80, 0x000FFFFF);
REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000);
@@ -830,10 +830,10 @@
REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000);
REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF);
- REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
+ REG_PATTERN_TEST(E1000_RDBAL(0), 0xFFFFFFF0, 0xFFFFFFFF);
if (!(adapter->flags & FLAG_IS_ICH))
REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF);
- REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
+ REG_PATTERN_TEST(E1000_TDBAL(0), 0xFFFFFFF0, 0xFFFFFFFF);
REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
mask = 0x8003FFFF;
switch (mac->type) {
@@ -1104,11 +1104,11 @@
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- ew32(TDBAL, ((u64) tx_ring->dma & 0x00000000FFFFFFFF));
- ew32(TDBAH, ((u64) tx_ring->dma >> 32));
- ew32(TDLEN, tx_ring->count * sizeof(struct e1000_tx_desc));
- ew32(TDH, 0);
- ew32(TDT, 0);
+ ew32(TDBAL(0), ((u64) tx_ring->dma & 0x00000000FFFFFFFF));
+ ew32(TDBAH(0), ((u64) tx_ring->dma >> 32));
+ ew32(TDLEN(0), tx_ring->count * sizeof(struct e1000_tx_desc));
+ ew32(TDH(0), 0);
+ ew32(TDT(0), 0);
ew32(TCTL, E1000_TCTL_PSP | E1000_TCTL_EN | E1000_TCTL_MULR |
E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT);
@@ -1168,11 +1168,11 @@
rctl = er32(RCTL);
if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
ew32(RCTL, rctl & ~E1000_RCTL_EN);
- ew32(RDBAL, ((u64) rx_ring->dma & 0xFFFFFFFF));
- ew32(RDBAH, ((u64) rx_ring->dma >> 32));
- ew32(RDLEN, rx_ring->size);
- ew32(RDH, 0);
- ew32(RDT, 0);
+ ew32(RDBAL(0), ((u64) rx_ring->dma & 0xFFFFFFFF));
+ ew32(RDBAH(0), ((u64) rx_ring->dma >> 32));
+ ew32(RDLEN(0), rx_ring->size);
+ ew32(RDH(0), 0);
+ ew32(RDT(0), 0);
rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |
E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_LPE |
E1000_RCTL_SBP | E1000_RCTL_SECRC |
@@ -1534,7 +1534,7 @@
int ret_val = 0;
unsigned long time;
- ew32(RDT, rx_ring->count - 1);
+ ew32(RDT(0), rx_ring->count - 1);
/*
* Calculate the loop count based on the largest descriptor ring
@@ -1561,7 +1561,7 @@
if (k == tx_ring->count)
k = 0;
}
- ew32(TDT, k);
+ ew32(TDT(0), k);
e1e_flush();
msleep(200);
time = jiffies; /* set the start time for the receive */
diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h
index f82ecf5..923d3fd 100644
--- a/drivers/net/ethernet/intel/e1000e/hw.h
+++ b/drivers/net/ethernet/intel/e1000e/hw.h
@@ -94,31 +94,40 @@
E1000_FCRTL = 0x02160, /* Flow Control Receive Threshold Low - RW */
E1000_FCRTH = 0x02168, /* Flow Control Receive Threshold High - RW */
E1000_PSRCTL = 0x02170, /* Packet Split Receive Control - RW */
- E1000_RDBAL = 0x02800, /* Rx Descriptor Base Address Low - RW */
- E1000_RDBAH = 0x02804, /* Rx Descriptor Base Address High - RW */
- E1000_RDLEN = 0x02808, /* Rx Descriptor Length - RW */
- E1000_RDH = 0x02810, /* Rx Descriptor Head - RW */
- E1000_RDT = 0x02818, /* Rx Descriptor Tail - RW */
+/*
+ * Convenience macros
+ *
+ * Note: "_n" is the queue number of the register to be written to.
+ *
+ * Example usage:
+ * E1000_RDBAL(current_rx_queue)
+ */
+ E1000_RDBAL_BASE = 0x02800, /* Rx Descriptor Base Address Low - RW */
+#define E1000_RDBAL(_n) (E1000_RDBAL_BASE + (_n << 8))
+ E1000_RDBAH_BASE = 0x02804, /* Rx Descriptor Base Address High - RW */
+#define E1000_RDBAH(_n) (E1000_RDBAH_BASE + (_n << 8))
+ E1000_RDLEN_BASE = 0x02808, /* Rx Descriptor Length - RW */
+#define E1000_RDLEN(_n) (E1000_RDLEN_BASE + (_n << 8))
+ E1000_RDH_BASE = 0x02810, /* Rx Descriptor Head - RW */
+#define E1000_RDH(_n) (E1000_RDH_BASE + (_n << 8))
+ E1000_RDT_BASE = 0x02818, /* Rx Descriptor Tail - RW */
+#define E1000_RDT(_n) (E1000_RDT_BASE + (_n << 8))
E1000_RDTR = 0x02820, /* Rx Delay Timer - RW */
E1000_RXDCTL_BASE = 0x02828, /* Rx Descriptor Control - RW */
#define E1000_RXDCTL(_n) (E1000_RXDCTL_BASE + (_n << 8))
E1000_RADV = 0x0282C, /* Rx Interrupt Absolute Delay Timer - RW */
-/* Convenience macros
- *
- * Note: "_n" is the queue number of the register to be written to.
- *
- * Example usage:
- * E1000_RDBAL_REG(current_rx_queue)
- *
- */
-#define E1000_RDBAL_REG(_n) (E1000_RDBAL + (_n << 8))
E1000_KABGTXD = 0x03004, /* AFE Band Gap Transmit Ref Data */
- E1000_TDBAL = 0x03800, /* Tx Descriptor Base Address Low - RW */
- E1000_TDBAH = 0x03804, /* Tx Descriptor Base Address High - RW */
- E1000_TDLEN = 0x03808, /* Tx Descriptor Length - RW */
- E1000_TDH = 0x03810, /* Tx Descriptor Head - RW */
- E1000_TDT = 0x03818, /* Tx Descriptor Tail - RW */
+ E1000_TDBAL_BASE = 0x03800, /* Tx Descriptor Base Address Low - RW */
+#define E1000_TDBAL(_n) (E1000_TDBAL_BASE + (_n << 8))
+ E1000_TDBAH_BASE = 0x03804, /* Tx Descriptor Base Address High - RW */
+#define E1000_TDBAH(_n) (E1000_TDBAH_BASE + (_n << 8))
+ E1000_TDLEN_BASE = 0x03808, /* Tx Descriptor Length - RW */
+#define E1000_TDLEN(_n) (E1000_TDLEN_BASE + (_n << 8))
+ E1000_TDH_BASE = 0x03810, /* Tx Descriptor Head - RW */
+#define E1000_TDH(_n) (E1000_TDH_BASE + (_n << 8))
+ E1000_TDT_BASE = 0x03818, /* Tx Descriptor Tail - RW */
+#define E1000_TDT(_n) (E1000_TDT_BASE + (_n << 8))
E1000_TIDV = 0x03820, /* Tx Interrupt Delay Value - RW */
E1000_TXDCTL_BASE = 0x03828, /* Tx Descriptor Control - RW */
#define E1000_TXDCTL(_n) (E1000_TXDCTL_BASE + (_n << 8))
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 19ab215..851f793 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -56,7 +56,7 @@
#define DRV_EXTRAVERSION "-k"
-#define DRV_VERSION "1.9.5" DRV_EXTRAVERSION
+#define DRV_VERSION "1.10.6" DRV_EXTRAVERSION
char e1000e_driver_name[] = "e1000e";
const char e1000e_driver_version[] = DRV_VERSION;
@@ -110,14 +110,14 @@
/* Rx Registers */
{E1000_RCTL, "RCTL"},
- {E1000_RDLEN, "RDLEN"},
- {E1000_RDH, "RDH"},
- {E1000_RDT, "RDT"},
+ {E1000_RDLEN(0), "RDLEN"},
+ {E1000_RDH(0), "RDH"},
+ {E1000_RDT(0), "RDT"},
{E1000_RDTR, "RDTR"},
{E1000_RXDCTL(0), "RXDCTL"},
{E1000_ERT, "ERT"},
- {E1000_RDBAL, "RDBAL"},
- {E1000_RDBAH, "RDBAH"},
+ {E1000_RDBAL(0), "RDBAL"},
+ {E1000_RDBAH(0), "RDBAH"},
{E1000_RDFH, "RDFH"},
{E1000_RDFT, "RDFT"},
{E1000_RDFHS, "RDFHS"},
@@ -126,11 +126,11 @@
/* Tx Registers */
{E1000_TCTL, "TCTL"},
- {E1000_TDBAL, "TDBAL"},
- {E1000_TDBAH, "TDBAH"},
- {E1000_TDLEN, "TDLEN"},
- {E1000_TDH, "TDH"},
- {E1000_TDT, "TDT"},
+ {E1000_TDBAL(0), "TDBAL"},
+ {E1000_TDBAH(0), "TDBAH"},
+ {E1000_TDLEN(0), "TDLEN"},
+ {E1000_TDH(0), "TDH"},
+ {E1000_TDT(0), "TDT"},
{E1000_TIDV, "TIDV"},
{E1000_TXDCTL(0), "TXDCTL"},
{E1000_TADV, "TADV"},
@@ -1053,7 +1053,8 @@
if (!adapter->tx_hang_recheck &&
(adapter->flags2 & FLAG2_DMA_BURST)) {
- /* May be block on write-back, flush and detect again
+ /*
+ * May be block on write-back, flush and detect again
* flush pending descriptor writebacks to memory
*/
ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
@@ -2530,33 +2531,31 @@
}
/**
- * e1000_clean - NAPI Rx polling callback
+ * e1000e_poll - NAPI Rx polling callback
* @napi: struct associated with this polling callback
- * @budget: amount of packets driver is allowed to process this poll
+ * @weight: number of packets driver is allowed to process this poll
**/
-static int e1000_clean(struct napi_struct *napi, int budget)
+static int e1000e_poll(struct napi_struct *napi, int weight)
{
- struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
+ struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter,
+ napi);
struct e1000_hw *hw = &adapter->hw;
struct net_device *poll_dev = adapter->netdev;
int tx_cleaned = 1, work_done = 0;
adapter = netdev_priv(poll_dev);
- if (adapter->msix_entries &&
- !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
- goto clean_rx;
+ if (!adapter->msix_entries ||
+ (adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
+ tx_cleaned = e1000_clean_tx_irq(adapter->tx_ring);
- tx_cleaned = e1000_clean_tx_irq(adapter->tx_ring);
-
-clean_rx:
- adapter->clean_rx(adapter->rx_ring, &work_done, budget);
+ adapter->clean_rx(adapter->rx_ring, &work_done, weight);
if (!tx_cleaned)
- work_done = budget;
+ work_done = weight;
- /* If budget not fully consumed, exit the polling mode */
- if (work_done < budget) {
+ /* If weight not fully consumed, exit the polling mode */
+ if (work_done < weight) {
if (adapter->itr_setting & 3)
e1000_set_itr(adapter);
napi_complete(napi);
@@ -2800,13 +2799,13 @@
/* Setup the HW Tx Head and Tail descriptor pointers */
tdba = tx_ring->dma;
tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
- ew32(TDBAL, (tdba & DMA_BIT_MASK(32)));
- ew32(TDBAH, (tdba >> 32));
- ew32(TDLEN, tdlen);
- ew32(TDH, 0);
- ew32(TDT, 0);
- tx_ring->head = adapter->hw.hw_addr + E1000_TDH;
- tx_ring->tail = adapter->hw.hw_addr + E1000_TDT;
+ ew32(TDBAL(0), (tdba & DMA_BIT_MASK(32)));
+ ew32(TDBAH(0), (tdba >> 32));
+ ew32(TDLEN(0), tdlen);
+ ew32(TDH(0), 0);
+ ew32(TDT(0), 0);
+ tx_ring->head = adapter->hw.hw_addr + E1000_TDH(0);
+ tx_ring->tail = adapter->hw.hw_addr + E1000_TDT(0);
/* Set the Tx Interrupt Delay register */
ew32(TIDV, adapter->tx_int_delay);
@@ -3110,13 +3109,13 @@
* the Base and Length of the Rx Descriptor Ring
*/
rdba = rx_ring->dma;
- ew32(RDBAL, (rdba & DMA_BIT_MASK(32)));
- ew32(RDBAH, (rdba >> 32));
- ew32(RDLEN, rdlen);
- ew32(RDH, 0);
- ew32(RDT, 0);
- rx_ring->head = adapter->hw.hw_addr + E1000_RDH;
- rx_ring->tail = adapter->hw.hw_addr + E1000_RDT;
+ ew32(RDBAL(0), (rdba & DMA_BIT_MASK(32)));
+ ew32(RDBAH(0), (rdba >> 32));
+ ew32(RDLEN(0), rdlen);
+ ew32(RDH(0), 0);
+ ew32(RDT(0), 0);
+ rx_ring->head = adapter->hw.hw_addr + E1000_RDH(0);
+ rx_ring->tail = adapter->hw.hw_addr + E1000_RDT(0);
/* Enable Receive Checksum Offload for TCP and UDP */
rxcsum = er32(RXCSUM);
@@ -6226,7 +6225,7 @@
netdev->netdev_ops = &e1000e_netdev_ops;
e1000e_set_ethtool_ops(netdev);
netdev->watchdog_timeo = 5 * HZ;
- netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
+ netif_napi_add(netdev, &adapter->napi, e1000e_poll, 64);
strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
netdev->mem_start = mmio_start;
diff --git a/drivers/net/ethernet/intel/igb/Makefile b/drivers/net/ethernet/intel/igb/Makefile
index 6565c46..4bd16e2 100644
--- a/drivers/net/ethernet/intel/igb/Makefile
+++ b/drivers/net/ethernet/intel/igb/Makefile
@@ -35,3 +35,4 @@
igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \
e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o
+igb-$(CONFIG_IGB_PTP) += igb_ptp.o
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 8e33bdd..3758ad2 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -35,8 +35,8 @@
#include "e1000_82575.h"
#include <linux/clocksource.h>
-#include <linux/timecompare.h>
#include <linux/net_tstamp.h>
+#include <linux/ptp_clock_kernel.h>
#include <linux/bitops.h>
#include <linux/if_vlan.h>
@@ -328,9 +328,6 @@
/* OS defined structs */
struct pci_dev *pdev;
- struct cyclecounter cycles;
- struct timecounter clock;
- struct timecompare compare;
struct hwtstamp_config hwtstamp_config;
spinlock_t stats64_lock;
@@ -364,6 +361,13 @@
u32 wvbr;
int node;
u32 *shadow_vfta;
+
+ struct ptp_clock *ptp_clock;
+ struct ptp_clock_info caps;
+ struct delayed_work overflow_work;
+ spinlock_t tmreg_lock;
+ struct cyclecounter cc;
+ struct timecounter tc;
};
#define IGB_FLAG_HAS_MSI (1 << 0)
@@ -378,7 +382,6 @@
#define IGB_DMCTLX_DCFLUSH_DIS 0x80000000 /* Disable DMA Coal Flush */
#define IGB_82576_TSYNC_SHIFT 19
-#define IGB_82580_TSYNC_SHIFT 24
#define IGB_TS_HDR_LEN 16
enum e1000_state_t {
__IGB_TESTING,
@@ -414,7 +417,15 @@
extern bool igb_has_link(struct igb_adapter *adapter);
extern void igb_set_ethtool_ops(struct net_device *);
extern void igb_power_up_link(struct igb_adapter *);
+#ifdef CONFIG_IGB_PTP
+extern void igb_ptp_init(struct igb_adapter *adapter);
+extern void igb_ptp_remove(struct igb_adapter *adapter);
+extern void igb_systim_to_hwtstamp(struct igb_adapter *adapter,
+ struct skb_shared_hwtstamps *hwtstamps,
+ u64 systim);
+
+#endif
static inline s32 igb_reset_phy(struct e1000_hw *hw)
{
if (hw->phy.ops.reset)
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 5ec3159..f022ff7 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -114,7 +114,6 @@
static void igb_setup_mrqc(struct igb_adapter *);
static int igb_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit igb_remove(struct pci_dev *pdev);
-static void igb_init_hw_timer(struct igb_adapter *adapter);
static int igb_sw_init(struct igb_adapter *);
static int igb_open(struct net_device *);
static int igb_close(struct net_device *);
@@ -565,33 +564,6 @@
return;
}
-
-/**
- * igb_read_clock - read raw cycle counter (to be used by time counter)
- */
-static cycle_t igb_read_clock(const struct cyclecounter *tc)
-{
- struct igb_adapter *adapter =
- container_of(tc, struct igb_adapter, cycles);
- struct e1000_hw *hw = &adapter->hw;
- u64 stamp = 0;
- int shift = 0;
-
- /*
- * The timestamp latches on lowest register read. For the 82580
- * the lowest register is SYSTIMR instead of SYSTIML. However we never
- * adjusted TIMINCA so SYSTIMR will just read as all 0s so ignore it.
- */
- if (hw->mac.type >= e1000_82580) {
- stamp = rd32(E1000_SYSTIMR) >> 8;
- shift = IGB_82580_TSYNC_SHIFT;
- }
-
- stamp |= (u64)rd32(E1000_SYSTIML) << shift;
- stamp |= (u64)rd32(E1000_SYSTIMH) << (shift + 32);
- return stamp;
-}
-
/**
* igb_get_hw_dev - return device
* used by hardware layer to print debugging information
@@ -2110,9 +2082,11 @@
}
#endif
+#ifdef CONFIG_IGB_PTP
/* do hw tstamp init after resetting */
- igb_init_hw_timer(adapter);
+ igb_ptp_init(adapter);
+#endif
dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
/* print bus type/speed/width info */
dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n",
@@ -2184,7 +2158,10 @@
struct e1000_hw *hw = &adapter->hw;
pm_runtime_get_noresume(&pdev->dev);
+#ifdef CONFIG_IGB_PTP
+ igb_ptp_remove(adapter);
+#endif
/*
* The watchdog timer may be rescheduled, so explicitly
* disable watchdog from being rescheduled.
@@ -2304,112 +2281,6 @@
}
/**
- * igb_init_hw_timer - Initialize hardware timer used with IEEE 1588 timestamp
- * @adapter: board private structure to initialize
- *
- * igb_init_hw_timer initializes the function pointer and values for the hw
- * timer found in hardware.
- **/
-static void igb_init_hw_timer(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- switch (hw->mac.type) {
- case e1000_i350:
- case e1000_82580:
- memset(&adapter->cycles, 0, sizeof(adapter->cycles));
- adapter->cycles.read = igb_read_clock;
- adapter->cycles.mask = CLOCKSOURCE_MASK(64);
- adapter->cycles.mult = 1;
- /*
- * The 82580 timesync updates the system timer every 8ns by 8ns
- * and the value cannot be shifted. Instead we need to shift
- * the registers to generate a 64bit timer value. As a result
- * SYSTIMR/L/H, TXSTMPL/H, RXSTMPL/H all have to be shifted by
- * 24 in order to generate a larger value for synchronization.
- */
- adapter->cycles.shift = IGB_82580_TSYNC_SHIFT;
- /* disable system timer temporarily by setting bit 31 */
- wr32(E1000_TSAUXC, 0x80000000);
- wrfl();
-
- /* Set registers so that rollover occurs soon to test this. */
- wr32(E1000_SYSTIMR, 0x00000000);
- wr32(E1000_SYSTIML, 0x80000000);
- wr32(E1000_SYSTIMH, 0x000000FF);
- wrfl();
-
- /* enable system timer by clearing bit 31 */
- wr32(E1000_TSAUXC, 0x0);
- wrfl();
-
- timecounter_init(&adapter->clock,
- &adapter->cycles,
- ktime_to_ns(ktime_get_real()));
- /*
- * Synchronize our NIC clock against system wall clock. NIC
- * time stamp reading requires ~3us per sample, each sample
- * was pretty stable even under load => only require 10
- * samples for each offset comparison.
- */
- memset(&adapter->compare, 0, sizeof(adapter->compare));
- adapter->compare.source = &adapter->clock;
- adapter->compare.target = ktime_get_real;
- adapter->compare.num_samples = 10;
- timecompare_update(&adapter->compare, 0);
- break;
- case e1000_82576:
- /*
- * Initialize hardware timer: we keep it running just in case
- * that some program needs it later on.
- */
- memset(&adapter->cycles, 0, sizeof(adapter->cycles));
- adapter->cycles.read = igb_read_clock;
- adapter->cycles.mask = CLOCKSOURCE_MASK(64);
- adapter->cycles.mult = 1;
- /**
- * Scale the NIC clock cycle by a large factor so that
- * relatively small clock corrections can be added or
- * subtracted at each clock tick. The drawbacks of a large
- * factor are a) that the clock register overflows more quickly
- * (not such a big deal) and b) that the increment per tick has
- * to fit into 24 bits. As a result we need to use a shift of
- * 19 so we can fit a value of 16 into the TIMINCA register.
- */
- adapter->cycles.shift = IGB_82576_TSYNC_SHIFT;
- wr32(E1000_TIMINCA,
- (1 << E1000_TIMINCA_16NS_SHIFT) |
- (16 << IGB_82576_TSYNC_SHIFT));
-
- /* Set registers so that rollover occurs soon to test this. */
- wr32(E1000_SYSTIML, 0x00000000);
- wr32(E1000_SYSTIMH, 0xFF800000);
- wrfl();
-
- timecounter_init(&adapter->clock,
- &adapter->cycles,
- ktime_to_ns(ktime_get_real()));
- /*
- * Synchronize our NIC clock against system wall clock. NIC
- * time stamp reading requires ~3us per sample, each sample
- * was pretty stable even under load => only require 10
- * samples for each offset comparison.
- */
- memset(&adapter->compare, 0, sizeof(adapter->compare));
- adapter->compare.source = &adapter->clock;
- adapter->compare.target = ktime_get_real;
- adapter->compare.num_samples = 10;
- timecompare_update(&adapter->compare, 0);
- break;
- case e1000_82575:
- /* 82575 does not support timesync */
- default:
- break;
- }
-
-}
-
-/**
* igb_sw_init - Initialize general software structures (struct igb_adapter)
* @adapter: board private structure to initialize
*
@@ -5718,35 +5589,7 @@
return 0;
}
-/**
- * igb_systim_to_hwtstamp - convert system time value to hw timestamp
- * @adapter: board private structure
- * @shhwtstamps: timestamp structure to update
- * @regval: unsigned 64bit system time value.
- *
- * We need to convert the system time value stored in the RX/TXSTMP registers
- * into a hwtstamp which can be used by the upper level timestamping functions
- */
-static void igb_systim_to_hwtstamp(struct igb_adapter *adapter,
- struct skb_shared_hwtstamps *shhwtstamps,
- u64 regval)
-{
- u64 ns;
-
- /*
- * The 82580 starts with 1ns at bit 0 in RX/TXSTMPL, shift this up to
- * 24 to match clock shift we setup earlier.
- */
- if (adapter->hw.mac.type >= e1000_82580)
- regval <<= IGB_82580_TSYNC_SHIFT;
-
- ns = timecounter_cyc2time(&adapter->clock, regval);
- timecompare_update(&adapter->compare, ns);
- memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
- shhwtstamps->hwtstamp = ns_to_ktime(ns);
- shhwtstamps->syststamp = timecompare_transform(&adapter->compare, ns);
-}
-
+#ifdef CONFIG_IGB_PTP
/**
* igb_tx_hwtstamp - utility function which checks for TX time stamp
* @q_vector: pointer to q_vector containing needed info
@@ -5776,6 +5619,7 @@
skb_tstamp_tx(buffer_info->skb, &shhwtstamps);
}
+#endif
/**
* igb_clean_tx_irq - Reclaim resources after transmit completes
* @q_vector: pointer to q_vector containing needed info
@@ -5819,9 +5663,11 @@
total_bytes += tx_buffer->bytecount;
total_packets += tx_buffer->gso_segs;
+#ifdef CONFIG_IGB_PTP
/* retrieve hardware timestamp */
igb_tx_hwtstamp(q_vector, tx_buffer);
+#endif
/* free the skb */
dev_kfree_skb_any(tx_buffer->skb);
tx_buffer->skb = NULL;
@@ -5993,6 +5839,7 @@
skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
}
+#ifdef CONFIG_IGB_PTP
static void igb_rx_hwtstamp(struct igb_q_vector *q_vector,
union e1000_adv_rx_desc *rx_desc,
struct sk_buff *skb)
@@ -6032,6 +5879,7 @@
igb_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
}
+#endif
static void igb_rx_vlan(struct igb_ring *ring,
union e1000_adv_rx_desc *rx_desc,
struct sk_buff *skb)
@@ -6142,7 +5990,9 @@
goto next_desc;
}
+#ifdef CONFIG_IGB_PTP
igb_rx_hwtstamp(q_vector, rx_desc, skb);
+#endif
igb_rx_hash(rx_ring, rx_desc, skb);
igb_rx_checksum(rx_ring, rx_desc, skb);
igb_rx_vlan(rx_ring, rx_desc, skb);
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
new file mode 100644
index 0000000..c9b71c5
--- /dev/null
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -0,0 +1,381 @@
+/*
+ * PTP Hardware Clock (PHC) driver for the Intel 82576 and 82580
+ *
+ * Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any 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. 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+
+#include "igb.h"
+
+#define INCVALUE_MASK 0x7fffffff
+#define ISGN 0x80000000
+
+/*
+ * The 82580 timesync updates the system timer every 8ns by 8ns,
+ * and this update value cannot be reprogrammed.
+ *
+ * Neither the 82576 nor the 82580 offer registers wide enough to hold
+ * nanoseconds time values for very long. For the 82580, SYSTIM always
+ * counts nanoseconds, but the upper 24 bits are not availible. The
+ * frequency is adjusted by changing the 32 bit fractional nanoseconds
+ * register, TIMINCA.
+ *
+ * For the 82576, the SYSTIM register time unit is affect by the
+ * choice of the 24 bit TININCA:IV (incvalue) field. Five bits of this
+ * field are needed to provide the nominal 16 nanosecond period,
+ * leaving 19 bits for fractional nanoseconds.
+ *
+ * We scale the NIC clock cycle by a large factor so that relatively
+ * small clock corrections can be added or subtracted at each clock
+ * tick. The drawbacks of a large factor are a) that the clock
+ * register overflows more quickly (not such a big deal) and b) that
+ * the increment per tick has to fit into 24 bits. As a result we
+ * need to use a shift of 19 so we can fit a value of 16 into the
+ * TIMINCA register.
+ *
+ *
+ * SYSTIMH SYSTIML
+ * +--------------+ +---+---+------+
+ * 82576 | 32 | | 8 | 5 | 19 |
+ * +--------------+ +---+---+------+
+ * \________ 45 bits _______/ fract
+ *
+ * +----------+---+ +--------------+
+ * 82580 | 24 | 8 | | 32 |
+ * +----------+---+ +--------------+
+ * reserved \______ 40 bits _____/
+ *
+ *
+ * The 45 bit 82576 SYSTIM overflows every
+ * 2^45 * 10^-9 / 3600 = 9.77 hours.
+ *
+ * The 40 bit 82580 SYSTIM overflows every
+ * 2^40 * 10^-9 / 60 = 18.3 minutes.
+ */
+
+#define IGB_OVERFLOW_PERIOD (HZ * 60 * 9)
+#define INCPERIOD_82576 (1 << E1000_TIMINCA_16NS_SHIFT)
+#define INCVALUE_82576_MASK ((1 << E1000_TIMINCA_16NS_SHIFT) - 1)
+#define INCVALUE_82576 (16 << IGB_82576_TSYNC_SHIFT)
+#define IGB_NBITS_82580 40
+
+/*
+ * SYSTIM read access for the 82576
+ */
+
+static cycle_t igb_82576_systim_read(const struct cyclecounter *cc)
+{
+ u64 val;
+ u32 lo, hi;
+ struct igb_adapter *igb = container_of(cc, struct igb_adapter, cc);
+ struct e1000_hw *hw = &igb->hw;
+
+ lo = rd32(E1000_SYSTIML);
+ hi = rd32(E1000_SYSTIMH);
+
+ val = ((u64) hi) << 32;
+ val |= lo;
+
+ return val;
+}
+
+/*
+ * SYSTIM read access for the 82580
+ */
+
+static cycle_t igb_82580_systim_read(const struct cyclecounter *cc)
+{
+ u64 val;
+ u32 lo, hi, jk;
+ struct igb_adapter *igb = container_of(cc, struct igb_adapter, cc);
+ struct e1000_hw *hw = &igb->hw;
+
+ /*
+ * The timestamp latches on lowest register read. For the 82580
+ * the lowest register is SYSTIMR instead of SYSTIML. However we only
+ * need to provide nanosecond resolution, so we just ignore it.
+ */
+ jk = rd32(E1000_SYSTIMR);
+ lo = rd32(E1000_SYSTIML);
+ hi = rd32(E1000_SYSTIMH);
+
+ val = ((u64) hi) << 32;
+ val |= lo;
+
+ return val;
+}
+
+/*
+ * PTP clock operations
+ */
+
+static int ptp_82576_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+ u64 rate;
+ u32 incvalue;
+ int neg_adj = 0;
+ struct igb_adapter *igb = container_of(ptp, struct igb_adapter, caps);
+ struct e1000_hw *hw = &igb->hw;
+
+ if (ppb < 0) {
+ neg_adj = 1;
+ ppb = -ppb;
+ }
+ rate = ppb;
+ rate <<= 14;
+ rate = div_u64(rate, 1953125);
+
+ incvalue = 16 << IGB_82576_TSYNC_SHIFT;
+
+ if (neg_adj)
+ incvalue -= rate;
+ else
+ incvalue += rate;
+
+ wr32(E1000_TIMINCA, INCPERIOD_82576 | (incvalue & INCVALUE_82576_MASK));
+
+ return 0;
+}
+
+static int ptp_82580_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+ u64 rate;
+ u32 inca;
+ int neg_adj = 0;
+ struct igb_adapter *igb = container_of(ptp, struct igb_adapter, caps);
+ struct e1000_hw *hw = &igb->hw;
+
+ if (ppb < 0) {
+ neg_adj = 1;
+ ppb = -ppb;
+ }
+ rate = ppb;
+ rate <<= 26;
+ rate = div_u64(rate, 1953125);
+
+ inca = rate & INCVALUE_MASK;
+ if (neg_adj)
+ inca |= ISGN;
+
+ wr32(E1000_TIMINCA, inca);
+
+ return 0;
+}
+
+static int igb_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+ s64 now;
+ unsigned long flags;
+ struct igb_adapter *igb = container_of(ptp, struct igb_adapter, caps);
+
+ spin_lock_irqsave(&igb->tmreg_lock, flags);
+
+ now = timecounter_read(&igb->tc);
+ now += delta;
+ timecounter_init(&igb->tc, &igb->cc, now);
+
+ spin_unlock_irqrestore(&igb->tmreg_lock, flags);
+
+ return 0;
+}
+
+static int igb_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+ u64 ns;
+ u32 remainder;
+ unsigned long flags;
+ struct igb_adapter *igb = container_of(ptp, struct igb_adapter, caps);
+
+ spin_lock_irqsave(&igb->tmreg_lock, flags);
+
+ ns = timecounter_read(&igb->tc);
+
+ spin_unlock_irqrestore(&igb->tmreg_lock, flags);
+
+ ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
+ ts->tv_nsec = remainder;
+
+ return 0;
+}
+
+static int igb_settime(struct ptp_clock_info *ptp, const struct timespec *ts)
+{
+ u64 ns;
+ unsigned long flags;
+ struct igb_adapter *igb = container_of(ptp, struct igb_adapter, caps);
+
+ ns = ts->tv_sec * 1000000000ULL;
+ ns += ts->tv_nsec;
+
+ spin_lock_irqsave(&igb->tmreg_lock, flags);
+
+ timecounter_init(&igb->tc, &igb->cc, ns);
+
+ spin_unlock_irqrestore(&igb->tmreg_lock, flags);
+
+ return 0;
+}
+
+static int ptp_82576_enable(struct ptp_clock_info *ptp,
+ struct ptp_clock_request *rq, int on)
+{
+ return -EOPNOTSUPP;
+}
+
+static int ptp_82580_enable(struct ptp_clock_info *ptp,
+ struct ptp_clock_request *rq, int on)
+{
+ return -EOPNOTSUPP;
+}
+
+static void igb_overflow_check(struct work_struct *work)
+{
+ struct timespec ts;
+ struct igb_adapter *igb =
+ container_of(work, struct igb_adapter, overflow_work.work);
+
+ igb_gettime(&igb->caps, &ts);
+
+ pr_debug("igb overflow check at %ld.%09lu\n", ts.tv_sec, ts.tv_nsec);
+
+ schedule_delayed_work(&igb->overflow_work, IGB_OVERFLOW_PERIOD);
+}
+
+void igb_ptp_init(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ switch (hw->mac.type) {
+ case e1000_i350:
+ case e1000_82580:
+ adapter->caps.owner = THIS_MODULE;
+ strcpy(adapter->caps.name, "igb-82580");
+ adapter->caps.max_adj = 62499999;
+ adapter->caps.n_ext_ts = 0;
+ adapter->caps.pps = 0;
+ adapter->caps.adjfreq = ptp_82580_adjfreq;
+ adapter->caps.adjtime = igb_adjtime;
+ adapter->caps.gettime = igb_gettime;
+ adapter->caps.settime = igb_settime;
+ adapter->caps.enable = ptp_82580_enable;
+ adapter->cc.read = igb_82580_systim_read;
+ adapter->cc.mask = CLOCKSOURCE_MASK(IGB_NBITS_82580);
+ adapter->cc.mult = 1;
+ adapter->cc.shift = 0;
+ /* Enable the timer functions by clearing bit 31. */
+ wr32(E1000_TSAUXC, 0x0);
+ break;
+
+ case e1000_82576:
+ adapter->caps.owner = THIS_MODULE;
+ strcpy(adapter->caps.name, "igb-82576");
+ adapter->caps.max_adj = 1000000000;
+ adapter->caps.n_ext_ts = 0;
+ adapter->caps.pps = 0;
+ adapter->caps.adjfreq = ptp_82576_adjfreq;
+ adapter->caps.adjtime = igb_adjtime;
+ adapter->caps.gettime = igb_gettime;
+ adapter->caps.settime = igb_settime;
+ adapter->caps.enable = ptp_82576_enable;
+ adapter->cc.read = igb_82576_systim_read;
+ adapter->cc.mask = CLOCKSOURCE_MASK(64);
+ adapter->cc.mult = 1;
+ adapter->cc.shift = IGB_82576_TSYNC_SHIFT;
+ /* Dial the nominal frequency. */
+ wr32(E1000_TIMINCA, INCPERIOD_82576 | INCVALUE_82576);
+ break;
+
+ default:
+ adapter->ptp_clock = NULL;
+ return;
+ }
+
+ wrfl();
+
+ timecounter_init(&adapter->tc, &adapter->cc,
+ ktime_to_ns(ktime_get_real()));
+
+ INIT_DELAYED_WORK(&adapter->overflow_work, igb_overflow_check);
+
+ spin_lock_init(&adapter->tmreg_lock);
+
+ schedule_delayed_work(&adapter->overflow_work, IGB_OVERFLOW_PERIOD);
+
+ adapter->ptp_clock = ptp_clock_register(&adapter->caps);
+ if (IS_ERR(adapter->ptp_clock)) {
+ adapter->ptp_clock = NULL;
+ dev_err(&adapter->pdev->dev, "ptp_clock_register failed\n");
+ } else
+ dev_info(&adapter->pdev->dev, "added PHC on %s\n",
+ adapter->netdev->name);
+}
+
+void igb_ptp_remove(struct igb_adapter *adapter)
+{
+ cancel_delayed_work_sync(&adapter->overflow_work);
+
+ if (adapter->ptp_clock) {
+ ptp_clock_unregister(adapter->ptp_clock);
+ dev_info(&adapter->pdev->dev, "removed PHC on %s\n",
+ adapter->netdev->name);
+ }
+}
+
+/**
+ * igb_systim_to_hwtstamp - convert system time value to hw timestamp
+ * @adapter: board private structure
+ * @hwtstamps: timestamp structure to update
+ * @systim: unsigned 64bit system time value.
+ *
+ * We need to convert the system time value stored in the RX/TXSTMP registers
+ * into a hwtstamp which can be used by the upper level timestamping functions.
+ *
+ * The 'tmreg_lock' spinlock is used to protect the consistency of the
+ * system time value. This is needed because reading the 64 bit time
+ * value involves reading two (or three) 32 bit registers. The first
+ * read latches the value. Ditto for writing.
+ *
+ * In addition, here have extended the system time with an overflow
+ * counter in software.
+ **/
+void igb_systim_to_hwtstamp(struct igb_adapter *adapter,
+ struct skb_shared_hwtstamps *hwtstamps,
+ u64 systim)
+{
+ u64 ns;
+ unsigned long flags;
+
+ switch (adapter->hw.mac.type) {
+ case e1000_i350:
+ case e1000_82580:
+ case e1000_82576:
+ break;
+ default:
+ return;
+ }
+
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+
+ ns = timecounter_cyc2time(&adapter->tc, systim);
+
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+
+ memset(hwtstamps, 0, sizeof(*hwtstamps));
+ hwtstamps->hwtstamp = ns_to_ktime(ns);
+}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index 85d2e2c..56fd468 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -91,29 +91,6 @@
IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr);
}
-/**
- * ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count
- * @hw: pointer to hardware structure
- *
- * Read PCIe configuration space, and get the MSI-X vector count from
- * the capabilities table.
- **/
-static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
-{
- struct ixgbe_adapter *adapter = hw->back;
- u16 msix_count;
- pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82598_CAPS,
- &msix_count);
- msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
-
- /* MSI-X count is zero-based in HW, so increment to give proper value */
- msix_count++;
-
- return msix_count;
-}
-
-/**
- */
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
@@ -126,7 +103,7 @@
mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
- mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
+ mac->max_msix_vectors = ixgbe_get_pcie_msix_count_generic(hw);
return 0;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 49aa41f..e598881 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -2783,17 +2783,36 @@
* Read PCIe configuration space, and get the MSI-X vector count from
* the capabilities table.
**/
-u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
+u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
{
struct ixgbe_adapter *adapter = hw->back;
- u16 msix_count;
- pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82599_CAPS,
- &msix_count);
+ u16 msix_count = 1;
+ u16 max_msix_count;
+ u16 pcie_offset;
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ pcie_offset = IXGBE_PCIE_MSIX_82598_CAPS;
+ max_msix_count = IXGBE_MAX_MSIX_VECTORS_82598;
+ break;
+ case ixgbe_mac_82599EB:
+ case ixgbe_mac_X540:
+ pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS;
+ max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599;
+ break;
+ default:
+ return msix_count;
+ }
+
+ pci_read_config_word(adapter->pdev, pcie_offset, &msix_count);
msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
- /* MSI-X count is zero-based in HW, so increment to give proper value */
+ /* MSI-X count is zero-based in HW */
msix_count++;
+ if (msix_count > max_msix_count)
+ msix_count = max_msix_count;
+
return msix_count;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
index 204f062..d6d3432 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -31,7 +31,7 @@
#include "ixgbe_type.h"
#include "ixgbe.h"
-u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw);
+u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 8636e83..ffa6679 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -1681,7 +1681,9 @@
#define IXGBE_DEVICE_CAPS 0x2C
#define IXGBE_SERIAL_NUMBER_MAC_ADDR 0x11
#define IXGBE_PCIE_MSIX_82599_CAPS 0x72
+#define IXGBE_MAX_MSIX_VECTORS_82599 0x40
#define IXGBE_PCIE_MSIX_82598_CAPS 0x62
+#define IXGBE_MAX_MSIX_VECTORS_82598 0x13
/* MSI-X capability fields masks */
#define IXGBE_PCIE_MSIX_TBL_SZ_MASK 0x7FF
@@ -2813,6 +2815,7 @@
u16 wwnn_prefix;
/* prefix for World Wide Port Name (WWPN) */
u16 wwpn_prefix;
+ u16 max_msix_vectors;
#define IXGBE_MAX_MTA 128
u32 mta_shadow[IXGBE_MAX_MTA];
s32 mc_filter_type;
@@ -2823,7 +2826,6 @@
u32 rx_pb_size;
u32 max_tx_queues;
u32 max_rx_queues;
- u32 max_msix_vectors;
u32 orig_autoc;
u32 orig_autoc2;
bool orig_link_settings_stored;
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 5e1ca0f..c8950da 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -1665,6 +1665,7 @@
.get_strings = mv643xx_eth_get_strings,
.get_ethtool_stats = mv643xx_eth_get_ethtool_stats,
.get_sset_count = mv643xx_eth_get_sset_count,
+ .get_ts_info = ethtool_op_get_ts_info,
};
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index efec6b6..1db023b 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -1456,6 +1456,7 @@
.set_settings = pxa168_set_settings,
.get_drvinfo = pxa168_get_drvinfo,
.get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static const struct net_device_ops pxa168_eth_netdev_ops = {
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index c9b504e..7732474 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4816,14 +4816,14 @@
init_waitqueue_head(&hw->msi_wait);
- sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
-
err = request_irq(pdev->irq, sky2_test_intr, 0, DRV_NAME, hw);
if (err) {
dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
return err;
}
+ sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
+
sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
sky2_read8(hw, B0_CTST);
diff --git a/drivers/net/ethernet/mellanox/mlx4/Kconfig b/drivers/net/ethernet/mellanox/mlx4/Kconfig
index 1bb9353..5f027f9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx4/Kconfig
@@ -11,6 +11,18 @@
This driver supports Mellanox Technologies ConnectX Ethernet
devices.
+config MLX4_EN_DCB
+ bool "Data Center Bridging (DCB) Support"
+ default y
+ depends on MLX4_EN && DCB
+ ---help---
+ Say Y here if you want to use Data Center Bridging (DCB) in the
+ driver.
+ If set to N, will not be able to configure QoS and ratelimit attributes.
+ This flag is depended on the kernel's DCB support.
+
+ If unsure, set to Y
+
config MLX4_CORE
tristate
depends on PCI
diff --git a/drivers/net/ethernet/mellanox/mlx4/Makefile b/drivers/net/ethernet/mellanox/mlx4/Makefile
index 4a40ab9..293127d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx4/Makefile
@@ -7,3 +7,4 @@
mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \
en_resources.o en_netdev.o en_selftest.o
+mlx4_en-$(CONFIG_MLX4_EN_DCB) += en_dcb_nl.o
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
new file mode 100644
index 0000000..0cc6c96
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2011 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/dcbnl.h>
+
+#include "mlx4_en.h"
+
+static int mlx4_en_dcbnl_ieee_getets(struct net_device *dev,
+ struct ieee_ets *ets)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct ieee_ets *my_ets = &priv->ets;
+
+ /* No IEEE PFC settings available */
+ if (!my_ets)
+ return -EINVAL;
+
+ ets->ets_cap = IEEE_8021QAZ_MAX_TCS;
+ ets->cbs = my_ets->cbs;
+ memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw));
+ memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
+ memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
+
+ return 0;
+}
+
+static int mlx4_en_ets_validate(struct mlx4_en_priv *priv, struct ieee_ets *ets)
+{
+ int i;
+ int total_ets_bw = 0;
+ int has_ets_tc = 0;
+
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+ if (ets->prio_tc[i] > MLX4_EN_NUM_UP) {
+ en_err(priv, "Bad priority in UP <=> TC mapping. TC: %d, UP: %d\n",
+ i, ets->prio_tc[i]);
+ return -EINVAL;
+ }
+
+ switch (ets->tc_tsa[i]) {
+ case IEEE_8021QAZ_TSA_STRICT:
+ break;
+ case IEEE_8021QAZ_TSA_ETS:
+ has_ets_tc = 1;
+ total_ets_bw += ets->tc_tx_bw[i];
+ break;
+ default:
+ en_err(priv, "TC[%d]: Not supported TSA: %d\n",
+ i, ets->tc_tsa[i]);
+ return -ENOTSUPP;
+ }
+ }
+
+ if (has_ets_tc && total_ets_bw != MLX4_EN_BW_MAX) {
+ en_err(priv, "Bad ETS BW sum: %d. Should be exactly 100%%\n",
+ total_ets_bw);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mlx4_en_config_port_scheduler(struct mlx4_en_priv *priv,
+ struct ieee_ets *ets, u16 *ratelimit)
+{
+ struct mlx4_en_dev *mdev = priv->mdev;
+ int num_strict = 0;
+ int i;
+ __u8 tc_tx_bw[IEEE_8021QAZ_MAX_TCS] = { 0 };
+ __u8 pg[IEEE_8021QAZ_MAX_TCS] = { 0 };
+
+ ets = ets ?: &priv->ets;
+ ratelimit = ratelimit ?: priv->maxrate;
+
+ /* higher TC means higher priority => lower pg */
+ for (i = IEEE_8021QAZ_MAX_TCS - 1; i >= 0; i--) {
+ switch (ets->tc_tsa[i]) {
+ case IEEE_8021QAZ_TSA_STRICT:
+ pg[i] = num_strict++;
+ tc_tx_bw[i] = MLX4_EN_BW_MAX;
+ break;
+ case IEEE_8021QAZ_TSA_ETS:
+ pg[i] = MLX4_EN_TC_ETS;
+ tc_tx_bw[i] = ets->tc_tx_bw[i] ?: MLX4_EN_BW_MIN;
+ break;
+ }
+ }
+
+ return mlx4_SET_PORT_SCHEDULER(mdev->dev, priv->port, tc_tx_bw, pg,
+ ratelimit);
+}
+
+static int
+mlx4_en_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct mlx4_en_dev *mdev = priv->mdev;
+ int err;
+
+ err = mlx4_en_ets_validate(priv, ets);
+ if (err)
+ return err;
+
+ err = mlx4_SET_PORT_PRIO2TC(mdev->dev, priv->port, ets->prio_tc);
+ if (err)
+ return err;
+
+ err = mlx4_en_config_port_scheduler(priv, ets, NULL);
+ if (err)
+ return err;
+
+ memcpy(&priv->ets, ets, sizeof(priv->ets));
+
+ return 0;
+}
+
+static int mlx4_en_dcbnl_ieee_getpfc(struct net_device *dev,
+ struct ieee_pfc *pfc)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+
+ pfc->pfc_cap = IEEE_8021QAZ_MAX_TCS;
+ pfc->pfc_en = priv->prof->tx_ppp;
+
+ return 0;
+}
+
+static int mlx4_en_dcbnl_ieee_setpfc(struct net_device *dev,
+ struct ieee_pfc *pfc)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ struct mlx4_en_dev *mdev = priv->mdev;
+ int err;
+
+ en_dbg(DRV, priv, "cap: 0x%x en: 0x%x mbc: 0x%x delay: %d\n",
+ pfc->pfc_cap,
+ pfc->pfc_en,
+ pfc->mbc,
+ pfc->delay);
+
+ priv->prof->rx_pause = priv->prof->tx_pause = !!pfc->pfc_en;
+ priv->prof->rx_ppp = priv->prof->tx_ppp = pfc->pfc_en;
+
+ err = mlx4_SET_PORT_general(mdev->dev, priv->port,
+ priv->rx_skb_size + ETH_FCS_LEN,
+ priv->prof->tx_pause,
+ priv->prof->tx_ppp,
+ priv->prof->rx_pause,
+ priv->prof->rx_ppp);
+ if (err)
+ en_err(priv, "Failed setting pause params\n");
+
+ return err;
+}
+
+static u8 mlx4_en_dcbnl_getdcbx(struct net_device *dev)
+{
+ return DCB_CAP_DCBX_VER_IEEE;
+}
+
+static u8 mlx4_en_dcbnl_setdcbx(struct net_device *dev, u8 mode)
+{
+ if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
+ (mode & DCB_CAP_DCBX_VER_CEE) ||
+ !(mode & DCB_CAP_DCBX_VER_IEEE) ||
+ !(mode & DCB_CAP_DCBX_HOST))
+ return 1;
+
+ return 0;
+}
+
+#define MLX4_RATELIMIT_UNITS_IN_KB 100000 /* rate-limit HW unit in Kbps */
+static int mlx4_en_dcbnl_ieee_getmaxrate(struct net_device *dev,
+ struct ieee_maxrate *maxrate)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ int i;
+
+ if (!priv->maxrate)
+ return -EINVAL;
+
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
+ maxrate->tc_maxrate[i] =
+ priv->maxrate[i] * MLX4_RATELIMIT_UNITS_IN_KB;
+
+ return 0;
+}
+
+static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev,
+ struct ieee_maxrate *maxrate)
+{
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ u16 tmp[IEEE_8021QAZ_MAX_TCS];
+ int i, err;
+
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+ /* Convert from Kbps into HW units, rounding result up.
+ * Setting to 0, means unlimited BW.
+ */
+ tmp[i] =
+ (maxrate->tc_maxrate[i] + MLX4_RATELIMIT_UNITS_IN_KB -
+ 1) / MLX4_RATELIMIT_UNITS_IN_KB;
+ }
+
+ err = mlx4_en_config_port_scheduler(priv, NULL, tmp);
+ if (err)
+ return err;
+
+ memcpy(priv->maxrate, tmp, sizeof(*priv->maxrate));
+
+ return 0;
+}
+
+const struct dcbnl_rtnl_ops mlx4_en_dcbnl_ops = {
+ .ieee_getets = mlx4_en_dcbnl_ieee_getets,
+ .ieee_setets = mlx4_en_dcbnl_ieee_setets,
+ .ieee_getmaxrate = mlx4_en_dcbnl_ieee_getmaxrate,
+ .ieee_setmaxrate = mlx4_en_dcbnl_ieee_setmaxrate,
+ .ieee_getpfc = mlx4_en_dcbnl_ieee_getpfc,
+ .ieee_setpfc = mlx4_en_dcbnl_ieee_setpfc,
+
+ .getdcbx = mlx4_en_dcbnl_getdcbx,
+ .setdcbx = mlx4_en_dcbnl_setdcbx,
+};
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index 2097a7d..346fdb2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -114,7 +114,7 @@
params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS +
- (!!pfcrx) * MLX4_EN_NUM_PPP_RINGS;
+ MLX4_EN_NUM_PPP_RINGS;
params->prof[i].rss_rings = 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 31b455a..35003ad 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -45,6 +45,14 @@
#include "mlx4_en.h"
#include "en_port.h"
+static int mlx4_en_setup_tc(struct net_device *dev, u8 up)
+{
+ if (up != MLX4_EN_NUM_UP)
+ return -EINVAL;
+
+ return 0;
+}
+
static int mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
@@ -650,7 +658,8 @@
/* Configure ring */
tx_ring = &priv->tx_ring[i];
- err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn);
+ err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn,
+ max(0, i - MLX4_EN_NUM_TX_RINGS));
if (err) {
en_err(priv, "Failed allocating Tx ring\n");
mlx4_en_deactivate_cq(priv, cq);
@@ -966,6 +975,7 @@
mutex_unlock(&mdev->state_lock);
mlx4_en_free_resources(priv);
+
free_netdev(dev);
}
@@ -1036,6 +1046,7 @@
.ndo_poll_controller = mlx4_en_netpoll,
#endif
.ndo_set_features = mlx4_en_set_features,
+ .ndo_setup_tc = mlx4_en_setup_tc,
};
int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
@@ -1079,6 +1090,10 @@
INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
+#ifdef CONFIG_MLX4_EN_DCB
+ if (!mlx4_is_slave(priv->mdev->dev))
+ dev->dcbnl_ops = &mlx4_en_dcbnl_ops;
+#endif
/* Query for default mac and max mtu */
priv->max_mtu = mdev->dev->caps.eth_mtu_cap[priv->port];
@@ -1113,6 +1128,15 @@
netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
+ netdev_set_num_tc(dev, MLX4_EN_NUM_UP);
+
+ /* First 9 rings are for UP 0 */
+ netdev_set_tc_queue(dev, 0, MLX4_EN_NUM_TX_RINGS + 1, 0);
+
+ /* Partition Tx queues evenly amongst UP's 1-7 */
+ for (i = 1; i < MLX4_EN_NUM_UP; i++)
+ netdev_set_tc_queue(dev, i, 1, MLX4_EN_NUM_TX_RINGS + i);
+
SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
/* Set defualt MAC */
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.h b/drivers/net/ethernet/mellanox/mlx4/en_port.h
index 6934fd7..745090b 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_port.h
+++ b/drivers/net/ethernet/mellanox/mlx4/en_port.h
@@ -39,6 +39,8 @@
#define SET_PORT_PROMISC_SHIFT 31
#define SET_PORT_MC_PROMISC_SHIFT 30
+#define MLX4_EN_NUM_TC 8
+
#define VLAN_FLTR_SIZE 128
struct mlx4_set_vlan_fltr_mbox {
__be32 entry[VLAN_FLTR_SIZE];
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_resources.c b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
index bcbc54c..10c24c7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_resources.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_resources.c
@@ -39,7 +39,7 @@
void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
int is_tx, int rss, int qpn, int cqn,
- struct mlx4_qp_context *context)
+ int user_prio, struct mlx4_qp_context *context)
{
struct mlx4_en_dev *mdev = priv->mdev;
@@ -57,6 +57,10 @@
context->local_qpn = cpu_to_be32(qpn);
context->pri_path.ackto = 1 & 0x07;
context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6;
+ if (user_prio >= 0) {
+ context->pri_path.sched_queue |= user_prio << 3;
+ context->pri_path.feup = 1 << 6;
+ }
context->pri_path.counter_index = 0xff;
context->cqn_send = cpu_to_be32(cqn);
context->cqn_recv = cpu_to_be32(cqn);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index 9adbd53..d49a7ac 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -823,7 +823,7 @@
memset(context, 0, sizeof *context);
mlx4_en_fill_qp_context(priv, ring->actual_size, ring->stride, 0, 0,
- qpn, ring->cqn, context);
+ qpn, ring->cqn, -1, context);
context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
/* Cancel FCS removal if FW allows */
@@ -890,7 +890,7 @@
}
rss_map->indir_qp.event = mlx4_en_sqp_event;
mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn,
- priv->rx_ring[0].cqn, &context);
+ priv->rx_ring[0].cqn, -1, &context);
if (!priv->prof->rss_rings || priv->prof->rss_rings > priv->rx_ring_num)
rss_rings = priv->rx_ring_num;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 1796824..d9bab53 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -156,7 +156,7 @@
int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
struct mlx4_en_tx_ring *ring,
- int cq)
+ int cq, int user_prio)
{
struct mlx4_en_dev *mdev = priv->mdev;
int err;
@@ -174,7 +174,7 @@
ring->doorbell_qpn = ring->qp.qpn << 8;
mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn,
- ring->cqn, &ring->context);
+ ring->cqn, user_prio, &ring->context);
if (ring->bf_enabled)
ring->context.usr_page = cpu_to_be32(ring->bf.uar->index);
@@ -570,13 +570,9 @@
u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
{
- struct mlx4_en_priv *priv = netdev_priv(dev);
u16 vlan_tag = 0;
- /* If we support per priority flow control and the packet contains
- * a vlan tag, send the packet to the TX ring assigned to that priority
- */
- if (priv->prof->rx_ppp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
vlan_tag = vlan_tx_tag_get(skb);
return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13);
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 2a0ff2c..cd56f1a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -53,6 +53,26 @@
#define DRV_VERSION "1.1"
#define DRV_RELDATE "Dec, 2011"
+#define MLX4_NUM_UP 8
+#define MLX4_NUM_TC 8
+#define MLX4_RATELIMIT_UNITS 3 /* 100 Mbps */
+#define MLX4_RATELIMIT_DEFAULT 0xffff
+
+struct mlx4_set_port_prio2tc_context {
+ u8 prio2tc[4];
+};
+
+struct mlx4_port_scheduler_tc_cfg_be {
+ __be16 pg;
+ __be16 bw_precentage;
+ __be16 max_bw_units; /* 3-100Mbps, 4-1Gbps, other values - reserved */
+ __be16 max_bw_value;
+};
+
+struct mlx4_set_port_scheduler_context {
+ struct mlx4_port_scheduler_tc_cfg_be tc[MLX4_NUM_TC];
+};
+
enum {
MLX4_HCR_BASE = 0x80680,
MLX4_HCR_SIZE = 0x0001c,
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index d69fee4..47e1c0f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -40,6 +40,9 @@
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/if_vlan.h>
+#ifdef CONFIG_MLX4_EN_DCB
+#include <linux/dcbnl.h>
+#endif
#include <linux/mlx4/device.h>
#include <linux/mlx4/qp.h>
@@ -111,6 +114,7 @@
#define MLX4_EN_NUM_TX_RINGS 8
#define MLX4_EN_NUM_PPP_RINGS 8
#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS)
+#define MLX4_EN_NUM_UP 8
#define MLX4_EN_DEF_TX_RING_SIZE 512
#define MLX4_EN_DEF_RX_RING_SIZE 1024
@@ -411,6 +415,15 @@
};
+#ifdef CONFIG_MLX4_EN_DCB
+/* Minimal TC BW - setting to 0 will block traffic */
+#define MLX4_EN_BW_MIN 1
+#define MLX4_EN_BW_MAX 100 /* Utilize 100% of the line */
+
+#define MLX4_EN_TC_ETS 7
+
+#endif
+
struct mlx4_en_priv {
struct mlx4_en_dev *mdev;
struct mlx4_en_port_profile *prof;
@@ -484,6 +497,11 @@
int vids[128];
bool wol;
struct device *ddev;
+
+#ifdef CONFIG_MLX4_EN_DCB
+ struct ieee_ets ets;
+ u16 maxrate[IEEE_8021QAZ_MAX_TCS];
+#endif
};
enum mlx4_en_wol {
@@ -522,7 +540,7 @@
void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring);
int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
struct mlx4_en_tx_ring *ring,
- int cq);
+ int cq, int user_prio);
void mlx4_en_deactivate_tx_ring(struct mlx4_en_priv *priv,
struct mlx4_en_tx_ring *ring);
@@ -540,8 +558,8 @@
int budget);
int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
- int is_tx, int rss, int qpn, int cqn,
- struct mlx4_qp_context *context);
+ int is_tx, int rss, int qpn, int cqn, int user_prio,
+ struct mlx4_qp_context *context);
void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event);
int mlx4_en_map_buffer(struct mlx4_buf *buf);
void mlx4_en_unmap_buffer(struct mlx4_buf *buf);
@@ -558,6 +576,10 @@
int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset);
int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port);
+#ifdef CONFIG_MLX4_EN_DCB
+extern const struct dcbnl_rtnl_ops mlx4_en_dcbnl_ops;
+#endif
+
#define MLX4_EN_NUM_SELF_TEST 5
void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf);
u64 mlx4_en_mac_to_u64(u8 *addr);
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index 77535ff..55b12e6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -834,6 +834,68 @@
}
EXPORT_SYMBOL(mlx4_SET_PORT_qpn_calc);
+int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc)
+{
+ struct mlx4_cmd_mailbox *mailbox;
+ struct mlx4_set_port_prio2tc_context *context;
+ int err;
+ u32 in_mod;
+ int i;
+
+ mailbox = mlx4_alloc_cmd_mailbox(dev);
+ if (IS_ERR(mailbox))
+ return PTR_ERR(mailbox);
+ context = mailbox->buf;
+ memset(context, 0, sizeof *context);
+
+ for (i = 0; i < MLX4_NUM_UP; i += 2)
+ context->prio2tc[i >> 1] = prio2tc[i] << 4 | prio2tc[i + 1];
+
+ in_mod = MLX4_SET_PORT_PRIO2TC << 8 | port;
+ err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
+ MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
+
+ mlx4_free_cmd_mailbox(dev, mailbox);
+ return err;
+}
+EXPORT_SYMBOL(mlx4_SET_PORT_PRIO2TC);
+
+int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
+ u8 *pg, u16 *ratelimit)
+{
+ struct mlx4_cmd_mailbox *mailbox;
+ struct mlx4_set_port_scheduler_context *context;
+ int err;
+ u32 in_mod;
+ int i;
+
+ mailbox = mlx4_alloc_cmd_mailbox(dev);
+ if (IS_ERR(mailbox))
+ return PTR_ERR(mailbox);
+ context = mailbox->buf;
+ memset(context, 0, sizeof *context);
+
+ for (i = 0; i < MLX4_NUM_TC; i++) {
+ struct mlx4_port_scheduler_tc_cfg_be *tc = &context->tc[i];
+ u16 r = ratelimit && ratelimit[i] ? ratelimit[i] :
+ MLX4_RATELIMIT_DEFAULT;
+
+ tc->pg = htons(pg[i]);
+ tc->bw_precentage = htons(tc_tx_bw[i]);
+
+ tc->max_bw_units = htons(MLX4_RATELIMIT_UNITS);
+ tc->max_bw_value = htons(r);
+ }
+
+ in_mod = MLX4_SET_PORT_SCHEDULER << 8 | port;
+ err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT,
+ MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
+
+ mlx4_free_cmd_mailbox(dev, mailbox);
+ return err;
+}
+EXPORT_SYMBOL(mlx4_SET_PORT_SCHEDULER);
+
int mlx4_SET_MCAST_FLTR_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_vhcr *vhcr,
struct mlx4_cmd_mailbox *inbox,
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 27273ae..90153fc 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -4033,7 +4033,6 @@
netdev->netdev_ops = &myri10ge_netdev_ops;
netdev->mtu = myri10ge_initial_mtu;
- netdev->base_addr = mgp->iomem_base;
netdev->hw_features = mgp->features | NETIF_F_LRO | NETIF_F_RXCSUM;
netdev->features = netdev->hw_features;
@@ -4047,12 +4046,10 @@
netdev->vlan_features &= ~NETIF_F_TSO;
/* make sure we can get an irq, and that MSI can be
- * setup (if available). Also ensure netdev->irq
- * is set to correct value if MSI is enabled */
+ * setup (if available). */
status = myri10ge_request_irq(mgp);
if (status != 0)
goto abort_with_firmware;
- netdev->irq = pdev->irq;
myri10ge_free_irq(mgp);
/* Save configuration space to be restored if the
@@ -4077,7 +4074,7 @@
else
dev_info(dev, "%s IRQ %d, tx bndry %d, fw %s, WC %s\n",
mgp->msi_enabled ? "MSI" : "xPIC",
- netdev->irq, mgp->tx_boundary, mgp->fw_name,
+ pdev->irq, mgp->tx_boundary, mgp->fw_name,
(mgp->wc_enabled ? "Enabled" : "Disabled"));
board_number++;
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index d38e48d..5b61d12 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -547,6 +547,7 @@
struct sk_buff *tx_skbuff[TX_RING_SIZE];
dma_addr_t tx_dma[TX_RING_SIZE];
struct net_device *dev;
+ void __iomem *ioaddr;
struct napi_struct napi;
/* Media monitoring timer */
struct timer_list timer;
@@ -699,7 +700,9 @@
static inline void __iomem *ns_ioaddr(struct net_device *dev)
{
- return (void __iomem *) dev->base_addr;
+ struct netdev_private *np = netdev_priv(dev);
+
+ return np->ioaddr;
}
static inline void natsemi_irq_enable(struct net_device *dev)
@@ -863,10 +866,9 @@
/* Store MAC Address in perm_addr */
memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
- dev->base_addr = (unsigned long __force) ioaddr;
- dev->irq = irq;
-
np = netdev_priv(dev);
+ np->ioaddr = ioaddr;
+
netif_napi_add(dev, &np->napi, natsemi_poll, 64);
np->dev = dev;
@@ -914,9 +916,6 @@
}
option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
- if (dev->mem_start)
- option = dev->mem_start;
-
/* The lower four bits are the media type. */
if (option) {
if (option & 0x200)
@@ -1532,20 +1531,21 @@
{
struct netdev_private *np = netdev_priv(dev);
void __iomem * ioaddr = ns_ioaddr(dev);
+ const int irq = np->pci_dev->irq;
int i;
/* Reset the chip, just in case. */
natsemi_reset(dev);
- i = request_irq(dev->irq, intr_handler, IRQF_SHARED, dev->name, dev);
+ i = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev);
if (i) return i;
if (netif_msg_ifup(np))
printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
- dev->name, dev->irq);
+ dev->name, irq);
i = alloc_ring(dev);
if (i < 0) {
- free_irq(dev->irq, dev);
+ free_irq(irq, dev);
return i;
}
napi_enable(&np->napi);
@@ -1794,6 +1794,7 @@
struct netdev_private *np = netdev_priv(dev);
void __iomem * ioaddr = ns_ioaddr(dev);
int next_tick = NATSEMI_TIMER_FREQ;
+ const int irq = np->pci_dev->irq;
if (netif_msg_timer(np)) {
/* DO NOT read the IntrStatus register,
@@ -1817,14 +1818,14 @@
if (netif_msg_drv(np))
printk(KERN_NOTICE "%s: possible phy reset: "
"re-initializing\n", dev->name);
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock_irq(&np->lock);
natsemi_stop_rxtx(dev);
dump_ring(dev);
reinit_ring(dev);
init_registers(dev);
spin_unlock_irq(&np->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
} else {
/* hurry back */
next_tick = HZ;
@@ -1841,10 +1842,10 @@
spin_unlock_irq(&np->lock);
}
if (np->oom) {
- disable_irq(dev->irq);
+ disable_irq(irq);
np->oom = 0;
refill_rx(dev);
- enable_irq(dev->irq);
+ enable_irq(irq);
if (!np->oom) {
writel(RxOn, ioaddr + ChipCmd);
} else {
@@ -1885,8 +1886,9 @@
{
struct netdev_private *np = netdev_priv(dev);
void __iomem * ioaddr = ns_ioaddr(dev);
+ const int irq = np->pci_dev->irq;
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock_irq(&np->lock);
if (!np->hands_off) {
if (netif_msg_tx_err(np))
@@ -1905,7 +1907,7 @@
dev->name);
}
spin_unlock_irq(&np->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
dev->trans_start = jiffies; /* prevent tx timeout */
dev->stats.tx_errors++;
@@ -2470,9 +2472,12 @@
#ifdef CONFIG_NET_POLL_CONTROLLER
static void natsemi_poll_controller(struct net_device *dev)
{
- disable_irq(dev->irq);
- intr_handler(dev->irq, dev);
- enable_irq(dev->irq);
+ struct netdev_private *np = netdev_priv(dev);
+ const int irq = np->pci_dev->irq;
+
+ disable_irq(irq);
+ intr_handler(irq, dev);
+ enable_irq(irq);
}
#endif
@@ -2523,8 +2528,9 @@
if (netif_running(dev)) {
struct netdev_private *np = netdev_priv(dev);
void __iomem * ioaddr = ns_ioaddr(dev);
+ const int irq = np->pci_dev->irq;
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock(&np->lock);
/* stop engines */
natsemi_stop_rxtx(dev);
@@ -2537,7 +2543,7 @@
/* restart engines */
writel(RxOn | TxOn, ioaddr + ChipCmd);
spin_unlock(&np->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
}
return 0;
}
@@ -3135,6 +3141,7 @@
{
void __iomem * ioaddr = ns_ioaddr(dev);
struct netdev_private *np = netdev_priv(dev);
+ const int irq = np->pci_dev->irq;
if (netif_msg_ifdown(np))
printk(KERN_DEBUG
@@ -3156,14 +3163,14 @@
*/
del_timer_sync(&np->timer);
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock_irq(&np->lock);
natsemi_irq_disable(dev);
np->hands_off = 1;
spin_unlock_irq(&np->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
- free_irq(dev->irq, dev);
+ free_irq(irq, dev);
/* Interrupt disabled, interrupt handler released,
* queue stopped, timer deleted, rtnl_lock held
@@ -3256,9 +3263,11 @@
rtnl_lock();
if (netif_running (dev)) {
+ const int irq = np->pci_dev->irq;
+
del_timer_sync(&np->timer);
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock_irq(&np->lock);
natsemi_irq_disable(dev);
@@ -3267,7 +3276,7 @@
netif_stop_queue(dev);
spin_unlock_irq(&np->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
napi_disable(&np->napi);
@@ -3307,6 +3316,8 @@
if (netif_device_present(dev))
goto out;
if (netif_running(dev)) {
+ const int irq = np->pci_dev->irq;
+
BUG_ON(!np->hands_off);
ret = pci_enable_device(pdev);
if (ret < 0) {
@@ -3320,13 +3331,13 @@
natsemi_reset(dev);
init_ring(dev);
- disable_irq(dev->irq);
+ disable_irq(irq);
spin_lock_irq(&np->lock);
np->hands_off = 0;
init_registers(dev);
netif_device_attach(dev);
spin_unlock_irq(&np->lock);
- enable_irq(dev->irq);
+ enable_irq(irq);
mod_timer(&np->timer, round_jiffies(jiffies + 1*HZ));
}
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index 6338ef8..bb36758 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -2846,6 +2846,7 @@
static void s2io_netpoll(struct net_device *dev)
{
struct s2io_nic *nic = netdev_priv(dev);
+ const int irq = nic->pdev->irq;
struct XENA_dev_config __iomem *bar0 = nic->bar0;
u64 val64 = 0xFFFFFFFFFFFFFFFFULL;
int i;
@@ -2855,7 +2856,7 @@
if (pci_channel_offline(nic->pdev))
return;
- disable_irq(dev->irq);
+ disable_irq(irq);
writeq(val64, &bar0->rx_traffic_int);
writeq(val64, &bar0->tx_traffic_int);
@@ -2884,7 +2885,7 @@
break;
}
}
- enable_irq(dev->irq);
+ enable_irq(irq);
}
#endif
@@ -3897,9 +3898,7 @@
static void remove_inta_isr(struct s2io_nic *sp)
{
- struct net_device *dev = sp->dev;
-
- free_irq(sp->pdev->irq, dev);
+ free_irq(sp->pdev->irq, sp->dev);
}
/* ********************************************************* *
@@ -7046,7 +7045,7 @@
}
}
if (sp->config.intr_type == INTA) {
- err = request_irq((int)sp->pdev->irq, s2io_isr, IRQF_SHARED,
+ err = request_irq(sp->pdev->irq, s2io_isr, IRQF_SHARED,
sp->name, dev);
if (err) {
DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
@@ -7908,9 +7907,6 @@
goto bar1_remap_failed;
}
- dev->irq = pdev->irq;
- dev->base_addr = (unsigned long)sp->bar0;
-
/* Initializing the BAR1 address as the start of the FIFO pointer. */
for (j = 0; j < MAX_TX_FIFOS; j++) {
mac_control->tx_FIFO_start[j] = sp->bar1 + (j * 0x00020000);
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c
index ef76725..51387c3 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c
@@ -1882,25 +1882,24 @@
*/
static void vxge_netpoll(struct net_device *dev)
{
- struct __vxge_hw_device *hldev;
- struct vxgedev *vdev;
-
- vdev = netdev_priv(dev);
- hldev = pci_get_drvdata(vdev->pdev);
+ struct vxgedev *vdev = netdev_priv(dev);
+ struct pci_dev *pdev = vdev->pdev;
+ struct __vxge_hw_device *hldev = pci_get_drvdata(pdev);
+ const int irq = pdev->irq;
vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
- if (pci_channel_offline(vdev->pdev))
+ if (pci_channel_offline(pdev))
return;
- disable_irq(dev->irq);
+ disable_irq(irq);
vxge_hw_device_clear_tx_rx(hldev);
vxge_hw_device_clear_tx_rx(hldev);
VXGE_COMPLETE_ALL_RX(vdev);
VXGE_COMPLETE_ALL_TX(vdev);
- enable_irq(dev->irq);
+ enable_irq(irq);
vxge_debug_entryexit(VXGE_TRACE,
"%s:%d Exiting...", __func__, __LINE__);
@@ -2860,12 +2859,12 @@
vdev->config.rx_pause_enable);
if (vdev->vp_reset_timer.function == NULL)
- vxge_os_timer(vdev->vp_reset_timer,
- vxge_poll_vp_reset, vdev, (HZ/2));
+ vxge_os_timer(&vdev->vp_reset_timer, vxge_poll_vp_reset, vdev,
+ HZ / 2);
/* There is no need to check for RxD leak and RxD lookup on Titan1A */
if (vdev->titan1 && vdev->vp_lockup_timer.function == NULL)
- vxge_os_timer(vdev->vp_lockup_timer, vxge_poll_vp_lockup, vdev,
+ vxge_os_timer(&vdev->vp_lockup_timer, vxge_poll_vp_lockup, vdev,
HZ / 2);
set_bit(__VXGE_STATE_CARD_UP, &vdev->state);
@@ -3424,9 +3423,6 @@
ndev->features |= ndev->hw_features |
NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
- /* Driver entry points */
- ndev->irq = vdev->pdev->irq;
- ndev->base_addr = (unsigned long) hldev->bar0;
ndev->netdev_ops = &vxge_netdev_ops;
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.h b/drivers/net/ethernet/neterion/vxge/vxge-main.h
index f52a42d..35f3e75 100644
--- a/drivers/net/ethernet/neterion/vxge/vxge-main.h
+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.h
@@ -416,12 +416,15 @@
static int p = val; \
module_param(p, int, 0)
-#define vxge_os_timer(timer, handle, arg, exp) do { \
- init_timer(&timer); \
- timer.function = handle; \
- timer.data = (unsigned long) arg; \
- mod_timer(&timer, (jiffies + exp)); \
- } while (0);
+static inline
+void vxge_os_timer(struct timer_list *timer, void (*func)(unsigned long data),
+ struct vxgedev *vdev, unsigned long timeout)
+{
+ init_timer(timer);
+ timer->function = func;
+ timer->data = (unsigned long)vdev;
+ mod_timer(timer, jiffies + timeout);
+}
void vxge_initialize_ethtool_ops(struct net_device *ndev);
enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index aca1304..d93a088 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -3942,13 +3942,11 @@
ret = pci_enable_msi(np->pci_dev);
if (ret == 0) {
np->msi_flags |= NV_MSI_ENABLED;
- dev->irq = np->pci_dev->irq;
if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
netdev_info(dev, "request_irq failed %d\n",
ret);
pci_disable_msi(np->pci_dev);
np->msi_flags &= ~NV_MSI_ENABLED;
- dev->irq = np->pci_dev->irq;
goto out_err;
}
@@ -5649,9 +5647,6 @@
np->base = ioremap(addr, np->register_size);
if (!np->base)
goto out_relreg;
- dev->base_addr = (unsigned long)np->base;
-
- dev->irq = pci_dev->irq;
np->rx_ring_size = RX_RING_DEFAULT;
np->tx_ring_size = TX_RING_DEFAULT;
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
index 6dfc26d..d3469d8 100644
--- a/drivers/net/ethernet/nxp/lpc_eth.c
+++ b/drivers/net/ethernet/nxp/lpc_eth.c
@@ -990,10 +990,10 @@
ndev->stats.rx_errors++;
} else {
/* Packet is good */
- skb = dev_alloc_skb(len + 8);
- if (!skb)
+ skb = dev_alloc_skb(len);
+ if (!skb) {
ndev->stats.rx_dropped++;
- else {
+ } else {
prdbuf = skb_put(skb, len);
/* Copy packet from buffer */
diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c
index 0d29f5f..c236715 100644
--- a/drivers/net/ethernet/packetengines/hamachi.c
+++ b/drivers/net/ethernet/packetengines/hamachi.c
@@ -683,8 +683,6 @@
}
hmp->base = ioaddr;
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
pci_set_drvdata(pdev, dev);
hmp->chip_id = chip_id;
@@ -859,14 +857,11 @@
u32 rx_int_var, tx_int_var;
u16 fifo_info;
- i = request_irq(dev->irq, hamachi_interrupt, IRQF_SHARED, dev->name, dev);
+ i = request_irq(hmp->pci_dev->irq, hamachi_interrupt, IRQF_SHARED,
+ dev->name, dev);
if (i)
return i;
- if (hamachi_debug > 1)
- printk(KERN_DEBUG "%s: hamachi_open() irq %d.\n",
- dev->name, dev->irq);
-
hamachi_init_ring(dev);
#if ADDRLEN == 64
@@ -1705,7 +1700,7 @@
}
#endif /* __i386__ debugging only */
- free_irq(dev->irq, dev);
+ free_irq(hmp->pci_dev->irq, dev);
del_timer_sync(&hmp->timer);
diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c
index 7757b80..04e622f 100644
--- a/drivers/net/ethernet/packetengines/yellowfin.c
+++ b/drivers/net/ethernet/packetengines/yellowfin.c
@@ -427,9 +427,6 @@
/* Reset the chip. */
iowrite32(0x80000000, ioaddr + DMACtrl);
- dev->base_addr = (unsigned long)ioaddr;
- dev->irq = irq;
-
pci_set_drvdata(pdev, dev);
spin_lock_init(&np->lock);
@@ -569,25 +566,20 @@
static int yellowfin_open(struct net_device *dev)
{
struct yellowfin_private *yp = netdev_priv(dev);
+ const int irq = yp->pci_dev->irq;
void __iomem *ioaddr = yp->base;
- int i, ret;
+ int i, rc;
/* Reset the chip. */
iowrite32(0x80000000, ioaddr + DMACtrl);
- ret = request_irq(dev->irq, yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
- if (ret)
- return ret;
+ rc = request_irq(irq, yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
+ if (rc)
+ return rc;
- if (yellowfin_debug > 1)
- netdev_printk(KERN_DEBUG, dev, "%s() irq %d\n",
- __func__, dev->irq);
-
- ret = yellowfin_init_ring(dev);
- if (ret) {
- free_irq(dev->irq, dev);
- return ret;
- }
+ rc = yellowfin_init_ring(dev);
+ if (rc < 0)
+ goto err_free_irq;
iowrite32(yp->rx_ring_dma, ioaddr + RxPtr);
iowrite32(yp->tx_ring_dma, ioaddr + TxPtr);
@@ -647,8 +639,12 @@
yp->timer.data = (unsigned long)dev;
yp->timer.function = yellowfin_timer; /* timer handler */
add_timer(&yp->timer);
+out:
+ return rc;
- return 0;
+err_free_irq:
+ free_irq(irq, dev);
+ goto out;
}
static void yellowfin_timer(unsigned long data)
@@ -1251,7 +1247,7 @@
}
#endif /* __i386__ debugging only */
- free_irq(dev->irq, dev);
+ free_irq(yp->pci_dev->irq, dev);
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
index b96e192..a26307f 100644
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -973,6 +973,7 @@
.get_settings = netdev_get_settings,
.set_settings = netdev_set_settings,
.get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static const struct net_device_ops r6040_netdev_ops = {
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index abc7907..69c7d69 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -635,9 +635,12 @@
*/
static void cp_poll_controller(struct net_device *dev)
{
- disable_irq(dev->irq);
- cp_interrupt(dev->irq, dev);
- enable_irq(dev->irq);
+ struct cp_private *cp = netdev_priv(dev);
+ const int irq = cp->pdev->irq;
+
+ disable_irq(irq);
+ cp_interrupt(irq, dev);
+ enable_irq(irq);
}
#endif
@@ -1114,6 +1117,7 @@
static int cp_open (struct net_device *dev)
{
struct cp_private *cp = netdev_priv(dev);
+ const int irq = cp->pdev->irq;
int rc;
netif_dbg(cp, ifup, dev, "enabling interface\n");
@@ -1126,7 +1130,7 @@
cp_init_hw(cp);
- rc = request_irq(dev->irq, cp_interrupt, IRQF_SHARED, dev->name, dev);
+ rc = request_irq(irq, cp_interrupt, IRQF_SHARED, dev->name, dev);
if (rc)
goto err_out_hw;
@@ -1161,7 +1165,7 @@
spin_unlock_irqrestore(&cp->lock, flags);
- free_irq(dev->irq, dev);
+ free_irq(cp->pdev->irq, dev);
cp_free_rings(cp);
return 0;
@@ -1909,7 +1913,6 @@
(unsigned long long)pciaddr);
goto err_out_res;
}
- dev->base_addr = (unsigned long) regs;
cp->regs = regs;
cp_stop_hw(cp);
@@ -1937,14 +1940,12 @@
dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
NETIF_F_HIGHDMA;
- dev->irq = pdev->irq;
-
rc = register_netdev(dev);
if (rc)
goto err_out_iomap;
- netdev_info(dev, "RTL-8139C+ at 0x%lx, %pM, IRQ %d\n",
- dev->base_addr, dev->dev_addr, dev->irq);
+ netdev_info(dev, "RTL-8139C+ at 0x%p, %pM, IRQ %d\n",
+ regs, dev->dev_addr, pdev->irq);
pci_set_drvdata(pdev, dev);
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index df7fd8d..03df076 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -148,9 +148,9 @@
/* Whether to use MMIO or PIO. Default to MMIO. */
#ifdef CONFIG_8139TOO_PIO
-static int use_io = 1;
+static bool use_io = true;
#else
-static int use_io = 0;
+static bool use_io = false;
#endif
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
@@ -620,7 +620,7 @@
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
-module_param(use_io, int, 0);
+module_param(use_io, bool, 0);
MODULE_PARM_DESC(use_io, "Force use of I/O access mode. 0=MMIO 1=PIO");
module_param(multicast_filter_limit, int, 0);
module_param_array(media, int, NULL, 0);
@@ -750,15 +750,22 @@
static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
{
+ struct device *d = &pdev->dev;
void __iomem *ioaddr;
struct net_device *dev;
struct rtl8139_private *tp;
u8 tmp8;
int rc, disable_dev_on_err = 0;
- unsigned int i;
- unsigned long pio_start, pio_end, pio_flags, pio_len;
- unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
+ unsigned int i, bar;
+ unsigned long io_len;
u32 version;
+ static const struct {
+ unsigned long mask;
+ char *type;
+ } res[] = {
+ { IORESOURCE_IO, "PIO" },
+ { IORESOURCE_MEM, "MMIO" }
+ };
assert (pdev != NULL);
@@ -777,78 +784,45 @@
if (rc)
goto err_out;
- pio_start = pci_resource_start (pdev, 0);
- pio_end = pci_resource_end (pdev, 0);
- pio_flags = pci_resource_flags (pdev, 0);
- pio_len = pci_resource_len (pdev, 0);
-
- mmio_start = pci_resource_start (pdev, 1);
- mmio_end = pci_resource_end (pdev, 1);
- mmio_flags = pci_resource_flags (pdev, 1);
- mmio_len = pci_resource_len (pdev, 1);
-
- /* set this immediately, we need to know before
- * we talk to the chip directly */
- pr_debug("PIO region size == 0x%02lX\n", pio_len);
- pr_debug("MMIO region size == 0x%02lX\n", mmio_len);
-
-retry:
- if (use_io) {
- /* make sure PCI base addr 0 is PIO */
- if (!(pio_flags & IORESOURCE_IO)) {
- dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- /* check for weird/broken PCI region reporting */
- if (pio_len < RTL_MIN_IO_SIZE) {
- dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- } else {
- /* make sure PCI base addr 1 is MMIO */
- if (!(mmio_flags & IORESOURCE_MEM)) {
- dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- if (mmio_len < RTL_MIN_IO_SIZE) {
- dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
- rc = -ENODEV;
- goto err_out;
- }
- }
-
rc = pci_request_regions (pdev, DRV_NAME);
if (rc)
goto err_out;
disable_dev_on_err = 1;
- /* enable PCI bus-mastering */
pci_set_master (pdev);
- if (use_io) {
- ioaddr = pci_iomap(pdev, 0, 0);
- if (!ioaddr) {
- dev_err(&pdev->dev, "cannot map PIO, aborting\n");
- rc = -EIO;
- goto err_out;
- }
- dev->base_addr = pio_start;
- tp->regs_len = pio_len;
- } else {
- /* ioremap MMIO region */
- ioaddr = pci_iomap(pdev, 1, 0);
- if (ioaddr == NULL) {
- dev_err(&pdev->dev, "cannot remap MMIO, trying PIO\n");
- pci_release_regions(pdev);
- use_io = 1;
+retry:
+ /* PIO bar register comes first. */
+ bar = !use_io;
+
+ io_len = pci_resource_len(pdev, bar);
+
+ dev_dbg(d, "%s region size = 0x%02lX\n", res[bar].type, io_len);
+
+ if (!(pci_resource_flags(pdev, bar) & res[bar].mask)) {
+ dev_err(d, "region #%d not a %s resource, aborting\n", bar,
+ res[bar].type);
+ rc = -ENODEV;
+ goto err_out;
+ }
+ if (io_len < RTL_MIN_IO_SIZE) {
+ dev_err(d, "Invalid PCI %s region size(s), aborting\n",
+ res[bar].type);
+ rc = -ENODEV;
+ goto err_out;
+ }
+
+ ioaddr = pci_iomap(pdev, bar, 0);
+ if (!ioaddr) {
+ dev_err(d, "cannot map %s\n", res[bar].type);
+ if (!use_io) {
+ use_io = true;
goto retry;
}
- dev->base_addr = (long) ioaddr;
- tp->regs_len = mmio_len;
+ rc = -ENODEV;
+ goto err_out;
}
+ tp->regs_len = io_len;
tp->mmio_addr = ioaddr;
/* Bring old chips out of low-power mode. */
@@ -1035,8 +1009,6 @@
dev->hw_features |= NETIF_F_RXALL;
dev->hw_features |= NETIF_F_RXFCS;
- dev->irq = pdev->irq;
-
/* tp zeroed and aligned in alloc_etherdev */
tp = netdev_priv(dev);
@@ -1062,9 +1034,9 @@
pci_set_drvdata (pdev, dev);
- netdev_info(dev, "%s at 0x%lx, %pM, IRQ %d\n",
+ netdev_info(dev, "%s at 0x%p, %pM, IRQ %d\n",
board_info[ent->driver_data].name,
- dev->base_addr, dev->dev_addr, dev->irq);
+ ioaddr, dev->dev_addr, pdev->irq);
netdev_dbg(dev, "Identified 8139 chip type '%s'\n",
rtl_chip_info[tp->chipset].name);
@@ -1339,10 +1311,11 @@
static int rtl8139_open (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
- int retval;
void __iomem *ioaddr = tp->mmio_addr;
+ const int irq = tp->pci_dev->irq;
+ int retval;
- retval = request_irq (dev->irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);
+ retval = request_irq(irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);
if (retval)
return retval;
@@ -1351,7 +1324,7 @@
tp->rx_ring = dma_alloc_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
&tp->rx_ring_dma, GFP_KERNEL);
if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
- free_irq(dev->irq, dev);
+ free_irq(irq, dev);
if (tp->tx_bufs)
dma_free_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
@@ -1377,7 +1350,7 @@
"%s() ioaddr %#llx IRQ %d GP Pins %02x %s-duplex\n",
__func__,
(unsigned long long)pci_resource_start (tp->pci_dev, 1),
- dev->irq, RTL_R8 (MediaStatus),
+ irq, RTL_R8 (MediaStatus),
tp->mii.full_duplex ? "full" : "half");
rtl8139_start_thread(tp);
@@ -2240,9 +2213,12 @@
*/
static void rtl8139_poll_controller(struct net_device *dev)
{
- disable_irq(dev->irq);
- rtl8139_interrupt(dev->irq, dev);
- enable_irq(dev->irq);
+ struct rtl8139_private *tp = netdev_priv(dev);
+ const int irq = tp->pci_dev->irq;
+
+ disable_irq(irq);
+ rtl8139_interrupt(irq, dev);
+ enable_irq(irq);
}
#endif
@@ -2295,7 +2271,7 @@
spin_unlock_irqrestore (&tp->lock, flags);
- free_irq (dev->irq, dev);
+ free_irq(tp->pci_dev->irq, dev);
rtl8139_tx_clear (tp);
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index f545093..71393ea 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -1853,6 +1853,7 @@
.get_strings = rtl8169_get_strings,
.get_sset_count = rtl8169_get_sset_count,
.get_ethtool_stats = rtl8169_get_ethtool_stats,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static void rtl8169_get_mac_version(struct rtl8169_private *tp,
diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig
index 3fb2355..46df3a0 100644
--- a/drivers/net/ethernet/renesas/Kconfig
+++ b/drivers/net/ethernet/renesas/Kconfig
@@ -4,11 +4,11 @@
config SH_ETH
tristate "Renesas SuperH Ethernet support"
- depends on SUPERH && \
+ depends on (SUPERH || ARCH_SHMOBILE) && \
(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \
- CPU_SUBTYPE_SH7757)
+ CPU_SUBTYPE_SH7757 || ARCH_R8A7740)
select CRC32
select NET_CORE
select MII
@@ -17,4 +17,5 @@
---help---
Renesas SuperH Ethernet device driver.
This driver supporting CPUs are:
- - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763 and SH7757.
+ - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757,
+ and R8A7740.
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index d63e09b..be3c221 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -386,6 +386,114 @@
sh_eth_write(ndev, 0x0, CSMR);
}
+#elif defined(CONFIG_ARCH_R8A7740)
+#define SH_ETH_HAS_TSU 1
+static void sh_eth_chip_reset(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ unsigned long mii;
+
+ /* reset device */
+ sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
+ mdelay(1);
+
+ switch (mdp->phy_interface) {
+ case PHY_INTERFACE_MODE_GMII:
+ mii = 2;
+ break;
+ case PHY_INTERFACE_MODE_MII:
+ mii = 1;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ default:
+ mii = 0;
+ break;
+ }
+ sh_eth_write(ndev, mii, RMII_MII);
+}
+
+static void sh_eth_reset(struct net_device *ndev)
+{
+ int cnt = 100;
+
+ sh_eth_write(ndev, EDSR_ENALL, EDSR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
+ while (cnt > 0) {
+ if (!(sh_eth_read(ndev, EDMR) & 0x3))
+ break;
+ mdelay(1);
+ cnt--;
+ }
+ if (cnt == 0)
+ printk(KERN_ERR "Device reset fail\n");
+
+ /* Table Init */
+ sh_eth_write(ndev, 0x0, TDLAR);
+ sh_eth_write(ndev, 0x0, TDFAR);
+ sh_eth_write(ndev, 0x0, TDFXR);
+ sh_eth_write(ndev, 0x0, TDFFR);
+ sh_eth_write(ndev, 0x0, RDLAR);
+ sh_eth_write(ndev, 0x0, RDFAR);
+ sh_eth_write(ndev, 0x0, RDFXR);
+ sh_eth_write(ndev, 0x0, RDFFR);
+}
+
+static void sh_eth_set_duplex(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ if (mdp->duplex) /* Full */
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
+ else /* Half */
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
+}
+
+static void sh_eth_set_rate(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ switch (mdp->speed) {
+ case 10: /* 10BASE */
+ sh_eth_write(ndev, GECMR_10, GECMR);
+ break;
+ case 100:/* 100BASE */
+ sh_eth_write(ndev, GECMR_100, GECMR);
+ break;
+ case 1000: /* 1000BASE */
+ sh_eth_write(ndev, GECMR_1000, GECMR);
+ break;
+ default:
+ break;
+ }
+}
+
+/* R8A7740 */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+ .chip_reset = sh_eth_chip_reset,
+ .set_duplex = sh_eth_set_duplex,
+ .set_rate = sh_eth_set_rate,
+
+ .ecsr_value = ECSR_ICD | ECSR_MPD,
+ .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
+ .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+
+ .tx_check = EESR_TC1 | EESR_FTC,
+ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
+ EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
+ EESR_ECI,
+ .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
+ EESR_TFE,
+
+ .apr = 1,
+ .mpr = 1,
+ .tpauser = 1,
+ .bculr = 1,
+ .hw_swap = 1,
+ .no_trimd = 1,
+ .no_ade = 1,
+ .tsu = 1,
+};
+
#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
#define SH_ETH_RESET_DEFAULT 1
static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
@@ -443,7 +551,7 @@
}
#endif
-#if defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
static void sh_eth_set_receive_align(struct sk_buff *skb)
{
int reserve;
@@ -919,6 +1027,10 @@
desc_status = edmac_to_cpu(mdp, rxdesc->status);
pkt_len = rxdesc->frame_length;
+#if defined(CONFIG_ARCH_R8A7740)
+ desc_status >>= 16;
+#endif
+
if (--boguscnt < 0)
break;
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 0fa14afc..57b8e1f 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -372,7 +372,7 @@
};
/* Driver's parameters */
-#if defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
#define SH4_SKB_RX_ALIGN 32
#else
#define SH2_SH3_SKB_RX_ALIGN 2
@@ -381,7 +381,8 @@
/*
* Register's bits
*/
-#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
+#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763) ||\
+ defined(CONFIG_ARCH_R8A7740)
/* EDSR */
enum EDSR_BIT {
EDSR_ENT = 0x01, EDSR_ENR = 0x02,
diff --git a/drivers/net/ethernet/silan/sc92031.c b/drivers/net/ethernet/silan/sc92031.c
index a284d64..32e5566 100644
--- a/drivers/net/ethernet/silan/sc92031.c
+++ b/drivers/net/ethernet/silan/sc92031.c
@@ -39,9 +39,7 @@
#define SC92031_NAME "sc92031"
/* BAR 0 is MMIO, BAR 1 is PIO */
-#ifndef SC92031_USE_BAR
-#define SC92031_USE_BAR 0
-#endif
+#define SC92031_USE_PIO 0
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). */
static int multicast_filter_limit = 64;
@@ -366,7 +364,7 @@
mmiowb();
/* wait for any concurrent interrupt/tasklet to finish */
- synchronize_irq(dev->irq);
+ synchronize_irq(priv->pdev->irq);
tasklet_disable(&priv->tasklet);
}
@@ -1114,10 +1112,13 @@
#ifdef CONFIG_NET_POLL_CONTROLLER
static void sc92031_poll_controller(struct net_device *dev)
{
- disable_irq(dev->irq);
- if (sc92031_interrupt(dev->irq, dev) != IRQ_NONE)
+ struct sc92031_priv *priv = netdev_priv(dev);
+ const int irq = priv->pdev->irq;
+
+ disable_irq(irq);
+ if (sc92031_interrupt(irq, dev) != IRQ_NONE)
sc92031_tasklet((unsigned long)dev);
- enable_irq(dev->irq);
+ enable_irq(irq);
}
#endif
@@ -1402,7 +1403,6 @@
struct net_device *dev;
struct sc92031_priv *priv;
u32 mac0, mac1;
- unsigned long base_addr;
err = pci_enable_device(pdev);
if (unlikely(err < 0))
@@ -1422,7 +1422,7 @@
if (unlikely(err < 0))
goto out_request_regions;
- port_base = pci_iomap(pdev, SC92031_USE_BAR, 0);
+ port_base = pci_iomap(pdev, SC92031_USE_PIO, 0);
if (unlikely(!port_base)) {
err = -EIO;
goto out_iomap;
@@ -1437,14 +1437,6 @@
pci_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
-#if SC92031_USE_BAR == 0
- dev->mem_start = pci_resource_start(pdev, SC92031_USE_BAR);
- dev->mem_end = pci_resource_end(pdev, SC92031_USE_BAR);
-#elif SC92031_USE_BAR == 1
- dev->base_addr = pci_resource_start(pdev, SC92031_USE_BAR);
-#endif
- dev->irq = pdev->irq;
-
/* faked with skb_copy_and_csum_dev */
dev->features = NETIF_F_SG | NETIF_F_HIGHDMA |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
@@ -1478,13 +1470,9 @@
if (err < 0)
goto out_register_netdev;
-#if SC92031_USE_BAR == 0
- base_addr = dev->mem_start;
-#elif SC92031_USE_BAR == 1
- base_addr = dev->base_addr;
-#endif
printk(KERN_INFO "%s: SC92031 at 0x%lx, %pM, IRQ %d\n", dev->name,
- base_addr, dev->dev_addr, dev->irq);
+ (long)pci_resource_start(pdev, SC92031_USE_PIO), dev->dev_addr,
+ pdev->irq);
return 0;
diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c
index a9deda8..4613591 100644
--- a/drivers/net/ethernet/sis/sis190.c
+++ b/drivers/net/ethernet/sis/sis190.c
@@ -729,7 +729,7 @@
* The interrupt handler does all of the Rx thread work and cleans up after
* the Tx thread.
*/
-static irqreturn_t sis190_interrupt(int irq, void *__dev)
+static irqreturn_t sis190_irq(int irq, void *__dev)
{
struct net_device *dev = __dev;
struct sis190_private *tp = netdev_priv(dev);
@@ -772,11 +772,11 @@
static void sis190_netpoll(struct net_device *dev)
{
struct sis190_private *tp = netdev_priv(dev);
- struct pci_dev *pdev = tp->pci_dev;
+ const int irq = tp->pci_dev->irq;
- disable_irq(pdev->irq);
- sis190_interrupt(pdev->irq, dev);
- enable_irq(pdev->irq);
+ disable_irq(irq);
+ sis190_irq(irq, dev);
+ enable_irq(irq);
}
#endif
@@ -1085,7 +1085,7 @@
sis190_request_timer(dev);
- rc = request_irq(dev->irq, sis190_interrupt, IRQF_SHARED, dev->name, dev);
+ rc = request_irq(pdev->irq, sis190_irq, IRQF_SHARED, dev->name, dev);
if (rc < 0)
goto err_release_timer_2;
@@ -1097,11 +1097,9 @@
sis190_delete_timer(dev);
sis190_rx_clear(tp);
err_free_rx_1:
- pci_free_consistent(tp->pci_dev, RX_RING_BYTES, tp->RxDescRing,
- tp->rx_dma);
+ pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
err_free_tx_0:
- pci_free_consistent(tp->pci_dev, TX_RING_BYTES, tp->TxDescRing,
- tp->tx_dma);
+ pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
goto out;
}
@@ -1141,7 +1139,7 @@
spin_unlock_irq(&tp->lock);
- synchronize_irq(dev->irq);
+ synchronize_irq(tp->pci_dev->irq);
if (!poll_locked)
poll_locked++;
@@ -1161,7 +1159,7 @@
sis190_down(dev);
- free_irq(dev->irq, dev);
+ free_irq(pdev->irq, dev);
pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
@@ -1884,8 +1882,6 @@
dev->netdev_ops = &sis190_netdev_ops;
SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
- dev->irq = pdev->irq;
- dev->base_addr = (unsigned long) 0xdead;
dev->watchdog_timeo = SIS190_TX_TIMEOUT;
spin_lock_init(&tp->lock);
@@ -1902,7 +1898,7 @@
netdev_info(dev, "%s: %s at %p (IRQ: %d), %pM\n",
pci_name(pdev),
sis_chip_info[ent->driver_data].name,
- ioaddr, dev->irq, dev->dev_addr);
+ ioaddr, pdev->irq, dev->dev_addr);
netdev_info(dev, "%s mode.\n",
(tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
}
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index 5ccf02e..203d9c6 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -168,6 +168,8 @@
unsigned int cur_phy;
struct mii_if_info mii_info;
+ void __iomem *ioaddr;
+
struct timer_list timer; /* Link status detection timer. */
u8 autong_complete; /* 1: auto-negotiate complete */
@@ -201,13 +203,18 @@
MODULE_PARM_DESC(max_interrupt_work, "SiS 900/7016 maximum events handled per interrupt");
MODULE_PARM_DESC(sis900_debug, "SiS 900/7016 bitmapped debugging message level");
+#define sw32(reg, val) iowrite32(val, ioaddr + (reg))
+#define sw8(reg, val) iowrite8(val, ioaddr + (reg))
+#define sr32(reg) ioread32(ioaddr + (reg))
+#define sr16(reg) ioread16(ioaddr + (reg))
+
#ifdef CONFIG_NET_POLL_CONTROLLER
static void sis900_poll(struct net_device *dev);
#endif
static int sis900_open(struct net_device *net_dev);
static int sis900_mii_probe (struct net_device * net_dev);
static void sis900_init_rxfilter (struct net_device * net_dev);
-static u16 read_eeprom(long ioaddr, int location);
+static u16 read_eeprom(void __iomem *ioaddr, int location);
static int mdio_read(struct net_device *net_dev, int phy_id, int location);
static void mdio_write(struct net_device *net_dev, int phy_id, int location, int val);
static void sis900_timer(unsigned long data);
@@ -231,7 +238,7 @@
static void sis900_set_capability( struct net_device *net_dev ,struct mii_phy *phy);
static u16 sis900_reset_phy(struct net_device *net_dev, int phy_addr);
static void sis900_auto_negotiate(struct net_device *net_dev, int phy_addr);
-static void sis900_set_mode (long ioaddr, int speed, int duplex);
+static void sis900_set_mode(struct sis900_private *, int speed, int duplex);
static const struct ethtool_ops sis900_ethtool_ops;
/**
@@ -246,7 +253,8 @@
static int __devinit sis900_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev)
{
- long ioaddr = pci_resource_start(pci_dev, 0);
+ struct sis900_private *sis_priv = netdev_priv(net_dev);
+ void __iomem *ioaddr = sis_priv->ioaddr;
u16 signature;
int i;
@@ -325,29 +333,30 @@
static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev,
struct net_device *net_dev)
{
- long ioaddr = net_dev->base_addr;
+ struct sis900_private *sis_priv = netdev_priv(net_dev);
+ void __iomem *ioaddr = sis_priv->ioaddr;
u32 rfcrSave;
u32 i;
- rfcrSave = inl(rfcr + ioaddr);
+ rfcrSave = sr32(rfcr);
- outl(rfcrSave | RELOAD, ioaddr + cr);
- outl(0, ioaddr + cr);
+ sw32(cr, rfcrSave | RELOAD);
+ sw32(cr, 0);
/* disable packet filtering before setting filter */
- outl(rfcrSave & ~RFEN, rfcr + ioaddr);
+ sw32(rfcr, rfcrSave & ~RFEN);
/* load MAC addr to filter data register */
for (i = 0 ; i < 3 ; i++) {
- outl((i << RFADDR_shift), ioaddr + rfcr);
- *( ((u16 *)net_dev->dev_addr) + i) = inw(ioaddr + rfdr);
+ sw32(rfcr, (i << RFADDR_shift));
+ *( ((u16 *)net_dev->dev_addr) + i) = sr16(rfdr);
}
/* Store MAC Address in perm_addr */
memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN);
/* enable packet filtering */
- outl(rfcrSave | RFEN, rfcr + ioaddr);
+ sw32(rfcr, rfcrSave | RFEN);
return 1;
}
@@ -371,31 +380,30 @@
static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev,
struct net_device *net_dev)
{
- long ioaddr = net_dev->base_addr;
- long ee_addr = ioaddr + mear;
- u32 waittime = 0;
- int i;
+ struct sis900_private *sis_priv = netdev_priv(net_dev);
+ void __iomem *ioaddr = sis_priv->ioaddr;
+ int wait, rc = 0;
- outl(EEREQ, ee_addr);
- while(waittime < 2000) {
- if(inl(ee_addr) & EEGNT) {
+ sw32(mear, EEREQ);
+ for (wait = 0; wait < 2000; wait++) {
+ if (sr32(mear) & EEGNT) {
+ u16 *mac = (u16 *)net_dev->dev_addr;
+ int i;
/* get MAC address from EEPROM */
for (i = 0; i < 3; i++)
- ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr);
+ mac[i] = read_eeprom(ioaddr, i + EEPROMMACAddr);
/* Store MAC Address in perm_addr */
memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN);
- outl(EEDONE, ee_addr);
- return 1;
- } else {
- udelay(1);
- waittime ++;
+ rc = 1;
+ break;
}
+ udelay(1);
}
- outl(EEDONE, ee_addr);
- return 0;
+ sw32(mear, EEDONE);
+ return rc;
}
static const struct net_device_ops sis900_netdev_ops = {
@@ -433,7 +441,7 @@
struct pci_dev *dev;
dma_addr_t ring_dma;
void *ring_space;
- long ioaddr;
+ void __iomem *ioaddr;
int i, ret;
const char *card_name = card_names[pci_id->driver_data];
const char *dev_name = pci_name(pci_dev);
@@ -464,14 +472,17 @@
SET_NETDEV_DEV(net_dev, &pci_dev->dev);
/* We do a request_region() to register /proc/ioports info. */
- ioaddr = pci_resource_start(pci_dev, 0);
ret = pci_request_regions(pci_dev, "sis900");
if (ret)
goto err_out;
+ /* IO region. */
+ ioaddr = pci_iomap(pci_dev, 0, 0);
+ if (!ioaddr)
+ goto err_out_cleardev;
+
sis_priv = netdev_priv(net_dev);
- net_dev->base_addr = ioaddr;
- net_dev->irq = pci_dev->irq;
+ sis_priv->ioaddr = ioaddr;
sis_priv->pci_dev = pci_dev;
spin_lock_init(&sis_priv->lock);
@@ -480,7 +491,7 @@
ring_space = pci_alloc_consistent(pci_dev, TX_TOTAL_SIZE, &ring_dma);
if (!ring_space) {
ret = -ENOMEM;
- goto err_out_cleardev;
+ goto err_out_unmap;
}
sis_priv->tx_ring = ring_space;
sis_priv->tx_ring_dma = ring_dma;
@@ -534,7 +545,7 @@
/* 630ET : set the mii access mode as software-mode */
if (sis_priv->chipset_rev == SIS630ET_900_REV)
- outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr);
+ sw32(cr, ACCESSMODE | sr32(cr));
/* probe for mii transceiver */
if (sis900_mii_probe(net_dev) == 0) {
@@ -556,25 +567,27 @@
goto err_unmap_rx;
/* print some information about our NIC */
- printk(KERN_INFO "%s: %s at %#lx, IRQ %d, %pM\n",
- net_dev->name, card_name, ioaddr, net_dev->irq,
+ printk(KERN_INFO "%s: %s at 0x%p, IRQ %d, %pM\n",
+ net_dev->name, card_name, ioaddr, pci_dev->irq,
net_dev->dev_addr);
/* Detect Wake on Lan support */
- ret = (inl(net_dev->base_addr + CFGPMC) & PMESP) >> 27;
+ ret = (sr32(CFGPMC) & PMESP) >> 27;
if (netif_msg_probe(sis_priv) && (ret & PME_D3C) == 0)
printk(KERN_INFO "%s: Wake on LAN only available from suspend to RAM.", net_dev->name);
return 0;
- err_unmap_rx:
+err_unmap_rx:
pci_free_consistent(pci_dev, RX_TOTAL_SIZE, sis_priv->rx_ring,
sis_priv->rx_ring_dma);
- err_unmap_tx:
+err_unmap_tx:
pci_free_consistent(pci_dev, TX_TOTAL_SIZE, sis_priv->tx_ring,
sis_priv->tx_ring_dma);
- err_out_cleardev:
- pci_set_drvdata(pci_dev, NULL);
+err_out_unmap:
+ pci_iounmap(pci_dev, ioaddr);
+err_out_cleardev:
+ pci_set_drvdata(pci_dev, NULL);
pci_release_regions(pci_dev);
err_out:
free_netdev(net_dev);
@@ -798,7 +811,7 @@
/* Delay between EEPROM clock transitions. */
-#define eeprom_delay() inl(ee_addr)
+#define eeprom_delay() sr32(mear)
/**
* read_eeprom - Read Serial EEPROM
@@ -809,41 +822,41 @@
* Note that location is in word (16 bits) unit
*/
-static u16 __devinit read_eeprom(long ioaddr, int location)
+static u16 __devinit read_eeprom(void __iomem *ioaddr, int location)
{
+ u32 read_cmd = location | EEread;
int i;
u16 retval = 0;
- long ee_addr = ioaddr + mear;
- u32 read_cmd = location | EEread;
- outl(0, ee_addr);
+ sw32(mear, 0);
eeprom_delay();
- outl(EECS, ee_addr);
+ sw32(mear, EECS);
eeprom_delay();
/* Shift the read command (9) bits out. */
for (i = 8; i >= 0; i--) {
u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS;
- outl(dataval, ee_addr);
+
+ sw32(mear, dataval);
eeprom_delay();
- outl(dataval | EECLK, ee_addr);
+ sw32(mear, dataval | EECLK);
eeprom_delay();
}
- outl(EECS, ee_addr);
+ sw32(mear, EECS);
eeprom_delay();
/* read the 16-bits data in */
for (i = 16; i > 0; i--) {
- outl(EECS, ee_addr);
+ sw32(mear, EECS);
eeprom_delay();
- outl(EECS | EECLK, ee_addr);
+ sw32(mear, EECS | EECLK);
eeprom_delay();
- retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0);
+ retval = (retval << 1) | ((sr32(mear) & EEDO) ? 1 : 0);
eeprom_delay();
}
/* Terminate the EEPROM access. */
- outl(0, ee_addr);
+ sw32(mear, 0);
eeprom_delay();
return retval;
@@ -852,24 +865,27 @@
/* Read and write the MII management registers using software-generated
serial MDIO protocol. Note that the command bits and data bits are
send out separately */
-#define mdio_delay() inl(mdio_addr)
+#define mdio_delay() sr32(mear)
-static void mdio_idle(long mdio_addr)
+static void mdio_idle(struct sis900_private *sp)
{
- outl(MDIO | MDDIR, mdio_addr);
+ void __iomem *ioaddr = sp->ioaddr;
+
+ sw32(mear, MDIO | MDDIR);
mdio_delay();
- outl(MDIO | MDDIR | MDC, mdio_addr);
+ sw32(mear, MDIO | MDDIR | MDC);
}
-/* Syncronize the MII management interface by shifting 32 one bits out. */
-static void mdio_reset(long mdio_addr)
+/* Synchronize the MII management interface by shifting 32 one bits out. */
+static void mdio_reset(struct sis900_private *sp)
{
+ void __iomem *ioaddr = sp->ioaddr;
int i;
for (i = 31; i >= 0; i--) {
- outl(MDDIR | MDIO, mdio_addr);
+ sw32(mear, MDDIR | MDIO);
mdio_delay();
- outl(MDDIR | MDIO | MDC, mdio_addr);
+ sw32(mear, MDDIR | MDIO | MDC);
mdio_delay();
}
}
@@ -887,31 +903,33 @@
static int mdio_read(struct net_device *net_dev, int phy_id, int location)
{
- long mdio_addr = net_dev->base_addr + mear;
int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
+ struct sis900_private *sp = netdev_priv(net_dev);
+ void __iomem *ioaddr = sp->ioaddr;
u16 retval = 0;
int i;
- mdio_reset(mdio_addr);
- mdio_idle(mdio_addr);
+ mdio_reset(sp);
+ mdio_idle(sp);
for (i = 15; i >= 0; i--) {
int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
- outl(dataval, mdio_addr);
+
+ sw32(mear, dataval);
mdio_delay();
- outl(dataval | MDC, mdio_addr);
+ sw32(mear, dataval | MDC);
mdio_delay();
}
/* Read the 16 data bits. */
for (i = 16; i > 0; i--) {
- outl(0, mdio_addr);
+ sw32(mear, 0);
mdio_delay();
- retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0);
- outl(MDC, mdio_addr);
+ retval = (retval << 1) | ((sr32(mear) & MDIO) ? 1 : 0);
+ sw32(mear, MDC);
mdio_delay();
}
- outl(0x00, mdio_addr);
+ sw32(mear, 0x00);
return retval;
}
@@ -931,19 +949,21 @@
static void mdio_write(struct net_device *net_dev, int phy_id, int location,
int value)
{
- long mdio_addr = net_dev->base_addr + mear;
int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
+ struct sis900_private *sp = netdev_priv(net_dev);
+ void __iomem *ioaddr = sp->ioaddr;
int i;
- mdio_reset(mdio_addr);
- mdio_idle(mdio_addr);
+ mdio_reset(sp);
+ mdio_idle(sp);
/* Shift the command bits out. */
for (i = 15; i >= 0; i--) {
int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
- outb(dataval, mdio_addr);
+
+ sw8(mear, dataval);
mdio_delay();
- outb(dataval | MDC, mdio_addr);
+ sw8(mear, dataval | MDC);
mdio_delay();
}
mdio_delay();
@@ -951,21 +971,22 @@
/* Shift the value bits out. */
for (i = 15; i >= 0; i--) {
int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR;
- outl(dataval, mdio_addr);
+
+ sw32(mear, dataval);
mdio_delay();
- outl(dataval | MDC, mdio_addr);
+ sw32(mear, dataval | MDC);
mdio_delay();
}
mdio_delay();
/* Clear out extra bits. */
for (i = 2; i > 0; i--) {
- outb(0, mdio_addr);
+ sw8(mear, 0);
mdio_delay();
- outb(MDC, mdio_addr);
+ sw8(mear, MDC);
mdio_delay();
}
- outl(0x00, mdio_addr);
+ sw32(mear, 0x00);
}
@@ -1000,9 +1021,12 @@
*/
static void sis900_poll(struct net_device *dev)
{
- disable_irq(dev->irq);
- sis900_interrupt(dev->irq, dev);
- enable_irq(dev->irq);
+ struct sis900_private *sp = netdev_priv(dev);
+ const int irq = sp->pci_dev->irq;
+
+ disable_irq(irq);
+ sis900_interrupt(irq, dev);
+ enable_irq(irq);
}
#endif
@@ -1018,7 +1042,7 @@
sis900_open(struct net_device *net_dev)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
int ret;
/* Soft reset the chip. */
@@ -1027,8 +1051,8 @@
/* Equalizer workaround Rule */
sis630_set_eq(net_dev, sis_priv->chipset_rev);
- ret = request_irq(net_dev->irq, sis900_interrupt, IRQF_SHARED,
- net_dev->name, net_dev);
+ ret = request_irq(sis_priv->pci_dev->irq, sis900_interrupt, IRQF_SHARED,
+ net_dev->name, net_dev);
if (ret)
return ret;
@@ -1042,12 +1066,12 @@
netif_start_queue(net_dev);
/* Workaround for EDB */
- sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
+ sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
/* Enable all known interrupts by setting the interrupt mask. */
- outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
- outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
- outl(IE, ioaddr + ier);
+ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
+ sw32(cr, RxENA | sr32(cr));
+ sw32(ier, IE);
sis900_check_mode(net_dev, sis_priv->mii);
@@ -1074,31 +1098,30 @@
sis900_init_rxfilter (struct net_device * net_dev)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
u32 rfcrSave;
u32 i;
- rfcrSave = inl(rfcr + ioaddr);
+ rfcrSave = sr32(rfcr);
/* disable packet filtering before setting filter */
- outl(rfcrSave & ~RFEN, rfcr + ioaddr);
+ sw32(rfcr, rfcrSave & ~RFEN);
/* load MAC addr to filter data register */
for (i = 0 ; i < 3 ; i++) {
- u32 w;
+ u32 w = (u32) *((u16 *)(net_dev->dev_addr)+i);
- w = (u32) *((u16 *)(net_dev->dev_addr)+i);
- outl((i << RFADDR_shift), ioaddr + rfcr);
- outl(w, ioaddr + rfdr);
+ sw32(rfcr, i << RFADDR_shift);
+ sw32(rfdr, w);
if (netif_msg_hw(sis_priv)) {
printk(KERN_DEBUG "%s: Receive Filter Addrss[%d]=%x\n",
- net_dev->name, i, inl(ioaddr + rfdr));
+ net_dev->name, i, sr32(rfdr));
}
}
/* enable packet filtering */
- outl(rfcrSave | RFEN, rfcr + ioaddr);
+ sw32(rfcr, rfcrSave | RFEN);
}
/**
@@ -1112,7 +1135,7 @@
sis900_init_tx_ring(struct net_device *net_dev)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
int i;
sis_priv->tx_full = 0;
@@ -1128,10 +1151,10 @@
}
/* load Transmit Descriptor Register */
- outl(sis_priv->tx_ring_dma, ioaddr + txdp);
+ sw32(txdp, sis_priv->tx_ring_dma);
if (netif_msg_hw(sis_priv))
printk(KERN_DEBUG "%s: TX descriptor register loaded with: %8.8x\n",
- net_dev->name, inl(ioaddr + txdp));
+ net_dev->name, sr32(txdp));
}
/**
@@ -1146,7 +1169,7 @@
sis900_init_rx_ring(struct net_device *net_dev)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
int i;
sis_priv->cur_rx = 0;
@@ -1181,10 +1204,10 @@
sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
/* load Receive Descriptor Register */
- outl(sis_priv->rx_ring_dma, ioaddr + rxdp);
+ sw32(rxdp, sis_priv->rx_ring_dma);
if (netif_msg_hw(sis_priv))
printk(KERN_DEBUG "%s: RX descriptor register loaded with: %8.8x\n",
- net_dev->name, inl(ioaddr + rxdp));
+ net_dev->name, sr32(rxdp));
}
/**
@@ -1298,7 +1321,7 @@
sis900_read_mode(net_dev, &speed, &duplex);
if (duplex){
- sis900_set_mode(net_dev->base_addr, speed, duplex);
+ sis900_set_mode(sis_priv, speed, duplex);
sis630_set_eq(net_dev, sis_priv->chipset_rev);
netif_start_queue(net_dev);
}
@@ -1359,25 +1382,25 @@
static void sis900_check_mode(struct net_device *net_dev, struct mii_phy *mii_phy)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
int speed, duplex;
if (mii_phy->phy_types == LAN) {
- outl(~EXD & inl(ioaddr + cfg), ioaddr + cfg);
+ sw32(cfg, ~EXD & sr32(cfg));
sis900_set_capability(net_dev , mii_phy);
sis900_auto_negotiate(net_dev, sis_priv->cur_phy);
} else {
- outl(EXD | inl(ioaddr + cfg), ioaddr + cfg);
+ sw32(cfg, EXD | sr32(cfg));
speed = HW_SPEED_HOME;
duplex = FDX_CAPABLE_HALF_SELECTED;
- sis900_set_mode(ioaddr, speed, duplex);
+ sis900_set_mode(sis_priv, speed, duplex);
sis_priv->autong_complete = 1;
}
}
/**
* sis900_set_mode - Set the media mode of mac register.
- * @ioaddr: the address of the device
+ * @sp: the device private data
* @speed : the transmit speed to be determined
* @duplex: the duplex mode to be determined
*
@@ -1388,11 +1411,12 @@
* double words.
*/
-static void sis900_set_mode (long ioaddr, int speed, int duplex)
+static void sis900_set_mode(struct sis900_private *sp, int speed, int duplex)
{
+ void __iomem *ioaddr = sp->ioaddr;
u32 tx_flags = 0, rx_flags = 0;
- if (inl(ioaddr + cfg) & EDB_MASTER_EN) {
+ if (sr32( cfg) & EDB_MASTER_EN) {
tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift) |
(TX_FILL_THRESH << TxFILLT_shift);
rx_flags = DMA_BURST_64 << RxMXDMA_shift;
@@ -1420,8 +1444,8 @@
rx_flags |= RxAJAB;
#endif
- outl (tx_flags, ioaddr + txcfg);
- outl (rx_flags, ioaddr + rxcfg);
+ sw32(txcfg, tx_flags);
+ sw32(rxcfg, rx_flags);
}
/**
@@ -1528,16 +1552,17 @@
static void sis900_tx_timeout(struct net_device *net_dev)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
unsigned long flags;
int i;
- if(netif_msg_tx_err(sis_priv))
+ if (netif_msg_tx_err(sis_priv)) {
printk(KERN_INFO "%s: Transmit timeout, status %8.8x %8.8x\n",
- net_dev->name, inl(ioaddr + cr), inl(ioaddr + isr));
+ net_dev->name, sr32(cr), sr32(isr));
+ }
/* Disable interrupts by clearing the interrupt mask. */
- outl(0x0000, ioaddr + imr);
+ sw32(imr, 0x0000);
/* use spinlock to prevent interrupt handler accessing buffer ring */
spin_lock_irqsave(&sis_priv->lock, flags);
@@ -1566,10 +1591,10 @@
net_dev->trans_start = jiffies; /* prevent tx timeout */
/* load Transmit Descriptor Register */
- outl(sis_priv->tx_ring_dma, ioaddr + txdp);
+ sw32(txdp, sis_priv->tx_ring_dma);
/* Enable all known interrupts by setting the interrupt mask. */
- outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
+ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
}
/**
@@ -1586,7 +1611,7 @@
sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
unsigned int entry;
unsigned long flags;
unsigned int index_cur_tx, index_dirty_tx;
@@ -1608,7 +1633,7 @@
sis_priv->tx_ring[entry].bufptr = pci_map_single(sis_priv->pci_dev,
skb->data, skb->len, PCI_DMA_TODEVICE);
sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
- outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
+ sw32(cr, TxENA | sr32(cr));
sis_priv->cur_tx ++;
index_cur_tx = sis_priv->cur_tx;
@@ -1654,14 +1679,14 @@
struct net_device *net_dev = dev_instance;
struct sis900_private *sis_priv = netdev_priv(net_dev);
int boguscnt = max_interrupt_work;
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
u32 status;
unsigned int handled = 0;
spin_lock (&sis_priv->lock);
do {
- status = inl(ioaddr + isr);
+ status = sr32(isr);
if ((status & (HIBERR|TxURN|TxERR|TxIDLE|RxORN|RxERR|RxOK)) == 0)
/* nothing intresting happened */
@@ -1696,7 +1721,7 @@
if(netif_msg_intr(sis_priv))
printk(KERN_DEBUG "%s: exiting interrupt, "
"interrupt status = 0x%#8.8x.\n",
- net_dev->name, inl(ioaddr + isr));
+ net_dev->name, sr32(isr));
spin_unlock (&sis_priv->lock);
return IRQ_RETVAL(handled);
@@ -1715,7 +1740,7 @@
static int sis900_rx(struct net_device *net_dev)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
int rx_work_limit;
@@ -1847,7 +1872,7 @@
}
}
/* re-enable the potentially idle receive state matchine */
- outl(RxENA | inl(ioaddr + cr), ioaddr + cr );
+ sw32(cr , RxENA | sr32(cr));
return 0;
}
@@ -1932,31 +1957,31 @@
static int sis900_close(struct net_device *net_dev)
{
- long ioaddr = net_dev->base_addr;
struct sis900_private *sis_priv = netdev_priv(net_dev);
+ struct pci_dev *pdev = sis_priv->pci_dev;
+ void __iomem *ioaddr = sis_priv->ioaddr;
struct sk_buff *skb;
int i;
netif_stop_queue(net_dev);
/* Disable interrupts by clearing the interrupt mask. */
- outl(0x0000, ioaddr + imr);
- outl(0x0000, ioaddr + ier);
+ sw32(imr, 0x0000);
+ sw32(ier, 0x0000);
/* Stop the chip's Tx and Rx Status Machine */
- outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
+ sw32(cr, RxDIS | TxDIS | sr32(cr));
del_timer(&sis_priv->timer);
- free_irq(net_dev->irq, net_dev);
+ free_irq(pdev->irq, net_dev);
/* Free Tx and RX skbuff */
for (i = 0; i < NUM_RX_DESC; i++) {
skb = sis_priv->rx_skbuff[i];
if (skb) {
- pci_unmap_single(sis_priv->pci_dev,
- sis_priv->rx_ring[i].bufptr,
- RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(pdev, sis_priv->rx_ring[i].bufptr,
+ RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
dev_kfree_skb(skb);
sis_priv->rx_skbuff[i] = NULL;
}
@@ -1964,9 +1989,8 @@
for (i = 0; i < NUM_TX_DESC; i++) {
skb = sis_priv->tx_skbuff[i];
if (skb) {
- pci_unmap_single(sis_priv->pci_dev,
- sis_priv->tx_ring[i].bufptr, skb->len,
- PCI_DMA_TODEVICE);
+ pci_unmap_single(pdev, sis_priv->tx_ring[i].bufptr,
+ skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb(skb);
sis_priv->tx_skbuff[i] = NULL;
}
@@ -2055,14 +2079,14 @@
static int sis900_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long pmctrl_addr = net_dev->base_addr + pmctrl;
+ void __iomem *ioaddr = sis_priv->ioaddr;
u32 cfgpmcsr = 0, pmctrl_bits = 0;
if (wol->wolopts == 0) {
pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr);
cfgpmcsr &= ~PME_EN;
pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr);
- outl(pmctrl_bits, pmctrl_addr);
+ sw32(pmctrl, pmctrl_bits);
if (netif_msg_wol(sis_priv))
printk(KERN_DEBUG "%s: Wake on LAN disabled\n", net_dev->name);
return 0;
@@ -2077,7 +2101,7 @@
if (wol->wolopts & WAKE_PHY)
pmctrl_bits |= LINKON;
- outl(pmctrl_bits, pmctrl_addr);
+ sw32(pmctrl, pmctrl_bits);
pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr);
cfgpmcsr |= PME_EN;
@@ -2090,10 +2114,11 @@
static void sis900_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
{
- long pmctrl_addr = net_dev->base_addr + pmctrl;
+ struct sis900_private *sp = netdev_priv(net_dev);
+ void __iomem *ioaddr = sp->ioaddr;
u32 pmctrl_bits;
- pmctrl_bits = inl(pmctrl_addr);
+ pmctrl_bits = sr32(pmctrl);
if (pmctrl_bits & MAGICPKT)
wol->wolopts |= WAKE_MAGIC;
if (pmctrl_bits & LINKON)
@@ -2279,8 +2304,8 @@
static void set_rx_mode(struct net_device *net_dev)
{
- long ioaddr = net_dev->base_addr;
struct sis900_private *sis_priv = netdev_priv(net_dev);
+ void __iomem *ioaddr = sis_priv->ioaddr;
u16 mc_filter[16] = {0}; /* 256/128 bits multicast hash table */
int i, table_entries;
u32 rx_mode;
@@ -2322,24 +2347,24 @@
/* update Multicast Hash Table in Receive Filter */
for (i = 0; i < table_entries; i++) {
/* why plus 0x04 ??, That makes the correct value for hash table. */
- outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
- outl(mc_filter[i], ioaddr + rfdr);
+ sw32(rfcr, (u32)(0x00000004 + i) << RFADDR_shift);
+ sw32(rfdr, mc_filter[i]);
}
- outl(RFEN | rx_mode, ioaddr + rfcr);
+ sw32(rfcr, RFEN | rx_mode);
/* sis900 is capable of looping back packets at MAC level for
* debugging purpose */
if (net_dev->flags & IFF_LOOPBACK) {
u32 cr_saved;
/* We must disable Tx/Rx before setting loopback mode */
- cr_saved = inl(ioaddr + cr);
- outl(cr_saved | TxDIS | RxDIS, ioaddr + cr);
+ cr_saved = sr32(cr);
+ sw32(cr, cr_saved | TxDIS | RxDIS);
/* enable loopback */
- outl(inl(ioaddr + txcfg) | TxMLB, ioaddr + txcfg);
- outl(inl(ioaddr + rxcfg) | RxATX, ioaddr + rxcfg);
+ sw32(txcfg, sr32(txcfg) | TxMLB);
+ sw32(rxcfg, sr32(rxcfg) | RxATX);
/* restore cr */
- outl(cr_saved, ioaddr + cr);
+ sw32(cr, cr_saved);
}
}
@@ -2355,26 +2380,25 @@
static void sis900_reset(struct net_device *net_dev)
{
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
- int i = 0;
+ void __iomem *ioaddr = sis_priv->ioaddr;
u32 status = TxRCMP | RxRCMP;
+ int i;
- outl(0, ioaddr + ier);
- outl(0, ioaddr + imr);
- outl(0, ioaddr + rfcr);
+ sw32(ier, 0);
+ sw32(imr, 0);
+ sw32(rfcr, 0);
- outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr);
+ sw32(cr, RxRESET | TxRESET | RESET | sr32(cr));
/* Check that the chip has finished the reset. */
- while (status && (i++ < 1000)) {
- status ^= (inl(isr + ioaddr) & status);
- }
+ for (i = 0; status && (i < 1000); i++)
+ status ^= sr32(isr) & status;
- if( (sis_priv->chipset_rev >= SIS635A_900_REV) ||
- (sis_priv->chipset_rev == SIS900B_900_REV) )
- outl(PESEL | RND_CNT, ioaddr + cfg);
+ if (sis_priv->chipset_rev >= SIS635A_900_REV ||
+ sis_priv->chipset_rev == SIS900B_900_REV)
+ sw32(cfg, PESEL | RND_CNT);
else
- outl(PESEL, ioaddr + cfg);
+ sw32(cfg, PESEL);
}
/**
@@ -2388,10 +2412,12 @@
{
struct net_device *net_dev = pci_get_drvdata(pci_dev);
struct sis900_private *sis_priv = netdev_priv(net_dev);
- struct mii_phy *phy = NULL;
+
+ unregister_netdev(net_dev);
while (sis_priv->first_mii) {
- phy = sis_priv->first_mii;
+ struct mii_phy *phy = sis_priv->first_mii;
+
sis_priv->first_mii = phy->next;
kfree(phy);
}
@@ -2400,7 +2426,7 @@
sis_priv->rx_ring_dma);
pci_free_consistent(pci_dev, TX_TOTAL_SIZE, sis_priv->tx_ring,
sis_priv->tx_ring_dma);
- unregister_netdev(net_dev);
+ pci_iounmap(pci_dev, sis_priv->ioaddr);
free_netdev(net_dev);
pci_release_regions(pci_dev);
pci_set_drvdata(pci_dev, NULL);
@@ -2411,7 +2437,8 @@
static int sis900_suspend(struct pci_dev *pci_dev, pm_message_t state)
{
struct net_device *net_dev = pci_get_drvdata(pci_dev);
- long ioaddr = net_dev->base_addr;
+ struct sis900_private *sis_priv = netdev_priv(net_dev);
+ void __iomem *ioaddr = sis_priv->ioaddr;
if(!netif_running(net_dev))
return 0;
@@ -2420,7 +2447,7 @@
netif_device_detach(net_dev);
/* Stop the chip's Tx and Rx Status Machine */
- outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
+ sw32(cr, RxDIS | TxDIS | sr32(cr));
pci_set_power_state(pci_dev, PCI_D3hot);
pci_save_state(pci_dev);
@@ -2432,7 +2459,7 @@
{
struct net_device *net_dev = pci_get_drvdata(pci_dev);
struct sis900_private *sis_priv = netdev_priv(net_dev);
- long ioaddr = net_dev->base_addr;
+ void __iomem *ioaddr = sis_priv->ioaddr;
if(!netif_running(net_dev))
return 0;
@@ -2453,9 +2480,9 @@
sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
/* Enable all known interrupts by setting the interrupt mask. */
- outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
- outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
- outl(IE, ioaddr + ier);
+ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
+ sw32(cr, RxENA | sr32(cr));
+ sw32(ier, IE);
sis900_check_mode(net_dev, sis_priv->mii);
diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c
index 2a662e6..d01e59c 100644
--- a/drivers/net/ethernet/smsc/epic100.c
+++ b/drivers/net/ethernet/smsc/epic100.c
@@ -146,6 +146,12 @@
#define EPIC_TOTAL_SIZE 0x100
#define USE_IO_OPS 1
+#ifdef USE_IO_OPS
+#define EPIC_BAR 0
+#else
+#define EPIC_BAR 1
+#endif
+
typedef enum {
SMSC_83C170_0,
SMSC_83C170,
@@ -176,21 +182,11 @@
};
MODULE_DEVICE_TABLE (pci, epic_pci_tbl);
-
-#ifndef USE_IO_OPS
-#undef inb
-#undef inw
-#undef inl
-#undef outb
-#undef outw
-#undef outl
-#define inb readb
-#define inw readw
-#define inl readl
-#define outb writeb
-#define outw writew
-#define outl writel
-#endif
+#define ew16(reg, val) iowrite16(val, ioaddr + (reg))
+#define ew32(reg, val) iowrite32(val, ioaddr + (reg))
+#define er8(reg) ioread8(ioaddr + (reg))
+#define er16(reg) ioread16(ioaddr + (reg))
+#define er32(reg) ioread32(ioaddr + (reg))
/* Offsets to registers, using the (ugh) SMC names. */
enum epic_registers {
@@ -275,6 +271,7 @@
u32 irq_mask;
unsigned int rx_buf_sz; /* Based on MTU+slack. */
+ void __iomem *ioaddr;
struct pci_dev *pci_dev; /* PCI bus location. */
int chip_id, chip_flags;
@@ -290,7 +287,7 @@
};
static int epic_open(struct net_device *dev);
-static int read_eeprom(long ioaddr, int location);
+static int read_eeprom(struct epic_private *, int);
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int loc, int val);
static void epic_restart(struct net_device *dev);
@@ -321,11 +318,11 @@
.ndo_validate_addr = eth_validate_addr,
};
-static int __devinit epic_init_one (struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int __devinit epic_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
static int card_idx = -1;
- long ioaddr;
+ void __iomem *ioaddr;
int chip_idx = (int) ent->driver_data;
int irq;
struct net_device *dev;
@@ -368,19 +365,15 @@
SET_NETDEV_DEV(dev, &pdev->dev);
-#ifdef USE_IO_OPS
- ioaddr = pci_resource_start (pdev, 0);
-#else
- ioaddr = pci_resource_start (pdev, 1);
- ioaddr = (long) pci_ioremap_bar(pdev, 1);
+ ioaddr = pci_iomap(pdev, EPIC_BAR, 0);
if (!ioaddr) {
dev_err(&pdev->dev, "ioremap failed\n");
goto err_out_free_netdev;
}
-#endif
pci_set_drvdata(pdev, dev);
ep = netdev_priv(dev);
+ ep->ioaddr = ioaddr;
ep->mii.dev = dev;
ep->mii.mdio_read = mdio_read;
ep->mii.mdio_write = mdio_write;
@@ -409,34 +402,31 @@
duplex = full_duplex[card_idx];
}
- dev->base_addr = ioaddr;
- dev->irq = irq;
-
spin_lock_init(&ep->lock);
spin_lock_init(&ep->napi_lock);
ep->reschedule_in_poll = 0;
/* Bring the chip out of low-power mode. */
- outl(0x4200, ioaddr + GENCTL);
+ ew32(GENCTL, 0x4200);
/* Magic?! If we don't set this bit the MII interface won't work. */
/* This magic is documented in SMSC app note 7.15 */
for (i = 16; i > 0; i--)
- outl(0x0008, ioaddr + TEST1);
+ ew32(TEST1, 0x0008);
/* Turn on the MII transceiver. */
- outl(0x12, ioaddr + MIICfg);
+ ew32(MIICfg, 0x12);
if (chip_idx == 1)
- outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
- outl(0x0200, ioaddr + GENCTL);
+ ew32(NVCTL, (er32(NVCTL) & ~0x003c) | 0x4800);
+ ew32(GENCTL, 0x0200);
/* Note: the '175 does not have a serial EEPROM. */
for (i = 0; i < 3; i++)
- ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(inw(ioaddr + LAN0 + i*4));
+ ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(er16(LAN0 + i*4));
if (debug > 2) {
dev_printk(KERN_DEBUG, &pdev->dev, "EEPROM contents:\n");
for (i = 0; i < 64; i++)
- printk(" %4.4x%s", read_eeprom(ioaddr, i),
+ printk(" %4.4x%s", read_eeprom(ep, i),
i % 16 == 15 ? "\n" : "");
}
@@ -481,8 +471,8 @@
/* Turn off the MII xcvr (175 only!), leave the chip in low-power mode. */
if (ep->chip_flags & MII_PWRDWN)
- outl(inl(ioaddr + NVCTL) & ~0x483C, ioaddr + NVCTL);
- outl(0x0008, ioaddr + GENCTL);
+ ew32(NVCTL, er32(NVCTL) & ~0x483c);
+ ew32(GENCTL, 0x0008);
/* The lower four bits are the media type. */
if (duplex) {
@@ -501,8 +491,9 @@
if (ret < 0)
goto err_out_unmap_rx;
- printk(KERN_INFO "%s: %s at %#lx, IRQ %d, %pM\n",
- dev->name, pci_id_tbl[chip_idx].name, ioaddr, dev->irq,
+ printk(KERN_INFO "%s: %s at %lx, IRQ %d, %pM\n",
+ dev->name, pci_id_tbl[chip_idx].name,
+ (long)pci_resource_start(pdev, EPIC_BAR), pdev->irq,
dev->dev_addr);
out:
@@ -513,10 +504,8 @@
err_out_unmap_tx:
pci_free_consistent(pdev, TX_TOTAL_SIZE, ep->tx_ring, ep->tx_ring_dma);
err_out_iounmap:
-#ifndef USE_IO_OPS
- iounmap(ioaddr);
+ pci_iounmap(pdev, ioaddr);
err_out_free_netdev:
-#endif
free_netdev(dev);
err_out_free_res:
pci_release_regions(pdev);
@@ -540,7 +529,7 @@
This serves to flush the operation to the PCI bus.
*/
-#define eeprom_delay() inl(ee_addr)
+#define eeprom_delay() er32(EECTL)
/* The EEPROM commands include the alway-set leading bit. */
#define EE_WRITE_CMD (5 << 6)
@@ -550,67 +539,67 @@
static void epic_disable_int(struct net_device *dev, struct epic_private *ep)
{
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = ep->ioaddr;
- outl(0x00000000, ioaddr + INTMASK);
+ ew32(INTMASK, 0x00000000);
}
-static inline void __epic_pci_commit(long ioaddr)
+static inline void __epic_pci_commit(void __iomem *ioaddr)
{
#ifndef USE_IO_OPS
- inl(ioaddr + INTMASK);
+ er32(INTMASK);
#endif
}
static inline void epic_napi_irq_off(struct net_device *dev,
struct epic_private *ep)
{
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = ep->ioaddr;
- outl(ep->irq_mask & ~EpicNapiEvent, ioaddr + INTMASK);
+ ew32(INTMASK, ep->irq_mask & ~EpicNapiEvent);
__epic_pci_commit(ioaddr);
}
static inline void epic_napi_irq_on(struct net_device *dev,
struct epic_private *ep)
{
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = ep->ioaddr;
/* No need to commit possible posted write */
- outl(ep->irq_mask | EpicNapiEvent, ioaddr + INTMASK);
+ ew32(INTMASK, ep->irq_mask | EpicNapiEvent);
}
-static int __devinit read_eeprom(long ioaddr, int location)
+static int __devinit read_eeprom(struct epic_private *ep, int location)
{
+ void __iomem *ioaddr = ep->ioaddr;
int i;
int retval = 0;
- long ee_addr = ioaddr + EECTL;
int read_cmd = location |
- (inl(ee_addr) & 0x40 ? EE_READ64_CMD : EE_READ256_CMD);
+ (er32(EECTL) & 0x40 ? EE_READ64_CMD : EE_READ256_CMD);
- outl(EE_ENB & ~EE_CS, ee_addr);
- outl(EE_ENB, ee_addr);
+ ew32(EECTL, EE_ENB & ~EE_CS);
+ ew32(EECTL, EE_ENB);
/* Shift the read command bits out. */
for (i = 12; i >= 0; i--) {
short dataval = (read_cmd & (1 << i)) ? EE_WRITE_1 : EE_WRITE_0;
- outl(EE_ENB | dataval, ee_addr);
+ ew32(EECTL, EE_ENB | dataval);
eeprom_delay();
- outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+ ew32(EECTL, EE_ENB | dataval | EE_SHIFT_CLK);
eeprom_delay();
}
- outl(EE_ENB, ee_addr);
+ ew32(EECTL, EE_ENB);
for (i = 16; i > 0; i--) {
- outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
+ ew32(EECTL, EE_ENB | EE_SHIFT_CLK);
eeprom_delay();
- retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
- outl(EE_ENB, ee_addr);
+ retval = (retval << 1) | ((er32(EECTL) & EE_DATA_READ) ? 1 : 0);
+ ew32(EECTL, EE_ENB);
eeprom_delay();
}
/* Terminate the EEPROM access. */
- outl(EE_ENB & ~EE_CS, ee_addr);
+ ew32(EECTL, EE_ENB & ~EE_CS);
return retval;
}
@@ -618,22 +607,23 @@
#define MII_WRITEOP 2
static int mdio_read(struct net_device *dev, int phy_id, int location)
{
- long ioaddr = dev->base_addr;
+ struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
int read_cmd = (phy_id << 9) | (location << 4) | MII_READOP;
int i;
- outl(read_cmd, ioaddr + MIICtrl);
+ ew32(MIICtrl, read_cmd);
/* Typical operation takes 25 loops. */
for (i = 400; i > 0; i--) {
barrier();
- if ((inl(ioaddr + MIICtrl) & MII_READOP) == 0) {
+ if ((er32(MIICtrl) & MII_READOP) == 0) {
/* Work around read failure bug. */
if (phy_id == 1 && location < 6 &&
- inw(ioaddr + MIIData) == 0xffff) {
- outl(read_cmd, ioaddr + MIICtrl);
+ er16(MIIData) == 0xffff) {
+ ew32(MIICtrl, read_cmd);
continue;
}
- return inw(ioaddr + MIIData);
+ return er16(MIIData);
}
}
return 0xffff;
@@ -641,14 +631,15 @@
static void mdio_write(struct net_device *dev, int phy_id, int loc, int value)
{
- long ioaddr = dev->base_addr;
+ struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
int i;
- outw(value, ioaddr + MIIData);
- outl((phy_id << 9) | (loc << 4) | MII_WRITEOP, ioaddr + MIICtrl);
+ ew16(MIIData, value);
+ ew32(MIICtrl, (phy_id << 9) | (loc << 4) | MII_WRITEOP);
for (i = 10000; i > 0; i--) {
barrier();
- if ((inl(ioaddr + MIICtrl) & MII_WRITEOP) == 0)
+ if ((er32(MIICtrl) & MII_WRITEOP) == 0)
break;
}
}
@@ -657,25 +648,26 @@
static int epic_open(struct net_device *dev)
{
struct epic_private *ep = netdev_priv(dev);
- long ioaddr = dev->base_addr;
- int i;
- int retval;
+ void __iomem *ioaddr = ep->ioaddr;
+ const int irq = ep->pci_dev->irq;
+ int rc, i;
/* Soft reset the chip. */
- outl(0x4001, ioaddr + GENCTL);
+ ew32(GENCTL, 0x4001);
napi_enable(&ep->napi);
- if ((retval = request_irq(dev->irq, epic_interrupt, IRQF_SHARED, dev->name, dev))) {
+ rc = request_irq(irq, epic_interrupt, IRQF_SHARED, dev->name, dev);
+ if (rc) {
napi_disable(&ep->napi);
- return retval;
+ return rc;
}
epic_init_ring(dev);
- outl(0x4000, ioaddr + GENCTL);
+ ew32(GENCTL, 0x4000);
/* This magic is documented in SMSC app note 7.15 */
for (i = 16; i > 0; i--)
- outl(0x0008, ioaddr + TEST1);
+ ew32(TEST1, 0x0008);
/* Pull the chip out of low-power mode, enable interrupts, and set for
PCI read multiple. The MIIcfg setting and strange write order are
@@ -683,29 +675,29 @@
wiring on the Ositech CardBus card.
*/
#if 0
- outl(dev->if_port == 1 ? 0x13 : 0x12, ioaddr + MIICfg);
+ ew32(MIICfg, dev->if_port == 1 ? 0x13 : 0x12);
#endif
if (ep->chip_flags & MII_PWRDWN)
- outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
+ ew32(NVCTL, (er32(NVCTL) & ~0x003c) | 0x4800);
/* Tell the chip to byteswap descriptors on big-endian hosts */
#ifdef __BIG_ENDIAN
- outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
- inl(ioaddr + GENCTL);
- outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
+ ew32(GENCTL, 0x4432 | (RX_FIFO_THRESH << 8));
+ er32(GENCTL);
+ ew32(GENCTL, 0x0432 | (RX_FIFO_THRESH << 8));
#else
- outl(0x4412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
- inl(ioaddr + GENCTL);
- outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
+ ew32(GENCTL, 0x4412 | (RX_FIFO_THRESH << 8));
+ er32(GENCTL);
+ ew32(GENCTL, 0x0412 | (RX_FIFO_THRESH << 8));
#endif
udelay(20); /* Looks like EPII needs that if you want reliable RX init. FIXME: pci posting bug? */
for (i = 0; i < 3; i++)
- outl(le16_to_cpu(((__le16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4);
+ ew32(LAN0 + i*4, le16_to_cpu(((__le16*)dev->dev_addr)[i]));
ep->tx_threshold = TX_FIFO_THRESH;
- outl(ep->tx_threshold, ioaddr + TxThresh);
+ ew32(TxThresh, ep->tx_threshold);
if (media2miictl[dev->if_port & 15]) {
if (ep->mii_phy_cnt)
@@ -731,26 +723,27 @@
}
}
- outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
- outl(ep->rx_ring_dma, ioaddr + PRxCDAR);
- outl(ep->tx_ring_dma, ioaddr + PTxCDAR);
+ ew32(TxCtrl, ep->mii.full_duplex ? 0x7f : 0x79);
+ ew32(PRxCDAR, ep->rx_ring_dma);
+ ew32(PTxCDAR, ep->tx_ring_dma);
/* Start the chip's Rx process. */
set_rx_mode(dev);
- outl(StartRx | RxQueued, ioaddr + COMMAND);
+ ew32(COMMAND, StartRx | RxQueued);
netif_start_queue(dev);
/* Enable interrupts by setting the interrupt mask. */
- outl((ep->chip_flags & TYPE2_INTR ? PCIBusErr175 : PCIBusErr170)
- | CntFull | TxUnderrun
- | RxError | RxHeader | EpicNapiEvent, ioaddr + INTMASK);
+ ew32(INTMASK, RxError | RxHeader | EpicNapiEvent | CntFull |
+ ((ep->chip_flags & TYPE2_INTR) ? PCIBusErr175 : PCIBusErr170) |
+ TxUnderrun);
- if (debug > 1)
- printk(KERN_DEBUG "%s: epic_open() ioaddr %lx IRQ %d status %4.4x "
- "%s-duplex.\n",
- dev->name, ioaddr, dev->irq, (int)inl(ioaddr + GENCTL),
- ep->mii.full_duplex ? "full" : "half");
+ if (debug > 1) {
+ printk(KERN_DEBUG "%s: epic_open() ioaddr %p IRQ %d "
+ "status %4.4x %s-duplex.\n",
+ dev->name, ioaddr, irq, er32(GENCTL),
+ ep->mii.full_duplex ? "full" : "half");
+ }
/* Set the timer to switch to check for link beat and perhaps switch
to an alternate media type. */
@@ -760,27 +753,29 @@
ep->timer.function = epic_timer; /* timer handler */
add_timer(&ep->timer);
- return 0;
+ return rc;
}
/* Reset the chip to recover from a PCI transaction error.
This may occur at interrupt time. */
static void epic_pause(struct net_device *dev)
{
- long ioaddr = dev->base_addr;
+ struct net_device_stats *stats = &dev->stats;
+ struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
netif_stop_queue (dev);
/* Disable interrupts by clearing the interrupt mask. */
- outl(0x00000000, ioaddr + INTMASK);
+ ew32(INTMASK, 0x00000000);
/* Stop the chip's Tx and Rx DMA processes. */
- outw(StopRx | StopTxDMA | StopRxDMA, ioaddr + COMMAND);
+ ew16(COMMAND, StopRx | StopTxDMA | StopRxDMA);
/* Update the error counts. */
- if (inw(ioaddr + COMMAND) != 0xffff) {
- dev->stats.rx_missed_errors += inb(ioaddr + MPCNT);
- dev->stats.rx_frame_errors += inb(ioaddr + ALICNT);
- dev->stats.rx_crc_errors += inb(ioaddr + CRCCNT);
+ if (er16(COMMAND) != 0xffff) {
+ stats->rx_missed_errors += er8(MPCNT);
+ stats->rx_frame_errors += er8(ALICNT);
+ stats->rx_crc_errors += er8(CRCCNT);
}
/* Remove the packets on the Rx queue. */
@@ -789,12 +784,12 @@
static void epic_restart(struct net_device *dev)
{
- long ioaddr = dev->base_addr;
struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
int i;
/* Soft reset the chip. */
- outl(0x4001, ioaddr + GENCTL);
+ ew32(GENCTL, 0x4001);
printk(KERN_DEBUG "%s: Restarting the EPIC chip, Rx %d/%d Tx %d/%d.\n",
dev->name, ep->cur_rx, ep->dirty_rx, ep->dirty_tx, ep->cur_tx);
@@ -802,47 +797,46 @@
/* This magic is documented in SMSC app note 7.15 */
for (i = 16; i > 0; i--)
- outl(0x0008, ioaddr + TEST1);
+ ew32(TEST1, 0x0008);
#ifdef __BIG_ENDIAN
- outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
+ ew32(GENCTL, 0x0432 | (RX_FIFO_THRESH << 8));
#else
- outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
+ ew32(GENCTL, 0x0412 | (RX_FIFO_THRESH << 8));
#endif
- outl(dev->if_port == 1 ? 0x13 : 0x12, ioaddr + MIICfg);
+ ew32(MIICfg, dev->if_port == 1 ? 0x13 : 0x12);
if (ep->chip_flags & MII_PWRDWN)
- outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
+ ew32(NVCTL, (er32(NVCTL) & ~0x003c) | 0x4800);
for (i = 0; i < 3; i++)
- outl(le16_to_cpu(((__le16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4);
+ ew32(LAN0 + i*4, le16_to_cpu(((__le16*)dev->dev_addr)[i]));
ep->tx_threshold = TX_FIFO_THRESH;
- outl(ep->tx_threshold, ioaddr + TxThresh);
- outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
- outl(ep->rx_ring_dma + (ep->cur_rx%RX_RING_SIZE)*
- sizeof(struct epic_rx_desc), ioaddr + PRxCDAR);
- outl(ep->tx_ring_dma + (ep->dirty_tx%TX_RING_SIZE)*
- sizeof(struct epic_tx_desc), ioaddr + PTxCDAR);
+ ew32(TxThresh, ep->tx_threshold);
+ ew32(TxCtrl, ep->mii.full_duplex ? 0x7f : 0x79);
+ ew32(PRxCDAR, ep->rx_ring_dma +
+ (ep->cur_rx % RX_RING_SIZE) * sizeof(struct epic_rx_desc));
+ ew32(PTxCDAR, ep->tx_ring_dma +
+ (ep->dirty_tx % TX_RING_SIZE) * sizeof(struct epic_tx_desc));
/* Start the chip's Rx process. */
set_rx_mode(dev);
- outl(StartRx | RxQueued, ioaddr + COMMAND);
+ ew32(COMMAND, StartRx | RxQueued);
/* Enable interrupts by setting the interrupt mask. */
- outl((ep->chip_flags & TYPE2_INTR ? PCIBusErr175 : PCIBusErr170)
- | CntFull | TxUnderrun
- | RxError | RxHeader | EpicNapiEvent, ioaddr + INTMASK);
+ ew32(INTMASK, RxError | RxHeader | EpicNapiEvent | CntFull |
+ ((ep->chip_flags & TYPE2_INTR) ? PCIBusErr175 : PCIBusErr170) |
+ TxUnderrun);
printk(KERN_DEBUG "%s: epic_restart() done, cmd status %4.4x, ctl %4.4x"
" interrupt %4.4x.\n",
- dev->name, (int)inl(ioaddr + COMMAND), (int)inl(ioaddr + GENCTL),
- (int)inl(ioaddr + INTSTAT));
+ dev->name, er32(COMMAND), er32(GENCTL), er32(INTSTAT));
}
static void check_media(struct net_device *dev)
{
struct epic_private *ep = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = ep->ioaddr;
int mii_lpa = ep->mii_phy_cnt ? mdio_read(dev, ep->phys[0], MII_LPA) : 0;
int negotiated = mii_lpa & ep->mii.advertising;
int duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
@@ -856,7 +850,7 @@
printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d link"
" partner capability of %4.4x.\n", dev->name,
ep->mii.full_duplex ? "full" : "half", ep->phys[0], mii_lpa);
- outl(ep->mii.full_duplex ? 0x7F : 0x79, ioaddr + TxCtrl);
+ ew32(TxCtrl, ep->mii.full_duplex ? 0x7F : 0x79);
}
}
@@ -864,16 +858,15 @@
{
struct net_device *dev = (struct net_device *)data;
struct epic_private *ep = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = ep->ioaddr;
int next_tick = 5*HZ;
if (debug > 3) {
printk(KERN_DEBUG "%s: Media monitor tick, Tx status %8.8x.\n",
- dev->name, (int)inl(ioaddr + TxSTAT));
+ dev->name, er32(TxSTAT));
printk(KERN_DEBUG "%s: Other registers are IntMask %4.4x "
- "IntStatus %4.4x RxStatus %4.4x.\n",
- dev->name, (int)inl(ioaddr + INTMASK),
- (int)inl(ioaddr + INTSTAT), (int)inl(ioaddr + RxSTAT));
+ "IntStatus %4.4x RxStatus %4.4x.\n", dev->name,
+ er32(INTMASK), er32(INTSTAT), er32(RxSTAT));
}
check_media(dev);
@@ -885,23 +878,22 @@
static void epic_tx_timeout(struct net_device *dev)
{
struct epic_private *ep = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = ep->ioaddr;
if (debug > 0) {
printk(KERN_WARNING "%s: Transmit timeout using MII device, "
- "Tx status %4.4x.\n",
- dev->name, (int)inw(ioaddr + TxSTAT));
+ "Tx status %4.4x.\n", dev->name, er16(TxSTAT));
if (debug > 1) {
printk(KERN_DEBUG "%s: Tx indices: dirty_tx %d, cur_tx %d.\n",
dev->name, ep->dirty_tx, ep->cur_tx);
}
}
- if (inw(ioaddr + TxSTAT) & 0x10) { /* Tx FIFO underflow. */
+ if (er16(TxSTAT) & 0x10) { /* Tx FIFO underflow. */
dev->stats.tx_fifo_errors++;
- outl(RestartTx, ioaddr + COMMAND);
+ ew32(COMMAND, RestartTx);
} else {
epic_restart(dev);
- outl(TxQueued, dev->base_addr + COMMAND);
+ ew32(COMMAND, TxQueued);
}
dev->trans_start = jiffies; /* prevent tx timeout */
@@ -959,6 +951,7 @@
static netdev_tx_t epic_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
int entry, free_count;
u32 ctrl_word;
unsigned long flags;
@@ -999,13 +992,12 @@
spin_unlock_irqrestore(&ep->lock, flags);
/* Trigger an immediate transmit demand. */
- outl(TxQueued, dev->base_addr + COMMAND);
+ ew32(COMMAND, TxQueued);
if (debug > 4)
printk(KERN_DEBUG "%s: Queued Tx packet size %d to slot %d, "
- "flag %2.2x Tx status %8.8x.\n",
- dev->name, (int)skb->len, entry, ctrl_word,
- (int)inl(dev->base_addr + TxSTAT));
+ "flag %2.2x Tx status %8.8x.\n", dev->name, skb->len,
+ entry, ctrl_word, er32(TxSTAT));
return NETDEV_TX_OK;
}
@@ -1086,18 +1078,17 @@
{
struct net_device *dev = dev_instance;
struct epic_private *ep = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = ep->ioaddr;
unsigned int handled = 0;
int status;
- status = inl(ioaddr + INTSTAT);
+ status = er32(INTSTAT);
/* Acknowledge all of the current interrupt sources ASAP. */
- outl(status & EpicNormalEvent, ioaddr + INTSTAT);
+ ew32(INTSTAT, status & EpicNormalEvent);
if (debug > 4) {
printk(KERN_DEBUG "%s: Interrupt, status=%#8.8x new "
- "intstat=%#8.8x.\n", dev->name, status,
- (int)inl(ioaddr + INTSTAT));
+ "intstat=%#8.8x.\n", dev->name, status, er32(INTSTAT));
}
if ((status & IntrSummary) == 0)
@@ -1118,19 +1109,21 @@
/* Check uncommon events all at once. */
if (status & (CntFull | TxUnderrun | PCIBusErr170 | PCIBusErr175)) {
+ struct net_device_stats *stats = &dev->stats;
+
if (status == EpicRemoved)
goto out;
/* Always update the error counts to avoid overhead later. */
- dev->stats.rx_missed_errors += inb(ioaddr + MPCNT);
- dev->stats.rx_frame_errors += inb(ioaddr + ALICNT);
- dev->stats.rx_crc_errors += inb(ioaddr + CRCCNT);
+ stats->rx_missed_errors += er8(MPCNT);
+ stats->rx_frame_errors += er8(ALICNT);
+ stats->rx_crc_errors += er8(CRCCNT);
if (status & TxUnderrun) { /* Tx FIFO underflow. */
- dev->stats.tx_fifo_errors++;
- outl(ep->tx_threshold += 128, ioaddr + TxThresh);
+ stats->tx_fifo_errors++;
+ ew32(TxThresh, ep->tx_threshold += 128);
/* Restart the transmit process. */
- outl(RestartTx, ioaddr + COMMAND);
+ ew32(COMMAND, RestartTx);
}
if (status & PCIBusErr170) {
printk(KERN_ERR "%s: PCI Bus Error! status %4.4x.\n",
@@ -1139,7 +1132,7 @@
epic_restart(dev);
}
/* Clear all error sources. */
- outl(status & 0x7f18, ioaddr + INTSTAT);
+ ew32(INTSTAT, status & 0x7f18);
}
out:
@@ -1248,17 +1241,17 @@
static void epic_rx_err(struct net_device *dev, struct epic_private *ep)
{
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = ep->ioaddr;
int status;
- status = inl(ioaddr + INTSTAT);
+ status = er32(INTSTAT);
if (status == EpicRemoved)
return;
if (status & RxOverflow) /* Missed a Rx frame. */
dev->stats.rx_errors++;
if (status & (RxOverflow | RxFull))
- outw(RxQueued, ioaddr + COMMAND);
+ ew16(COMMAND, RxQueued);
}
static int epic_poll(struct napi_struct *napi, int budget)
@@ -1266,7 +1259,7 @@
struct epic_private *ep = container_of(napi, struct epic_private, napi);
struct net_device *dev = ep->mii.dev;
int work_done = 0;
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = ep->ioaddr;
rx_action:
@@ -1287,7 +1280,7 @@
more = ep->reschedule_in_poll;
if (!more) {
__napi_complete(napi);
- outl(EpicNapiEvent, ioaddr + INTSTAT);
+ ew32(INTSTAT, EpicNapiEvent);
epic_napi_irq_on(dev, ep);
} else
ep->reschedule_in_poll--;
@@ -1303,8 +1296,9 @@
static int epic_close(struct net_device *dev)
{
- long ioaddr = dev->base_addr;
struct epic_private *ep = netdev_priv(dev);
+ struct pci_dev *pdev = ep->pci_dev;
+ void __iomem *ioaddr = ep->ioaddr;
struct sk_buff *skb;
int i;
@@ -1313,13 +1307,13 @@
if (debug > 1)
printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, (int)inl(ioaddr + INTSTAT));
+ dev->name, er32(INTSTAT));
del_timer_sync(&ep->timer);
epic_disable_int(dev, ep);
- free_irq(dev->irq, dev);
+ free_irq(pdev->irq, dev);
epic_pause(dev);
@@ -1330,7 +1324,7 @@
ep->rx_ring[i].rxstatus = 0; /* Not owned by Epic chip. */
ep->rx_ring[i].buflength = 0;
if (skb) {
- pci_unmap_single(ep->pci_dev, ep->rx_ring[i].bufaddr,
+ pci_unmap_single(pdev, ep->rx_ring[i].bufaddr,
ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
dev_kfree_skb(skb);
}
@@ -1341,26 +1335,28 @@
ep->tx_skbuff[i] = NULL;
if (!skb)
continue;
- pci_unmap_single(ep->pci_dev, ep->tx_ring[i].bufaddr,
- skb->len, PCI_DMA_TODEVICE);
+ pci_unmap_single(pdev, ep->tx_ring[i].bufaddr, skb->len,
+ PCI_DMA_TODEVICE);
dev_kfree_skb(skb);
}
/* Green! Leave the chip in low-power mode. */
- outl(0x0008, ioaddr + GENCTL);
+ ew32(GENCTL, 0x0008);
return 0;
}
static struct net_device_stats *epic_get_stats(struct net_device *dev)
{
- long ioaddr = dev->base_addr;
+ struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
if (netif_running(dev)) {
- /* Update the error counts. */
- dev->stats.rx_missed_errors += inb(ioaddr + MPCNT);
- dev->stats.rx_frame_errors += inb(ioaddr + ALICNT);
- dev->stats.rx_crc_errors += inb(ioaddr + CRCCNT);
+ struct net_device_stats *stats = &dev->stats;
+
+ stats->rx_missed_errors += er8(MPCNT);
+ stats->rx_frame_errors += er8(ALICNT);
+ stats->rx_crc_errors += er8(CRCCNT);
}
return &dev->stats;
@@ -1373,13 +1369,13 @@
static void set_rx_mode(struct net_device *dev)
{
- long ioaddr = dev->base_addr;
struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
unsigned char mc_filter[8]; /* Multicast hash filter */
int i;
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
- outl(0x002C, ioaddr + RxCtrl);
+ ew32(RxCtrl, 0x002c);
/* Unconditionally log net taps. */
memset(mc_filter, 0xff, sizeof(mc_filter));
} else if ((!netdev_mc_empty(dev)) || (dev->flags & IFF_ALLMULTI)) {
@@ -1387,9 +1383,9 @@
is never enabled. */
/* Too many to filter perfectly -- accept all multicasts. */
memset(mc_filter, 0xff, sizeof(mc_filter));
- outl(0x000C, ioaddr + RxCtrl);
+ ew32(RxCtrl, 0x000c);
} else if (netdev_mc_empty(dev)) {
- outl(0x0004, ioaddr + RxCtrl);
+ ew32(RxCtrl, 0x0004);
return;
} else { /* Never executed, for now. */
struct netdev_hw_addr *ha;
@@ -1404,7 +1400,7 @@
/* ToDo: perhaps we need to stop the Tx and Rx process here? */
if (memcmp(mc_filter, ep->mc_filter, sizeof(mc_filter))) {
for (i = 0; i < 4; i++)
- outw(((u16 *)mc_filter)[i], ioaddr + MC0 + i*4);
+ ew16(MC0 + i*4, ((u16 *)mc_filter)[i]);
memcpy(ep->mc_filter, mc_filter, sizeof(mc_filter));
}
}
@@ -1466,22 +1462,26 @@
static int ethtool_begin(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
+ struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
+
/* power-up, if interface is down */
- if (! netif_running(dev)) {
- outl(0x0200, ioaddr + GENCTL);
- outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
+ if (!netif_running(dev)) {
+ ew32(GENCTL, 0x0200);
+ ew32(NVCTL, (er32(NVCTL) & ~0x003c) | 0x4800);
}
return 0;
}
static void ethtool_complete(struct net_device *dev)
{
- unsigned long ioaddr = dev->base_addr;
+ struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
+
/* power-down, if interface is down */
- if (! netif_running(dev)) {
- outl(0x0008, ioaddr + GENCTL);
- outl((inl(ioaddr + NVCTL) & ~0x483C) | 0x0000, ioaddr + NVCTL);
+ if (!netif_running(dev)) {
+ ew32(GENCTL, 0x0008);
+ ew32(NVCTL, (er32(NVCTL) & ~0x483c) | 0x0000);
}
}
@@ -1500,14 +1500,14 @@
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct epic_private *np = netdev_priv(dev);
- long ioaddr = dev->base_addr;
+ void __iomem *ioaddr = np->ioaddr;
struct mii_ioctl_data *data = if_mii(rq);
int rc;
/* power-up, if interface is down */
if (! netif_running(dev)) {
- outl(0x0200, ioaddr + GENCTL);
- outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
+ ew32(GENCTL, 0x0200);
+ ew32(NVCTL, (er32(NVCTL) & ~0x003c) | 0x4800);
}
/* all non-ethtool ioctls (the SIOC[GS]MIIxxx ioctls) */
@@ -1517,14 +1517,14 @@
/* power-down, if interface is down */
if (! netif_running(dev)) {
- outl(0x0008, ioaddr + GENCTL);
- outl((inl(ioaddr + NVCTL) & ~0x483C) | 0x0000, ioaddr + NVCTL);
+ ew32(GENCTL, 0x0008);
+ ew32(NVCTL, (er32(NVCTL) & ~0x483c) | 0x0000);
}
return rc;
}
-static void __devexit epic_remove_one (struct pci_dev *pdev)
+static void __devexit epic_remove_one(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct epic_private *ep = netdev_priv(dev);
@@ -1532,9 +1532,7 @@
pci_free_consistent(pdev, TX_TOTAL_SIZE, ep->tx_ring, ep->tx_ring_dma);
pci_free_consistent(pdev, RX_TOTAL_SIZE, ep->rx_ring, ep->rx_ring_dma);
unregister_netdev(dev);
-#ifndef USE_IO_OPS
- iounmap((void*) dev->base_addr);
-#endif
+ pci_iounmap(pdev, ep->ioaddr);
pci_release_regions(pdev);
free_netdev(dev);
pci_disable_device(pdev);
@@ -1548,13 +1546,14 @@
static int epic_suspend (struct pci_dev *pdev, pm_message_t state)
{
struct net_device *dev = pci_get_drvdata(pdev);
- long ioaddr = dev->base_addr;
+ struct epic_private *ep = netdev_priv(dev);
+ void __iomem *ioaddr = ep->ioaddr;
if (!netif_running(dev))
return 0;
epic_pause(dev);
/* Put the chip into low-power mode. */
- outl(0x0008, ioaddr + GENCTL);
+ ew32(GENCTL, 0x0008);
/* pci_power_off(pdev, -1); */
return 0;
}
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 4a69710..519ed8e 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -2070,6 +2070,7 @@
.get_eeprom_len = smsc911x_ethtool_get_eeprom_len,
.get_eeprom = smsc911x_ethtool_get_eeprom,
.set_eeprom = smsc911x_ethtool_set_eeprom,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static const struct net_device_ops smsc911x_netdev_ops = {
diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c
index 3838647..fd33b21 100644
--- a/drivers/net/ethernet/smsc/smsc9420.c
+++ b/drivers/net/ethernet/smsc/smsc9420.c
@@ -54,7 +54,7 @@
};
struct smsc9420_pdata {
- void __iomem *base_addr;
+ void __iomem *ioaddr;
struct pci_dev *pdev;
struct net_device *dev;
@@ -114,13 +114,13 @@
static inline u32 smsc9420_reg_read(struct smsc9420_pdata *pd, u32 offset)
{
- return ioread32(pd->base_addr + offset);
+ return ioread32(pd->ioaddr + offset);
}
static inline void
smsc9420_reg_write(struct smsc9420_pdata *pd, u32 offset, u32 value)
{
- iowrite32(value, pd->base_addr + offset);
+ iowrite32(value, pd->ioaddr + offset);
}
static inline void smsc9420_pci_flush_write(struct smsc9420_pdata *pd)
@@ -469,6 +469,7 @@
.set_eeprom = smsc9420_ethtool_set_eeprom,
.get_regs_len = smsc9420_ethtool_getregslen,
.get_regs = smsc9420_ethtool_getregs,
+ .get_ts_info = ethtool_op_get_ts_info,
};
/* Sets the device MAC address to dev_addr */
@@ -659,7 +660,7 @@
ulong flags;
BUG_ON(!pd);
- BUG_ON(!pd->base_addr);
+ BUG_ON(!pd->ioaddr);
int_cfg = smsc9420_reg_read(pd, INT_CFG);
@@ -720,9 +721,12 @@
#ifdef CONFIG_NET_POLL_CONTROLLER
static void smsc9420_poll_controller(struct net_device *dev)
{
- disable_irq(dev->irq);
+ struct smsc9420_pdata *pd = netdev_priv(dev);
+ const int irq = pd->pdev->irq;
+
+ disable_irq(irq);
smsc9420_isr(0, dev);
- enable_irq(dev->irq);
+ enable_irq(irq);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -759,7 +763,7 @@
smsc9420_stop_rx(pd);
smsc9420_free_rx_ring(pd);
- free_irq(dev->irq, pd);
+ free_irq(pd->pdev->irq, pd);
smsc9420_dmac_soft_reset(pd);
@@ -1331,15 +1335,12 @@
static int smsc9420_open(struct net_device *dev)
{
- struct smsc9420_pdata *pd;
+ struct smsc9420_pdata *pd = netdev_priv(dev);
u32 bus_mode, mac_cr, dmac_control, int_cfg, dma_intr_ena, int_ctl;
+ const int irq = pd->pdev->irq;
unsigned long flags;
int result = 0, timeout;
- BUG_ON(!dev);
- pd = netdev_priv(dev);
- BUG_ON(!pd);
-
if (!is_valid_ether_addr(dev->dev_addr)) {
smsc_warn(IFUP, "dev_addr is not a valid MAC address");
result = -EADDRNOTAVAIL;
@@ -1358,9 +1359,10 @@
smsc9420_reg_write(pd, INT_STAT, 0xFFFFFFFF);
smsc9420_pci_flush_write(pd);
- if (request_irq(dev->irq, smsc9420_isr, IRQF_SHARED | IRQF_DISABLED,
- DRV_NAME, pd)) {
- smsc_warn(IFUP, "Unable to use IRQ = %d", dev->irq);
+ result = request_irq(irq, smsc9420_isr, IRQF_SHARED | IRQF_DISABLED,
+ DRV_NAME, pd);
+ if (result) {
+ smsc_warn(IFUP, "Unable to use IRQ = %d", irq);
result = -ENODEV;
goto out_0;
}
@@ -1395,7 +1397,7 @@
smsc9420_pci_flush_write(pd);
/* test the IRQ connection to the ISR */
- smsc_dbg(IFUP, "Testing ISR using IRQ %d", dev->irq);
+ smsc_dbg(IFUP, "Testing ISR using IRQ %d", irq);
pd->software_irq_signal = false;
spin_lock_irqsave(&pd->int_lock, flags);
@@ -1430,7 +1432,7 @@
goto out_free_irq_1;
}
- smsc_dbg(IFUP, "ISR passed test using IRQ %d", dev->irq);
+ smsc_dbg(IFUP, "ISR passed test using IRQ %d", irq);
result = smsc9420_alloc_tx_ring(pd);
if (result) {
@@ -1490,7 +1492,7 @@
out_free_tx_ring_2:
smsc9420_free_tx_ring(pd);
out_free_irq_1:
- free_irq(dev->irq, pd);
+ free_irq(irq, pd);
out_0:
return result;
}
@@ -1519,7 +1521,7 @@
smsc9420_stop_rx(pd);
smsc9420_free_rx_ring(pd);
- free_irq(dev->irq, pd);
+ free_irq(pd->pdev->irq, pd);
netif_device_detach(dev);
}
@@ -1552,6 +1554,7 @@
smsc_warn(IFUP, "pci_enable_wake failed: %d", err);
if (netif_running(dev)) {
+ /* FIXME: gross. It looks like ancient PM relic.*/
err = smsc9420_open(dev);
netif_device_attach(dev);
}
@@ -1625,8 +1628,6 @@
/* registers are double mapped with 0 offset for LE and 0x200 for BE */
virt_addr += LAN9420_CPSR_ENDIAN_OFFSET;
- dev->base_addr = (ulong)virt_addr;
-
pd = netdev_priv(dev);
/* pci descriptors are created in the PCI consistent area */
@@ -1646,7 +1647,7 @@
pd->pdev = pdev;
pd->dev = dev;
- pd->base_addr = virt_addr;
+ pd->ioaddr = virt_addr;
pd->msg_enable = smsc_debug;
pd->rx_csum = true;
@@ -1669,7 +1670,6 @@
dev->netdev_ops = &smsc9420_netdev_ops;
dev->ethtool_ops = &smsc9420_ethtool_ops;
- dev->irq = pdev->irq;
netif_napi_add(dev, &pd->napi, smsc9420_rx_poll, NAPI_WEIGHT);
@@ -1727,7 +1727,7 @@
pci_free_consistent(pdev, sizeof(struct smsc9420_dma_desc) *
(RX_RING_SIZE + TX_RING_SIZE), pd->rx_ring, pd->rx_dma_addr);
- iounmap(pd->base_addr - LAN9420_CPSR_ENDIAN_OFFSET);
+ iounmap(pd->ioaddr - LAN9420_CPSR_ENDIAN_OFFSET);
pci_release_regions(pdev);
free_netdev(dev);
pci_disable_device(pdev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 0319d64..9e42b5d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -97,6 +97,16 @@
unsigned long normal_irq_n;
};
+/* CSR Frequency Access Defines*/
+#define CSR_F_35M 35000000
+#define CSR_F_60M 60000000
+#define CSR_F_100M 100000000
+#define CSR_F_150M 150000000
+#define CSR_F_250M 250000000
+#define CSR_F_300M 300000000
+
+#define MAC_CSR_H_FRQ_MASK 0x20
+
#define HASH_TABLE_SIZE 64
#define PAUSE_TIME 0x200
@@ -228,7 +238,7 @@
int (*get_rx_owner) (struct dma_desc *p);
void (*set_rx_owner) (struct dma_desc *p);
/* Get the receive frame size */
- int (*get_rx_frame_len) (struct dma_desc *p);
+ int (*get_rx_frame_len) (struct dma_desc *p, int rx_coe_type);
/* Return the reception status looking at the RDES1 */
int (*rx_status) (void *data, struct stmmac_extra_stats *x,
struct dma_desc *p);
@@ -236,7 +246,8 @@
struct stmmac_dma_ops {
/* DMA core initialization */
- int (*init) (void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
+ int (*init) (void __iomem *ioaddr, int pbl, int fb, int burst_len,
+ u32 dma_tx, u32 dma_rx);
/* Dump DMA registers */
void (*dump_regs) (void __iomem *ioaddr);
/* Set tx/rx threshold in the csr6 register
@@ -261,8 +272,8 @@
struct stmmac_ops {
/* MAC core initialization */
void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned;
- /* Support checksum offload engine */
- int (*rx_coe) (void __iomem *ioaddr);
+ /* Enable and verify that the IPC module is supported */
+ int (*rx_ipc) (void __iomem *ioaddr);
/* Dump MAC registers */
void (*dump_regs) (void __iomem *ioaddr);
/* Handle extra events on specific interrupts hw dependent */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index cfcef0e..54339a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -142,7 +142,7 @@
#define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */
#define DMA_BUS_MODE_RPBL_SHIFT 17
#define DMA_BUS_MODE_USP 0x00800000
-#define DMA_BUS_MODE_4PBL 0x01000000
+#define DMA_BUS_MODE_PBL 0x01000000
#define DMA_BUS_MODE_AAL 0x02000000
/* DMA CRS Control and Status Register Mapping */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index b1c48b9..e7cbcd9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -46,7 +46,7 @@
#endif
}
-static int dwmac1000_rx_coe_supported(void __iomem *ioaddr)
+static int dwmac1000_rx_ipc_enable(void __iomem *ioaddr)
{
u32 value = readl(ioaddr + GMAC_CONTROL);
@@ -211,7 +211,7 @@
static const struct stmmac_ops dwmac1000_ops = {
.core_init = dwmac1000_core_init,
- .rx_coe = dwmac1000_rx_coe_supported,
+ .rx_ipc = dwmac1000_rx_ipc_enable,
.dump_regs = dwmac1000_dump_regs,
.host_irq_status = dwmac1000_irq_status,
.set_filter = dwmac1000_set_filter,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 4d5402a..3675c57 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -30,8 +30,8 @@
#include "dwmac1000.h"
#include "dwmac_dma.h"
-static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
- u32 dma_rx)
+static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb,
+ int burst_len, u32 dma_tx, u32 dma_rx)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
int limit;
@@ -48,15 +48,47 @@
if (limit < 0)
return -EBUSY;
- value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
- ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
- (pbl << DMA_BUS_MODE_RPBL_SHIFT));
+ /*
+ * Set the DMA PBL (Programmable Burst Length) mode
+ * Before stmmac core 3.50 this mode bit was 4xPBL, and
+ * post 3.5 mode bit acts as 8*PBL.
+ * For core rev < 3.5, when the core is set for 4xPBL mode, the
+ * DMA transfers the data in 4, 8, 16, 32, 64 & 128 beats
+ * depending on pbl value.
+ * For core rev > 3.5, when the core is set for 8xPBL mode, the
+ * DMA transfers the data in 8, 16, 32, 64, 128 & 256 beats
+ * depending on pbl value.
+ */
+ value = DMA_BUS_MODE_PBL | ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
+ (pbl << DMA_BUS_MODE_RPBL_SHIFT));
+
+ /* Set the Fixed burst mode */
+ if (fb)
+ value |= DMA_BUS_MODE_FB;
#ifdef CONFIG_STMMAC_DA
value |= DMA_BUS_MODE_DA; /* Rx has priority over tx */
#endif
writel(value, ioaddr + DMA_BUS_MODE);
+ /* In case of GMAC AXI configuration, program the DMA_AXI_BUS_MODE
+ * for supported bursts.
+ *
+ * Note: This is applicable only for revision GMACv3.61a. For
+ * older version this register is reserved and shall have no
+ * effect.
+ *
+ * Note:
+ * For Fixed Burst Mode: if we directly write 0xFF to this
+ * register using the configurations pass from platform code,
+ * this would ensure that all bursts supported by core are set
+ * and those which are not supported would remain ineffective.
+ *
+ * For Non Fixed Burst Mode: provide the maximum value of the
+ * burst length. Any burst equal or below the provided burst
+ * length would be allowed to perform. */
+ writel(burst_len, ioaddr + DMA_AXI_BUS_MODE);
+
/* Mask interrupts by writing to CSR7 */
writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index 138fb8dd..efde50f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -43,11 +43,6 @@
#endif
}
-static int dwmac100_rx_coe_supported(void __iomem *ioaddr)
-{
- return 0;
-}
-
static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
{
pr_info("\t----------------------------------------------\n"
@@ -72,6 +67,11 @@
readl(ioaddr + MAC_VLAN2));
}
+static int dwmac100_rx_ipc_enable(void __iomem *ioaddr)
+{
+ return 0;
+}
+
static void dwmac100_irq_status(void __iomem *ioaddr)
{
return;
@@ -160,7 +160,7 @@
static const struct stmmac_ops dwmac100_ops = {
.core_init = dwmac100_core_init,
- .rx_coe = dwmac100_rx_coe_supported,
+ .rx_ipc = dwmac100_rx_ipc_enable,
.dump_regs = dwmac100_dump_mac_regs,
.host_irq_status = dwmac100_irq_status,
.set_filter = dwmac100_set_filter,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
index bc17fd0..92ed2e0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
@@ -32,8 +32,8 @@
#include "dwmac100.h"
#include "dwmac_dma.h"
-static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
- u32 dma_rx)
+static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb,
+ int burst_len, u32 dma_tx, u32 dma_rx)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
int limit;
@@ -52,7 +52,7 @@
/* Enable Application Access by writing to DMA CSR0 */
writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
- ioaddr + DMA_BUS_MODE);
+ ioaddr + DMA_BUS_MODE);
/* Mask interrupts by writing to CSR7 */
writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 437edac..6e0360f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -32,6 +32,7 @@
#define DMA_CONTROL 0x00001018 /* Ctrl (Operational Mode) */
#define DMA_INTR_ENA 0x0000101c /* Interrupt Enable */
#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */
+#define DMA_AXI_BUS_MODE 0x00001028 /* AXI Bus Mode */
#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */
#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */
#define DMA_HW_FEATURE 0x00001058 /* HW Feature Register */
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index ad1b627..2fc8ef9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -22,6 +22,7 @@
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/
+#include <linux/stmmac.h>
#include "common.h"
#include "descs_com.h"
@@ -309,9 +310,17 @@
p->des01.etx.interrupt = 1;
}
-static int enh_desc_get_rx_frame_len(struct dma_desc *p)
+static int enh_desc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
{
- return p->des01.erx.frame_length;
+ /* The type-1 checksum offload engines append the checksum at
+ * the end of frame and the two bytes of checksum are added in
+ * the length.
+ * Adjust for that in the framelen for type-1 checksum offload
+ * engines. */
+ if (rx_coe_type == STMMAC_RX_COE_TYPE1)
+ return p->des01.erx.frame_length - 2;
+ else
+ return p->des01.erx.frame_length;
}
const struct stmmac_desc_ops enh_desc_ops = {
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
index 25953bb..68962c5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -22,6 +22,7 @@
Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/
+#include <linux/stmmac.h>
#include "common.h"
#include "descs_com.h"
@@ -201,9 +202,17 @@
p->des01.tx.interrupt = 1;
}
-static int ndesc_get_rx_frame_len(struct dma_desc *p)
+static int ndesc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
{
- return p->des01.rx.frame_length;
+ /* The type-1 checksum offload engines append the checksum at
+ * the end of frame and the two bytes of checksum are added in
+ * the length.
+ * Adjust for that in the framelen for type-1 checksum offload
+ * engines. */
+ if (rx_coe_type == STMMAC_RX_COE_TYPE1)
+ return p->des01.rx.frame_length - 2;
+ else
+ return p->des01.rx.frame_length;
}
const struct stmmac_desc_ops ndesc_ops = {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index b4b095f..9f2435c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -21,7 +21,9 @@
*******************************************************************************/
#define STMMAC_RESOURCE_NAME "stmmaceth"
-#define DRV_MODULE_VERSION "Feb_2012"
+#define DRV_MODULE_VERSION "March_2012"
+
+#include <linux/clk.h>
#include <linux/stmmac.h>
#include <linux/phy.h>
#include "common.h"
@@ -56,8 +58,6 @@
struct stmmac_extra_stats xstats;
struct napi_struct napi;
-
- int rx_coe;
int no_csum_insertion;
struct phy_device *phydev;
@@ -81,6 +81,10 @@
struct stmmac_counters mmc;
struct dma_features dma_cap;
int hw_cap_support;
+#ifdef CONFIG_HAVE_CLK
+ struct clk *stmmac_clk;
+#endif
+ int clk_csr;
};
extern int phyaddr;
@@ -99,3 +103,41 @@
struct stmmac_priv *stmmac_dvr_probe(struct device *device,
struct plat_stmmacenet_data *plat_dat,
void __iomem *addr);
+
+#ifdef CONFIG_HAVE_CLK
+static inline int stmmac_clk_enable(struct stmmac_priv *priv)
+{
+ if (priv->stmmac_clk)
+ return clk_enable(priv->stmmac_clk);
+
+ return 0;
+}
+
+static inline void stmmac_clk_disable(struct stmmac_priv *priv)
+{
+ if (priv->stmmac_clk)
+ clk_disable(priv->stmmac_clk);
+}
+static inline int stmmac_clk_get(struct stmmac_priv *priv)
+{
+ priv->stmmac_clk = clk_get(priv->device, NULL);
+
+ if (IS_ERR(priv->stmmac_clk)) {
+ pr_err("%s: ERROR clk_get failed\n", __func__);
+ return PTR_ERR(priv->stmmac_clk);
+ }
+ return 0;
+}
+#else
+static inline int stmmac_clk_enable(struct stmmac_priv *priv)
+{
+ return 0;
+}
+static inline void stmmac_clk_disable(struct stmmac_priv *priv)
+{
+}
+static inline int stmmac_clk_get(struct stmmac_priv *priv)
+{
+ return 0;
+}
+#endif /* CONFIG_HAVE_CLK */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index f98e151..ce43184 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -481,6 +481,7 @@
.get_wol = stmmac_get_wol,
.set_wol = stmmac_set_wol,
.get_sset_count = stmmac_get_sset_count,
+ .get_ts_info = ethtool_op_get_ts_info,
};
void stmmac_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 48d56da..a64f0d4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -163,6 +163,35 @@
pause = PAUSE_TIME;
}
+static void stmmac_clk_csr_set(struct stmmac_priv *priv)
+{
+#ifdef CONFIG_HAVE_CLK
+ u32 clk_rate;
+
+ clk_rate = clk_get_rate(priv->stmmac_clk);
+
+ /* Platform provided default clk_csr would be assumed valid
+ * for all other cases except for the below mentioned ones. */
+ if (!(priv->clk_csr & MAC_CSR_H_FRQ_MASK)) {
+ if (clk_rate < CSR_F_35M)
+ priv->clk_csr = STMMAC_CSR_20_35M;
+ else if ((clk_rate >= CSR_F_35M) && (clk_rate < CSR_F_60M))
+ priv->clk_csr = STMMAC_CSR_35_60M;
+ else if ((clk_rate >= CSR_F_60M) && (clk_rate < CSR_F_100M))
+ priv->clk_csr = STMMAC_CSR_60_100M;
+ else if ((clk_rate >= CSR_F_100M) && (clk_rate < CSR_F_150M))
+ priv->clk_csr = STMMAC_CSR_100_150M;
+ else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M))
+ priv->clk_csr = STMMAC_CSR_150_250M;
+ else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M))
+ priv->clk_csr = STMMAC_CSR_250_300M;
+ } /* For values higher than the IEEE 802.3 specified frequency
+ * we can not estimate the proper divider as it is not known
+ * the frequency of clk_csr_i. So we do not change the default
+ * divider. */
+#endif
+}
+
#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
static void print_pkt(unsigned char *buf, int len)
{
@@ -307,7 +336,13 @@
priv->speed = 0;
priv->oldduplex = -1;
- snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", priv->plat->bus_id);
+ if (priv->plat->phy_bus_name)
+ snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
+ priv->plat->phy_bus_name, priv->plat->bus_id);
+ else
+ snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
+ priv->plat->bus_id);
+
snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
priv->plat->phy_addr);
pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
@@ -898,6 +933,8 @@
struct stmmac_priv *priv = netdev_priv(dev);
int ret;
+ stmmac_clk_enable(priv);
+
stmmac_check_ether_addr(priv);
/* MDIO bus Registration */
@@ -905,13 +942,15 @@
if (ret < 0) {
pr_debug("%s: MDIO bus (id: %d) registration failed",
__func__, priv->plat->bus_id);
- return ret;
+ goto open_clk_dis;
}
#ifdef CONFIG_STMMAC_TIMER
priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
- if (unlikely(priv->tm == NULL))
- return -ENOMEM;
+ if (unlikely(priv->tm == NULL)) {
+ ret = -ENOMEM;
+ goto open_clk_dis;
+ }
priv->tm->freq = tmrate;
@@ -938,7 +977,9 @@
init_dma_desc_rings(dev);
/* DMA initialization and SW reset */
- ret = priv->hw->dma->init(priv->ioaddr, priv->plat->pbl,
+ ret = priv->hw->dma->init(priv->ioaddr, priv->plat->dma_cfg->pbl,
+ priv->plat->dma_cfg->fixed_burst,
+ priv->plat->dma_cfg->burst_len,
priv->dma_tx_phy, priv->dma_rx_phy);
if (ret < 0) {
pr_err("%s: DMA initialization failed\n", __func__);
@@ -1026,6 +1067,8 @@
if (priv->phydev)
phy_disconnect(priv->phydev);
+open_clk_dis:
+ stmmac_clk_disable(priv);
return ret;
}
@@ -1078,6 +1121,7 @@
stmmac_exit_fs();
#endif
stmmac_mdio_unregister(dev);
+ stmmac_clk_disable(priv);
return 0;
}
@@ -1276,7 +1320,8 @@
struct sk_buff *skb;
int frame_len;
- frame_len = priv->hw->desc->get_rx_frame_len(p);
+ frame_len = priv->hw->desc->get_rx_frame_len(p,
+ priv->plat->rx_coe);
/* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
* Type frames (LLC/LLC-SNAP) */
if (unlikely(status != llc_snap))
@@ -1312,7 +1357,7 @@
#endif
skb->protocol = eth_type_trans(skb, priv->dev);
- if (unlikely(!priv->rx_coe)) {
+ if (unlikely(!priv->plat->rx_coe)) {
/* No RX COE for old mac10/100 devices */
skb_checksum_none_assert(skb);
netif_receive_skb(skb);
@@ -1459,8 +1504,10 @@
{
struct stmmac_priv *priv = netdev_priv(dev);
- if (!priv->rx_coe)
+ if (priv->plat->rx_coe == STMMAC_RX_COE_NONE)
features &= ~NETIF_F_RXCSUM;
+ else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1)
+ features &= ~NETIF_F_IPV6_CSUM;
if (!priv->plat->tx_coe)
features &= ~NETIF_F_ALL_CSUM;
@@ -1765,17 +1812,32 @@
* register (if supported).
*/
priv->plat->enh_desc = priv->dma_cap.enh_desc;
- priv->plat->tx_coe = priv->dma_cap.tx_coe;
priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up;
+
+ priv->plat->tx_coe = priv->dma_cap.tx_coe;
+
+ if (priv->dma_cap.rx_coe_type2)
+ priv->plat->rx_coe = STMMAC_RX_COE_TYPE2;
+ else if (priv->dma_cap.rx_coe_type1)
+ priv->plat->rx_coe = STMMAC_RX_COE_TYPE1;
+
} else
pr_info(" No HW DMA feature register supported");
/* Select the enhnaced/normal descriptor structures */
stmmac_selec_desc_mode(priv);
- priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
- if (priv->rx_coe)
- pr_info(" RX Checksum Offload Engine supported\n");
+ /* Enable the IPC (Checksum Offload) and check if the feature has been
+ * enabled during the core configuration. */
+ ret = priv->hw->mac->rx_ipc(priv->ioaddr);
+ if (!ret) {
+ pr_warning(" RX IPC Checksum Offload not configured.\n");
+ priv->plat->rx_coe = STMMAC_RX_COE_NONE;
+ }
+
+ if (priv->plat->rx_coe)
+ pr_info(" RX Checksum Offload Engine supported (type %d)\n",
+ priv->plat->rx_coe);
if (priv->plat->tx_coe)
pr_info(" TX Checksum insertion supported\n");
@@ -1856,6 +1918,20 @@
goto error;
}
+ if (stmmac_clk_get(priv))
+ goto error;
+
+ /* If a specific clk_csr value is passed from the platform
+ * this means that the CSR Clock Range selection cannot be
+ * changed at run-time and it is fixed. Viceversa the driver'll try to
+ * set the MDC clock dynamically according to the csr actual
+ * clock input.
+ */
+ if (!priv->plat->clk_csr)
+ stmmac_clk_csr_set(priv);
+ else
+ priv->clk_csr = priv->plat->clk_csr;
+
return priv;
error:
@@ -1925,9 +2001,11 @@
/* Enable Power down mode by programming the PMT regs */
if (device_may_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
- else
+ else {
stmmac_set_mac(priv->ioaddr, false);
-
+ /* Disable clock in case of PWM is off */
+ stmmac_clk_disable(priv);
+ }
spin_unlock(&priv->lock);
return 0;
}
@@ -1948,6 +2026,9 @@
* from another devices (e.g. serial console). */
if (device_may_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, 0);
+ else
+ /* enable the clk prevously disabled */
+ stmmac_clk_enable(priv);
netif_device_attach(ndev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 7319532..ade1082 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -34,6 +34,22 @@
#define MII_BUSY 0x00000001
#define MII_WRITE 0x00000002
+static int stmmac_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_addr)
+{
+ unsigned long curr;
+ unsigned long finish = jiffies + 3 * HZ;
+
+ do {
+ curr = jiffies;
+ if (readl(ioaddr + mii_addr) & MII_BUSY)
+ cpu_relax();
+ else
+ return 0;
+ } while (!time_after_eq(curr, finish));
+
+ return -EBUSY;
+}
+
/**
* stmmac_mdio_read
* @bus: points to the mii_bus structure
@@ -54,11 +70,15 @@
int data;
u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
((phyreg << 6) & (0x000007C0)));
- regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
+ regValue |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+ if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
+ return -EBUSY;
+
writel(regValue, priv->ioaddr + mii_address);
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+
+ if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
+ return -EBUSY;
/* Read the data from the MII data register */
data = (int)readl(priv->ioaddr + mii_data);
@@ -86,20 +106,18 @@
(((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
| MII_WRITE;
- value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
-
+ value |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
/* Wait until any existing MII operation is complete */
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+ if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
+ return -EBUSY;
/* Set the MII address register to write */
writel(phydata, priv->ioaddr + mii_data);
writel(value, priv->ioaddr + mii_address);
/* Wait until any existing MII operation is complete */
- do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
-
- return 0;
+ return stmmac_mdio_busy_wait(priv->ioaddr, mii_address);
}
/**
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index da66ed7..65e0f98 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -35,7 +35,8 @@
plat_dat.bus_id = 1;
plat_dat.phy_addr = 0;
plat_dat.interface = PHY_INTERFACE_MODE_GMII;
- plat_dat.pbl = 32;
+ plat_dat.dma_cfg->pbl = 32;
+ plat_dat.dma_cfg->burst_len = DMA_AXI_BLEN_256;
plat_dat.clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
plat_dat.has_gmac = 1;
plat_dat.force_sf_dma_mode = 1;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 116529a..12bd221 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -50,7 +50,7 @@
* once needed on other platforms.
*/
if (of_device_is_compatible(np, "st,spear600-gmac")) {
- plat->pbl = 8;
+ plat->dma_cfg->pbl = 8;
plat->has_gmac = 1;
plat->pmt = 1;
}
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index 558409f..dfd4b1d 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -2898,7 +2898,6 @@
}
gp->pdev = pdev;
- dev->base_addr = (long) pdev;
gp->dev = dev;
gp->msg_enable = DEFAULT_MSG;
@@ -2972,7 +2971,6 @@
netif_napi_add(dev, &gp->napi, gem_poll, 64);
dev->ethtool_ops = &gem_ethtool_ops;
dev->watchdog_timeo = 5 * HZ;
- dev->irq = pdev->irq;
dev->dma = 0;
/* Set that now, in case PM kicks in now */
diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index b95e7e6..dfc00c4 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -2182,11 +2182,12 @@
* into a single source which we register handling at probe time.
*/
if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) {
- if (request_irq(dev->irq, happy_meal_interrupt,
- IRQF_SHARED, dev->name, (void *)dev)) {
+ res = request_irq(hp->irq, happy_meal_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (res) {
HMD(("EAGAIN\n"));
printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n",
- dev->irq);
+ hp->irq);
return -EAGAIN;
}
@@ -2199,7 +2200,7 @@
spin_unlock_irq(&hp->happy_lock);
if (res && ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO))
- free_irq(dev->irq, dev);
+ free_irq(hp->irq, dev);
return res;
}
@@ -2221,7 +2222,7 @@
* time and never unregister.
*/
if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO)
- free_irq(dev->irq, dev);
+ free_irq(hp->irq, dev);
return 0;
}
@@ -2777,7 +2778,7 @@
dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
dev->features |= dev->hw_features | NETIF_F_RXCSUM;
- dev->irq = op->archdata.irqs[0];
+ hp->irq = op->archdata.irqs[0];
#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
/* Hook up SBUS register/descriptor accessors. */
@@ -2981,8 +2982,6 @@
if (hme_version_printed++ == 0)
printk(KERN_INFO "%s", version);
- dev->base_addr = (long) pdev;
-
hp = netdev_priv(dev);
hp->happy_dev = pdev;
@@ -3087,12 +3086,11 @@
init_timer(&hp->happy_timer);
+ hp->irq = pdev->irq;
hp->dev = dev;
dev->netdev_ops = &hme_netdev_ops;
dev->watchdog_timeo = 5*HZ;
dev->ethtool_ops = &hme_ethtool_ops;
- dev->irq = pdev->irq;
- dev->dma = 0;
/* Happy Meal can do it all... */
dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
diff --git a/drivers/net/ethernet/sun/sunhme.h b/drivers/net/ethernet/sun/sunhme.h
index 64f2783..f430765 100644
--- a/drivers/net/ethernet/sun/sunhme.h
+++ b/drivers/net/ethernet/sun/sunhme.h
@@ -432,6 +432,7 @@
dma_addr_t hblock_dvma; /* DVMA visible address happy block */
unsigned int happy_flags; /* Driver state flags */
+ int irq;
enum happy_transceiver tcvr_type; /* Kind of transceiver in use */
unsigned int happy_bursts; /* Get your mind out of the gutter */
unsigned int paddr; /* PHY address for transceiver */
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c
index ad973ff..dc242e2 100644
--- a/drivers/net/ethernet/tehuti/tehuti.c
+++ b/drivers/net/ethernet/tehuti/tehuti.c
@@ -1988,10 +1988,6 @@
/* these fields are used for info purposes only
* so we can have them same for all ports of the board */
ndev->if_port = port;
- ndev->base_addr = pciaddr;
- ndev->mem_start = pciaddr;
- ndev->mem_end = pciaddr + regionSize;
- ndev->irq = pdev->irq;
ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO
| NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER | NETIF_F_RXCSUM
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 174a334..8aa3332 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -627,6 +627,7 @@
.get_link = ethtool_op_get_link,
.get_coalesce = emac_get_coalesce,
.set_coalesce = emac_set_coalesce,
+ .get_ts_info = ethtool_op_get_ts_info,
};
/**
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index fcfa01f..0459c09 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -689,9 +689,12 @@
#ifdef CONFIG_NET_POLL_CONTROLLER
static void rhine_poll(struct net_device *dev)
{
- disable_irq(dev->irq);
- rhine_interrupt(dev->irq, (void *)dev);
- enable_irq(dev->irq);
+ struct rhine_private *rp = netdev_priv(dev);
+ const int irq = rp->pdev->irq;
+
+ disable_irq(irq);
+ rhine_interrupt(irq, dev);
+ enable_irq(irq);
}
#endif
@@ -972,7 +975,6 @@
}
#endif /* USE_MMIO */
- dev->base_addr = (unsigned long)ioaddr;
rp->base = ioaddr;
/* Get chip registers into a sane state */
@@ -995,8 +997,6 @@
if (!phy_id)
phy_id = ioread8(ioaddr + 0x6C);
- dev->irq = pdev->irq;
-
spin_lock_init(&rp->lock);
mutex_init(&rp->task_lock);
INIT_WORK(&rp->reset_task, rhine_reset_task);
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index 8a5d7c1..ea3e0a2 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -2488,8 +2488,8 @@
if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED)
velocity_get_ip(vptr);
- if (dev->irq != 0)
- free_irq(dev->irq, dev);
+
+ free_irq(vptr->pdev->irq, dev);
velocity_free_rings(vptr);
@@ -2755,8 +2755,6 @@
if (ret < 0)
goto err_free_dev;
- dev->irq = pdev->irq;
-
ret = velocity_get_pci_info(vptr, pdev);
if (ret < 0) {
/* error message already printed */
@@ -2779,8 +2777,6 @@
mac_wol_reset(regs);
- dev->base_addr = vptr->ioaddr;
-
for (i = 0; i < 6; i++)
dev->dev_addr[i] = readb(®s->PAR[i]);
@@ -2806,7 +2802,6 @@
vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
- dev->irq = pdev->irq;
dev->netdev_ops = &velocity_netdev_ops;
dev->ethtool_ops = &velocity_ethtool_ops;
netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
diff --git a/drivers/net/ethernet/wiznet/Kconfig b/drivers/net/ethernet/wiznet/Kconfig
new file mode 100644
index 0000000..c8291bf
--- /dev/null
+++ b/drivers/net/ethernet/wiznet/Kconfig
@@ -0,0 +1,81 @@
+#
+# WIZnet devices configuration
+#
+
+config NET_VENDOR_WIZNET
+ bool "WIZnet devices"
+ default y
+ ---help---
+ If you have a network (Ethernet) card belonging to this class, say Y
+ and read the Ethernet-HOWTO, available from
+ <http://www.tldp.org/docs.html#howto>.
+
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about WIZnet devices. If you say Y, you will be asked
+ for your specific card in the following questions.
+
+if NET_VENDOR_WIZNET
+
+config WIZNET_W5100
+ tristate "WIZnet W5100 Ethernet support"
+ depends on HAS_IOMEM
+ ---help---
+ Support for WIZnet W5100 chips.
+
+ W5100 is a single chip with integrated 10/100 Ethernet MAC,
+ PHY and hardware TCP/IP stack, but this driver is limited to
+ the MAC and PHY functions only, onchip TCP/IP is unused.
+
+ To compile this driver as a module, choose M here: the module
+ will be called w5100.
+
+config WIZNET_W5300
+ tristate "WIZnet W5300 Ethernet support"
+ depends on HAS_IOMEM
+ ---help---
+ Support for WIZnet W5300 chips.
+
+ W5300 is a single chip with integrated 10/100 Ethernet MAC,
+ PHY and hardware TCP/IP stack, but this driver is limited to
+ the MAC and PHY functions only, onchip TCP/IP is unused.
+
+ To compile this driver as a module, choose M here: the module
+ will be called w5300.
+
+choice
+ prompt "WIZnet interface mode"
+ depends on WIZNET_W5100 || WIZNET_W5300
+ default WIZNET_BUS_ANY
+
+config WIZNET_BUS_DIRECT
+ bool "Direct address bus mode"
+ ---help---
+ In direct address mode host system can directly access all registers
+ after mapping to Memory-Mapped I/O space.
+
+config WIZNET_BUS_INDIRECT
+ bool "Indirect address bus mode"
+ ---help---
+ In indirect address mode host system indirectly accesses registers
+ using Indirect Mode Address Register and Indirect Mode Data Register,
+ which are directly mapped to Memory-Mapped I/O space.
+
+config WIZNET_BUS_ANY
+ bool "Select interface mode in runtime"
+ ---help---
+ If interface mode is unknown in compile time, it can be selected
+ in runtime from board/platform resources configuration.
+
+ Performance may decrease compared to explicitly selected bus mode.
+endchoice
+
+config WIZNET_TX_FLOW
+ bool "Use transmit flow control"
+ depends on WIZNET_W5100 || WIZNET_W5300
+ default y
+ help
+ This enables transmit flow control for WIZnet chips.
+ If unsure, say Y.
+
+endif # NET_VENDOR_WIZNET
diff --git a/drivers/net/ethernet/wiznet/Makefile b/drivers/net/ethernet/wiznet/Makefile
new file mode 100644
index 0000000..c614535
--- /dev/null
+++ b/drivers/net/ethernet/wiznet/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_WIZNET_W5100) += w5100.o
+obj-$(CONFIG_WIZNET_W5300) += w5300.o
diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiznet/w5100.c
new file mode 100644
index 0000000..c28e1d5
--- /dev/null
+++ b/drivers/net/ethernet/wiznet/w5100.c
@@ -0,0 +1,808 @@
+/*
+ * Ethernet driver for the WIZnet W5100 chip.
+ *
+ * Copyright (C) 2006-2008 WIZnet Co.,Ltd.
+ * Copyright (C) 2012 Mike Sinkovsky <msink@permonline.ru>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kconfig.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/wiznet.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#define DRV_NAME "w5100"
+#define DRV_VERSION "2012-04-04"
+
+MODULE_DESCRIPTION("WIZnet W5100 Ethernet driver v"DRV_VERSION);
+MODULE_AUTHOR("Mike Sinkovsky <msink@permonline.ru>");
+MODULE_ALIAS("platform:"DRV_NAME);
+MODULE_LICENSE("GPL");
+
+/*
+ * Registers
+ */
+#define W5100_COMMON_REGS 0x0000
+#define W5100_MR 0x0000 /* Mode Register */
+#define MR_RST 0x80 /* S/W reset */
+#define MR_PB 0x10 /* Ping block */
+#define MR_AI 0x02 /* Address Auto-Increment */
+#define MR_IND 0x01 /* Indirect mode */
+#define W5100_SHAR 0x0009 /* Source MAC address */
+#define W5100_IR 0x0015 /* Interrupt Register */
+#define W5100_IMR 0x0016 /* Interrupt Mask Register */
+#define IR_S0 0x01 /* S0 interrupt */
+#define W5100_RTR 0x0017 /* Retry Time-value Register */
+#define RTR_DEFAULT 2000 /* =0x07d0 (2000) */
+#define W5100_RMSR 0x001a /* Receive Memory Size */
+#define W5100_TMSR 0x001b /* Transmit Memory Size */
+#define W5100_COMMON_REGS_LEN 0x0040
+
+#define W5100_S0_REGS 0x0400
+#define W5100_S0_MR 0x0400 /* S0 Mode Register */
+#define S0_MR_MACRAW 0x04 /* MAC RAW mode (promiscous) */
+#define S0_MR_MACRAW_MF 0x44 /* MAC RAW mode (filtered) */
+#define W5100_S0_CR 0x0401 /* S0 Command Register */
+#define S0_CR_OPEN 0x01 /* OPEN command */
+#define S0_CR_CLOSE 0x10 /* CLOSE command */
+#define S0_CR_SEND 0x20 /* SEND command */
+#define S0_CR_RECV 0x40 /* RECV command */
+#define W5100_S0_IR 0x0402 /* S0 Interrupt Register */
+#define S0_IR_SENDOK 0x10 /* complete sending */
+#define S0_IR_RECV 0x04 /* receiving data */
+#define W5100_S0_SR 0x0403 /* S0 Status Register */
+#define S0_SR_MACRAW 0x42 /* mac raw mode */
+#define W5100_S0_TX_FSR 0x0420 /* S0 Transmit free memory size */
+#define W5100_S0_TX_RD 0x0422 /* S0 Transmit memory read pointer */
+#define W5100_S0_TX_WR 0x0424 /* S0 Transmit memory write pointer */
+#define W5100_S0_RX_RSR 0x0426 /* S0 Receive free memory size */
+#define W5100_S0_RX_RD 0x0428 /* S0 Receive memory read pointer */
+#define W5100_S0_REGS_LEN 0x0040
+
+#define W5100_TX_MEM_START 0x4000
+#define W5100_TX_MEM_END 0x5fff
+#define W5100_TX_MEM_MASK 0x1fff
+#define W5100_RX_MEM_START 0x6000
+#define W5100_RX_MEM_END 0x7fff
+#define W5100_RX_MEM_MASK 0x1fff
+
+/*
+ * Device driver private data structure
+ */
+struct w5100_priv {
+ void __iomem *base;
+ spinlock_t reg_lock;
+ bool indirect;
+ u8 (*read)(struct w5100_priv *priv, u16 addr);
+ void (*write)(struct w5100_priv *priv, u16 addr, u8 data);
+ u16 (*read16)(struct w5100_priv *priv, u16 addr);
+ void (*write16)(struct w5100_priv *priv, u16 addr, u16 data);
+ void (*readbuf)(struct w5100_priv *priv, u16 addr, u8 *buf, int len);
+ void (*writebuf)(struct w5100_priv *priv, u16 addr, u8 *buf, int len);
+ int irq;
+ int link_irq;
+ int link_gpio;
+
+ struct napi_struct napi;
+ struct net_device *ndev;
+ bool promisc;
+ u32 msg_enable;
+};
+
+/************************************************************************
+ *
+ * Lowlevel I/O functions
+ *
+ ***********************************************************************/
+
+/*
+ * In direct address mode host system can directly access W5100 registers
+ * after mapping to Memory-Mapped I/O space.
+ *
+ * 0x8000 bytes are required for memory space.
+ */
+static inline u8 w5100_read_direct(struct w5100_priv *priv, u16 addr)
+{
+ return ioread8(priv->base + (addr << CONFIG_WIZNET_BUS_SHIFT));
+}
+
+static inline void w5100_write_direct(struct w5100_priv *priv,
+ u16 addr, u8 data)
+{
+ iowrite8(data, priv->base + (addr << CONFIG_WIZNET_BUS_SHIFT));
+}
+
+static u16 w5100_read16_direct(struct w5100_priv *priv, u16 addr)
+{
+ u16 data;
+ data = w5100_read_direct(priv, addr) << 8;
+ data |= w5100_read_direct(priv, addr + 1);
+ return data;
+}
+
+static void w5100_write16_direct(struct w5100_priv *priv, u16 addr, u16 data)
+{
+ w5100_write_direct(priv, addr, data >> 8);
+ w5100_write_direct(priv, addr + 1, data);
+}
+
+static void w5100_readbuf_direct(struct w5100_priv *priv,
+ u16 offset, u8 *buf, int len)
+{
+ u16 addr = W5100_RX_MEM_START + (offset & W5100_RX_MEM_MASK);
+ int i;
+
+ for (i = 0; i < len; i++, addr++) {
+ if (unlikely(addr > W5100_RX_MEM_END))
+ addr = W5100_RX_MEM_START;
+ *buf++ = w5100_read_direct(priv, addr);
+ }
+}
+
+static void w5100_writebuf_direct(struct w5100_priv *priv,
+ u16 offset, u8 *buf, int len)
+{
+ u16 addr = W5100_TX_MEM_START + (offset & W5100_TX_MEM_MASK);
+ int i;
+
+ for (i = 0; i < len; i++, addr++) {
+ if (unlikely(addr > W5100_TX_MEM_END))
+ addr = W5100_TX_MEM_START;
+ w5100_write_direct(priv, addr, *buf++);
+ }
+}
+
+/*
+ * In indirect address mode host system indirectly accesses registers by
+ * using Indirect Mode Address Register (IDM_AR) and Indirect Mode Data
+ * Register (IDM_DR), which are directly mapped to Memory-Mapped I/O space.
+ * Mode Register (MR) is directly accessible.
+ *
+ * Only 0x04 bytes are required for memory space.
+ */
+#define W5100_IDM_AR 0x01 /* Indirect Mode Address Register */
+#define W5100_IDM_DR 0x03 /* Indirect Mode Data Register */
+
+static u8 w5100_read_indirect(struct w5100_priv *priv, u16 addr)
+{
+ unsigned long flags;
+ u8 data;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ w5100_write16_direct(priv, W5100_IDM_AR, addr);
+ mmiowb();
+ data = w5100_read_direct(priv, W5100_IDM_DR);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+ return data;
+}
+
+static void w5100_write_indirect(struct w5100_priv *priv, u16 addr, u8 data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ w5100_write16_direct(priv, W5100_IDM_AR, addr);
+ mmiowb();
+ w5100_write_direct(priv, W5100_IDM_DR, data);
+ mmiowb();
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+static u16 w5100_read16_indirect(struct w5100_priv *priv, u16 addr)
+{
+ unsigned long flags;
+ u16 data;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ w5100_write16_direct(priv, W5100_IDM_AR, addr);
+ mmiowb();
+ data = w5100_read_direct(priv, W5100_IDM_DR) << 8;
+ data |= w5100_read_direct(priv, W5100_IDM_DR);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+ return data;
+}
+
+static void w5100_write16_indirect(struct w5100_priv *priv, u16 addr, u16 data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ w5100_write16_direct(priv, W5100_IDM_AR, addr);
+ mmiowb();
+ w5100_write_direct(priv, W5100_IDM_DR, data >> 8);
+ w5100_write_direct(priv, W5100_IDM_DR, data);
+ mmiowb();
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+static void w5100_readbuf_indirect(struct w5100_priv *priv,
+ u16 offset, u8 *buf, int len)
+{
+ u16 addr = W5100_RX_MEM_START + (offset & W5100_RX_MEM_MASK);
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ w5100_write16_direct(priv, W5100_IDM_AR, addr);
+ mmiowb();
+
+ for (i = 0; i < len; i++, addr++) {
+ if (unlikely(addr > W5100_RX_MEM_END)) {
+ addr = W5100_RX_MEM_START;
+ w5100_write16_direct(priv, W5100_IDM_AR, addr);
+ mmiowb();
+ }
+ *buf++ = w5100_read_direct(priv, W5100_IDM_DR);
+ }
+ mmiowb();
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+static void w5100_writebuf_indirect(struct w5100_priv *priv,
+ u16 offset, u8 *buf, int len)
+{
+ u16 addr = W5100_TX_MEM_START + (offset & W5100_TX_MEM_MASK);
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ w5100_write16_direct(priv, W5100_IDM_AR, addr);
+ mmiowb();
+
+ for (i = 0; i < len; i++, addr++) {
+ if (unlikely(addr > W5100_TX_MEM_END)) {
+ addr = W5100_TX_MEM_START;
+ w5100_write16_direct(priv, W5100_IDM_AR, addr);
+ mmiowb();
+ }
+ w5100_write_direct(priv, W5100_IDM_DR, *buf++);
+ }
+ mmiowb();
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+#if defined(CONFIG_WIZNET_BUS_DIRECT)
+#define w5100_read w5100_read_direct
+#define w5100_write w5100_write_direct
+#define w5100_read16 w5100_read16_direct
+#define w5100_write16 w5100_write16_direct
+#define w5100_readbuf w5100_readbuf_direct
+#define w5100_writebuf w5100_writebuf_direct
+
+#elif defined(CONFIG_WIZNET_BUS_INDIRECT)
+#define w5100_read w5100_read_indirect
+#define w5100_write w5100_write_indirect
+#define w5100_read16 w5100_read16_indirect
+#define w5100_write16 w5100_write16_indirect
+#define w5100_readbuf w5100_readbuf_indirect
+#define w5100_writebuf w5100_writebuf_indirect
+
+#else /* CONFIG_WIZNET_BUS_ANY */
+#define w5100_read priv->read
+#define w5100_write priv->write
+#define w5100_read16 priv->read16
+#define w5100_write16 priv->write16
+#define w5100_readbuf priv->readbuf
+#define w5100_writebuf priv->writebuf
+#endif
+
+static int w5100_command(struct w5100_priv *priv, u16 cmd)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+ w5100_write(priv, W5100_S0_CR, cmd);
+ mmiowb();
+
+ while (w5100_read(priv, W5100_S0_CR) != 0) {
+ if (time_after(jiffies, timeout))
+ return -EIO;
+ cpu_relax();
+ }
+
+ return 0;
+}
+
+static void w5100_write_macaddr(struct w5100_priv *priv)
+{
+ struct net_device *ndev = priv->ndev;
+ int i;
+
+ for (i = 0; i < ETH_ALEN; i++)
+ w5100_write(priv, W5100_SHAR + i, ndev->dev_addr[i]);
+ mmiowb();
+}
+
+static void w5100_hw_reset(struct w5100_priv *priv)
+{
+ w5100_write_direct(priv, W5100_MR, MR_RST);
+ mmiowb();
+ mdelay(5);
+ w5100_write_direct(priv, W5100_MR, priv->indirect ?
+ MR_PB | MR_AI | MR_IND :
+ MR_PB);
+ mmiowb();
+ w5100_write(priv, W5100_IMR, 0);
+ w5100_write_macaddr(priv);
+
+ /* Configure 16K of internal memory
+ * as 8K RX buffer and 8K TX buffer
+ */
+ w5100_write(priv, W5100_RMSR, 0x03);
+ w5100_write(priv, W5100_TMSR, 0x03);
+ mmiowb();
+}
+
+static void w5100_hw_start(struct w5100_priv *priv)
+{
+ w5100_write(priv, W5100_S0_MR, priv->promisc ?
+ S0_MR_MACRAW : S0_MR_MACRAW_MF);
+ mmiowb();
+ w5100_command(priv, S0_CR_OPEN);
+ w5100_write(priv, W5100_IMR, IR_S0);
+ mmiowb();
+}
+
+static void w5100_hw_close(struct w5100_priv *priv)
+{
+ w5100_write(priv, W5100_IMR, 0);
+ mmiowb();
+ w5100_command(priv, S0_CR_CLOSE);
+}
+
+/***********************************************************************
+ *
+ * Device driver functions / callbacks
+ *
+ ***********************************************************************/
+
+static void w5100_get_drvinfo(struct net_device *ndev,
+ struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ strlcpy(info->bus_info, dev_name(ndev->dev.parent),
+ sizeof(info->bus_info));
+}
+
+static u32 w5100_get_link(struct net_device *ndev)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ if (gpio_is_valid(priv->link_gpio))
+ return !!gpio_get_value(priv->link_gpio);
+
+ return 1;
+}
+
+static u32 w5100_get_msglevel(struct net_device *ndev)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ return priv->msg_enable;
+}
+
+static void w5100_set_msglevel(struct net_device *ndev, u32 value)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ priv->msg_enable = value;
+}
+
+static int w5100_get_regs_len(struct net_device *ndev)
+{
+ return W5100_COMMON_REGS_LEN + W5100_S0_REGS_LEN;
+}
+
+static void w5100_get_regs(struct net_device *ndev,
+ struct ethtool_regs *regs, void *_buf)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+ u8 *buf = _buf;
+ u16 i;
+
+ regs->version = 1;
+ for (i = 0; i < W5100_COMMON_REGS_LEN; i++)
+ *buf++ = w5100_read(priv, W5100_COMMON_REGS + i);
+ for (i = 0; i < W5100_S0_REGS_LEN; i++)
+ *buf++ = w5100_read(priv, W5100_S0_REGS + i);
+}
+
+static void w5100_tx_timeout(struct net_device *ndev)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ netif_stop_queue(ndev);
+ w5100_hw_reset(priv);
+ w5100_hw_start(priv);
+ ndev->stats.tx_errors++;
+ ndev->trans_start = jiffies;
+ netif_wake_queue(ndev);
+}
+
+static int w5100_start_tx(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+ u16 offset;
+
+ if (IS_ENABLED(CONFIG_WIZNET_TX_FLOW))
+ netif_stop_queue(ndev);
+
+ offset = w5100_read16(priv, W5100_S0_TX_WR);
+ w5100_writebuf(priv, offset, skb->data, skb->len);
+ w5100_write16(priv, W5100_S0_TX_WR, offset + skb->len);
+ mmiowb();
+ ndev->stats.tx_bytes += skb->len;
+ ndev->stats.tx_packets++;
+ dev_kfree_skb(skb);
+
+ w5100_command(priv, S0_CR_SEND);
+
+ return NETDEV_TX_OK;
+}
+
+static int w5100_napi_poll(struct napi_struct *napi, int budget)
+{
+ struct w5100_priv *priv = container_of(napi, struct w5100_priv, napi);
+ struct net_device *ndev = priv->ndev;
+ struct sk_buff *skb;
+ int rx_count;
+ u16 rx_len;
+ u16 offset;
+ u8 header[2];
+
+ for (rx_count = 0; rx_count < budget; rx_count++) {
+ u16 rx_buf_len = w5100_read16(priv, W5100_S0_RX_RSR);
+ if (rx_buf_len == 0)
+ break;
+
+ offset = w5100_read16(priv, W5100_S0_RX_RD);
+ w5100_readbuf(priv, offset, header, 2);
+ rx_len = get_unaligned_be16(header) - 2;
+
+ skb = netdev_alloc_skb_ip_align(ndev, rx_len);
+ if (unlikely(!skb)) {
+ w5100_write16(priv, W5100_S0_RX_RD,
+ offset + rx_buf_len);
+ w5100_command(priv, S0_CR_RECV);
+ ndev->stats.rx_dropped++;
+ return -ENOMEM;
+ }
+
+ skb_put(skb, rx_len);
+ w5100_readbuf(priv, offset + 2, skb->data, rx_len);
+ w5100_write16(priv, W5100_S0_RX_RD, offset + 2 + rx_len);
+ mmiowb();
+ w5100_command(priv, S0_CR_RECV);
+ skb->protocol = eth_type_trans(skb, ndev);
+
+ netif_receive_skb(skb);
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += rx_len;
+ }
+
+ if (rx_count < budget) {
+ w5100_write(priv, W5100_IMR, IR_S0);
+ mmiowb();
+ napi_complete(napi);
+ }
+
+ return rx_count;
+}
+
+static irqreturn_t w5100_interrupt(int irq, void *ndev_instance)
+{
+ struct net_device *ndev = ndev_instance;
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ int ir = w5100_read(priv, W5100_S0_IR);
+ if (!ir)
+ return IRQ_NONE;
+ w5100_write(priv, W5100_S0_IR, ir);
+ mmiowb();
+
+ if (IS_ENABLED(CONFIG_WIZNET_TX_FLOW) && (ir & S0_IR_SENDOK)) {
+ netif_dbg(priv, tx_done, ndev, "tx done\n");
+ netif_wake_queue(ndev);
+ }
+
+ if (ir & S0_IR_RECV) {
+ if (napi_schedule_prep(&priv->napi)) {
+ w5100_write(priv, W5100_IMR, 0);
+ mmiowb();
+ __napi_schedule(&priv->napi);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t w5100_detect_link(int irq, void *ndev_instance)
+{
+ struct net_device *ndev = ndev_instance;
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ if (netif_running(ndev)) {
+ if (gpio_get_value(priv->link_gpio) != 0) {
+ netif_info(priv, link, ndev, "link is up\n");
+ netif_carrier_on(ndev);
+ } else {
+ netif_info(priv, link, ndev, "link is down\n");
+ netif_carrier_off(ndev);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void w5100_set_rx_mode(struct net_device *ndev)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+ bool set_promisc = (ndev->flags & IFF_PROMISC) != 0;
+
+ if (priv->promisc != set_promisc) {
+ priv->promisc = set_promisc;
+ w5100_hw_start(priv);
+ }
+}
+
+static int w5100_set_macaddr(struct net_device *ndev, void *addr)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+ struct sockaddr *sock_addr = addr;
+
+ if (!is_valid_ether_addr(sock_addr->sa_data))
+ return -EADDRNOTAVAIL;
+ memcpy(ndev->dev_addr, sock_addr->sa_data, ETH_ALEN);
+ ndev->addr_assign_type &= ~NET_ADDR_RANDOM;
+ w5100_write_macaddr(priv);
+ return 0;
+}
+
+static int w5100_open(struct net_device *ndev)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ netif_info(priv, ifup, ndev, "enabling\n");
+ if (!is_valid_ether_addr(ndev->dev_addr))
+ return -EINVAL;
+ w5100_hw_start(priv);
+ napi_enable(&priv->napi);
+ netif_start_queue(ndev);
+ if (!gpio_is_valid(priv->link_gpio) ||
+ gpio_get_value(priv->link_gpio) != 0)
+ netif_carrier_on(ndev);
+ return 0;
+}
+
+static int w5100_stop(struct net_device *ndev)
+{
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ netif_info(priv, ifdown, ndev, "shutting down\n");
+ w5100_hw_close(priv);
+ netif_carrier_off(ndev);
+ netif_stop_queue(ndev);
+ napi_disable(&priv->napi);
+ return 0;
+}
+
+static const struct ethtool_ops w5100_ethtool_ops = {
+ .get_drvinfo = w5100_get_drvinfo,
+ .get_msglevel = w5100_get_msglevel,
+ .set_msglevel = w5100_set_msglevel,
+ .get_link = w5100_get_link,
+ .get_regs_len = w5100_get_regs_len,
+ .get_regs = w5100_get_regs,
+};
+
+static const struct net_device_ops w5100_netdev_ops = {
+ .ndo_open = w5100_open,
+ .ndo_stop = w5100_stop,
+ .ndo_start_xmit = w5100_start_tx,
+ .ndo_tx_timeout = w5100_tx_timeout,
+ .ndo_set_rx_mode = w5100_set_rx_mode,
+ .ndo_set_mac_address = w5100_set_macaddr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+};
+
+static int __devinit w5100_hw_probe(struct platform_device *pdev)
+{
+ struct wiznet_platform_data *data = pdev->dev.platform_data;
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct w5100_priv *priv = netdev_priv(ndev);
+ const char *name = netdev_name(ndev);
+ struct resource *mem;
+ int mem_size;
+ int irq;
+ int ret;
+
+ if (data && is_valid_ether_addr(data->mac_addr)) {
+ memcpy(ndev->dev_addr, data->mac_addr, ETH_ALEN);
+ } else {
+ random_ether_addr(ndev->dev_addr);
+ ndev->addr_assign_type |= NET_ADDR_RANDOM;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return -ENXIO;
+ mem_size = resource_size(mem);
+ if (!devm_request_mem_region(&pdev->dev, mem->start, mem_size, name))
+ return -EBUSY;
+ priv->base = devm_ioremap(&pdev->dev, mem->start, mem_size);
+ if (!priv->base)
+ return -EBUSY;
+
+ spin_lock_init(&priv->reg_lock);
+ priv->indirect = mem_size < W5100_BUS_DIRECT_SIZE;
+ if (priv->indirect) {
+ priv->read = w5100_read_indirect;
+ priv->write = w5100_write_indirect;
+ priv->read16 = w5100_read16_indirect;
+ priv->write16 = w5100_write16_indirect;
+ priv->readbuf = w5100_readbuf_indirect;
+ priv->writebuf = w5100_writebuf_indirect;
+ } else {
+ priv->read = w5100_read_direct;
+ priv->write = w5100_write_direct;
+ priv->read16 = w5100_read16_direct;
+ priv->write16 = w5100_write16_direct;
+ priv->readbuf = w5100_readbuf_direct;
+ priv->writebuf = w5100_writebuf_direct;
+ }
+
+ w5100_hw_reset(priv);
+ if (w5100_read16(priv, W5100_RTR) != RTR_DEFAULT)
+ return -ENODEV;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+ ret = request_irq(irq, w5100_interrupt,
+ IRQ_TYPE_LEVEL_LOW, name, ndev);
+ if (ret < 0)
+ return ret;
+ priv->irq = irq;
+
+ priv->link_gpio = data->link_gpio;
+ if (gpio_is_valid(priv->link_gpio)) {
+ char *link_name = devm_kzalloc(&pdev->dev, 16, GFP_KERNEL);
+ if (!link_name)
+ return -ENOMEM;
+ snprintf(link_name, 16, "%s-link", name);
+ priv->link_irq = gpio_to_irq(priv->link_gpio);
+ if (request_any_context_irq(priv->link_irq, w5100_detect_link,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ link_name, priv->ndev) < 0)
+ priv->link_gpio = -EINVAL;
+ }
+
+ netdev_info(ndev, "at 0x%llx irq %d\n", (u64)mem->start, irq);
+ return 0;
+}
+
+static int __devinit w5100_probe(struct platform_device *pdev)
+{
+ struct w5100_priv *priv;
+ struct net_device *ndev;
+ int err;
+
+ ndev = alloc_etherdev(sizeof(*priv));
+ if (!ndev)
+ return -ENOMEM;
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+ platform_set_drvdata(pdev, ndev);
+ priv = netdev_priv(ndev);
+ priv->ndev = ndev;
+
+ ether_setup(ndev);
+ ndev->netdev_ops = &w5100_netdev_ops;
+ ndev->ethtool_ops = &w5100_ethtool_ops;
+ ndev->watchdog_timeo = HZ;
+ netif_napi_add(ndev, &priv->napi, w5100_napi_poll, 16);
+
+ /* This chip doesn't support VLAN packets with normal MTU,
+ * so disable VLAN for this device.
+ */
+ ndev->features |= NETIF_F_VLAN_CHALLENGED;
+
+ err = register_netdev(ndev);
+ if (err < 0)
+ goto err_register;
+
+ err = w5100_hw_probe(pdev);
+ if (err < 0)
+ goto err_hw_probe;
+
+ return 0;
+
+err_hw_probe:
+ unregister_netdev(ndev);
+err_register:
+ free_netdev(ndev);
+ platform_set_drvdata(pdev, NULL);
+ return err;
+}
+
+static int __devexit w5100_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ w5100_hw_reset(priv);
+ free_irq(priv->irq, ndev);
+ if (gpio_is_valid(priv->link_gpio))
+ free_irq(priv->link_irq, ndev);
+
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int w5100_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ if (netif_running(ndev)) {
+ netif_carrier_off(ndev);
+ netif_device_detach(ndev);
+
+ w5100_hw_close(priv);
+ }
+ return 0;
+}
+
+static int w5100_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct w5100_priv *priv = netdev_priv(ndev);
+
+ if (netif_running(ndev)) {
+ w5100_hw_reset(priv);
+ w5100_hw_start(priv);
+
+ netif_device_attach(ndev);
+ if (!gpio_is_valid(priv->link_gpio) ||
+ gpio_get_value(priv->link_gpio) != 0)
+ netif_carrier_on(ndev);
+ }
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static SIMPLE_DEV_PM_OPS(w5100_pm_ops, w5100_suspend, w5100_resume);
+
+static struct platform_driver w5100_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &w5100_pm_ops,
+ },
+ .probe = w5100_probe,
+ .remove = __devexit_p(w5100_remove),
+};
+
+module_platform_driver(w5100_driver);
diff --git a/drivers/net/ethernet/wiznet/w5300.c b/drivers/net/ethernet/wiznet/w5300.c
new file mode 100644
index 0000000..88afde9
--- /dev/null
+++ b/drivers/net/ethernet/wiznet/w5300.c
@@ -0,0 +1,722 @@
+/*
+ * Ethernet driver for the WIZnet W5300 chip.
+ *
+ * Copyright (C) 2008-2009 WIZnet Co.,Ltd.
+ * Copyright (C) 2011 Taehun Kim <kth3321 <at> gmail.com>
+ * Copyright (C) 2012 Mike Sinkovsky <msink@permonline.ru>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kconfig.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/wiznet.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#define DRV_NAME "w5300"
+#define DRV_VERSION "2012-04-04"
+
+MODULE_DESCRIPTION("WIZnet W5300 Ethernet driver v"DRV_VERSION);
+MODULE_AUTHOR("Mike Sinkovsky <msink@permonline.ru>");
+MODULE_ALIAS("platform:"DRV_NAME);
+MODULE_LICENSE("GPL");
+
+/*
+ * Registers
+ */
+#define W5300_MR 0x0000 /* Mode Register */
+#define MR_DBW (1 << 15) /* Data bus width */
+#define MR_MPF (1 << 14) /* Mac layer pause frame */
+#define MR_WDF(n) (((n)&7)<<11) /* Write data fetch time */
+#define MR_RDH (1 << 10) /* Read data hold time */
+#define MR_FS (1 << 8) /* FIFO swap */
+#define MR_RST (1 << 7) /* S/W reset */
+#define MR_PB (1 << 4) /* Ping block */
+#define MR_DBS (1 << 2) /* Data bus swap */
+#define MR_IND (1 << 0) /* Indirect mode */
+#define W5300_IR 0x0002 /* Interrupt Register */
+#define W5300_IMR 0x0004 /* Interrupt Mask Register */
+#define IR_S0 0x0001 /* S0 interrupt */
+#define W5300_SHARL 0x0008 /* Source MAC address (0123) */
+#define W5300_SHARH 0x000c /* Source MAC address (45) */
+#define W5300_TMSRL 0x0020 /* Transmit Memory Size (0123) */
+#define W5300_TMSRH 0x0024 /* Transmit Memory Size (4567) */
+#define W5300_RMSRL 0x0028 /* Receive Memory Size (0123) */
+#define W5300_RMSRH 0x002c /* Receive Memory Size (4567) */
+#define W5300_MTYPE 0x0030 /* Memory Type */
+#define W5300_IDR 0x00fe /* Chip ID register */
+#define IDR_W5300 0x5300 /* =0x5300 for WIZnet W5300 */
+#define W5300_S0_MR 0x0200 /* S0 Mode Register */
+#define S0_MR_CLOSED 0x0000 /* Close mode */
+#define S0_MR_MACRAW 0x0004 /* MAC RAW mode (promiscous) */
+#define S0_MR_MACRAW_MF 0x0044 /* MAC RAW mode (filtered) */
+#define W5300_S0_CR 0x0202 /* S0 Command Register */
+#define S0_CR_OPEN 0x0001 /* OPEN command */
+#define S0_CR_CLOSE 0x0010 /* CLOSE command */
+#define S0_CR_SEND 0x0020 /* SEND command */
+#define S0_CR_RECV 0x0040 /* RECV command */
+#define W5300_S0_IMR 0x0204 /* S0 Interrupt Mask Register */
+#define W5300_S0_IR 0x0206 /* S0 Interrupt Register */
+#define S0_IR_RECV 0x0004 /* Receive interrupt */
+#define S0_IR_SENDOK 0x0010 /* Send OK interrupt */
+#define W5300_S0_SSR 0x0208 /* S0 Socket Status Register */
+#define W5300_S0_TX_WRSR 0x0220 /* S0 TX Write Size Register */
+#define W5300_S0_TX_FSR 0x0224 /* S0 TX Free Size Register */
+#define W5300_S0_RX_RSR 0x0228 /* S0 Received data Size */
+#define W5300_S0_TX_FIFO 0x022e /* S0 Transmit FIFO */
+#define W5300_S0_RX_FIFO 0x0230 /* S0 Receive FIFO */
+#define W5300_REGS_LEN 0x0400
+
+/*
+ * Device driver private data structure
+ */
+struct w5300_priv {
+ void __iomem *base;
+ spinlock_t reg_lock;
+ bool indirect;
+ u16 (*read) (struct w5300_priv *priv, u16 addr);
+ void (*write)(struct w5300_priv *priv, u16 addr, u16 data);
+ int irq;
+ int link_irq;
+ int link_gpio;
+
+ struct napi_struct napi;
+ struct net_device *ndev;
+ bool promisc;
+ u32 msg_enable;
+};
+
+/************************************************************************
+ *
+ * Lowlevel I/O functions
+ *
+ ***********************************************************************/
+
+/*
+ * In direct address mode host system can directly access W5300 registers
+ * after mapping to Memory-Mapped I/O space.
+ *
+ * 0x400 bytes are required for memory space.
+ */
+static inline u16 w5300_read_direct(struct w5300_priv *priv, u16 addr)
+{
+ return ioread16(priv->base + (addr << CONFIG_WIZNET_BUS_SHIFT));
+}
+
+static inline void w5300_write_direct(struct w5300_priv *priv,
+ u16 addr, u16 data)
+{
+ iowrite16(data, priv->base + (addr << CONFIG_WIZNET_BUS_SHIFT));
+}
+
+/*
+ * In indirect address mode host system indirectly accesses registers by
+ * using Indirect Mode Address Register (IDM_AR) and Indirect Mode Data
+ * Register (IDM_DR), which are directly mapped to Memory-Mapped I/O space.
+ * Mode Register (MR) is directly accessible.
+ *
+ * Only 0x06 bytes are required for memory space.
+ */
+#define W5300_IDM_AR 0x0002 /* Indirect Mode Address */
+#define W5300_IDM_DR 0x0004 /* Indirect Mode Data */
+
+static u16 w5300_read_indirect(struct w5300_priv *priv, u16 addr)
+{
+ unsigned long flags;
+ u16 data;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ w5300_write_direct(priv, W5300_IDM_AR, addr);
+ mmiowb();
+ data = w5300_read_direct(priv, W5300_IDM_DR);
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+ return data;
+}
+
+static void w5300_write_indirect(struct w5300_priv *priv, u16 addr, u16 data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->reg_lock, flags);
+ w5300_write_direct(priv, W5300_IDM_AR, addr);
+ mmiowb();
+ w5300_write_direct(priv, W5300_IDM_DR, data);
+ mmiowb();
+ spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+#if defined(CONFIG_WIZNET_BUS_DIRECT)
+#define w5300_read w5300_read_direct
+#define w5300_write w5300_write_direct
+
+#elif defined(CONFIG_WIZNET_BUS_INDIRECT)
+#define w5300_read w5300_read_indirect
+#define w5300_write w5300_write_indirect
+
+#else /* CONFIG_WIZNET_BUS_ANY */
+#define w5300_read priv->read
+#define w5300_write priv->write
+#endif
+
+static u32 w5300_read32(struct w5300_priv *priv, u16 addr)
+{
+ u32 data;
+ data = w5300_read(priv, addr) << 16;
+ data |= w5300_read(priv, addr + 2);
+ return data;
+}
+
+static void w5300_write32(struct w5300_priv *priv, u16 addr, u32 data)
+{
+ w5300_write(priv, addr, data >> 16);
+ w5300_write(priv, addr + 2, data);
+}
+
+static int w5300_command(struct w5300_priv *priv, u16 cmd)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+
+ w5300_write(priv, W5300_S0_CR, cmd);
+ mmiowb();
+
+ while (w5300_read(priv, W5300_S0_CR) != 0) {
+ if (time_after(jiffies, timeout))
+ return -EIO;
+ cpu_relax();
+ }
+
+ return 0;
+}
+
+static void w5300_read_frame(struct w5300_priv *priv, u8 *buf, int len)
+{
+ u16 fifo;
+ int i;
+
+ for (i = 0; i < len; i += 2) {
+ fifo = w5300_read(priv, W5300_S0_RX_FIFO);
+ *buf++ = fifo >> 8;
+ *buf++ = fifo;
+ }
+ fifo = w5300_read(priv, W5300_S0_RX_FIFO);
+ fifo = w5300_read(priv, W5300_S0_RX_FIFO);
+}
+
+static void w5300_write_frame(struct w5300_priv *priv, u8 *buf, int len)
+{
+ u16 fifo;
+ int i;
+
+ for (i = 0; i < len; i += 2) {
+ fifo = *buf++ << 8;
+ fifo |= *buf++;
+ w5300_write(priv, W5300_S0_TX_FIFO, fifo);
+ }
+ w5300_write32(priv, W5300_S0_TX_WRSR, len);
+}
+
+static void w5300_write_macaddr(struct w5300_priv *priv)
+{
+ struct net_device *ndev = priv->ndev;
+ w5300_write32(priv, W5300_SHARL,
+ ndev->dev_addr[0] << 24 |
+ ndev->dev_addr[1] << 16 |
+ ndev->dev_addr[2] << 8 |
+ ndev->dev_addr[3]);
+ w5300_write(priv, W5300_SHARH,
+ ndev->dev_addr[4] << 8 |
+ ndev->dev_addr[5]);
+ mmiowb();
+}
+
+static void w5300_hw_reset(struct w5300_priv *priv)
+{
+ w5300_write_direct(priv, W5300_MR, MR_RST);
+ mmiowb();
+ mdelay(5);
+ w5300_write_direct(priv, W5300_MR, priv->indirect ?
+ MR_WDF(7) | MR_PB | MR_IND :
+ MR_WDF(7) | MR_PB);
+ mmiowb();
+ w5300_write(priv, W5300_IMR, 0);
+ w5300_write_macaddr(priv);
+
+ /* Configure 128K of internal memory
+ * as 64K RX fifo and 64K TX fifo
+ */
+ w5300_write32(priv, W5300_RMSRL, 64 << 24);
+ w5300_write32(priv, W5300_RMSRH, 0);
+ w5300_write32(priv, W5300_TMSRL, 64 << 24);
+ w5300_write32(priv, W5300_TMSRH, 0);
+ w5300_write(priv, W5300_MTYPE, 0x00ff);
+ mmiowb();
+}
+
+static void w5300_hw_start(struct w5300_priv *priv)
+{
+ w5300_write(priv, W5300_S0_MR, priv->promisc ?
+ S0_MR_MACRAW : S0_MR_MACRAW_MF);
+ mmiowb();
+ w5300_command(priv, S0_CR_OPEN);
+ w5300_write(priv, W5300_S0_IMR, IS_ENABLED(CONFIG_WIZNET_TX_FLOW) ?
+ S0_IR_RECV | S0_IR_SENDOK :
+ S0_IR_RECV);
+ w5300_write(priv, W5300_IMR, IR_S0);
+ mmiowb();
+}
+
+static void w5300_hw_close(struct w5300_priv *priv)
+{
+ w5300_write(priv, W5300_IMR, 0);
+ mmiowb();
+ w5300_command(priv, S0_CR_CLOSE);
+}
+
+/***********************************************************************
+ *
+ * Device driver functions / callbacks
+ *
+ ***********************************************************************/
+
+static void w5300_get_drvinfo(struct net_device *ndev,
+ struct ethtool_drvinfo *info)
+{
+ strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+ strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+ strlcpy(info->bus_info, dev_name(ndev->dev.parent),
+ sizeof(info->bus_info));
+}
+
+static u32 w5300_get_link(struct net_device *ndev)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ if (gpio_is_valid(priv->link_gpio))
+ return !!gpio_get_value(priv->link_gpio);
+
+ return 1;
+}
+
+static u32 w5300_get_msglevel(struct net_device *ndev)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ return priv->msg_enable;
+}
+
+static void w5300_set_msglevel(struct net_device *ndev, u32 value)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ priv->msg_enable = value;
+}
+
+static int w5300_get_regs_len(struct net_device *ndev)
+{
+ return W5300_REGS_LEN;
+}
+
+static void w5300_get_regs(struct net_device *ndev,
+ struct ethtool_regs *regs, void *_buf)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+ u8 *buf = _buf;
+ u16 addr;
+ u16 data;
+
+ regs->version = 1;
+ for (addr = 0; addr < W5300_REGS_LEN; addr += 2) {
+ switch (addr & 0x23f) {
+ case W5300_S0_TX_FIFO: /* cannot read TX_FIFO */
+ case W5300_S0_RX_FIFO: /* cannot read RX_FIFO */
+ data = 0xffff;
+ break;
+ default:
+ data = w5300_read(priv, addr);
+ break;
+ }
+ *buf++ = data >> 8;
+ *buf++ = data;
+ }
+}
+
+static void w5300_tx_timeout(struct net_device *ndev)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ netif_stop_queue(ndev);
+ w5300_hw_reset(priv);
+ w5300_hw_start(priv);
+ ndev->stats.tx_errors++;
+ ndev->trans_start = jiffies;
+ netif_wake_queue(ndev);
+}
+
+static int w5300_start_tx(struct sk_buff *skb, struct net_device *ndev)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ if (IS_ENABLED(CONFIG_WIZNET_TX_FLOW))
+ netif_stop_queue(ndev);
+
+ w5300_write_frame(priv, skb->data, skb->len);
+ mmiowb();
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += skb->len;
+ dev_kfree_skb(skb);
+ netif_dbg(priv, tx_queued, ndev, "tx queued\n");
+
+ w5300_command(priv, S0_CR_SEND);
+
+ return NETDEV_TX_OK;
+}
+
+static int w5300_napi_poll(struct napi_struct *napi, int budget)
+{
+ struct w5300_priv *priv = container_of(napi, struct w5300_priv, napi);
+ struct net_device *ndev = priv->ndev;
+ struct sk_buff *skb;
+ int rx_count;
+ u16 rx_len;
+
+ for (rx_count = 0; rx_count < budget; rx_count++) {
+ u32 rx_fifo_len = w5300_read32(priv, W5300_S0_RX_RSR);
+ if (rx_fifo_len == 0)
+ break;
+
+ rx_len = w5300_read(priv, W5300_S0_RX_FIFO);
+
+ skb = netdev_alloc_skb_ip_align(ndev, roundup(rx_len, 2));
+ if (unlikely(!skb)) {
+ u32 i;
+ for (i = 0; i < rx_fifo_len; i += 2)
+ w5300_read(priv, W5300_S0_RX_FIFO);
+ ndev->stats.rx_dropped++;
+ return -ENOMEM;
+ }
+
+ skb_put(skb, rx_len);
+ w5300_read_frame(priv, skb->data, rx_len);
+ skb->protocol = eth_type_trans(skb, ndev);
+
+ netif_receive_skb(skb);
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += rx_len;
+ }
+
+ if (rx_count < budget) {
+ w5300_write(priv, W5300_IMR, IR_S0);
+ mmiowb();
+ napi_complete(napi);
+ }
+
+ return rx_count;
+}
+
+static irqreturn_t w5300_interrupt(int irq, void *ndev_instance)
+{
+ struct net_device *ndev = ndev_instance;
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ int ir = w5300_read(priv, W5300_S0_IR);
+ if (!ir)
+ return IRQ_NONE;
+ w5300_write(priv, W5300_S0_IR, ir);
+ mmiowb();
+
+ if (IS_ENABLED(CONFIG_WIZNET_TX_FLOW) && (ir & S0_IR_SENDOK)) {
+ netif_dbg(priv, tx_done, ndev, "tx done\n");
+ netif_wake_queue(ndev);
+ }
+
+ if (ir & S0_IR_RECV) {
+ if (napi_schedule_prep(&priv->napi)) {
+ w5300_write(priv, W5300_IMR, 0);
+ mmiowb();
+ __napi_schedule(&priv->napi);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t w5300_detect_link(int irq, void *ndev_instance)
+{
+ struct net_device *ndev = ndev_instance;
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ if (netif_running(ndev)) {
+ if (gpio_get_value(priv->link_gpio) != 0) {
+ netif_info(priv, link, ndev, "link is up\n");
+ netif_carrier_on(ndev);
+ } else {
+ netif_info(priv, link, ndev, "link is down\n");
+ netif_carrier_off(ndev);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void w5300_set_rx_mode(struct net_device *ndev)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+ bool set_promisc = (ndev->flags & IFF_PROMISC) != 0;
+
+ if (priv->promisc != set_promisc) {
+ priv->promisc = set_promisc;
+ w5300_hw_start(priv);
+ }
+}
+
+static int w5300_set_macaddr(struct net_device *ndev, void *addr)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+ struct sockaddr *sock_addr = addr;
+
+ if (!is_valid_ether_addr(sock_addr->sa_data))
+ return -EADDRNOTAVAIL;
+ memcpy(ndev->dev_addr, sock_addr->sa_data, ETH_ALEN);
+ ndev->addr_assign_type &= ~NET_ADDR_RANDOM;
+ w5300_write_macaddr(priv);
+ return 0;
+}
+
+static int w5300_open(struct net_device *ndev)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ netif_info(priv, ifup, ndev, "enabling\n");
+ if (!is_valid_ether_addr(ndev->dev_addr))
+ return -EINVAL;
+ w5300_hw_start(priv);
+ napi_enable(&priv->napi);
+ netif_start_queue(ndev);
+ if (!gpio_is_valid(priv->link_gpio) ||
+ gpio_get_value(priv->link_gpio) != 0)
+ netif_carrier_on(ndev);
+ return 0;
+}
+
+static int w5300_stop(struct net_device *ndev)
+{
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ netif_info(priv, ifdown, ndev, "shutting down\n");
+ w5300_hw_close(priv);
+ netif_carrier_off(ndev);
+ netif_stop_queue(ndev);
+ napi_disable(&priv->napi);
+ return 0;
+}
+
+static const struct ethtool_ops w5300_ethtool_ops = {
+ .get_drvinfo = w5300_get_drvinfo,
+ .get_msglevel = w5300_get_msglevel,
+ .set_msglevel = w5300_set_msglevel,
+ .get_link = w5300_get_link,
+ .get_regs_len = w5300_get_regs_len,
+ .get_regs = w5300_get_regs,
+};
+
+static const struct net_device_ops w5300_netdev_ops = {
+ .ndo_open = w5300_open,
+ .ndo_stop = w5300_stop,
+ .ndo_start_xmit = w5300_start_tx,
+ .ndo_tx_timeout = w5300_tx_timeout,
+ .ndo_set_rx_mode = w5300_set_rx_mode,
+ .ndo_set_mac_address = w5300_set_macaddr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+};
+
+static int __devinit w5300_hw_probe(struct platform_device *pdev)
+{
+ struct wiznet_platform_data *data = pdev->dev.platform_data;
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct w5300_priv *priv = netdev_priv(ndev);
+ const char *name = netdev_name(ndev);
+ struct resource *mem;
+ int mem_size;
+ int irq;
+ int ret;
+
+ if (data && is_valid_ether_addr(data->mac_addr)) {
+ memcpy(ndev->dev_addr, data->mac_addr, ETH_ALEN);
+ } else {
+ random_ether_addr(ndev->dev_addr);
+ ndev->addr_assign_type |= NET_ADDR_RANDOM;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return -ENXIO;
+ mem_size = resource_size(mem);
+ if (!devm_request_mem_region(&pdev->dev, mem->start, mem_size, name))
+ return -EBUSY;
+ priv->base = devm_ioremap(&pdev->dev, mem->start, mem_size);
+ if (!priv->base)
+ return -EBUSY;
+
+ spin_lock_init(&priv->reg_lock);
+ priv->indirect = mem_size < W5300_BUS_DIRECT_SIZE;
+ if (priv->indirect) {
+ priv->read = w5300_read_indirect;
+ priv->write = w5300_write_indirect;
+ } else {
+ priv->read = w5300_read_direct;
+ priv->write = w5300_write_direct;
+ }
+
+ w5300_hw_reset(priv);
+ if (w5300_read(priv, W5300_IDR) != IDR_W5300)
+ return -ENODEV;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+ ret = request_irq(irq, w5300_interrupt,
+ IRQ_TYPE_LEVEL_LOW, name, ndev);
+ if (ret < 0)
+ return ret;
+ priv->irq = irq;
+
+ priv->link_gpio = data->link_gpio;
+ if (gpio_is_valid(priv->link_gpio)) {
+ char *link_name = devm_kzalloc(&pdev->dev, 16, GFP_KERNEL);
+ if (!link_name)
+ return -ENOMEM;
+ snprintf(link_name, 16, "%s-link", name);
+ priv->link_irq = gpio_to_irq(priv->link_gpio);
+ if (request_any_context_irq(priv->link_irq, w5300_detect_link,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ link_name, priv->ndev) < 0)
+ priv->link_gpio = -EINVAL;
+ }
+
+ netdev_info(ndev, "at 0x%llx irq %d\n", (u64)mem->start, irq);
+ return 0;
+}
+
+static int __devinit w5300_probe(struct platform_device *pdev)
+{
+ struct w5300_priv *priv;
+ struct net_device *ndev;
+ int err;
+
+ ndev = alloc_etherdev(sizeof(*priv));
+ if (!ndev)
+ return -ENOMEM;
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+ platform_set_drvdata(pdev, ndev);
+ priv = netdev_priv(ndev);
+ priv->ndev = ndev;
+
+ ether_setup(ndev);
+ ndev->netdev_ops = &w5300_netdev_ops;
+ ndev->ethtool_ops = &w5300_ethtool_ops;
+ ndev->watchdog_timeo = HZ;
+ netif_napi_add(ndev, &priv->napi, w5300_napi_poll, 16);
+
+ /* This chip doesn't support VLAN packets with normal MTU,
+ * so disable VLAN for this device.
+ */
+ ndev->features |= NETIF_F_VLAN_CHALLENGED;
+
+ err = register_netdev(ndev);
+ if (err < 0)
+ goto err_register;
+
+ err = w5300_hw_probe(pdev);
+ if (err < 0)
+ goto err_hw_probe;
+
+ return 0;
+
+err_hw_probe:
+ unregister_netdev(ndev);
+err_register:
+ free_netdev(ndev);
+ platform_set_drvdata(pdev, NULL);
+ return err;
+}
+
+static int __devexit w5300_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ w5300_hw_reset(priv);
+ free_irq(priv->irq, ndev);
+ if (gpio_is_valid(priv->link_gpio))
+ free_irq(priv->link_irq, ndev);
+
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int w5300_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ if (netif_running(ndev)) {
+ netif_carrier_off(ndev);
+ netif_device_detach(ndev);
+
+ w5300_hw_close(priv);
+ }
+ return 0;
+}
+
+static int w5300_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct w5300_priv *priv = netdev_priv(ndev);
+
+ if (!netif_running(ndev)) {
+ w5300_hw_reset(priv);
+ w5300_hw_start(priv);
+
+ netif_device_attach(ndev);
+ if (!gpio_is_valid(priv->link_gpio) ||
+ gpio_get_value(priv->link_gpio) != 0)
+ netif_carrier_on(ndev);
+ }
+ return 0;
+}
+#endif /* CONFIG_PM */
+
+static SIMPLE_DEV_PM_OPS(w5300_pm_ops, w5300_suspend, w5300_resume);
+
+static struct platform_driver w5300_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &w5300_pm_ops,
+ },
+ .probe = w5300_probe,
+ .remove = __devexit_p(w5300_remove),
+};
+
+module_platform_driver(w5300_driver);
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index d21591a..1eaf712 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -1000,6 +1000,7 @@
.set_settings = temac_set_settings,
.nway_reset = temac_nway_reset,
.get_link = ethtool_op_get_link,
+ .get_ts_info = ethtool_op_get_ts_info,
};
static int __devinit temac_of_probe(struct platform_device *op)
diff --git a/drivers/net/ethernet/xscale/Kconfig b/drivers/net/ethernet/xscale/Kconfig
index cf67352..3f43101 100644
--- a/drivers/net/ethernet/xscale/Kconfig
+++ b/drivers/net/ethernet/xscale/Kconfig
@@ -5,8 +5,8 @@
config NET_VENDOR_XSCALE
bool "Intel XScale IXP devices"
default y
- depends on NET_VENDOR_INTEL && ((ARM && ARCH_IXP4XX && \
- IXP4XX_NPE && IXP4XX_QMGR) || ARCH_ENP2611)
+ depends on NET_VENDOR_INTEL && (ARM && ARCH_IXP4XX && \
+ IXP4XX_NPE && IXP4XX_QMGR)
---help---
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
@@ -27,6 +27,4 @@
Say Y here if you want to use built-in Ethernet ports
on IXP4xx processor.
-source "drivers/net/ethernet/xscale/ixp2000/Kconfig"
-
endif # NET_VENDOR_XSCALE
diff --git a/drivers/net/ethernet/xscale/Makefile b/drivers/net/ethernet/xscale/Makefile
index b195b9d..abc3b03 100644
--- a/drivers/net/ethernet/xscale/Makefile
+++ b/drivers/net/ethernet/xscale/Makefile
@@ -2,5 +2,4 @@
# Makefile for the Intel XScale IXP device drivers.
#
-obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o
diff --git a/drivers/net/ethernet/xscale/ixp2000/Kconfig b/drivers/net/ethernet/xscale/ixp2000/Kconfig
deleted file mode 100644
index 58dbc5b..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-config ENP2611_MSF_NET
- tristate "Radisys ENP2611 MSF network interface support"
- depends on ARCH_ENP2611
- ---help---
- This is a driver for the MSF network interface unit in
- the IXP2400 on the Radisys ENP2611 platform.
diff --git a/drivers/net/ethernet/xscale/ixp2000/Makefile b/drivers/net/ethernet/xscale/ixp2000/Makefile
deleted file mode 100644
index fd38351..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_ENP2611_MSF_NET) += enp2611_mod.o
-
-enp2611_mod-objs := caleb.o enp2611.o ixp2400-msf.o ixpdev.o pm3386.o
diff --git a/drivers/net/ethernet/xscale/ixp2000/caleb.c b/drivers/net/ethernet/xscale/ixp2000/caleb.c
deleted file mode 100644
index 7dea5b9..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/caleb.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include "caleb.h"
-
-#define CALEB_IDLO 0x00
-#define CALEB_IDHI 0x01
-#define CALEB_RID 0x02
-#define CALEB_RESET 0x03
-#define CALEB_INTREN0 0x04
-#define CALEB_INTREN1 0x05
-#define CALEB_INTRSTAT0 0x06
-#define CALEB_INTRSTAT1 0x07
-#define CALEB_PORTEN 0x08
-#define CALEB_BURST 0x09
-#define CALEB_PORTPAUS 0x0A
-#define CALEB_PORTPAUSD 0x0B
-#define CALEB_PHY0RX 0x10
-#define CALEB_PHY1RX 0x11
-#define CALEB_PHY0TX 0x12
-#define CALEB_PHY1TX 0x13
-#define CALEB_IXPRX_HI_CNTR 0x15
-#define CALEB_PHY0RX_HI_CNTR 0x16
-#define CALEB_PHY1RX_HI_CNTR 0x17
-#define CALEB_IXPRX_CNTR 0x18
-#define CALEB_PHY0RX_CNTR 0x19
-#define CALEB_PHY1RX_CNTR 0x1A
-#define CALEB_IXPTX_CNTR 0x1B
-#define CALEB_PHY0TX_CNTR 0x1C
-#define CALEB_PHY1TX_CNTR 0x1D
-#define CALEB_DEBUG0 0x1E
-#define CALEB_DEBUG1 0x1F
-
-
-static u8 caleb_reg_read(int reg)
-{
- u8 value;
-
- value = *((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg));
-
-// printk(KERN_INFO "caleb_reg_read(%d) = %.2x\n", reg, value);
-
- return value;
-}
-
-static void caleb_reg_write(int reg, u8 value)
-{
- u8 dummy;
-
-// printk(KERN_INFO "caleb_reg_write(%d, %.2x)\n", reg, value);
-
- *((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg)) = value;
-
- dummy = *((volatile u8 *)ENP2611_CALEB_VIRT_BASE);
- __asm__ __volatile__("mov %0, %0" : "+r" (dummy));
-}
-
-
-void caleb_reset(void)
-{
- /*
- * Perform a chip reset.
- */
- caleb_reg_write(CALEB_RESET, 0x02);
- udelay(1);
-
- /*
- * Enable all interrupt sources. This is needed to get
- * meaningful results out of the status bits (register 6
- * and 7.)
- */
- caleb_reg_write(CALEB_INTREN0, 0xff);
- caleb_reg_write(CALEB_INTREN1, 0x07);
-
- /*
- * Set RX and TX FIFO thresholds to 1.5kb.
- */
- caleb_reg_write(CALEB_PHY0RX, 0x11);
- caleb_reg_write(CALEB_PHY1RX, 0x11);
- caleb_reg_write(CALEB_PHY0TX, 0x11);
- caleb_reg_write(CALEB_PHY1TX, 0x11);
-
- /*
- * Program SPI-3 burst size.
- */
- caleb_reg_write(CALEB_BURST, 0); // 64-byte RBUF mpackets
-// caleb_reg_write(CALEB_BURST, 1); // 128-byte RBUF mpackets
-// caleb_reg_write(CALEB_BURST, 2); // 256-byte RBUF mpackets
-}
-
-void caleb_enable_rx(int port)
-{
- u8 temp;
-
- temp = caleb_reg_read(CALEB_PORTEN);
- temp |= 1 << port;
- caleb_reg_write(CALEB_PORTEN, temp);
-}
-
-void caleb_disable_rx(int port)
-{
- u8 temp;
-
- temp = caleb_reg_read(CALEB_PORTEN);
- temp &= ~(1 << port);
- caleb_reg_write(CALEB_PORTEN, temp);
-}
-
-void caleb_enable_tx(int port)
-{
- u8 temp;
-
- temp = caleb_reg_read(CALEB_PORTEN);
- temp |= 1 << (port + 4);
- caleb_reg_write(CALEB_PORTEN, temp);
-}
-
-void caleb_disable_tx(int port)
-{
- u8 temp;
-
- temp = caleb_reg_read(CALEB_PORTEN);
- temp &= ~(1 << (port + 4));
- caleb_reg_write(CALEB_PORTEN, temp);
-}
diff --git a/drivers/net/ethernet/xscale/ixp2000/caleb.h b/drivers/net/ethernet/xscale/ixp2000/caleb.h
deleted file mode 100644
index e93a1ef..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/caleb.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __CALEB_H
-#define __CALEB_H
-
-void caleb_reset(void);
-void caleb_enable_rx(int port);
-void caleb_disable_rx(int port);
-void caleb_enable_tx(int port);
-void caleb_disable_tx(int port);
-
-
-#endif
diff --git a/drivers/net/ethernet/xscale/ixp2000/enp2611.c b/drivers/net/ethernet/xscale/ixp2000/enp2611.c
deleted file mode 100644
index 34a6cfd..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/enp2611.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * IXP2400 MSF network device driver for the Radisys ENP2611
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/moduleparam.h>
-#include <asm/hardware/uengine.h>
-#include <asm/mach-types.h>
-#include <asm/io.h>
-#include "ixpdev.h"
-#include "caleb.h"
-#include "ixp2400-msf.h"
-#include "pm3386.h"
-
-/***********************************************************************
- * The Radisys ENP2611 is a PCI form factor board with three SFP GBIC
- * slots, connected via two PMC/Sierra 3386s and an SPI-3 bridge FPGA
- * to the IXP2400.
- *
- * +-------------+
- * SFP GBIC #0 ---+ | +---------+
- * | PM3386 #0 +-------+ |
- * SFP GBIC #1 ---+ | | "Caleb" | +---------+
- * +-------------+ | | | |
- * | SPI-3 +---------+ IXP2400 |
- * +-------------+ | bridge | | |
- * SFP GBIC #2 ---+ | | FPGA | +---------+
- * | PM3386 #1 +-------+ |
- * | | +---------+
- * +-------------+
- * ^ ^ ^
- * | 1.25Gbaud | 104MHz | 104MHz
- * | SERDES ea. | SPI-3 ea. | SPI-3
- *
- ***********************************************************************/
-static struct ixp2400_msf_parameters enp2611_msf_parameters =
-{
- .rx_mode = IXP2400_RX_MODE_UTOPIA_POS |
- IXP2400_RX_MODE_1x32 |
- IXP2400_RX_MODE_MPHY |
- IXP2400_RX_MODE_MPHY_32 |
- IXP2400_RX_MODE_MPHY_POLLED_STATUS |
- IXP2400_RX_MODE_MPHY_LEVEL3 |
- IXP2400_RX_MODE_RBUF_SIZE_64,
-
- .rxclk01_multiplier = IXP2400_PLL_MULTIPLIER_16,
-
- .rx_poll_ports = 3,
-
- .rx_channel_mode = {
- IXP2400_PORT_RX_MODE_MASTER |
- IXP2400_PORT_RX_MODE_POS_PHY |
- IXP2400_PORT_RX_MODE_POS_PHY_L3 |
- IXP2400_PORT_RX_MODE_ODD_PARITY |
- IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
-
- IXP2400_PORT_RX_MODE_MASTER |
- IXP2400_PORT_RX_MODE_POS_PHY |
- IXP2400_PORT_RX_MODE_POS_PHY_L3 |
- IXP2400_PORT_RX_MODE_ODD_PARITY |
- IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
-
- IXP2400_PORT_RX_MODE_MASTER |
- IXP2400_PORT_RX_MODE_POS_PHY |
- IXP2400_PORT_RX_MODE_POS_PHY_L3 |
- IXP2400_PORT_RX_MODE_ODD_PARITY |
- IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
-
- IXP2400_PORT_RX_MODE_MASTER |
- IXP2400_PORT_RX_MODE_POS_PHY |
- IXP2400_PORT_RX_MODE_POS_PHY_L3 |
- IXP2400_PORT_RX_MODE_ODD_PARITY |
- IXP2400_PORT_RX_MODE_2_CYCLE_DECODE
- },
-
- .tx_mode = IXP2400_TX_MODE_UTOPIA_POS |
- IXP2400_TX_MODE_1x32 |
- IXP2400_TX_MODE_MPHY |
- IXP2400_TX_MODE_MPHY_32 |
- IXP2400_TX_MODE_MPHY_POLLED_STATUS |
- IXP2400_TX_MODE_MPHY_LEVEL3 |
- IXP2400_TX_MODE_TBUF_SIZE_64,
-
- .txclk01_multiplier = IXP2400_PLL_MULTIPLIER_16,
-
- .tx_poll_ports = 3,
-
- .tx_channel_mode = {
- IXP2400_PORT_TX_MODE_MASTER |
- IXP2400_PORT_TX_MODE_POS_PHY |
- IXP2400_PORT_TX_MODE_ODD_PARITY |
- IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
-
- IXP2400_PORT_TX_MODE_MASTER |
- IXP2400_PORT_TX_MODE_POS_PHY |
- IXP2400_PORT_TX_MODE_ODD_PARITY |
- IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
-
- IXP2400_PORT_TX_MODE_MASTER |
- IXP2400_PORT_TX_MODE_POS_PHY |
- IXP2400_PORT_TX_MODE_ODD_PARITY |
- IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
-
- IXP2400_PORT_TX_MODE_MASTER |
- IXP2400_PORT_TX_MODE_POS_PHY |
- IXP2400_PORT_TX_MODE_ODD_PARITY |
- IXP2400_PORT_TX_MODE_2_CYCLE_DECODE
- }
-};
-
-static struct net_device *nds[3];
-static struct timer_list link_check_timer;
-
-/* @@@ Poll the SFP moddef0 line too. */
-/* @@@ Try to use the pm3386 DOOL interrupt as well. */
-static void enp2611_check_link_status(unsigned long __dummy)
-{
- int i;
-
- for (i = 0; i < 3; i++) {
- struct net_device *dev;
- int status;
-
- dev = nds[i];
- if (dev == NULL)
- continue;
-
- status = pm3386_is_link_up(i);
- if (status && !netif_carrier_ok(dev)) {
- /* @@@ Should report autonegotiation status. */
- printk(KERN_INFO "%s: NIC Link is Up\n", dev->name);
-
- pm3386_enable_tx(i);
- caleb_enable_tx(i);
- netif_carrier_on(dev);
- } else if (!status && netif_carrier_ok(dev)) {
- printk(KERN_INFO "%s: NIC Link is Down\n", dev->name);
-
- netif_carrier_off(dev);
- caleb_disable_tx(i);
- pm3386_disable_tx(i);
- }
- }
-
- link_check_timer.expires = jiffies + HZ / 10;
- add_timer(&link_check_timer);
-}
-
-static void enp2611_set_port_admin_status(int port, int up)
-{
- if (up) {
- caleb_enable_rx(port);
-
- pm3386_set_carrier(port, 1);
- pm3386_enable_rx(port);
- } else {
- caleb_disable_tx(port);
- pm3386_disable_tx(port);
- /* @@@ Flush out pending packets. */
- pm3386_set_carrier(port, 0);
-
- pm3386_disable_rx(port);
- caleb_disable_rx(port);
- }
-}
-
-static int __init enp2611_init_module(void)
-{
- int ports;
- int i;
-
- if (!machine_is_enp2611())
- return -ENODEV;
-
- caleb_reset();
- pm3386_reset();
-
- ports = pm3386_port_count();
- for (i = 0; i < ports; i++) {
- nds[i] = ixpdev_alloc(i, sizeof(struct ixpdev_priv));
- if (nds[i] == NULL) {
- while (--i >= 0)
- free_netdev(nds[i]);
- return -ENOMEM;
- }
-
- pm3386_init_port(i);
- pm3386_get_mac(i, nds[i]->dev_addr);
- }
-
- ixp2400_msf_init(&enp2611_msf_parameters);
-
- if (ixpdev_init(ports, nds, enp2611_set_port_admin_status)) {
- for (i = 0; i < ports; i++)
- if (nds[i])
- free_netdev(nds[i]);
- return -EINVAL;
- }
-
- init_timer(&link_check_timer);
- link_check_timer.function = enp2611_check_link_status;
- link_check_timer.expires = jiffies;
- add_timer(&link_check_timer);
-
- return 0;
-}
-
-static void __exit enp2611_cleanup_module(void)
-{
- int i;
-
- del_timer_sync(&link_check_timer);
-
- ixpdev_deinit();
- for (i = 0; i < 3; i++)
- free_netdev(nds[i]);
-}
-
-module_init(enp2611_init_module);
-module_exit(enp2611_cleanup_module);
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/xscale/ixp2000/ixp2400-msf.c b/drivers/net/ethernet/xscale/ixp2000/ixp2400-msf.c
deleted file mode 100644
index f5ffd7e..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/ixp2400-msf.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Generic library functions for the MSF (Media and Switch Fabric) unit
- * found on the Intel IXP2400 network processor.
- *
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <mach/hardware.h>
-#include <mach/ixp2000-regs.h>
-#include <asm/delay.h>
-#include <asm/io.h>
-#include "ixp2400-msf.h"
-
-/*
- * This is the Intel recommended PLL init procedure as described on
- * page 340 of the IXP2400/IXP2800 Programmer's Reference Manual.
- */
-static void ixp2400_pll_init(struct ixp2400_msf_parameters *mp)
-{
- int rx_dual_clock;
- int tx_dual_clock;
- u32 value;
-
- /*
- * If the RX mode is not 1x32, we have to enable both RX PLLs
- * (#0 and #1.) The same thing for the TX direction.
- */
- rx_dual_clock = !!(mp->rx_mode & IXP2400_RX_MODE_WIDTH_MASK);
- tx_dual_clock = !!(mp->tx_mode & IXP2400_TX_MODE_WIDTH_MASK);
-
- /*
- * Read initial value.
- */
- value = ixp2000_reg_read(IXP2000_MSF_CLK_CNTRL);
-
- /*
- * Put PLLs in powerdown and bypass mode.
- */
- value |= 0x0000f0f0;
- ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
-
- /*
- * Set single or dual clock mode bits.
- */
- value &= ~0x03000000;
- value |= (rx_dual_clock << 24) | (tx_dual_clock << 25);
-
- /*
- * Set multipliers.
- */
- value &= ~0x00ff0000;
- value |= mp->rxclk01_multiplier << 16;
- value |= mp->rxclk23_multiplier << 18;
- value |= mp->txclk01_multiplier << 20;
- value |= mp->txclk23_multiplier << 22;
-
- /*
- * And write value.
- */
- ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
-
- /*
- * Disable PLL bypass mode.
- */
- value &= ~(0x00005000 | rx_dual_clock << 13 | tx_dual_clock << 15);
- ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
-
- /*
- * Turn on PLLs.
- */
- value &= ~(0x00000050 | rx_dual_clock << 5 | tx_dual_clock << 7);
- ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
-
- /*
- * Wait for PLLs to lock. There are lock status bits, but IXP2400
- * erratum #65 says that these lock bits should not be relied upon
- * as they might not accurately reflect the true state of the PLLs.
- */
- udelay(100);
-}
-
-/*
- * Needed according to p480 of Programmer's Reference Manual.
- */
-static void ixp2400_msf_free_rbuf_entries(struct ixp2400_msf_parameters *mp)
-{
- int size_bits;
- int i;
-
- /*
- * Work around IXP2400 erratum #69 (silent RBUF-to-DRAM transfer
- * corruption) in the Intel-recommended way: do not add the RBUF
- * elements susceptible to corruption to the freelist.
- */
- size_bits = mp->rx_mode & IXP2400_RX_MODE_RBUF_SIZE_MASK;
- if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_64) {
- for (i = 1; i < 128; i++) {
- if (i == 9 || i == 18 || i == 27)
- continue;
- ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
- }
- } else if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_128) {
- for (i = 1; i < 64; i++) {
- if (i == 4 || i == 9 || i == 13)
- continue;
- ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
- }
- } else if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_256) {
- for (i = 1; i < 32; i++) {
- if (i == 2 || i == 4 || i == 6)
- continue;
- ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
- }
- }
-}
-
-static u32 ixp2400_msf_valid_channels(u32 reg)
-{
- u32 channels;
-
- channels = 0;
- switch (reg & IXP2400_RX_MODE_WIDTH_MASK) {
- case IXP2400_RX_MODE_1x32:
- channels = 0x1;
- if (reg & IXP2400_RX_MODE_MPHY &&
- !(reg & IXP2400_RX_MODE_MPHY_32))
- channels = 0xf;
- break;
-
- case IXP2400_RX_MODE_2x16:
- channels = 0x5;
- break;
-
- case IXP2400_RX_MODE_4x8:
- channels = 0xf;
- break;
-
- case IXP2400_RX_MODE_1x16_2x8:
- channels = 0xd;
- break;
- }
-
- return channels;
-}
-
-static void ixp2400_msf_enable_rx(struct ixp2400_msf_parameters *mp)
-{
- u32 value;
-
- value = ixp2000_reg_read(IXP2000_MSF_RX_CONTROL) & 0x0fffffff;
- value |= ixp2400_msf_valid_channels(mp->rx_mode) << 28;
- ixp2000_reg_write(IXP2000_MSF_RX_CONTROL, value);
-}
-
-static void ixp2400_msf_enable_tx(struct ixp2400_msf_parameters *mp)
-{
- u32 value;
-
- value = ixp2000_reg_read(IXP2000_MSF_TX_CONTROL) & 0x0fffffff;
- value |= ixp2400_msf_valid_channels(mp->tx_mode) << 28;
- ixp2000_reg_write(IXP2000_MSF_TX_CONTROL, value);
-}
-
-
-void ixp2400_msf_init(struct ixp2400_msf_parameters *mp)
-{
- u32 value;
- int i;
-
- /*
- * Init the RX/TX PLLs based on the passed parameter block.
- */
- ixp2400_pll_init(mp);
-
- /*
- * Reset MSF. Bit 7 in IXP_RESET_0 resets the MSF.
- */
- value = ixp2000_reg_read(IXP2000_RESET0);
- ixp2000_reg_write(IXP2000_RESET0, value | 0x80);
- ixp2000_reg_write(IXP2000_RESET0, value & ~0x80);
-
- /*
- * Initialise the RX section.
- */
- ixp2000_reg_write(IXP2000_MSF_RX_MPHY_POLL_LIMIT, mp->rx_poll_ports - 1);
- ixp2000_reg_write(IXP2000_MSF_RX_CONTROL, mp->rx_mode);
- for (i = 0; i < 4; i++) {
- ixp2000_reg_write(IXP2000_MSF_RX_UP_CONTROL_0 + i,
- mp->rx_channel_mode[i]);
- }
- ixp2400_msf_free_rbuf_entries(mp);
- ixp2400_msf_enable_rx(mp);
-
- /*
- * Initialise the TX section.
- */
- ixp2000_reg_write(IXP2000_MSF_TX_MPHY_POLL_LIMIT, mp->tx_poll_ports - 1);
- ixp2000_reg_write(IXP2000_MSF_TX_CONTROL, mp->tx_mode);
- for (i = 0; i < 4; i++) {
- ixp2000_reg_write(IXP2000_MSF_TX_UP_CONTROL_0 + i,
- mp->tx_channel_mode[i]);
- }
- ixp2400_msf_enable_tx(mp);
-}
diff --git a/drivers/net/ethernet/xscale/ixp2000/ixp2400-msf.h b/drivers/net/ethernet/xscale/ixp2000/ixp2400-msf.h
deleted file mode 100644
index 3ac1af2..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/ixp2400-msf.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Generic library functions for the MSF (Media and Switch Fabric) unit
- * found on the Intel IXP2400 network processor.
- *
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- */
-
-#ifndef __IXP2400_MSF_H
-#define __IXP2400_MSF_H
-
-struct ixp2400_msf_parameters
-{
- u32 rx_mode;
- unsigned rxclk01_multiplier:2;
- unsigned rxclk23_multiplier:2;
- unsigned rx_poll_ports:6;
- u32 rx_channel_mode[4];
-
- u32 tx_mode;
- unsigned txclk01_multiplier:2;
- unsigned txclk23_multiplier:2;
- unsigned tx_poll_ports:6;
- u32 tx_channel_mode[4];
-};
-
-void ixp2400_msf_init(struct ixp2400_msf_parameters *mp);
-
-#define IXP2400_PLL_MULTIPLIER_48 0x00
-#define IXP2400_PLL_MULTIPLIER_24 0x01
-#define IXP2400_PLL_MULTIPLIER_16 0x02
-#define IXP2400_PLL_MULTIPLIER_12 0x03
-
-#define IXP2400_RX_MODE_CSIX 0x00400000
-#define IXP2400_RX_MODE_UTOPIA_POS 0x00000000
-#define IXP2400_RX_MODE_WIDTH_MASK 0x00300000
-#define IXP2400_RX_MODE_1x16_2x8 0x00300000
-#define IXP2400_RX_MODE_4x8 0x00200000
-#define IXP2400_RX_MODE_2x16 0x00100000
-#define IXP2400_RX_MODE_1x32 0x00000000
-#define IXP2400_RX_MODE_MPHY 0x00080000
-#define IXP2400_RX_MODE_SPHY 0x00000000
-#define IXP2400_RX_MODE_MPHY_32 0x00040000
-#define IXP2400_RX_MODE_MPHY_4 0x00000000
-#define IXP2400_RX_MODE_MPHY_POLLED_STATUS 0x00020000
-#define IXP2400_RX_MODE_MPHY_DIRECT_STATUS 0x00000000
-#define IXP2400_RX_MODE_CBUS_FULL_DUPLEX 0x00010000
-#define IXP2400_RX_MODE_CBUS_SIMPLEX 0x00000000
-#define IXP2400_RX_MODE_MPHY_LEVEL2 0x00004000
-#define IXP2400_RX_MODE_MPHY_LEVEL3 0x00000000
-#define IXP2400_RX_MODE_CBUS_8BIT 0x00002000
-#define IXP2400_RX_MODE_CBUS_4BIT 0x00000000
-#define IXP2400_RX_MODE_CSIX_SINGLE_FREELIST 0x00000200
-#define IXP2400_RX_MODE_CSIX_SPLIT_FREELISTS 0x00000000
-#define IXP2400_RX_MODE_RBUF_SIZE_MASK 0x0000000c
-#define IXP2400_RX_MODE_RBUF_SIZE_256 0x00000008
-#define IXP2400_RX_MODE_RBUF_SIZE_128 0x00000004
-#define IXP2400_RX_MODE_RBUF_SIZE_64 0x00000000
-
-#define IXP2400_PORT_RX_MODE_SLAVE 0x00000040
-#define IXP2400_PORT_RX_MODE_MASTER 0x00000000
-#define IXP2400_PORT_RX_MODE_POS_PHY_L3 0x00000020
-#define IXP2400_PORT_RX_MODE_POS_PHY_L2 0x00000000
-#define IXP2400_PORT_RX_MODE_POS_PHY 0x00000010
-#define IXP2400_PORT_RX_MODE_UTOPIA 0x00000000
-#define IXP2400_PORT_RX_MODE_EVEN_PARITY 0x0000000c
-#define IXP2400_PORT_RX_MODE_ODD_PARITY 0x00000008
-#define IXP2400_PORT_RX_MODE_NO_PARITY 0x00000000
-#define IXP2400_PORT_RX_MODE_UTOPIA_BIG_CELLS 0x00000002
-#define IXP2400_PORT_RX_MODE_UTOPIA_NORMAL_CELLS 0x00000000
-#define IXP2400_PORT_RX_MODE_2_CYCLE_DECODE 0x00000001
-#define IXP2400_PORT_RX_MODE_1_CYCLE_DECODE 0x00000000
-
-#define IXP2400_TX_MODE_CSIX 0x00400000
-#define IXP2400_TX_MODE_UTOPIA_POS 0x00000000
-#define IXP2400_TX_MODE_WIDTH_MASK 0x00300000
-#define IXP2400_TX_MODE_1x16_2x8 0x00300000
-#define IXP2400_TX_MODE_4x8 0x00200000
-#define IXP2400_TX_MODE_2x16 0x00100000
-#define IXP2400_TX_MODE_1x32 0x00000000
-#define IXP2400_TX_MODE_MPHY 0x00080000
-#define IXP2400_TX_MODE_SPHY 0x00000000
-#define IXP2400_TX_MODE_MPHY_32 0x00040000
-#define IXP2400_TX_MODE_MPHY_4 0x00000000
-#define IXP2400_TX_MODE_MPHY_POLLED_STATUS 0x00020000
-#define IXP2400_TX_MODE_MPHY_DIRECT_STATUS 0x00000000
-#define IXP2400_TX_MODE_CBUS_FULL_DUPLEX 0x00010000
-#define IXP2400_TX_MODE_CBUS_SIMPLEX 0x00000000
-#define IXP2400_TX_MODE_MPHY_LEVEL2 0x00004000
-#define IXP2400_TX_MODE_MPHY_LEVEL3 0x00000000
-#define IXP2400_TX_MODE_CBUS_8BIT 0x00002000
-#define IXP2400_TX_MODE_CBUS_4BIT 0x00000000
-#define IXP2400_TX_MODE_TBUF_SIZE_MASK 0x0000000c
-#define IXP2400_TX_MODE_TBUF_SIZE_256 0x00000008
-#define IXP2400_TX_MODE_TBUF_SIZE_128 0x00000004
-#define IXP2400_TX_MODE_TBUF_SIZE_64 0x00000000
-
-#define IXP2400_PORT_TX_MODE_SLAVE 0x00000040
-#define IXP2400_PORT_TX_MODE_MASTER 0x00000000
-#define IXP2400_PORT_TX_MODE_POS_PHY 0x00000010
-#define IXP2400_PORT_TX_MODE_UTOPIA 0x00000000
-#define IXP2400_PORT_TX_MODE_EVEN_PARITY 0x0000000c
-#define IXP2400_PORT_TX_MODE_ODD_PARITY 0x00000008
-#define IXP2400_PORT_TX_MODE_NO_PARITY 0x00000000
-#define IXP2400_PORT_TX_MODE_UTOPIA_BIG_CELLS 0x00000002
-#define IXP2400_PORT_TX_MODE_2_CYCLE_DECODE 0x00000001
-#define IXP2400_PORT_TX_MODE_1_CYCLE_DECODE 0x00000000
-
-
-#endif
diff --git a/drivers/net/ethernet/xscale/ixp2000/ixp2400_rx.uc b/drivers/net/ethernet/xscale/ixp2000/ixp2400_rx.uc
deleted file mode 100644
index 42a73e35..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/ixp2400_rx.uc
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * RX ucode for the Intel IXP2400 in POS-PHY mode.
- * Copyright (C) 2004, 2005 Lennert Buytenhek
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Assumptions made in this code:
- * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where
- * only one full element list is used. This includes, for example,
- * 1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4. (This
- * is not an exhaustive list.)
- * - The RBUF uses 64-byte mpackets.
- * - RX descriptors reside in SRAM, and have the following format:
- * struct rx_desc
- * {
- * // to uengine
- * u32 buf_phys_addr;
- * u32 buf_length;
- *
- * // from uengine
- * u32 channel;
- * u32 pkt_length;
- * };
- * - Packet data resides in DRAM.
- * - Packet buffer addresses are 8-byte aligned.
- * - Scratch ring 0 is rx_pending.
- * - Scratch ring 1 is rx_done, and has status condition 'full'.
- * - The host triggers rx_done flush and rx_pending refill on seeing INTA.
- * - This code is run on all eight threads of the microengine it runs on.
- *
- * Local memory is used for per-channel RX state.
- */
-
-#define RX_THREAD_FREELIST_0 0x0030
-#define RBUF_ELEMENT_DONE 0x0044
-
-#define CHANNEL_FLAGS *l$index0[0]
-#define CHANNEL_FLAG_RECEIVING 1
-#define PACKET_LENGTH *l$index0[1]
-#define PACKET_CHECKSUM *l$index0[2]
-#define BUFFER_HANDLE *l$index0[3]
-#define BUFFER_START *l$index0[4]
-#define BUFFER_LENGTH *l$index0[5]
-
-#define CHANNEL_STATE_SIZE 24 // in bytes
-#define CHANNEL_STATE_SHIFT 5 // ceil(log2(state size))
-
-
- .sig volatile sig1
- .sig volatile sig2
- .sig volatile sig3
-
- .sig mpacket_arrived
- .reg add_to_rx_freelist
- .reg read $rsw0, $rsw1
- .xfer_order $rsw0 $rsw1
-
- .reg zero
-
- /*
- * Initialise add_to_rx_freelist.
- */
- .begin
- .reg temp
- .reg temp2
-
- immed[add_to_rx_freelist, RX_THREAD_FREELIST_0]
- immed_w1[add_to_rx_freelist, (&$rsw0 | (&mpacket_arrived << 12))]
-
- local_csr_rd[ACTIVE_CTX_STS]
- immed[temp, 0]
- alu[temp2, temp, and, 0x1f]
- alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<20]
- alu[temp2, temp, and, 0x80]
- alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<18]
- .end
-
- immed[zero, 0]
-
- /*
- * Skip context 0 initialisation?
- */
- .begin
- br!=ctx[0, mpacket_receive_loop#]
- .end
-
- /*
- * Initialise local memory.
- */
- .begin
- .reg addr
- .reg temp
-
- immed[temp, 0]
- init_local_mem_loop#:
- alu_shf[addr, --, b, temp, <<CHANNEL_STATE_SHIFT]
- local_csr_wr[ACTIVE_LM_ADDR_0, addr]
- nop
- nop
- nop
-
- immed[CHANNEL_FLAGS, 0]
-
- alu[temp, temp, +, 1]
- alu[--, temp, and, 0x20]
- beq[init_local_mem_loop#]
- .end
-
- /*
- * Initialise signal pipeline.
- */
- .begin
- local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]
- .set_sig sig1
-
- local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]
- .set_sig sig2
-
- local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]
- .set_sig sig3
- .end
-
-mpacket_receive_loop#:
- /*
- * Synchronise and wait for mpacket.
- */
- .begin
- ctx_arb[sig1]
- local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]
-
- msf[fast_wr, --, add_to_rx_freelist, 0]
- .set_sig mpacket_arrived
- ctx_arb[mpacket_arrived]
- .set $rsw0 $rsw1
- .end
-
- /*
- * We halt if we see {inbparerr,parerr,null,soperror}.
- */
- .begin
- alu_shf[--, 0x1b, and, $rsw0, >>8]
- bne[abort_rswerr#]
- .end
-
- /*
- * Point local memory pointer to this channel's state area.
- */
- .begin
- .reg chanaddr
-
- alu[chanaddr, $rsw0, and, 0x1f]
- alu_shf[chanaddr, --, b, chanaddr, <<CHANNEL_STATE_SHIFT]
- local_csr_wr[ACTIVE_LM_ADDR_0, chanaddr]
- nop
- nop
- nop
- .end
-
- /*
- * Check whether we received a SOP mpacket while we were already
- * working on a packet, or a non-SOP mpacket while there was no
- * packet pending. (SOP == RECEIVING -> abort) If everything's
- * okay, update the RECEIVING flag to reflect our new state.
- */
- .begin
- .reg temp
- .reg eop
-
- #if CHANNEL_FLAG_RECEIVING != 1
- #error CHANNEL_FLAG_RECEIVING is not 1
- #endif
-
- alu_shf[temp, 1, and, $rsw0, >>15]
- alu[temp, temp, xor, CHANNEL_FLAGS]
- alu[--, temp, and, CHANNEL_FLAG_RECEIVING]
- beq[abort_proterr#]
-
- alu_shf[eop, 1, and, $rsw0, >>14]
- alu[CHANNEL_FLAGS, temp, xor, eop]
- .end
-
- /*
- * Copy the mpacket into the right spot, and in case of EOP,
- * write back the descriptor and pass the packet on.
- */
- .begin
- .reg buffer_offset
- .reg _packet_length
- .reg _packet_checksum
- .reg _buffer_handle
- .reg _buffer_start
- .reg _buffer_length
-
- /*
- * Determine buffer_offset, _packet_length and
- * _packet_checksum.
- */
- .begin
- .reg temp
-
- alu[--, 1, and, $rsw0, >>15]
- beq[not_sop#]
-
- immed[PACKET_LENGTH, 0]
- immed[PACKET_CHECKSUM, 0]
-
- not_sop#:
- alu[buffer_offset, --, b, PACKET_LENGTH]
- alu_shf[temp, 0xff, and, $rsw0, >>16]
- alu[_packet_length, buffer_offset, +, temp]
- alu[PACKET_LENGTH, --, b, _packet_length]
-
- immed[temp, 0xffff]
- alu[temp, $rsw1, and, temp]
- alu[_packet_checksum, PACKET_CHECKSUM, +, temp]
- alu[PACKET_CHECKSUM, --, b, _packet_checksum]
- .end
-
- /*
- * Allocate buffer in case of SOP.
- */
- .begin
- .reg temp
-
- alu[temp, 1, and, $rsw0, >>15]
- beq[skip_buffer_alloc#]
-
- .begin
- .sig zzz
- .reg read $stemp $stemp2
- .xfer_order $stemp $stemp2
-
- rx_nobufs#:
- scratch[get, $stemp, zero, 0, 1], ctx_swap[zzz]
- alu[_buffer_handle, --, b, $stemp]
- beq[rx_nobufs#]
-
- sram[read, $stemp, _buffer_handle, 0, 2],
- ctx_swap[zzz]
- alu[_buffer_start, --, b, $stemp]
- alu[_buffer_length, --, b, $stemp2]
- .end
-
- skip_buffer_alloc#:
- .end
-
- /*
- * Resynchronise.
- */
- .begin
- ctx_arb[sig2]
- local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]
- .end
-
- /*
- * Synchronise buffer state.
- */
- .begin
- .reg temp
-
- alu[temp, 1, and, $rsw0, >>15]
- beq[copy_from_local_mem#]
-
- alu[BUFFER_HANDLE, --, b, _buffer_handle]
- alu[BUFFER_START, --, b, _buffer_start]
- alu[BUFFER_LENGTH, --, b, _buffer_length]
- br[sync_state_done#]
-
- copy_from_local_mem#:
- alu[_buffer_handle, --, b, BUFFER_HANDLE]
- alu[_buffer_start, --, b, BUFFER_START]
- alu[_buffer_length, --, b, BUFFER_LENGTH]
-
- sync_state_done#:
- .end
-
-#if 0
- /*
- * Debug buffer state management.
- */
- .begin
- .reg temp
-
- alu[temp, 1, and, $rsw0, >>14]
- beq[no_poison#]
- immed[BUFFER_HANDLE, 0xdead]
- immed[BUFFER_START, 0xdead]
- immed[BUFFER_LENGTH, 0xdead]
- no_poison#:
-
- immed[temp, 0xdead]
- alu[--, _buffer_handle, -, temp]
- beq[state_corrupted#]
- alu[--, _buffer_start, -, temp]
- beq[state_corrupted#]
- alu[--, _buffer_length, -, temp]
- beq[state_corrupted#]
- .end
-#endif
-
- /*
- * Check buffer length.
- */
- .begin
- alu[--, _buffer_length, -, _packet_length]
- blo[buffer_overflow#]
- .end
-
- /*
- * Copy the mpacket and give back the RBUF element.
- */
- .begin
- .reg element
- .reg xfer_size
- .reg temp
- .sig copy_sig
-
- alu_shf[element, 0x7f, and, $rsw0, >>24]
- alu_shf[xfer_size, 0xff, and, $rsw0, >>16]
-
- alu[xfer_size, xfer_size, -, 1]
- alu_shf[xfer_size, 0x10, or, xfer_size, >>3]
- alu_shf[temp, 0x10, or, xfer_size, <<21]
- alu_shf[temp, temp, or, element, <<11]
- alu_shf[--, temp, or, 1, <<18]
-
- dram[rbuf_rd, --, _buffer_start, buffer_offset, max_8],
- indirect_ref, sig_done[copy_sig]
- ctx_arb[copy_sig]
-
- alu[temp, RBUF_ELEMENT_DONE, or, element, <<16]
- msf[fast_wr, --, temp, 0]
- .end
-
- /*
- * If EOP, write back the packet descriptor.
- */
- .begin
- .reg write $stemp $stemp2
- .xfer_order $stemp $stemp2
- .sig zzz
-
- alu_shf[--, 1, and, $rsw0, >>14]
- beq[no_writeback#]
-
- alu[$stemp, $rsw0, and, 0x1f]
- alu[$stemp2, --, b, _packet_length]
- sram[write, $stemp, _buffer_handle, 8, 2], ctx_swap[zzz]
-
- no_writeback#:
- .end
-
- /*
- * Resynchronise.
- */
- .begin
- ctx_arb[sig3]
- local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]
- .end
-
- /*
- * If EOP, put the buffer back onto the scratch ring.
- */
- .begin
- .reg write $stemp
- .sig zzz
-
- br_inp_state[SCR_Ring1_Status, rx_done_ring_overflow#]
-
- alu_shf[--, 1, and, $rsw0, >>14]
- beq[mpacket_receive_loop#]
-
- alu[--, 1, and, $rsw0, >>10]
- bne[rxerr#]
-
- alu[$stemp, --, b, _buffer_handle]
- scratch[put, $stemp, zero, 4, 1], ctx_swap[zzz]
- cap[fast_wr, 0, XSCALE_INT_A]
- br[mpacket_receive_loop#]
-
- rxerr#:
- alu[$stemp, --, b, _buffer_handle]
- scratch[put, $stemp, zero, 0, 1], ctx_swap[zzz]
- br[mpacket_receive_loop#]
- .end
- .end
-
-
-abort_rswerr#:
- halt
-
-abort_proterr#:
- halt
-
-state_corrupted#:
- halt
-
-buffer_overflow#:
- halt
-
-rx_done_ring_overflow#:
- halt
-
-
diff --git a/drivers/net/ethernet/xscale/ixp2000/ixp2400_rx.ucode b/drivers/net/ethernet/xscale/ixp2000/ixp2400_rx.ucode
deleted file mode 100644
index e8aee2f..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/ixp2400_rx.ucode
+++ /dev/null
@@ -1,130 +0,0 @@
-static struct ixp2000_uengine_code ixp2400_rx =
-{
- .cpu_model_bitmask = 0x000003fe,
- .cpu_min_revision = 0,
- .cpu_max_revision = 255,
-
- .uengine_parameters = IXP2000_UENGINE_8_CONTEXTS |
- IXP2000_UENGINE_PRN_UPDATE_EVERY |
- IXP2000_UENGINE_NN_FROM_PREVIOUS |
- IXP2000_UENGINE_ASSERT_EMPTY_AT_0 |
- IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT |
- IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT,
-
- .initial_reg_values = (struct ixp2000_reg_value []) {
- { -1, -1 }
- },
-
- .num_insns = 109,
- .insns = (u8 []) {
- 0xf0, 0x00, 0x0c, 0xc0, 0x05,
- 0xf4, 0x44, 0x0c, 0x00, 0x05,
- 0xfc, 0x04, 0x4c, 0x00, 0x00,
- 0xf0, 0x00, 0x00, 0x3b, 0x00,
- 0xb4, 0x40, 0xf0, 0x3b, 0x1f,
- 0x8a, 0xc0, 0x50, 0x3e, 0x05,
- 0xb4, 0x40, 0xf0, 0x3b, 0x80,
- 0x9a, 0xe0, 0x00, 0x3e, 0x05,
- 0xf0, 0x00, 0x00, 0x07, 0x00,
- 0xd8, 0x05, 0xc0, 0x00, 0x11,
- 0xf0, 0x00, 0x00, 0x0f, 0x00,
- 0x91, 0xb0, 0x20, 0x0e, 0x00,
- 0xfc, 0x06, 0x60, 0x0b, 0x00,
- 0xf0, 0x00, 0x0c, 0x03, 0x00,
- 0xf0, 0x00, 0x0c, 0x03, 0x00,
- 0xf0, 0x00, 0x0c, 0x03, 0x00,
- 0xf0, 0x00, 0x0c, 0x02, 0x00,
- 0xb0, 0xc0, 0x30, 0x0f, 0x01,
- 0xa4, 0x70, 0x00, 0x0f, 0x20,
- 0xd8, 0x02, 0xc0, 0x01, 0x00,
- 0xfc, 0x10, 0xac, 0x23, 0x08,
- 0xfc, 0x10, 0xac, 0x43, 0x10,
- 0xfc, 0x10, 0xac, 0x63, 0x18,
- 0xe0, 0x00, 0x00, 0x00, 0x02,
- 0xfc, 0x10, 0xae, 0x23, 0x88,
- 0x3d, 0x00, 0x04, 0x03, 0x20,
- 0xe0, 0x00, 0x00, 0x00, 0x10,
- 0x84, 0x82, 0x02, 0x01, 0x3b,
- 0xd8, 0x1a, 0x00, 0x01, 0x01,
- 0xb4, 0x00, 0x8c, 0x7d, 0x80,
- 0x91, 0xb0, 0x80, 0x22, 0x00,
- 0xfc, 0x06, 0x60, 0x23, 0x00,
- 0xf0, 0x00, 0x0c, 0x03, 0x00,
- 0xf0, 0x00, 0x0c, 0x03, 0x00,
- 0xf0, 0x00, 0x0c, 0x03, 0x00,
- 0x94, 0xf0, 0x92, 0x01, 0x21,
- 0xac, 0x40, 0x60, 0x26, 0x00,
- 0xa4, 0x30, 0x0c, 0x04, 0x06,
- 0xd8, 0x1a, 0x40, 0x01, 0x00,
- 0x94, 0xe0, 0xa2, 0x01, 0x21,
- 0xac, 0x20, 0x00, 0x28, 0x06,
- 0x84, 0xf2, 0x02, 0x01, 0x21,
- 0xd8, 0x0b, 0x40, 0x01, 0x00,
- 0xf0, 0x00, 0x0c, 0x02, 0x01,
- 0xf0, 0x00, 0x0c, 0x02, 0x02,
- 0xa0, 0x00, 0x08, 0x04, 0x00,
- 0x95, 0x00, 0xc6, 0x01, 0xff,
- 0xa0, 0x80, 0x10, 0x30, 0x00,
- 0xa0, 0x60, 0x1c, 0x00, 0x01,
- 0xf0, 0x0f, 0xf0, 0x33, 0xff,
- 0xb4, 0x00, 0xc0, 0x31, 0x81,
- 0xb0, 0x80, 0xb0, 0x32, 0x02,
- 0xa0, 0x20, 0x20, 0x2c, 0x00,
- 0x94, 0xf0, 0xd2, 0x01, 0x21,
- 0xd8, 0x0f, 0x40, 0x01, 0x00,
- 0x19, 0x40, 0x10, 0x04, 0x20,
- 0xa0, 0x00, 0x26, 0x04, 0x00,
- 0xd8, 0x0d, 0xc0, 0x01, 0x00,
- 0x00, 0x42, 0x10, 0x80, 0x02,
- 0xb0, 0x00, 0x46, 0x04, 0x00,
- 0xb0, 0x00, 0x56, 0x08, 0x00,
- 0xe0, 0x00, 0x00, 0x00, 0x04,
- 0xfc, 0x10, 0xae, 0x43, 0x90,
- 0x84, 0xf0, 0x32, 0x01, 0x21,
- 0xd8, 0x11, 0x40, 0x01, 0x00,
- 0xa0, 0x60, 0x3c, 0x00, 0x02,
- 0xa0, 0x20, 0x40, 0x10, 0x00,
- 0xa0, 0x20, 0x50, 0x14, 0x00,
- 0xd8, 0x12, 0x00, 0x00, 0x18,
- 0xa0, 0x00, 0x28, 0x0c, 0x00,
- 0xb0, 0x00, 0x48, 0x10, 0x00,
- 0xb0, 0x00, 0x58, 0x14, 0x00,
- 0xaa, 0xf0, 0x00, 0x14, 0x01,
- 0xd8, 0x1a, 0xc0, 0x01, 0x05,
- 0x85, 0x80, 0x42, 0x01, 0xff,
- 0x95, 0x00, 0x66, 0x01, 0xff,
- 0xba, 0xc0, 0x60, 0x1b, 0x01,
- 0x9a, 0x30, 0x60, 0x19, 0x30,
- 0x9a, 0xb0, 0x70, 0x1a, 0x30,
- 0x9b, 0x50, 0x78, 0x1e, 0x04,
- 0x8a, 0xe2, 0x08, 0x1e, 0x21,
- 0x6a, 0x4e, 0x00, 0x13, 0x00,
- 0xe0, 0x00, 0x00, 0x00, 0x30,
- 0x9b, 0x00, 0x7a, 0x92, 0x04,
- 0x3d, 0x00, 0x04, 0x1f, 0x20,
- 0x84, 0xe2, 0x02, 0x01, 0x21,
- 0xd8, 0x16, 0x80, 0x01, 0x00,
- 0xa4, 0x18, 0x0c, 0x7d, 0x80,
- 0xa0, 0x58, 0x1c, 0x00, 0x01,
- 0x01, 0x42, 0x00, 0xa0, 0x02,
- 0xe0, 0x00, 0x00, 0x00, 0x08,
- 0xfc, 0x10, 0xae, 0x63, 0x98,
- 0xd8, 0x1b, 0x00, 0xc2, 0x14,
- 0x84, 0xe2, 0x02, 0x01, 0x21,
- 0xd8, 0x05, 0xc0, 0x01, 0x00,
- 0x84, 0xa2, 0x02, 0x01, 0x21,
- 0xd8, 0x19, 0x40, 0x01, 0x01,
- 0xa0, 0x58, 0x0c, 0x00, 0x02,
- 0x1a, 0x40, 0x00, 0x04, 0x24,
- 0x33, 0x00, 0x01, 0x2f, 0x20,
- 0xd8, 0x05, 0xc0, 0x00, 0x18,
- 0xa0, 0x58, 0x0c, 0x00, 0x02,
- 0x1a, 0x40, 0x00, 0x04, 0x20,
- 0xd8, 0x05, 0xc0, 0x00, 0x18,
- 0xe0, 0x00, 0x02, 0x00, 0x00,
- 0xe0, 0x00, 0x02, 0x00, 0x00,
- 0xe0, 0x00, 0x02, 0x00, 0x00,
- 0xe0, 0x00, 0x02, 0x00, 0x00,
- 0xe0, 0x00, 0x02, 0x00, 0x00,
- }
-};
diff --git a/drivers/net/ethernet/xscale/ixp2000/ixp2400_tx.uc b/drivers/net/ethernet/xscale/ixp2000/ixp2400_tx.uc
deleted file mode 100644
index d090d18..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/ixp2400_tx.uc
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * TX ucode for the Intel IXP2400 in POS-PHY mode.
- * Copyright (C) 2004, 2005 Lennert Buytenhek
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Assumptions made in this code:
- * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where
- * only one TBUF partition is used. This includes, for example,
- * 1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4. (This
- * is not an exhaustive list.)
- * - The TBUF uses 64-byte mpackets.
- * - TX descriptors reside in SRAM, and have the following format:
- * struct tx_desc
- * {
- * // to uengine
- * u32 buf_phys_addr;
- * u32 pkt_length;
- * u32 channel;
- * };
- * - Packet data resides in DRAM.
- * - Packet buffer addresses are 8-byte aligned.
- * - Scratch ring 2 is tx_pending.
- * - Scratch ring 3 is tx_done, and has status condition 'full'.
- * - This code is run on all eight threads of the microengine it runs on.
- */
-
-#define TX_SEQUENCE_0 0x0060
-#define TBUF_CTRL 0x1800
-
-#define PARTITION_SIZE 128
-#define PARTITION_THRESH 96
-
-
- .sig volatile sig1
- .sig volatile sig2
- .sig volatile sig3
-
- .reg @old_tx_seq_0
- .reg @mpkts_in_flight
- .reg @next_tbuf_mpacket
-
- .reg @buffer_handle
- .reg @buffer_start
- .reg @packet_length
- .reg @channel
- .reg @packet_offset
-
- .reg zero
-
- immed[zero, 0]
-
- /*
- * Skip context 0 initialisation?
- */
- .begin
- br!=ctx[0, mpacket_tx_loop#]
- .end
-
- /*
- * Wait until all pending TBUF elements have been transmitted.
- */
- .begin
- .reg read $tx
- .sig zzz
-
- loop_empty#:
- msf[read, $tx, zero, TX_SEQUENCE_0, 1], ctx_swap[zzz]
- alu_shf[--, --, b, $tx, >>31]
- beq[loop_empty#]
-
- alu[@old_tx_seq_0, --, b, $tx]
- .end
-
- immed[@mpkts_in_flight, 0]
- alu[@next_tbuf_mpacket, @old_tx_seq_0, and, (PARTITION_SIZE - 1)]
-
- immed[@buffer_handle, 0]
-
- /*
- * Initialise signal pipeline.
- */
- .begin
- local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]
- .set_sig sig1
-
- local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]
- .set_sig sig2
-
- local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]
- .set_sig sig3
- .end
-
-mpacket_tx_loop#:
- .begin
- .reg tbuf_element_index
- .reg buffer_handle
- .reg sop_eop
- .reg packet_data
- .reg channel
- .reg mpacket_size
-
- /*
- * If there is no packet currently being transmitted,
- * dequeue the next TX descriptor, and fetch the buffer
- * address, packet length and destination channel number.
- */
- .begin
- .reg read $stemp $stemp2 $stemp3
- .xfer_order $stemp $stemp2 $stemp3
- .sig zzz
-
- ctx_arb[sig1]
-
- alu[--, --, b, @buffer_handle]
- bne[already_got_packet#]
-
- tx_nobufs#:
- scratch[get, $stemp, zero, 8, 1], ctx_swap[zzz]
- alu[@buffer_handle, --, b, $stemp]
- beq[tx_nobufs#]
-
- sram[read, $stemp, $stemp, 0, 3], ctx_swap[zzz]
- alu[@buffer_start, --, b, $stemp]
- alu[@packet_length, --, b, $stemp2]
- beq[zero_byte_packet#]
- alu[@channel, --, b, $stemp3]
- immed[@packet_offset, 0]
-
- already_got_packet#:
- local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]
- .end
-
- /*
- * Determine tbuf element index, SOP/EOP flags, mpacket
- * offset and mpacket size and cache buffer_handle and
- * channel number.
- */
- .begin
- alu[tbuf_element_index, --, b, @next_tbuf_mpacket]
- alu[@next_tbuf_mpacket, @next_tbuf_mpacket, +, 1]
- alu[@next_tbuf_mpacket, @next_tbuf_mpacket, and,
- (PARTITION_SIZE - 1)]
-
- alu[buffer_handle, --, b, @buffer_handle]
- immed[@buffer_handle, 0]
-
- immed[sop_eop, 1]
-
- alu[packet_data, --, b, @packet_offset]
- bne[no_sop#]
- alu[sop_eop, sop_eop, or, 2]
- no_sop#:
- alu[packet_data, packet_data, +, @buffer_start]
-
- alu[channel, --, b, @channel]
-
- alu[mpacket_size, @packet_length, -, @packet_offset]
- alu[--, 64, -, mpacket_size]
- bhs[eop#]
- alu[@buffer_handle, --, b, buffer_handle]
- immed[mpacket_size, 64]
- alu[sop_eop, sop_eop, and, 2]
- eop#:
-
- alu[@packet_offset, @packet_offset, +, mpacket_size]
- .end
-
- /*
- * Wait until there's enough space in the TBUF.
- */
- .begin
- .reg read $tx
- .reg temp
- .sig zzz
-
- ctx_arb[sig2]
-
- br[test_space#]
-
- loop_space#:
- msf[read, $tx, zero, TX_SEQUENCE_0, 1], ctx_swap[zzz]
-
- alu[temp, $tx, -, @old_tx_seq_0]
- alu[temp, temp, and, 0xff]
- alu[@mpkts_in_flight, @mpkts_in_flight, -, temp]
-
- alu[@old_tx_seq_0, --, b, $tx]
-
- test_space#:
- alu[--, PARTITION_THRESH, -, @mpkts_in_flight]
- blo[loop_space#]
-
- alu[@mpkts_in_flight, @mpkts_in_flight, +, 1]
-
- local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]
- .end
-
- /*
- * Copy the packet data to the TBUF.
- */
- .begin
- .reg temp
- .sig copy_sig
-
- alu[temp, mpacket_size, -, 1]
- alu_shf[temp, 0x10, or, temp, >>3]
- alu_shf[temp, 0x10, or, temp, <<21]
- alu_shf[temp, temp, or, tbuf_element_index, <<11]
- alu_shf[--, temp, or, 1, <<18]
-
- dram[tbuf_wr, --, packet_data, 0, max_8],
- indirect_ref, sig_done[copy_sig]
- ctx_arb[copy_sig]
- .end
-
- /*
- * Mark TBUF element as ready-to-be-transmitted.
- */
- .begin
- .reg write $tsw $tsw2
- .xfer_order $tsw $tsw2
- .reg temp
- .sig zzz
-
- alu_shf[temp, channel, or, mpacket_size, <<24]
- alu_shf[$tsw, temp, or, sop_eop, <<8]
- immed[$tsw2, 0]
-
- immed[temp, TBUF_CTRL]
- alu_shf[temp, temp, or, tbuf_element_index, <<3]
- msf[write, $tsw, temp, 0, 2], ctx_swap[zzz]
- .end
-
- /*
- * Resynchronise.
- */
- .begin
- ctx_arb[sig3]
- local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]
- .end
-
- /*
- * If this was an EOP mpacket, recycle the TX buffer
- * and signal the host.
- */
- .begin
- .reg write $stemp
- .sig zzz
-
- alu[--, sop_eop, and, 1]
- beq[mpacket_tx_loop#]
-
- tx_done_ring_full#:
- br_inp_state[SCR_Ring3_Status, tx_done_ring_full#]
-
- alu[$stemp, --, b, buffer_handle]
- scratch[put, $stemp, zero, 12, 1], ctx_swap[zzz]
- cap[fast_wr, 0, XSCALE_INT_A]
- br[mpacket_tx_loop#]
- .end
- .end
-
-
-zero_byte_packet#:
- halt
-
-
diff --git a/drivers/net/ethernet/xscale/ixp2000/ixp2400_tx.ucode b/drivers/net/ethernet/xscale/ixp2000/ixp2400_tx.ucode
deleted file mode 100644
index a433e24..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/ixp2400_tx.ucode
+++ /dev/null
@@ -1,98 +0,0 @@
-static struct ixp2000_uengine_code ixp2400_tx =
-{
- .cpu_model_bitmask = 0x000003fe,
- .cpu_min_revision = 0,
- .cpu_max_revision = 255,
-
- .uengine_parameters = IXP2000_UENGINE_8_CONTEXTS |
- IXP2000_UENGINE_PRN_UPDATE_EVERY |
- IXP2000_UENGINE_NN_FROM_PREVIOUS |
- IXP2000_UENGINE_ASSERT_EMPTY_AT_0 |
- IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT |
- IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT,
-
- .initial_reg_values = (struct ixp2000_reg_value []) {
- { -1, -1 }
- },
-
- .num_insns = 77,
- .insns = (u8 []) {
- 0xf0, 0x00, 0x00, 0x07, 0x00,
- 0xd8, 0x03, 0x00, 0x00, 0x11,
- 0x3c, 0x40, 0x00, 0x04, 0xe0,
- 0x81, 0xf2, 0x02, 0x01, 0x00,
- 0xd8, 0x00, 0x80, 0x01, 0x00,
- 0xb0, 0x08, 0x06, 0x00, 0x00,
- 0xf0, 0x00, 0x0c, 0x00, 0x80,
- 0xb4, 0x49, 0x02, 0x03, 0x7f,
- 0xf0, 0x00, 0x02, 0x83, 0x00,
- 0xfc, 0x10, 0xac, 0x23, 0x08,
- 0xfc, 0x10, 0xac, 0x43, 0x10,
- 0xfc, 0x10, 0xac, 0x63, 0x18,
- 0xe0, 0x00, 0x00, 0x00, 0x02,
- 0xa0, 0x30, 0x02, 0x80, 0x00,
- 0xd8, 0x06, 0x00, 0x01, 0x01,
- 0x19, 0x40, 0x00, 0x04, 0x28,
- 0xb0, 0x0a, 0x06, 0x00, 0x00,
- 0xd8, 0x03, 0xc0, 0x01, 0x00,
- 0x00, 0x44, 0x00, 0x80, 0x80,
- 0xa0, 0x09, 0x06, 0x00, 0x00,
- 0xb0, 0x0b, 0x06, 0x04, 0x00,
- 0xd8, 0x13, 0x00, 0x01, 0x00,
- 0xb0, 0x0c, 0x06, 0x08, 0x00,
- 0xf0, 0x00, 0x0c, 0x00, 0xa0,
- 0xfc, 0x10, 0xae, 0x23, 0x88,
- 0xa0, 0x00, 0x12, 0x40, 0x00,
- 0xb0, 0xc9, 0x02, 0x43, 0x01,
- 0xb4, 0x49, 0x02, 0x43, 0x7f,
- 0xb0, 0x00, 0x22, 0x80, 0x00,
- 0xf0, 0x00, 0x02, 0x83, 0x00,
- 0xf0, 0x00, 0x0c, 0x04, 0x02,
- 0xb0, 0x40, 0x6c, 0x00, 0xa0,
- 0xd8, 0x08, 0x80, 0x01, 0x01,
- 0xaa, 0x00, 0x2c, 0x08, 0x02,
- 0xa0, 0xc0, 0x30, 0x18, 0x90,
- 0xa0, 0x00, 0x43, 0x00, 0x00,
- 0xba, 0xc0, 0x32, 0xc0, 0xa0,
- 0xaa, 0xb0, 0x00, 0x0f, 0x40,
- 0xd8, 0x0a, 0x80, 0x01, 0x04,
- 0xb0, 0x0a, 0x00, 0x08, 0x00,
- 0xf0, 0x00, 0x00, 0x0f, 0x40,
- 0xa4, 0x00, 0x2c, 0x08, 0x02,
- 0xa0, 0x8a, 0x00, 0x0c, 0xa0,
- 0xe0, 0x00, 0x00, 0x00, 0x04,
- 0xd8, 0x0c, 0x80, 0x00, 0x18,
- 0x3c, 0x40, 0x00, 0x04, 0xe0,
- 0xba, 0x80, 0x42, 0x01, 0x80,
- 0xb4, 0x40, 0x40, 0x13, 0xff,
- 0xaa, 0x88, 0x00, 0x10, 0x80,
- 0xb0, 0x08, 0x06, 0x00, 0x00,
- 0xaa, 0xf0, 0x0d, 0x80, 0x80,
- 0xd8, 0x0b, 0x40, 0x01, 0x05,
- 0xa0, 0x88, 0x0c, 0x04, 0x80,
- 0xfc, 0x10, 0xae, 0x43, 0x90,
- 0xba, 0xc0, 0x50, 0x0f, 0x01,
- 0x9a, 0x30, 0x50, 0x15, 0x30,
- 0x9a, 0xb0, 0x50, 0x16, 0x30,
- 0x9b, 0x50, 0x58, 0x16, 0x01,
- 0x8a, 0xe2, 0x08, 0x16, 0x21,
- 0x6b, 0x4e, 0x00, 0x83, 0x03,
- 0xe0, 0x00, 0x00, 0x00, 0x30,
- 0x9a, 0x80, 0x70, 0x0e, 0x04,
- 0x8b, 0x88, 0x08, 0x1e, 0x02,
- 0xf0, 0x00, 0x0c, 0x01, 0x81,
- 0xf0, 0x01, 0x80, 0x1f, 0x00,
- 0x9b, 0xd0, 0x78, 0x1e, 0x01,
- 0x3d, 0x42, 0x00, 0x1c, 0x20,
- 0xe0, 0x00, 0x00, 0x00, 0x08,
- 0xfc, 0x10, 0xae, 0x63, 0x98,
- 0xa4, 0x30, 0x0c, 0x04, 0x02,
- 0xd8, 0x03, 0x00, 0x01, 0x00,
- 0xd8, 0x11, 0xc1, 0x42, 0x14,
- 0xa0, 0x18, 0x00, 0x08, 0x00,
- 0x1a, 0x40, 0x00, 0x04, 0x2c,
- 0x33, 0x00, 0x01, 0x2f, 0x20,
- 0xd8, 0x03, 0x00, 0x00, 0x18,
- 0xe0, 0x00, 0x02, 0x00, 0x00,
- }
-};
diff --git a/drivers/net/ethernet/xscale/ixp2000/ixpdev.c b/drivers/net/ethernet/xscale/ixp2000/ixpdev.c
deleted file mode 100644
index 4500837..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/ixpdev.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * IXP2000 MSF network device driver
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/moduleparam.h>
-#include <linux/gfp.h>
-#include <asm/hardware/uengine.h>
-#include <asm/io.h>
-#include "ixp2400_rx.ucode"
-#include "ixp2400_tx.ucode"
-#include "ixpdev_priv.h"
-#include "ixpdev.h"
-#include "pm3386.h"
-
-#define DRV_MODULE_VERSION "0.2"
-
-static int nds_count;
-static struct net_device **nds;
-static int nds_open;
-static void (*set_port_admin_status)(int port, int up);
-
-static struct ixpdev_rx_desc * const rx_desc =
- (struct ixpdev_rx_desc *)(IXP2000_SRAM0_VIRT_BASE + RX_BUF_DESC_BASE);
-static struct ixpdev_tx_desc * const tx_desc =
- (struct ixpdev_tx_desc *)(IXP2000_SRAM0_VIRT_BASE + TX_BUF_DESC_BASE);
-static int tx_pointer;
-
-
-static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct ixpdev_priv *ip = netdev_priv(dev);
- struct ixpdev_tx_desc *desc;
- int entry;
- unsigned long flags;
-
- if (unlikely(skb->len > PAGE_SIZE)) {
- /* @@@ Count drops. */
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
-
- entry = tx_pointer;
- tx_pointer = (tx_pointer + 1) % TX_BUF_COUNT;
-
- desc = tx_desc + entry;
- desc->pkt_length = skb->len;
- desc->channel = ip->channel;
-
- skb_copy_and_csum_dev(skb, phys_to_virt(desc->buf_addr));
- dev_kfree_skb(skb);
-
- ixp2000_reg_write(RING_TX_PENDING,
- TX_BUF_DESC_BASE + (entry * sizeof(struct ixpdev_tx_desc)));
-
- local_irq_save(flags);
- ip->tx_queue_entries++;
- if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
- netif_stop_queue(dev);
- local_irq_restore(flags);
-
- return NETDEV_TX_OK;
-}
-
-
-static int ixpdev_rx(struct net_device *dev, int processed, int budget)
-{
- while (processed < budget) {
- struct ixpdev_rx_desc *desc;
- struct sk_buff *skb;
- void *buf;
- u32 _desc;
-
- _desc = ixp2000_reg_read(RING_RX_DONE);
- if (_desc == 0)
- return 0;
-
- desc = rx_desc +
- ((_desc - RX_BUF_DESC_BASE) / sizeof(struct ixpdev_rx_desc));
- buf = phys_to_virt(desc->buf_addr);
-
- if (desc->pkt_length < 4 || desc->pkt_length > PAGE_SIZE) {
- printk(KERN_ERR "ixp2000: rx err, length %d\n",
- desc->pkt_length);
- goto err;
- }
-
- if (desc->channel < 0 || desc->channel >= nds_count) {
- printk(KERN_ERR "ixp2000: rx err, channel %d\n",
- desc->channel);
- goto err;
- }
-
- /* @@@ Make FCS stripping configurable. */
- desc->pkt_length -= 4;
-
- if (unlikely(!netif_running(nds[desc->channel])))
- goto err;
-
- skb = netdev_alloc_skb_ip_align(dev, desc->pkt_length);
- if (likely(skb != NULL)) {
- skb_copy_to_linear_data(skb, buf, desc->pkt_length);
- skb_put(skb, desc->pkt_length);
- skb->protocol = eth_type_trans(skb, nds[desc->channel]);
-
- netif_receive_skb(skb);
- }
-
-err:
- ixp2000_reg_write(RING_RX_PENDING, _desc);
- processed++;
- }
-
- return processed;
-}
-
-/* dev always points to nds[0]. */
-static int ixpdev_poll(struct napi_struct *napi, int budget)
-{
- struct ixpdev_priv *ip = container_of(napi, struct ixpdev_priv, napi);
- struct net_device *dev = ip->dev;
- int rx;
-
- rx = 0;
- do {
- ixp2000_reg_write(IXP2000_IRQ_THD_RAW_STATUS_A_0, 0x00ff);
-
- rx = ixpdev_rx(dev, rx, budget);
- if (rx >= budget)
- break;
- } while (ixp2000_reg_read(IXP2000_IRQ_THD_RAW_STATUS_A_0) & 0x00ff);
-
- napi_complete(napi);
- ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0x00ff);
-
- return rx;
-}
-
-static void ixpdev_tx_complete(void)
-{
- int channel;
- u32 wake;
-
- wake = 0;
- while (1) {
- struct ixpdev_priv *ip;
- u32 desc;
- int entry;
-
- desc = ixp2000_reg_read(RING_TX_DONE);
- if (desc == 0)
- break;
-
- /* @@@ Check whether entries come back in order. */
- entry = (desc - TX_BUF_DESC_BASE) / sizeof(struct ixpdev_tx_desc);
- channel = tx_desc[entry].channel;
-
- if (channel < 0 || channel >= nds_count) {
- printk(KERN_ERR "ixp2000: txcomp channel index "
- "out of bounds (%d, %.8i, %d)\n",
- channel, (unsigned int)desc, entry);
- continue;
- }
-
- ip = netdev_priv(nds[channel]);
- if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
- wake |= 1 << channel;
- ip->tx_queue_entries--;
- }
-
- for (channel = 0; wake != 0; channel++) {
- if (wake & (1 << channel)) {
- netif_wake_queue(nds[channel]);
- wake &= ~(1 << channel);
- }
- }
-}
-
-static irqreturn_t ixpdev_interrupt(int irq, void *dev_id)
-{
- u32 status;
-
- status = ixp2000_reg_read(IXP2000_IRQ_THD_STATUS_A_0);
- if (status == 0)
- return IRQ_NONE;
-
- /*
- * Any of the eight receive units signaled RX?
- */
- if (status & 0x00ff) {
- struct net_device *dev = nds[0];
- struct ixpdev_priv *ip = netdev_priv(dev);
-
- ixp2000_reg_wrb(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0x00ff);
- if (likely(napi_schedule_prep(&ip->napi))) {
- __napi_schedule(&ip->napi);
- } else {
- printk(KERN_CRIT "ixp2000: irq while polling!!\n");
- }
- }
-
- /*
- * Any of the eight transmit units signaled TXdone?
- */
- if (status & 0xff00) {
- ixp2000_reg_wrb(IXP2000_IRQ_THD_RAW_STATUS_A_0, 0xff00);
- ixpdev_tx_complete();
- }
-
- return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void ixpdev_poll_controller(struct net_device *dev)
-{
- disable_irq(IRQ_IXP2000_THDA0);
- ixpdev_interrupt(IRQ_IXP2000_THDA0, dev);
- enable_irq(IRQ_IXP2000_THDA0);
-}
-#endif
-
-static int ixpdev_open(struct net_device *dev)
-{
- struct ixpdev_priv *ip = netdev_priv(dev);
- int err;
-
- napi_enable(&ip->napi);
- if (!nds_open++) {
- err = request_irq(IRQ_IXP2000_THDA0, ixpdev_interrupt,
- IRQF_SHARED, "ixp2000_eth", nds);
- if (err) {
- nds_open--;
- napi_disable(&ip->napi);
- return err;
- }
-
- ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0xffff);
- }
-
- set_port_admin_status(ip->channel, 1);
- netif_start_queue(dev);
-
- return 0;
-}
-
-static int ixpdev_close(struct net_device *dev)
-{
- struct ixpdev_priv *ip = netdev_priv(dev);
-
- netif_stop_queue(dev);
- napi_disable(&ip->napi);
- set_port_admin_status(ip->channel, 0);
-
- if (!--nds_open) {
- ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0xffff);
- free_irq(IRQ_IXP2000_THDA0, nds);
- }
-
- 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 = {
- .ndo_open = ixpdev_open,
- .ndo_stop = ixpdev_close,
- .ndo_start_xmit = ixpdev_xmit,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_get_stats = ixpdev_get_stats,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = ixpdev_poll_controller,
-#endif
-};
-
-struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
-{
- struct net_device *dev;
- struct ixpdev_priv *ip;
-
- dev = alloc_etherdev(sizeof_priv);
- if (dev == NULL)
- return NULL;
-
- dev->netdev_ops = &ixpdev_netdev_ops;
-
- dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
-
- ip = netdev_priv(dev);
- ip->dev = dev;
- netif_napi_add(dev, &ip->napi, ixpdev_poll, 64);
- ip->channel = channel;
- ip->tx_queue_entries = 0;
-
- return dev;
-}
-
-int ixpdev_init(int __nds_count, struct net_device **__nds,
- void (*__set_port_admin_status)(int port, int up))
-{
- int i;
- int err;
-
- BUILD_BUG_ON(RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192);
-
- printk(KERN_INFO "IXP2000 MSF ethernet driver %s\n", DRV_MODULE_VERSION);
-
- nds_count = __nds_count;
- nds = __nds;
- set_port_admin_status = __set_port_admin_status;
-
- for (i = 0; i < RX_BUF_COUNT; i++) {
- void *buf;
-
- buf = (void *)get_zeroed_page(GFP_KERNEL);
- if (buf == NULL) {
- err = -ENOMEM;
- while (--i >= 0)
- free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
- goto err_out;
- }
- rx_desc[i].buf_addr = virt_to_phys(buf);
- rx_desc[i].buf_length = PAGE_SIZE;
- }
-
- /* @@@ Maybe we shouldn't be preallocating TX buffers. */
- for (i = 0; i < TX_BUF_COUNT; i++) {
- void *buf;
-
- buf = (void *)get_zeroed_page(GFP_KERNEL);
- if (buf == NULL) {
- err = -ENOMEM;
- while (--i >= 0)
- free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
- goto err_free_rx;
- }
- tx_desc[i].buf_addr = virt_to_phys(buf);
- }
-
- /* 256 entries, ring status set means 'empty', base address 0x0000. */
- ixp2000_reg_write(RING_RX_PENDING_BASE, 0x44000000);
- ixp2000_reg_write(RING_RX_PENDING_HEAD, 0x00000000);
- ixp2000_reg_write(RING_RX_PENDING_TAIL, 0x00000000);
-
- /* 256 entries, ring status set means 'full', base address 0x0400. */
- ixp2000_reg_write(RING_RX_DONE_BASE, 0x40000400);
- ixp2000_reg_write(RING_RX_DONE_HEAD, 0x00000000);
- ixp2000_reg_write(RING_RX_DONE_TAIL, 0x00000000);
-
- for (i = 0; i < RX_BUF_COUNT; i++) {
- ixp2000_reg_write(RING_RX_PENDING,
- RX_BUF_DESC_BASE + (i * sizeof(struct ixpdev_rx_desc)));
- }
-
- ixp2000_uengine_load(0, &ixp2400_rx);
- ixp2000_uengine_start_contexts(0, 0xff);
-
- /* 256 entries, ring status set means 'empty', base address 0x0800. */
- ixp2000_reg_write(RING_TX_PENDING_BASE, 0x44000800);
- ixp2000_reg_write(RING_TX_PENDING_HEAD, 0x00000000);
- ixp2000_reg_write(RING_TX_PENDING_TAIL, 0x00000000);
-
- /* 256 entries, ring status set means 'full', base address 0x0c00. */
- ixp2000_reg_write(RING_TX_DONE_BASE, 0x40000c00);
- ixp2000_reg_write(RING_TX_DONE_HEAD, 0x00000000);
- ixp2000_reg_write(RING_TX_DONE_TAIL, 0x00000000);
-
- ixp2000_uengine_load(1, &ixp2400_tx);
- ixp2000_uengine_start_contexts(1, 0xff);
-
- for (i = 0; i < nds_count; i++) {
- err = register_netdev(nds[i]);
- if (err) {
- while (--i >= 0)
- unregister_netdev(nds[i]);
- goto err_free_tx;
- }
- }
-
- for (i = 0; i < nds_count; i++) {
- printk(KERN_INFO "%s: IXP2000 MSF ethernet (port %d), %pM.\n",
- nds[i]->name, i, nds[i]->dev_addr);
- }
-
- return 0;
-
-err_free_tx:
- for (i = 0; i < TX_BUF_COUNT; i++)
- free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
-
-err_free_rx:
- for (i = 0; i < RX_BUF_COUNT; i++)
- free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
-
-err_out:
- return err;
-}
-
-void ixpdev_deinit(void)
-{
- int i;
-
- /* @@@ Flush out pending packets. */
-
- for (i = 0; i < nds_count; i++)
- unregister_netdev(nds[i]);
-
- ixp2000_uengine_stop_contexts(1, 0xff);
- ixp2000_uengine_stop_contexts(0, 0xff);
- ixp2000_uengine_reset(0x3);
-
- for (i = 0; i < TX_BUF_COUNT; i++)
- free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
-
- for (i = 0; i < RX_BUF_COUNT; i++)
- free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
-}
diff --git a/drivers/net/ethernet/xscale/ixp2000/ixpdev.h b/drivers/net/ethernet/xscale/ixp2000/ixpdev.h
deleted file mode 100644
index 391ece6..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/ixpdev.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * IXP2000 MSF network device driver
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __IXPDEV_H
-#define __IXPDEV_H
-
-struct ixpdev_priv
-{
- struct net_device *dev;
- struct napi_struct napi;
- int channel;
- int tx_queue_entries;
-};
-
-struct net_device *ixpdev_alloc(int channel, int sizeof_priv);
-int ixpdev_init(int num_ports, struct net_device **nds,
- void (*set_port_admin_status)(int port, int up));
-void ixpdev_deinit(void);
-
-
-#endif
diff --git a/drivers/net/ethernet/xscale/ixp2000/ixpdev_priv.h b/drivers/net/ethernet/xscale/ixp2000/ixpdev_priv.h
deleted file mode 100644
index 86aa08e..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/ixpdev_priv.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * IXP2000 MSF network device driver
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __IXPDEV_PRIV_H
-#define __IXPDEV_PRIV_H
-
-#define RX_BUF_DESC_BASE 0x00001000
-#define RX_BUF_COUNT ((3 * PAGE_SIZE) / (4 * sizeof(struct ixpdev_rx_desc)))
-#define TX_BUF_DESC_BASE 0x00002000
-#define TX_BUF_COUNT ((3 * PAGE_SIZE) / (4 * sizeof(struct ixpdev_tx_desc)))
-#define TX_BUF_COUNT_PER_CHAN (TX_BUF_COUNT / 4)
-
-#define RING_RX_PENDING ((u32 *)IXP2000_SCRATCH_RING_VIRT_BASE)
-#define RING_RX_DONE ((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 4))
-#define RING_TX_PENDING ((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 8))
-#define RING_TX_DONE ((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 12))
-
-#define SCRATCH_REG(x) ((u32 *)(IXP2000_GLOBAL_REG_VIRT_BASE | 0x0800 | (x)))
-#define RING_RX_PENDING_BASE SCRATCH_REG(0x00)
-#define RING_RX_PENDING_HEAD SCRATCH_REG(0x04)
-#define RING_RX_PENDING_TAIL SCRATCH_REG(0x08)
-#define RING_RX_DONE_BASE SCRATCH_REG(0x10)
-#define RING_RX_DONE_HEAD SCRATCH_REG(0x14)
-#define RING_RX_DONE_TAIL SCRATCH_REG(0x18)
-#define RING_TX_PENDING_BASE SCRATCH_REG(0x20)
-#define RING_TX_PENDING_HEAD SCRATCH_REG(0x24)
-#define RING_TX_PENDING_TAIL SCRATCH_REG(0x28)
-#define RING_TX_DONE_BASE SCRATCH_REG(0x30)
-#define RING_TX_DONE_HEAD SCRATCH_REG(0x34)
-#define RING_TX_DONE_TAIL SCRATCH_REG(0x38)
-
-struct ixpdev_rx_desc
-{
- u32 buf_addr;
- u32 buf_length;
- u32 channel;
- u32 pkt_length;
-};
-
-struct ixpdev_tx_desc
-{
- u32 buf_addr;
- u32 pkt_length;
- u32 channel;
- u32 unused;
-};
-
-
-#endif
diff --git a/drivers/net/ethernet/xscale/ixp2000/pm3386.c b/drivers/net/ethernet/xscale/ixp2000/pm3386.c
deleted file mode 100644
index e08d3f9..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/pm3386.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Helper functions for the PM3386s on the Radisys ENP2611
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <asm/io.h>
-#include "pm3386.h"
-
-/*
- * Read from register 'reg' of PM3386 device 'pm'.
- */
-static u16 pm3386_reg_read(int pm, int reg)
-{
- void *_reg;
- u16 value;
-
- _reg = (void *)ENP2611_PM3386_0_VIRT_BASE;
- if (pm == 1)
- _reg = (void *)ENP2611_PM3386_1_VIRT_BASE;
-
- value = *((volatile u16 *)(_reg + (reg << 1)));
-
-// printk(KERN_INFO "pm3386_reg_read(%d, %.3x) = %.8x\n", pm, reg, value);
-
- return value;
-}
-
-/*
- * Write to register 'reg' of PM3386 device 'pm', and perform
- * a readback from the identification register.
- */
-static void pm3386_reg_write(int pm, int reg, u16 value)
-{
- void *_reg;
- u16 dummy;
-
-// printk(KERN_INFO "pm3386_reg_write(%d, %.3x, %.8x)\n", pm, reg, value);
-
- _reg = (void *)ENP2611_PM3386_0_VIRT_BASE;
- if (pm == 1)
- _reg = (void *)ENP2611_PM3386_1_VIRT_BASE;
-
- *((volatile u16 *)(_reg + (reg << 1))) = value;
-
- dummy = *((volatile u16 *)_reg);
- __asm__ __volatile__("mov %0, %0" : "+r" (dummy));
-}
-
-/*
- * Read from port 'port' register 'reg', where the registers
- * for the different ports are 'spacing' registers apart.
- */
-static u16 pm3386_port_reg_read(int port, int _reg, int spacing)
-{
- int reg;
-
- reg = _reg;
- if (port & 1)
- reg += spacing;
-
- return pm3386_reg_read(port >> 1, reg);
-}
-
-/*
- * Write to port 'port' register 'reg', where the registers
- * for the different ports are 'spacing' registers apart.
- */
-static void pm3386_port_reg_write(int port, int _reg, int spacing, u16 value)
-{
- int reg;
-
- reg = _reg;
- if (port & 1)
- reg += spacing;
-
- pm3386_reg_write(port >> 1, reg, value);
-}
-
-int pm3386_secondary_present(void)
-{
- return pm3386_reg_read(1, 0) == 0x3386;
-}
-
-void pm3386_reset(void)
-{
- u8 mac[3][6];
- int secondary;
-
- secondary = pm3386_secondary_present();
-
- /* Save programmed MAC addresses. */
- pm3386_get_mac(0, mac[0]);
- pm3386_get_mac(1, mac[1]);
- if (secondary)
- pm3386_get_mac(2, mac[2]);
-
- /* Assert analog and digital reset. */
- pm3386_reg_write(0, 0x002, 0x0060);
- if (secondary)
- pm3386_reg_write(1, 0x002, 0x0060);
- mdelay(1);
-
- /* Deassert analog reset. */
- pm3386_reg_write(0, 0x002, 0x0062);
- if (secondary)
- pm3386_reg_write(1, 0x002, 0x0062);
- mdelay(10);
-
- /* Deassert digital reset. */
- pm3386_reg_write(0, 0x002, 0x0063);
- if (secondary)
- pm3386_reg_write(1, 0x002, 0x0063);
- mdelay(10);
-
- /* Restore programmed MAC addresses. */
- pm3386_set_mac(0, mac[0]);
- pm3386_set_mac(1, mac[1]);
- if (secondary)
- pm3386_set_mac(2, mac[2]);
-
- /* Disable carrier on all ports. */
- pm3386_set_carrier(0, 0);
- pm3386_set_carrier(1, 0);
- if (secondary)
- pm3386_set_carrier(2, 0);
-}
-
-static u16 swaph(u16 x)
-{
- return ((x << 8) | (x >> 8)) & 0xffff;
-}
-
-int pm3386_port_count(void)
-{
- return 2 + pm3386_secondary_present();
-}
-
-void pm3386_init_port(int port)
-{
- int pm = port >> 1;
-
- /*
- * Work around ENP2611 bootloader programming MAC address
- * in reverse.
- */
- if (pm3386_port_reg_read(port, 0x30a, 0x100) == 0x0000 &&
- (pm3386_port_reg_read(port, 0x309, 0x100) & 0xff00) == 0x5000) {
- u16 temp[3];
-
- temp[0] = pm3386_port_reg_read(port, 0x308, 0x100);
- temp[1] = pm3386_port_reg_read(port, 0x309, 0x100);
- temp[2] = pm3386_port_reg_read(port, 0x30a, 0x100);
- pm3386_port_reg_write(port, 0x308, 0x100, swaph(temp[2]));
- pm3386_port_reg_write(port, 0x309, 0x100, swaph(temp[1]));
- pm3386_port_reg_write(port, 0x30a, 0x100, swaph(temp[0]));
- }
-
- /*
- * Initialise narrowbanding mode. See application note 2010486
- * for more information. (@@@ We also need to issue a reset
- * when ROOL or DOOL are detected.)
- */
- pm3386_port_reg_write(port, 0x708, 0x10, 0xd055);
- udelay(500);
- pm3386_port_reg_write(port, 0x708, 0x10, 0x5055);
-
- /*
- * SPI-3 ingress block. Set 64 bytes SPI-3 burst size
- * towards SPI-3 bridge.
- */
- pm3386_port_reg_write(port, 0x122, 0x20, 0x0002);
-
- /*
- * Enable ingress protocol checking, and soft reset the
- * SPI-3 ingress block.
- */
- pm3386_reg_write(pm, 0x103, 0x0003);
- while (!(pm3386_reg_read(pm, 0x103) & 0x80))
- ;
-
- /*
- * SPI-3 egress block. Gather 12288 bytes of the current
- * packet in the TX fifo before initiating transmit on the
- * SERDES interface. (Prevents TX underflows.)
- */
- pm3386_port_reg_write(port, 0x221, 0x20, 0x0007);
-
- /*
- * Enforce odd parity from the SPI-3 bridge, and soft reset
- * the SPI-3 egress block.
- */
- pm3386_reg_write(pm, 0x203, 0x000d & ~(4 << (port & 1)));
- while ((pm3386_reg_read(pm, 0x203) & 0x000c) != 0x000c)
- ;
-
- /*
- * EGMAC block. Set this channels to reject long preambles,
- * not send or transmit PAUSE frames, enable preamble checking,
- * disable frame length checking, enable FCS appending, enable
- * TX frame padding.
- */
- pm3386_port_reg_write(port, 0x302, 0x100, 0x0113);
-
- /*
- * Soft reset the EGMAC block.
- */
- pm3386_port_reg_write(port, 0x301, 0x100, 0x8000);
- pm3386_port_reg_write(port, 0x301, 0x100, 0x0000);
-
- /*
- * Auto-sense autonegotiation status.
- */
- pm3386_port_reg_write(port, 0x306, 0x100, 0x0100);
-
- /*
- * Allow reception of jumbo frames.
- */
- pm3386_port_reg_write(port, 0x310, 0x100, 9018);
-
- /*
- * Allow transmission of jumbo frames.
- */
- pm3386_port_reg_write(port, 0x336, 0x100, 9018);
-
- /* @@@ Should set 0x337/0x437 (RX forwarding threshold.) */
-
- /*
- * Set autonegotiation parameters to 'no PAUSE, full duplex.'
- */
- pm3386_port_reg_write(port, 0x31c, 0x100, 0x0020);
-
- /*
- * Enable and restart autonegotiation.
- */
- pm3386_port_reg_write(port, 0x318, 0x100, 0x0003);
- pm3386_port_reg_write(port, 0x318, 0x100, 0x0002);
-}
-
-void pm3386_get_mac(int port, u8 *mac)
-{
- u16 temp;
-
- temp = pm3386_port_reg_read(port, 0x308, 0x100);
- mac[0] = temp & 0xff;
- mac[1] = (temp >> 8) & 0xff;
-
- temp = pm3386_port_reg_read(port, 0x309, 0x100);
- mac[2] = temp & 0xff;
- mac[3] = (temp >> 8) & 0xff;
-
- temp = pm3386_port_reg_read(port, 0x30a, 0x100);
- mac[4] = temp & 0xff;
- mac[5] = (temp >> 8) & 0xff;
-}
-
-void pm3386_set_mac(int port, u8 *mac)
-{
- pm3386_port_reg_write(port, 0x308, 0x100, (mac[1] << 8) | mac[0]);
- pm3386_port_reg_write(port, 0x309, 0x100, (mac[3] << 8) | mac[2]);
- pm3386_port_reg_write(port, 0x30a, 0x100, (mac[5] << 8) | mac[4]);
-}
-
-static u32 pm3386_get_stat(int port, u16 base)
-{
- u32 value;
-
- value = pm3386_port_reg_read(port, base, 0x100);
- value |= pm3386_port_reg_read(port, base + 1, 0x100) << 16;
-
- return value;
-}
-
-void pm3386_get_stats(int port, struct net_device_stats *stats)
-{
- /*
- * Snapshot statistics counters.
- */
- pm3386_port_reg_write(port, 0x500, 0x100, 0x0001);
- while (pm3386_port_reg_read(port, 0x500, 0x100) & 0x0001)
- ;
-
- memset(stats, 0, sizeof(*stats));
-
- stats->rx_packets = pm3386_get_stat(port, 0x510);
- stats->tx_packets = pm3386_get_stat(port, 0x590);
- stats->rx_bytes = pm3386_get_stat(port, 0x514);
- stats->tx_bytes = pm3386_get_stat(port, 0x594);
- /* @@@ Add other stats. */
-}
-
-void pm3386_set_carrier(int port, int state)
-{
- pm3386_port_reg_write(port, 0x703, 0x10, state ? 0x1001 : 0x0000);
-}
-
-int pm3386_is_link_up(int port)
-{
- u16 temp;
-
- temp = pm3386_port_reg_read(port, 0x31a, 0x100);
- temp = pm3386_port_reg_read(port, 0x31a, 0x100);
-
- return !!(temp & 0x0002);
-}
-
-void pm3386_enable_rx(int port)
-{
- u16 temp;
-
- temp = pm3386_port_reg_read(port, 0x303, 0x100);
- temp |= 0x1000;
- pm3386_port_reg_write(port, 0x303, 0x100, temp);
-}
-
-void pm3386_disable_rx(int port)
-{
- u16 temp;
-
- temp = pm3386_port_reg_read(port, 0x303, 0x100);
- temp &= 0xefff;
- pm3386_port_reg_write(port, 0x303, 0x100, temp);
-}
-
-void pm3386_enable_tx(int port)
-{
- u16 temp;
-
- temp = pm3386_port_reg_read(port, 0x303, 0x100);
- temp |= 0x4000;
- pm3386_port_reg_write(port, 0x303, 0x100, temp);
-}
-
-void pm3386_disable_tx(int port)
-{
- u16 temp;
-
- temp = pm3386_port_reg_read(port, 0x303, 0x100);
- temp &= 0xbfff;
- pm3386_port_reg_write(port, 0x303, 0x100, temp);
-}
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/xscale/ixp2000/pm3386.h b/drivers/net/ethernet/xscale/ixp2000/pm3386.h
deleted file mode 100644
index cc4183d..0000000
--- a/drivers/net/ethernet/xscale/ixp2000/pm3386.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Helper functions for the PM3386s on the Radisys ENP2611
- * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
- * Dedicated to Marija Kulikova.
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __PM3386_H
-#define __PM3386_H
-
-void pm3386_reset(void);
-int pm3386_port_count(void);
-void pm3386_init_port(int port);
-void pm3386_get_mac(int port, u8 *mac);
-void pm3386_set_mac(int port, u8 *mac);
-void pm3386_get_stats(int port, struct net_device_stats *stats);
-void pm3386_set_carrier(int port, int state);
-int pm3386_is_link_up(int port);
-void pm3386_enable_rx(int port);
-void pm3386_disable_rx(int port);
-void pm3386_enable_tx(int port);
-void pm3386_disable_tx(int port);
-
-
-#endif
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 41a8b5a..482648f 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -1002,12 +1002,41 @@
return phy_start_aneg(port->phydev);
}
+int ixp46x_phc_index = -1;
+
+static int ixp4xx_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ if (!cpu_is_ixp46x()) {
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE;
+ info->phc_index = -1;
+ return 0;
+ }
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->phc_index = ixp46x_phc_index;
+ info->tx_types =
+ (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON);
+ info->rx_filters =
+ (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ);
+ return 0;
+}
+
static const struct ethtool_ops ixp4xx_ethtool_ops = {
.get_drvinfo = ixp4xx_get_drvinfo,
.get_settings = ixp4xx_get_settings,
.set_settings = ixp4xx_set_settings,
.nway_reset = ixp4xx_nway_reset,
.get_link = ethtool_op_get_link,
+ .get_ts_info = ixp4xx_get_ts_info,
};
diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c
index 168c8f4..b6a2bde 100644
--- a/drivers/net/hippi/rrunner.c
+++ b/drivers/net/hippi/rrunner.c
@@ -113,10 +113,9 @@
SET_NETDEV_DEV(dev, &pdev->dev);
- if (pci_request_regions(pdev, "rrunner")) {
- ret = -EIO;
+ ret = pci_request_regions(pdev, "rrunner");
+ if (ret < 0)
goto out;
- }
pci_set_drvdata(pdev, dev);
@@ -124,11 +123,8 @@
spin_lock_init(&rrpriv->lock);
- dev->irq = pdev->irq;
dev->netdev_ops = &rr_netdev_ops;
- dev->base_addr = pci_resource_start(pdev, 0);
-
/* display version info if adapter is found */
if (!version_disp) {
/* set display flag to TRUE so that */
@@ -146,16 +142,14 @@
pci_set_master(pdev);
printk(KERN_INFO "%s: Essential RoadRunner serial HIPPI "
- "at 0x%08lx, irq %i, PCI latency %i\n", dev->name,
- dev->base_addr, dev->irq, pci_latency);
+ "at 0x%08llx, irq %i, PCI latency %i\n", dev->name,
+ pci_resource_start(pdev, 0), pdev->irq, pci_latency);
/*
- * Remap the regs into kernel space.
+ * Remap the MMIO regs into kernel space.
*/
-
- rrpriv->regs = ioremap(dev->base_addr, 0x1000);
-
- if (!rrpriv->regs){
+ rrpriv->regs = pci_iomap(pdev, 0, 0x1000);
+ if (!rrpriv->regs) {
printk(KERN_ERR "%s: Unable to map I/O register, "
"RoadRunner will be disabled.\n", dev->name);
ret = -EIO;
@@ -202,8 +196,6 @@
rr_init(dev);
- dev->base_addr = 0;
-
ret = register_netdev(dev);
if (ret)
goto out;
@@ -217,7 +209,7 @@
pci_free_consistent(pdev, TX_TOTAL_SIZE, rrpriv->tx_ring,
rrpriv->tx_ring_dma);
if (rrpriv->regs)
- iounmap(rrpriv->regs);
+ pci_iounmap(pdev, rrpriv->regs);
if (pdev) {
pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
@@ -231,29 +223,26 @@
static void __devexit rr_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ struct rr_private *rr = netdev_priv(dev);
- if (dev) {
- struct rr_private *rr = netdev_priv(dev);
-
- if (!(readl(&rr->regs->HostCtrl) & NIC_HALTED)){
- printk(KERN_ERR "%s: trying to unload running NIC\n",
- dev->name);
- writel(HALT_NIC, &rr->regs->HostCtrl);
- }
-
- pci_free_consistent(pdev, EVT_RING_SIZE, rr->evt_ring,
- rr->evt_ring_dma);
- pci_free_consistent(pdev, RX_TOTAL_SIZE, rr->rx_ring,
- rr->rx_ring_dma);
- pci_free_consistent(pdev, TX_TOTAL_SIZE, rr->tx_ring,
- rr->tx_ring_dma);
- unregister_netdev(dev);
- iounmap(rr->regs);
- free_netdev(dev);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
+ if (!(readl(&rr->regs->HostCtrl) & NIC_HALTED)) {
+ printk(KERN_ERR "%s: trying to unload running NIC\n",
+ dev->name);
+ writel(HALT_NIC, &rr->regs->HostCtrl);
}
+
+ unregister_netdev(dev);
+ pci_free_consistent(pdev, EVT_RING_SIZE, rr->evt_ring,
+ rr->evt_ring_dma);
+ pci_free_consistent(pdev, RX_TOTAL_SIZE, rr->rx_ring,
+ rr->rx_ring_dma);
+ pci_free_consistent(pdev, TX_TOTAL_SIZE, rr->tx_ring,
+ rr->tx_ring_dma);
+ pci_iounmap(pdev, rr->regs);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+ free_netdev(dev);
}
@@ -1229,9 +1218,9 @@
readl(®s->HostCtrl);
spin_unlock_irqrestore(&rrpriv->lock, flags);
- if (request_irq(dev->irq, rr_interrupt, IRQF_SHARED, dev->name, dev)) {
+ if (request_irq(pdev->irq, rr_interrupt, IRQF_SHARED, dev->name, dev)) {
printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
- dev->name, dev->irq);
+ dev->name, pdev->irq);
ecode = -EAGAIN;
goto error;
}
@@ -1338,16 +1327,15 @@
static int rr_close(struct net_device *dev)
{
- struct rr_private *rrpriv;
- struct rr_regs __iomem *regs;
+ struct rr_private *rrpriv = netdev_priv(dev);
+ struct rr_regs __iomem *regs = rrpriv->regs;
+ struct pci_dev *pdev = rrpriv->pci_dev;
unsigned long flags;
u32 tmp;
short i;
netif_stop_queue(dev);
- rrpriv = netdev_priv(dev);
- regs = rrpriv->regs;
/*
* Lock to make sure we are not cleaning up while another CPU
@@ -1386,15 +1374,15 @@
rr_raz_tx(rrpriv, dev);
rr_raz_rx(rrpriv, dev);
- pci_free_consistent(rrpriv->pci_dev, 256 * sizeof(struct ring_ctrl),
+ pci_free_consistent(pdev, 256 * sizeof(struct ring_ctrl),
rrpriv->rx_ctrl, rrpriv->rx_ctrl_dma);
rrpriv->rx_ctrl = NULL;
- pci_free_consistent(rrpriv->pci_dev, sizeof(struct rr_info),
- rrpriv->info, rrpriv->info_dma);
+ pci_free_consistent(pdev, sizeof(struct rr_info), rrpriv->info,
+ rrpriv->info_dma);
rrpriv->info = NULL;
- free_irq(dev->irq, dev);
+ free_irq(pdev->irq, dev);
spin_unlock_irqrestore(&rrpriv->lock, flags);
return 0;
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index d025c83..8b91947 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -428,6 +428,24 @@
return 0;
}
+
+#define RING_AVAIL_PERCENT_HIWATER 20
+#define RING_AVAIL_PERCENT_LOWATER 10
+
+/*
+ * Get the percentage of available bytes to write in the ring.
+ * The return value is in range from 0 to 100.
+ */
+static inline u32 hv_ringbuf_avail_percent(
+ struct hv_ring_buffer_info *ring_info)
+{
+ u32 avail_read, avail_write;
+
+ hv_get_ringbuffer_availbytes(ring_info, &avail_read, &avail_write);
+
+ return avail_write * 100 / ring_info->ring_datasize;
+}
+
static void netvsc_send_completion(struct hv_device *device,
struct vmpacket_descriptor *packet)
{
@@ -455,6 +473,8 @@
complete(&net_device->channel_init_wait);
} else if (nvsp_packet->hdr.msg_type ==
NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) {
+ int num_outstanding_sends;
+
/* Get the send context */
nvsc_packet = (struct hv_netvsc_packet *)(unsigned long)
packet->trans_id;
@@ -463,10 +483,14 @@
nvsc_packet->completion.send.send_completion(
nvsc_packet->completion.send.send_completion_ctx);
- atomic_dec(&net_device->num_outstanding_sends);
+ num_outstanding_sends =
+ atomic_dec_return(&net_device->num_outstanding_sends);
- if (netif_queue_stopped(ndev) && !net_device->start_remove)
- netif_wake_queue(ndev);
+ if (netif_queue_stopped(ndev) && !net_device->start_remove &&
+ (hv_ringbuf_avail_percent(&device->channel->outbound)
+ > RING_AVAIL_PERCENT_HIWATER ||
+ num_outstanding_sends < 1))
+ netif_wake_queue(ndev);
} else {
netdev_err(ndev, "Unknown send completion packet type- "
"%d received!!\n", nvsp_packet->hdr.msg_type);
@@ -519,10 +543,19 @@
if (ret == 0) {
atomic_inc(&net_device->num_outstanding_sends);
+ if (hv_ringbuf_avail_percent(&device->channel->outbound) <
+ RING_AVAIL_PERCENT_LOWATER) {
+ netif_stop_queue(ndev);
+ if (atomic_read(&net_device->
+ num_outstanding_sends) < 1)
+ netif_wake_queue(ndev);
+ }
} else if (ret == -EAGAIN) {
netif_stop_queue(ndev);
- if (atomic_read(&net_device->num_outstanding_sends) < 1)
+ if (atomic_read(&net_device->num_outstanding_sends) < 1) {
netif_wake_queue(ndev);
+ ret = -ENOSPC;
+ }
} else {
netdev_err(ndev, "Unable to send packet %p ret %d\n",
packet, ret);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index dd29478..a0cc127 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -224,9 +224,13 @@
net->stats.tx_packets++;
} else {
kfree(packet);
+ if (ret != -EAGAIN) {
+ dev_kfree_skb_any(skb);
+ net->stats.tx_dropped++;
+ }
}
- return ret ? NETDEV_TX_BUSY : NETDEV_TX_OK;
+ return (ret == -EAGAIN) ? NETDEV_TX_BUSY : NETDEV_TX_OK;
}
/*
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index f975afd..b17fc90 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -773,7 +773,8 @@
{
struct macvlan_dev *vlan = netdev_priv(dev);
- NLA_PUT_U32(skb, IFLA_MACVLAN_MODE, vlan->mode);
+ if (nla_put_u32(skb, IFLA_MACVLAN_MODE, vlan->mode))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c
index e16f98c..cd802eb 100644
--- a/drivers/net/phy/bcm63xx.c
+++ b/drivers/net/phy/bcm63xx.c
@@ -39,10 +39,7 @@
MII_BCM63XX_IR_SPEED |
MII_BCM63XX_IR_LINK) |
MII_BCM63XX_IR_EN;
- err = phy_write(phydev, MII_BCM63XX_IR, reg);
- if (err < 0)
- return err;
- return 0;
+ return phy_write(phydev, MII_BCM63XX_IR, reg);
}
static int bcm63xx_ack_interrupt(struct phy_device *phydev)
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 2f774ac..5f59cc0 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -134,12 +134,7 @@
return err;
/* Reconnect the PHY, and enable Autonegotiation */
- err = phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
-
- if (err < 0)
- return err;
-
- return 0;
+ return phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
}
static int dm9161_ack_interrupt(struct phy_device *phydev)
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index dd7ae19..940b290 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -1215,6 +1215,36 @@
}
}
+static int dp83640_ts_info(struct phy_device *dev, struct ethtool_ts_info *info)
+{
+ struct dp83640_private *dp83640 = dev->priv;
+
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+ info->phc_index = ptp_clock_index(dp83640->clock->ptp_clock);
+ info->tx_types =
+ (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON) |
+ (1 << HWTSTAMP_TX_ONESTEP_SYNC);
+ info->rx_filters =
+ (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ);
+ return 0;
+}
+
static struct phy_driver dp83640_driver = {
.phy_id = DP83640_PHY_ID,
.phy_id_mask = 0xfffffff0,
@@ -1225,6 +1255,7 @@
.remove = dp83640_remove,
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
+ .ts_info = dp83640_ts_info,
.hwtstamp = dp83640_hwtstamp,
.rxtstamp = dp83640_rxtstamp,
.txtstamp = dp83640_txtstamp,
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index e8b9c53..418928d 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -455,11 +455,7 @@
if (err < 0)
return err;
- err = phy_write(phydev, MII_BMCR, BMCR_RESET);
- if (err < 0)
- return err;
-
- return 0;
+ return phy_write(phydev, MII_BMCR, BMCR_RESET);
}
static int m88e1118_config_aneg(struct phy_device *phydev)
@@ -515,11 +511,7 @@
if (err < 0)
return err;
- err = phy_write(phydev, MII_BMCR, BMCR_RESET);
- if (err < 0)
- return err;
-
- return 0;
+ return phy_write(phydev, MII_BMCR, BMCR_RESET);
}
static int m88e1149_config_init(struct phy_device *phydev)
@@ -545,11 +537,7 @@
if (err < 0)
return err;
- err = phy_write(phydev, MII_BMCR, BMCR_RESET);
- if (err < 0)
- return err;
-
- return 0;
+ return phy_write(phydev, MII_BMCR, BMCR_RESET);
}
static int m88e1145_config_init(struct phy_device *phydev)
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index 885dbdd..72b50f5 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -116,8 +116,8 @@
int i;
rcu_read_lock();
- for (i = find_next_bit(callid_bitmap, MAX_CALLID, 1); i < MAX_CALLID;
- i = find_next_bit(callid_bitmap, MAX_CALLID, i + 1)) {
+ i = 1;
+ for_each_set_bit_from(i, callid_bitmap, MAX_CALLID) {
sock = rcu_dereference(callid_sock[i]);
if (!sock)
continue;
diff --git a/drivers/net/team/Kconfig b/drivers/net/team/Kconfig
index 248a144..89024d5 100644
--- a/drivers/net/team/Kconfig
+++ b/drivers/net/team/Kconfig
@@ -40,4 +40,15 @@
To compile this team mode as a module, choose M here: the module
will be called team_mode_activebackup.
+config NET_TEAM_MODE_LOADBALANCE
+ tristate "Load-balance mode support"
+ depends on NET_TEAM
+ ---help---
+ This mode provides load balancing functionality. Tx port selection
+ is done using BPF function set up from userspace (bpf_hash_func
+ option)
+
+ To compile this team mode as a module, choose M here: the module
+ will be called team_mode_loadbalance.
+
endif # NET_TEAM
diff --git a/drivers/net/team/Makefile b/drivers/net/team/Makefile
index 85f2028..fb9f4c1 100644
--- a/drivers/net/team/Makefile
+++ b/drivers/net/team/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_NET_TEAM) += team.o
obj-$(CONFIG_NET_TEAM_MODE_ROUNDROBIN) += team_mode_roundrobin.o
obj-$(CONFIG_NET_TEAM_MODE_ACTIVEBACKUP) += team_mode_activebackup.o
+obj-$(CONFIG_NET_TEAM_MODE_LOADBALANCE) += team_mode_loadbalance.o
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 8f81805..ea96f82 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1145,10 +1145,7 @@
},
[TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG },
[TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 },
- [TEAM_ATTR_OPTION_DATA] = {
- .type = NLA_BINARY,
- .len = TEAM_STRING_MAX_LEN,
- },
+ [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY },
};
static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
@@ -1248,7 +1245,8 @@
if (IS_ERR(hdr))
return PTR_ERR(hdr);
- NLA_PUT_U32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex);
+ if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
+ goto nla_put_failure;
option_list = nla_nest_start(skb, TEAM_ATTR_LIST_OPTION);
if (!option_list)
return -EMSGSIZE;
@@ -1256,6 +1254,7 @@
list_for_each_entry(option, &team->option_list, list) {
struct nlattr *option_item;
long arg;
+ struct team_option_binary tbinary;
/* Include only changed options if fill all mode is not on */
if (!fillall && !option->changed)
@@ -1263,24 +1262,40 @@
option_item = nla_nest_start(skb, TEAM_ATTR_ITEM_OPTION);
if (!option_item)
goto nla_put_failure;
- NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_NAME, option->name);
+ if (nla_put_string(skb, TEAM_ATTR_OPTION_NAME, option->name))
+ goto nla_put_failure;
if (option->changed) {
- NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_CHANGED);
+ if (nla_put_flag(skb, TEAM_ATTR_OPTION_CHANGED))
+ goto nla_put_failure;
option->changed = false;
}
- if (option->removed)
- NLA_PUT_FLAG(skb, TEAM_ATTR_OPTION_REMOVED);
+ if (option->removed &&
+ nla_put_flag(skb, TEAM_ATTR_OPTION_REMOVED))
+ goto nla_put_failure;
switch (option->type) {
case TEAM_OPTION_TYPE_U32:
- NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32);
+ if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_U32))
+ goto nla_put_failure;
team_option_get(team, option, &arg);
- NLA_PUT_U32(skb, TEAM_ATTR_OPTION_DATA, arg);
+ if (nla_put_u32(skb, TEAM_ATTR_OPTION_DATA, arg))
+ goto nla_put_failure;
break;
case TEAM_OPTION_TYPE_STRING:
- NLA_PUT_U8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING);
+ if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_STRING))
+ goto nla_put_failure;
team_option_get(team, option, &arg);
- NLA_PUT_STRING(skb, TEAM_ATTR_OPTION_DATA,
- (char *) arg);
+ if (nla_put_string(skb, TEAM_ATTR_OPTION_DATA,
+ (char *) arg))
+ goto nla_put_failure;
+ break;
+ case TEAM_OPTION_TYPE_BINARY:
+ if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY))
+ goto nla_put_failure;
+ arg = (long) &tbinary;
+ team_option_get(team, option, &arg);
+ if (nla_put(skb, TEAM_ATTR_OPTION_DATA,
+ tbinary.data_len, tbinary.data))
+ goto nla_put_failure;
break;
default:
BUG();
@@ -1366,6 +1381,9 @@
case NLA_STRING:
opt_type = TEAM_OPTION_TYPE_STRING;
break;
+ case NLA_BINARY:
+ opt_type = TEAM_OPTION_TYPE_BINARY;
+ break;
default:
goto team_put;
}
@@ -1374,19 +1392,31 @@
list_for_each_entry(option, &team->option_list, list) {
long arg;
struct nlattr *opt_data_attr;
+ struct team_option_binary tbinary;
+ int data_len;
if (option->type != opt_type ||
strcmp(option->name, opt_name))
continue;
opt_found = true;
opt_data_attr = mode_attrs[TEAM_ATTR_OPTION_DATA];
+ data_len = nla_len(opt_data_attr);
switch (opt_type) {
case TEAM_OPTION_TYPE_U32:
arg = nla_get_u32(opt_data_attr);
break;
case TEAM_OPTION_TYPE_STRING:
+ if (data_len > TEAM_STRING_MAX_LEN) {
+ err = -EINVAL;
+ goto team_put;
+ }
arg = (long) nla_data(opt_data_attr);
break;
+ case TEAM_OPTION_TYPE_BINARY:
+ tbinary.data_len = data_len;
+ tbinary.data = nla_data(opt_data_attr);
+ arg = (long) &tbinary;
+ break;
default:
BUG();
}
@@ -1420,7 +1450,8 @@
if (IS_ERR(hdr))
return PTR_ERR(hdr);
- NLA_PUT_U32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex);
+ if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
+ goto nla_put_failure;
port_list = nla_nest_start(skb, TEAM_ATTR_LIST_PORT);
if (!port_list)
return -EMSGSIZE;
@@ -1434,17 +1465,20 @@
port_item = nla_nest_start(skb, TEAM_ATTR_ITEM_PORT);
if (!port_item)
goto nla_put_failure;
- NLA_PUT_U32(skb, TEAM_ATTR_PORT_IFINDEX, port->dev->ifindex);
+ if (nla_put_u32(skb, TEAM_ATTR_PORT_IFINDEX, port->dev->ifindex))
+ goto nla_put_failure;
if (port->changed) {
- NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_CHANGED);
+ if (nla_put_flag(skb, TEAM_ATTR_PORT_CHANGED))
+ goto nla_put_failure;
port->changed = false;
}
- if (port->removed)
- NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_REMOVED);
- if (port->linkup)
- NLA_PUT_FLAG(skb, TEAM_ATTR_PORT_LINKUP);
- NLA_PUT_U32(skb, TEAM_ATTR_PORT_SPEED, port->speed);
- NLA_PUT_U8(skb, TEAM_ATTR_PORT_DUPLEX, port->duplex);
+ if ((port->removed &&
+ nla_put_flag(skb, TEAM_ATTR_PORT_REMOVED)) ||
+ (port->linkup &&
+ nla_put_flag(skb, TEAM_ATTR_PORT_LINKUP)) ||
+ nla_put_u32(skb, TEAM_ATTR_PORT_SPEED, port->speed) ||
+ nla_put_u8(skb, TEAM_ATTR_PORT_DUPLEX, port->duplex))
+ goto nla_put_failure;
nla_nest_end(skb, port_item);
}
diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
new file mode 100644
index 0000000..ed20f39
--- /dev/null
+++ b/drivers/net/team/team_mode_loadbalance.c
@@ -0,0 +1,188 @@
+/*
+ * drivers/net/team/team_mode_loadbalance.c - Load-balancing mode for team
+ * Copyright (c) 2012 Jiri Pirko <jpirko@redhat.com>
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/if_team.h>
+
+struct lb_priv {
+ struct sk_filter __rcu *fp;
+ struct sock_fprog *orig_fprog;
+};
+
+static struct lb_priv *lb_priv(struct team *team)
+{
+ return (struct lb_priv *) &team->mode_priv;
+}
+
+static bool lb_transmit(struct team *team, struct sk_buff *skb)
+{
+ struct sk_filter *fp;
+ struct team_port *port;
+ unsigned int hash;
+ int port_index;
+
+ fp = rcu_dereference(lb_priv(team)->fp);
+ if (unlikely(!fp))
+ goto drop;
+ hash = SK_RUN_FILTER(fp, skb);
+ port_index = hash % team->port_count;
+ port = team_get_port_by_index_rcu(team, port_index);
+ if (unlikely(!port))
+ goto drop;
+ skb->dev = port->dev;
+ if (dev_queue_xmit(skb))
+ return false;
+ return true;
+
+drop:
+ dev_kfree_skb_any(skb);
+ return false;
+}
+
+static int lb_bpf_func_get(struct team *team, void *arg)
+{
+ struct team_option_binary *tbinary = team_optarg_tbinary(arg);
+
+ memset(tbinary, 0, sizeof(*tbinary));
+ if (!lb_priv(team)->orig_fprog)
+ return 0;
+
+ tbinary->data_len = lb_priv(team)->orig_fprog->len *
+ sizeof(struct sock_filter);
+ tbinary->data = lb_priv(team)->orig_fprog->filter;
+ return 0;
+}
+
+static int __fprog_create(struct sock_fprog **pfprog, u32 data_len,
+ void *data)
+{
+ struct sock_fprog *fprog;
+ struct sock_filter *filter = (struct sock_filter *) data;
+
+ if (data_len % sizeof(struct sock_filter))
+ return -EINVAL;
+ fprog = kmalloc(sizeof(struct sock_fprog), GFP_KERNEL);
+ if (!fprog)
+ return -ENOMEM;
+ fprog->filter = kmemdup(filter, data_len, GFP_KERNEL);
+ if (!fprog->filter) {
+ kfree(fprog);
+ return -ENOMEM;
+ }
+ fprog->len = data_len / sizeof(struct sock_filter);
+ *pfprog = fprog;
+ return 0;
+}
+
+static void __fprog_destroy(struct sock_fprog *fprog)
+{
+ kfree(fprog->filter);
+ kfree(fprog);
+}
+
+static int lb_bpf_func_set(struct team *team, void *arg)
+{
+ struct team_option_binary *tbinary = team_optarg_tbinary(arg);
+ struct sk_filter *fp = NULL;
+ struct sock_fprog *fprog = NULL;
+ int err;
+
+ if (tbinary->data_len) {
+ err = __fprog_create(&fprog, tbinary->data_len,
+ tbinary->data);
+ if (err)
+ return err;
+ err = sk_unattached_filter_create(&fp, fprog);
+ if (err) {
+ __fprog_destroy(fprog);
+ return err;
+ }
+ }
+
+ if (lb_priv(team)->orig_fprog) {
+ /* Clear old filter data */
+ __fprog_destroy(lb_priv(team)->orig_fprog);
+ sk_unattached_filter_destroy(lb_priv(team)->fp);
+ }
+
+ rcu_assign_pointer(lb_priv(team)->fp, fp);
+ lb_priv(team)->orig_fprog = fprog;
+ return 0;
+}
+
+static const struct team_option lb_options[] = {
+ {
+ .name = "bpf_hash_func",
+ .type = TEAM_OPTION_TYPE_BINARY,
+ .getter = lb_bpf_func_get,
+ .setter = lb_bpf_func_set,
+ },
+};
+
+int lb_init(struct team *team)
+{
+ return team_options_register(team, lb_options,
+ ARRAY_SIZE(lb_options));
+}
+
+void lb_exit(struct team *team)
+{
+ team_options_unregister(team, lb_options,
+ ARRAY_SIZE(lb_options));
+}
+
+static int lb_port_enter(struct team *team, struct team_port *port)
+{
+ return team_port_set_team_mac(port);
+}
+
+static void lb_port_change_mac(struct team *team, struct team_port *port)
+{
+ team_port_set_team_mac(port);
+}
+
+static const struct team_mode_ops lb_mode_ops = {
+ .init = lb_init,
+ .exit = lb_exit,
+ .transmit = lb_transmit,
+ .port_enter = lb_port_enter,
+ .port_change_mac = lb_port_change_mac,
+};
+
+static struct team_mode lb_mode = {
+ .kind = "loadbalance",
+ .owner = THIS_MODULE,
+ .priv_size = sizeof(struct lb_priv),
+ .ops = &lb_mode_ops,
+};
+
+static int __init lb_init_module(void)
+{
+ return team_mode_register(&lb_mode);
+}
+
+static void __exit lb_cleanup_module(void)
+{
+ team_mode_unregister(&lb_mode);
+}
+
+module_init(lb_init_module);
+module_exit(lb_cleanup_module);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Jiri Pirko <jpirko@redhat.com>");
+MODULE_DESCRIPTION("Load-balancing mode for team");
+MODULE_ALIAS("team-mode-loadbalance");
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index b7b3f5b..db99536 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -884,6 +884,7 @@
.get_drvinfo = usbnet_get_drvinfo,
.get_msglevel = usbnet_get_msglevel,
.set_msglevel = usbnet_set_msglevel,
+ .get_ts_info = ethtool_op_get_ts_info,
};
/*-------------------------------------------------------------------------*/
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c
index 6675c92..acc9aa8 100644
--- a/drivers/net/wireless/ath/ath6kl/testmode.c
+++ b/drivers/net/wireless/ath/ath6kl/testmode.c
@@ -55,8 +55,9 @@
ath6kl_warn("failed to allocate testmode rx skb!\n");
return;
}
- NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD);
- NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf);
+ if (nla_put_u32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD) ||
+ nla_put(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf))
+ goto nla_put_failure;
cfg80211_testmode_event(skb, GFP_KERNEL);
return;
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index f0551f8..3c06c6b 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -343,38 +343,50 @@
static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
{
- *val = readl((void __iomem *)(dev->base_addr + reg));
+ struct ipw2100_priv *priv = libipw_priv(dev);
+
+ *val = ioread32(priv->ioaddr + reg);
IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
}
static inline void write_register(struct net_device *dev, u32 reg, u32 val)
{
- writel(val, (void __iomem *)(dev->base_addr + reg));
+ struct ipw2100_priv *priv = libipw_priv(dev);
+
+ iowrite32(val, priv->ioaddr + reg);
IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
}
static inline void read_register_word(struct net_device *dev, u32 reg,
u16 * val)
{
- *val = readw((void __iomem *)(dev->base_addr + reg));
+ struct ipw2100_priv *priv = libipw_priv(dev);
+
+ *val = ioread16(priv->ioaddr + reg);
IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
}
static inline void read_register_byte(struct net_device *dev, u32 reg, u8 * val)
{
- *val = readb((void __iomem *)(dev->base_addr + reg));
+ struct ipw2100_priv *priv = libipw_priv(dev);
+
+ *val = ioread8(priv->ioaddr + reg);
IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
}
static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
{
- writew(val, (void __iomem *)(dev->base_addr + reg));
+ struct ipw2100_priv *priv = libipw_priv(dev);
+
+ iowrite16(val, priv->ioaddr + reg);
IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
}
static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
{
- writeb(val, (void __iomem *)(dev->base_addr + reg));
+ struct ipw2100_priv *priv = libipw_priv(dev);
+
+ iowrite8(val, priv->ioaddr + reg);
IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
}
@@ -506,13 +518,13 @@
read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
}
-static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
+static bool ipw2100_hw_is_adapter_in_system(struct net_device *dev)
{
- return (dev->base_addr &&
- (readl
- ((void __iomem *)(dev->base_addr +
- IPW_REG_DOA_DEBUG_AREA_START))
- == IPW_DATA_DOA_DEBUG_VALUE));
+ u32 dbg;
+
+ read_register(dev, IPW_REG_DOA_DEBUG_AREA_START, &dbg);
+
+ return dbg == IPW_DATA_DOA_DEBUG_VALUE;
}
static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
@@ -6082,9 +6094,7 @@
/* Look into using netdev destructor to shutdown libipw? */
static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
- void __iomem * base_addr,
- unsigned long mem_start,
- unsigned long mem_len)
+ void __iomem * ioaddr)
{
struct ipw2100_priv *priv;
struct net_device *dev;
@@ -6096,6 +6106,7 @@
priv->ieee = netdev_priv(dev);
priv->pci_dev = pci_dev;
priv->net_dev = dev;
+ priv->ioaddr = ioaddr;
priv->ieee->hard_start_xmit = ipw2100_tx;
priv->ieee->set_security = shim__set_security;
@@ -6111,10 +6122,6 @@
dev->watchdog_timeo = 3 * HZ;
dev->irq = 0;
- dev->base_addr = (unsigned long)base_addr;
- dev->mem_start = mem_start;
- dev->mem_end = dev->mem_start + mem_len - 1;
-
/* NOTE: We don't use the wireless_handlers hook
* in dev as the system will start throwing WX requests
* to us before we're actually initialized and it just
@@ -6215,8 +6222,7 @@
static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
const struct pci_device_id *ent)
{
- unsigned long mem_start, mem_len, mem_flags;
- void __iomem *base_addr = NULL;
+ void __iomem *ioaddr;
struct net_device *dev = NULL;
struct ipw2100_priv *priv = NULL;
int err = 0;
@@ -6225,18 +6231,14 @@
IPW_DEBUG_INFO("enter\n");
- mem_start = pci_resource_start(pci_dev, 0);
- mem_len = pci_resource_len(pci_dev, 0);
- mem_flags = pci_resource_flags(pci_dev, 0);
-
- if ((mem_flags & IORESOURCE_MEM) != IORESOURCE_MEM) {
+ if (!(pci_resource_flags(pci_dev, 0) & IORESOURCE_MEM)) {
IPW_DEBUG_INFO("weird - resource type is not memory\n");
err = -ENODEV;
- goto fail;
+ goto out;
}
- base_addr = ioremap_nocache(mem_start, mem_len);
- if (!base_addr) {
+ ioaddr = pci_iomap(pci_dev, 0, 0);
+ if (!ioaddr) {
printk(KERN_WARNING DRV_NAME
"Error calling ioremap_nocache.\n");
err = -EIO;
@@ -6244,7 +6246,7 @@
}
/* allocate and initialize our net_device */
- dev = ipw2100_alloc_device(pci_dev, base_addr, mem_start, mem_len);
+ dev = ipw2100_alloc_device(pci_dev, ioaddr);
if (!dev) {
printk(KERN_WARNING DRV_NAME
"Error calling ipw2100_alloc_device.\n");
@@ -6379,8 +6381,8 @@
priv->status |= STATUS_INITIALIZED;
mutex_unlock(&priv->action_mutex);
-
- return 0;
+out:
+ return err;
fail_unlock:
mutex_unlock(&priv->action_mutex);
@@ -6409,63 +6411,56 @@
pci_set_drvdata(pci_dev, NULL);
}
- if (base_addr)
- iounmap(base_addr);
+ pci_iounmap(pci_dev, ioaddr);
pci_release_regions(pci_dev);
pci_disable_device(pci_dev);
-
- return err;
+ goto out;
}
static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
{
struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
- struct net_device *dev;
+ struct net_device *dev = priv->net_dev;
- if (priv) {
- mutex_lock(&priv->action_mutex);
+ mutex_lock(&priv->action_mutex);
- priv->status &= ~STATUS_INITIALIZED;
+ priv->status &= ~STATUS_INITIALIZED;
- dev = priv->net_dev;
- sysfs_remove_group(&pci_dev->dev.kobj,
- &ipw2100_attribute_group);
+ sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
#ifdef CONFIG_PM
- if (ipw2100_firmware.version)
- ipw2100_release_firmware(priv, &ipw2100_firmware);
+ if (ipw2100_firmware.version)
+ ipw2100_release_firmware(priv, &ipw2100_firmware);
#endif
- /* Take down the hardware */
- ipw2100_down(priv);
+ /* Take down the hardware */
+ ipw2100_down(priv);
- /* Release the mutex so that the network subsystem can
- * complete any needed calls into the driver... */
- mutex_unlock(&priv->action_mutex);
+ /* Release the mutex so that the network subsystem can
+ * complete any needed calls into the driver... */
+ mutex_unlock(&priv->action_mutex);
- /* Unregister the device first - this results in close()
- * being called if the device is open. If we free storage
- * first, then close() will crash. */
- unregister_netdev(dev);
+ /* Unregister the device first - this results in close()
+ * being called if the device is open. If we free storage
+ * first, then close() will crash.
+ * FIXME: remove the comment above. */
+ unregister_netdev(dev);
- ipw2100_kill_works(priv);
+ ipw2100_kill_works(priv);
- ipw2100_queues_free(priv);
+ ipw2100_queues_free(priv);
- /* Free potential debugging firmware snapshot */
- ipw2100_snapshot_free(priv);
+ /* Free potential debugging firmware snapshot */
+ ipw2100_snapshot_free(priv);
- if (dev->irq)
- free_irq(dev->irq, priv);
+ free_irq(dev->irq, priv);
- if (dev->base_addr)
- iounmap((void __iomem *)dev->base_addr);
+ pci_iounmap(pci_dev, priv->ioaddr);
- /* wiphy_unregister needs to be here, before free_libipw */
- wiphy_unregister(priv->ieee->wdev.wiphy);
- kfree(priv->ieee->bg_band.channels);
- free_libipw(dev, 0);
- }
+ /* wiphy_unregister needs to be here, before free_libipw */
+ wiphy_unregister(priv->ieee->wdev.wiphy);
+ kfree(priv->ieee->bg_band.channels);
+ free_libipw(dev, 0);
pci_release_regions(pci_dev);
pci_disable_device(pci_dev);
@@ -8609,7 +8604,7 @@
struct net_device *dev = priv->net_dev;
const unsigned char *microcode_data = fw->uc.data;
unsigned int microcode_data_left = fw->uc.size;
- void __iomem *reg = (void __iomem *)dev->base_addr;
+ void __iomem *reg = priv->ioaddr;
struct symbol_alive_response response;
int i, j;
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h
index 99cba96..e5b1c77 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.h
+++ b/drivers/net/wireless/ipw2x00/ipw2100.h
@@ -488,6 +488,7 @@
#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
struct ipw2100_priv {
+ void __iomem *ioaddr;
int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 2b02257..57af0fc 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11826,10 +11826,6 @@
net_dev->wireless_data = &priv->wireless_data;
net_dev->wireless_handlers = &ipw_wx_handler_def;
net_dev->ethtool_ops = &ipw_ethtool_ops;
- net_dev->irq = pdev->irq;
- net_dev->base_addr = (unsigned long)priv->hw_base;
- net_dev->mem_start = pci_resource_start(pdev, 0);
- net_dev->mem_end = net_dev->mem_start + pci_resource_len(pdev, 0) - 1;
err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
if (err) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c
index 76f7f92..a54e20e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c
@@ -184,9 +184,10 @@
"Run out of memory for messages to user space ?\n");
return;
}
- NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
- /* the length doesn't include len_n_flags field, so add it manually */
- NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data);
+ if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
+ /* the length doesn't include len_n_flags field, so add it manually */
+ nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data))
+ goto nla_put_failure;
cfg80211_testmode_event(skb, GFP_ATOMIC);
return;
@@ -314,8 +315,9 @@
memcpy(reply_buf, &(pkt->hdr), reply_len);
iwl_free_resp(&cmd);
- NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
- NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf);
+ if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
+ nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf))
+ goto nla_put_failure;
return cfg80211_testmode_reply(skb);
nla_put_failure:
@@ -379,7 +381,8 @@
IWL_ERR(priv, "Memory allocation fail\n");
return -ENOMEM;
}
- NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
+ if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0)
IWL_ERR(priv, "Error sending msg : %d\n", status);
@@ -478,10 +481,11 @@
IWL_ERR(priv, "Memory allocation fail\n");
return -ENOMEM;
}
- NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
- IWL_TM_CMD_DEV2APP_SYNC_RSP);
- NLA_PUT(skb, IWL_TM_ATTR_SYNC_RSP,
- rsp_data_len, rsp_data_ptr);
+ if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
+ IWL_TM_CMD_DEV2APP_SYNC_RSP) ||
+ nla_put(skb, IWL_TM_ATTR_SYNC_RSP,
+ rsp_data_len, rsp_data_ptr))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0)
IWL_ERR(priv, "Error sending msg : %d\n", status);
@@ -536,11 +540,12 @@
IWL_ERR(priv, "Memory allocation fail\n");
return -ENOMEM;
}
- NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
- IWL_TM_CMD_DEV2APP_EEPROM_RSP);
- NLA_PUT(skb, IWL_TM_ATTR_EEPROM,
- cfg(priv)->base_params->eeprom_size,
- priv->shrd->eeprom);
+ if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
+ IWL_TM_CMD_DEV2APP_EEPROM_RSP) ||
+ nla_put(skb, IWL_TM_ATTR_EEPROM,
+ cfg(priv)->base_params->eeprom_size,
+ priv->shrd->eeprom))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0)
IWL_ERR(priv, "Error sending msg : %d\n",
@@ -566,8 +571,9 @@
IWL_ERR(priv, "Memory allocation fail\n");
return -ENOMEM;
}
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION,
- priv->fw->ucode_ver);
+ if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION,
+ priv->fw->ucode_ver))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0)
IWL_ERR(priv, "Error sending msg : %d\n", status);
@@ -582,7 +588,8 @@
IWL_ERR(priv, "Memory allocation fail\n");
return -ENOMEM;
}
- NLA_PUT_U32(skb, IWL_TM_ATTR_DEVICE_ID, devid);
+ if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0)
IWL_ERR(priv, "Error sending msg : %d\n", status);
@@ -602,9 +609,10 @@
inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
}
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
+ if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type) ||
+ nla_put_u32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size) ||
+ nla_put_u32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0)
IWL_ERR(priv, "Error sending msg : %d\n", status);
@@ -678,9 +686,10 @@
iwl_trace_cleanup(priv);
return -ENOMEM;
}
- NLA_PUT(skb, IWL_TM_ATTR_TRACE_ADDR,
- sizeof(priv->testmode_trace.dma_addr),
- (u64 *)&priv->testmode_trace.dma_addr);
+ if (nla_put(skb, IWL_TM_ATTR_TRACE_ADDR,
+ sizeof(priv->testmode_trace.dma_addr),
+ (u64 *)&priv->testmode_trace.dma_addr))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0) {
IWL_ERR(priv, "Error sending msg : %d\n", status);
@@ -725,9 +734,10 @@
length = priv->testmode_trace.buff_size %
DUMP_CHUNK_SIZE;
- NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length,
- priv->testmode_trace.trace_addr +
- (DUMP_CHUNK_SIZE * idx));
+ if (nla_put(skb, IWL_TM_ATTR_TRACE_DUMP, length,
+ priv->testmode_trace.trace_addr +
+ (DUMP_CHUNK_SIZE * idx)))
+ goto nla_put_failure;
idx++;
cb->args[4] = idx;
return 0;
@@ -922,9 +932,10 @@
length = priv->testmode_mem.buff_size %
DUMP_CHUNK_SIZE;
- NLA_PUT(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
- priv->testmode_mem.buff_addr +
- (DUMP_CHUNK_SIZE * idx));
+ if (nla_put(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
+ priv->testmode_mem.buff_addr +
+ (DUMP_CHUNK_SIZE * idx)))
+ goto nla_put_failure;
idx++;
cb->args[4] = idx;
return 0;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index b7ce6a6..538783f 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -582,11 +582,13 @@
goto nla_put_failure;
}
- NLA_PUT(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
- sizeof(struct mac_address), data->addresses[1].addr);
+ if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
+ sizeof(struct mac_address), data->addresses[1].addr))
+ goto nla_put_failure;
/* We get the skb->data */
- NLA_PUT(skb, HWSIM_ATTR_FRAME, my_skb->len, my_skb->data);
+ if (nla_put(skb, HWSIM_ATTR_FRAME, my_skb->len, my_skb->data))
+ goto nla_put_failure;
/* We get the flags for this transmission, and we translate them to
wmediumd flags */
@@ -597,7 +599,8 @@
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
hwsim_flags |= HWSIM_TX_CTL_NO_ACK;
- NLA_PUT_U32(skb, HWSIM_ATTR_FLAGS, hwsim_flags);
+ if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags))
+ goto nla_put_failure;
/* We get the tx control (rate and retries) info*/
@@ -606,12 +609,14 @@
tx_attempts[i].count = info->status.rates[i].count;
}
- NLA_PUT(skb, HWSIM_ATTR_TX_INFO,
- sizeof(struct hwsim_tx_rate)*IEEE80211_TX_MAX_RATES,
- tx_attempts);
+ if (nla_put(skb, HWSIM_ATTR_TX_INFO,
+ sizeof(struct hwsim_tx_rate)*IEEE80211_TX_MAX_RATES,
+ tx_attempts))
+ goto nla_put_failure;
/* We create a cookie to identify this skb */
- NLA_PUT_U64(skb, HWSIM_ATTR_COOKIE, (unsigned long) my_skb);
+ if (nla_put_u64(skb, HWSIM_ATTR_COOKIE, (unsigned long) my_skb))
+ goto nla_put_failure;
genlmsg_end(skb, msg_head);
genlmsg_unicast(&init_net, skb, dst_pid);
@@ -1108,7 +1113,8 @@
nla_total_size(sizeof(u32)));
if (!skb)
return -ENOMEM;
- NLA_PUT_U32(skb, HWSIM_TM_ATTR_PS, hwsim->ps);
+ if (nla_put_u32(skb, HWSIM_TM_ATTR_PS, hwsim->ps))
+ goto nla_put_failure;
return cfg80211_testmode_reply(skb);
default:
return -EOPNOTSUPP;
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c
index 1e93bb9..b41428f 100644
--- a/drivers/net/wireless/wl12xx/testmode.c
+++ b/drivers/net/wireless/wl12xx/testmode.c
@@ -116,7 +116,8 @@
goto out_sleep;
}
- NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf);
+ if (nla_put(skb, WL1271_TM_ATTR_DATA, buf_len, buf))
+ goto nla_put_failure;
ret = cfg80211_testmode_reply(skb);
if (ret < 0)
goto out_sleep;
@@ -178,7 +179,8 @@
goto out_free;
}
- NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd);
+ if (nla_put(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd))
+ goto nla_put_failure;
ret = cfg80211_testmode_reply(skb);
if (ret < 0)
goto out_free;
@@ -297,7 +299,8 @@
goto out;
}
- NLA_PUT(skb, WL1271_TM_ATTR_DATA, ETH_ALEN, mac_addr);
+ if (nla_put(skb, WL1271_TM_ATTR_DATA, ETH_ALEN, mac_addr))
+ goto nla_put_failure;
ret = cfg80211_testmode_reply(skb);
if (ret < 0)
goto out;
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index f519a13..1e528b5 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -304,6 +304,12 @@
}
EXPORT_SYMBOL(ptp_clock_event);
+int ptp_clock_index(struct ptp_clock *ptp)
+{
+ return ptp->index;
+}
+EXPORT_SYMBOL(ptp_clock_index);
+
/* module operations */
static void __exit ptp_exit(void)
diff --git a/drivers/ptp/ptp_ixp46x.c b/drivers/ptp/ptp_ixp46x.c
index 6f2782b..9d13a71 100644
--- a/drivers/ptp/ptp_ixp46x.c
+++ b/drivers/ptp/ptp_ixp46x.c
@@ -284,6 +284,7 @@
{
free_irq(MASTER_IRQ, &ixp_clock);
free_irq(SLAVE_IRQ, &ixp_clock);
+ ixp46x_phc_clock = -1;
ptp_clock_unregister(ixp_clock.ptp_clock);
}
@@ -302,6 +303,8 @@
if (IS_ERR(ixp_clock.ptp_clock))
return PTR_ERR(ixp_clock.ptp_clock);
+ ixp46x_phc_clock = ptp_clock_index(ixp_clock.ptp_clock);
+
__raw_writel(DEFAULT_ADDEND, &ixp_clock.regs->addend);
__raw_writel(1, &ixp_clock.regs->trgt_lo);
__raw_writel(0, &ixp_clock.regs->trgt_hi);
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h
index 65a2562..6bb4338 100644
--- a/include/linux/dcbnl.h
+++ b/include/linux/dcbnl.h
@@ -67,6 +67,17 @@
__u8 reco_prio_tc[IEEE_8021QAZ_MAX_TCS];
};
+/* This structure contains rate limit extension to the IEEE 802.1Qaz ETS
+ * managed object.
+ * Values are 64 bits long and specified in Kbps to enable usage over both
+ * slow and very fast networks.
+ *
+ * @tc_maxrate: maximal tc tx bandwidth indexed by traffic class
+ */
+struct ieee_maxrate {
+ __u64 tc_maxrate[IEEE_8021QAZ_MAX_TCS];
+};
+
/* This structure contains the IEEE 802.1Qaz PFC managed object
*
* @pfc_cap: Indicates the number of traffic classes on the local device
@@ -321,6 +332,7 @@
DCB_ATTR_IEEE_PEER_ETS,
DCB_ATTR_IEEE_PEER_PFC,
DCB_ATTR_IEEE_PEER_APP,
+ DCB_ATTR_IEEE_MAXRATE,
__DCB_ATTR_IEEE_MAX
};
#define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index f5647b5..89d68d8 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -726,6 +726,29 @@
struct ethtool_set_features_block features[0];
};
+/**
+ * struct ethtool_ts_info - holds a device's timestamping and PHC association
+ * @cmd: command number = %ETHTOOL_GET_TS_INFO
+ * @so_timestamping: bit mask of the sum of the supported SO_TIMESTAMPING flags
+ * @phc_index: device index of the associated PHC, or -1 if there is none
+ * @tx_types: bit mask of the supported hwtstamp_tx_types enumeration values
+ * @rx_filters: bit mask of the supported hwtstamp_rx_filters enumeration values
+ *
+ * The bits in the 'tx_types' and 'rx_filters' fields correspond to
+ * the 'hwtstamp_tx_types' and 'hwtstamp_rx_filters' enumeration values,
+ * respectively. For example, if the device supports HWTSTAMP_TX_ON,
+ * then (1 << HWTSTAMP_TX_ON) in 'tx_types' will be set.
+ */
+struct ethtool_ts_info {
+ __u32 cmd;
+ __u32 so_timestamping;
+ __s32 phc_index;
+ __u32 tx_types;
+ __u32 tx_reserved[3];
+ __u32 rx_filters;
+ __u32 rx_reserved[3];
+};
+
/*
* %ETHTOOL_SFEATURES changes features present in features[].valid to the
* values of corresponding bits in features[].requested. Bits in .requested
@@ -788,6 +811,7 @@
/* Some generic methods drivers may use in their ethtool_ops */
u32 ethtool_op_get_link(struct net_device *dev);
+int ethtool_op_get_ts_info(struct net_device *dev, struct ethtool_ts_info *eti);
/**
* ethtool_rxfh_indir_default - get default value for RX flow hash indirection
@@ -893,6 +917,9 @@
* and flag of the device.
* @get_dump_data: Get dump data.
* @set_dump: Set dump specific flags to the device.
+ * @get_ts_info: Get the time stamping and PTP hardware clock capabilities.
+ * Drivers supporting transmit time stamps in software should set this to
+ * ethtool_op_get_ts_info().
*
* All operations are optional (i.e. the function pointer may be set
* to %NULL) and callers must take this into account. Callers must
@@ -954,6 +981,7 @@
int (*get_dump_data)(struct net_device *,
struct ethtool_dump *, void *);
int (*set_dump)(struct net_device *, struct ethtool_dump *);
+ int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *);
};
#endif /* __KERNEL__ */
@@ -1028,6 +1056,7 @@
#define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */
#define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */
#define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */
+#define ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 8eeb205..7209099 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -126,7 +126,8 @@
#define SKF_AD_HATYPE 28
#define SKF_AD_RXHASH 32
#define SKF_AD_CPU 36
-#define SKF_AD_MAX 40
+#define SKF_AD_ALU_XOR_X 40
+#define SKF_AD_MAX 44
#define SKF_NET_OFF (-0x100000)
#define SKF_LL_OFF (-0x200000)
@@ -153,6 +154,9 @@
extern int sk_filter(struct sock *sk, struct sk_buff *skb);
extern unsigned int sk_run_filter(const struct sk_buff *skb,
const struct sock_filter *filter);
+extern int sk_unattached_filter_create(struct sk_filter **pfp,
+ struct sock_fprog *fprog);
+extern void sk_unattached_filter_destroy(struct sk_filter *fp);
extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
extern int sk_detach_filter(struct sock *sk);
extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
@@ -228,6 +232,7 @@
BPF_S_ANC_HATYPE,
BPF_S_ANC_RXHASH,
BPF_S_ANC_CPU,
+ BPF_S_ANC_ALU_XOR_X,
};
#endif /* __KERNEL__ */
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 5852545..6af8738 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -274,6 +274,33 @@
u32 bytes_avail_towrite;
};
+
+/*
+ *
+ * hv_get_ringbuffer_availbytes()
+ *
+ * Get number of bytes available to read and to write to
+ * for the specified ring buffer
+ */
+static inline void
+hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
+ u32 *read, u32 *write)
+{
+ u32 read_loc, write_loc, dsize;
+
+ smp_read_barrier_depends();
+
+ /* Capture the read/write indices before they changed */
+ read_loc = rbi->ring_buffer->read_index;
+ write_loc = rbi->ring_buffer->write_index;
+ dsize = rbi->ring_datasize;
+
+ *write = write_loc >= read_loc ? dsize - (write_loc - read_loc) :
+ read_loc - write_loc;
+ *read = dsize - *write;
+}
+
+
/*
* We use the same version numbering for all Hyper-V modules.
*
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 4b24ff4..2f4fa93 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -138,6 +138,8 @@
IFLA_GROUP, /* Group the device belongs to */
IFLA_NET_NS_FD,
IFLA_EXT_MASK, /* Extended info mask, VFs, etc */
+ IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */
+#define IFLA_PROMISCUITY IFLA_PROMISCUITY
__IFLA_MAX
};
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 58404b0..41163ac 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -68,6 +68,7 @@
enum team_option_type {
TEAM_OPTION_TYPE_U32,
TEAM_OPTION_TYPE_STRING,
+ TEAM_OPTION_TYPE_BINARY,
};
struct team_option {
@@ -82,6 +83,13 @@
bool removed;
};
+struct team_option_binary {
+ u32 data_len;
+ void *data;
+};
+
+#define team_optarg_tbinary(arg) (*((struct team_option_binary **) arg))
+
struct team_mode {
struct list_head list;
const char *kind;
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 9958ff2..1f3860a 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -150,6 +150,10 @@
/* statistics commands */
MLX4_CMD_QUERY_IF_STAT = 0X54,
MLX4_CMD_SET_IF_STAT = 0X55,
+
+ /* set port opcode modifiers */
+ MLX4_SET_PORT_PRIO2TC = 0x8,
+ MLX4_SET_PORT_SCHEDULER = 0x9,
};
enum {
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 834c96c..6d02824 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -628,6 +628,9 @@
u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx);
int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn,
u8 promisc);
+int mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc);
+int mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw,
+ u8 *pg, u16 *ratelimit);
int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index);
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index 091f9e7..96005d7 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -139,7 +139,8 @@
u8 rgid[16];
u8 sched_queue;
u8 vlan_index;
- u8 reserved3[2];
+ u8 feup;
+ u8 reserved3;
u8 reserved4[2];
u8 dmac[6];
};
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index 2f8e18a..d6d549c 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -411,26 +411,32 @@
#define ipset_nest_start(skb, attr) nla_nest_start(skb, attr | NLA_F_NESTED)
#define ipset_nest_end(skb, start) nla_nest_end(skb, start)
-#define NLA_PUT_IPADDR4(skb, type, ipaddr) \
-do { \
- struct nlattr *__nested = ipset_nest_start(skb, type); \
- \
- if (!__nested) \
- goto nla_put_failure; \
- NLA_PUT_NET32(skb, IPSET_ATTR_IPADDR_IPV4, ipaddr); \
- ipset_nest_end(skb, __nested); \
-} while (0)
+static inline int nla_put_ipaddr4(struct sk_buff *skb, int type, __be32 ipaddr)
+{
+ struct nlattr *__nested = ipset_nest_start(skb, type);
+ int ret;
-#define NLA_PUT_IPADDR6(skb, type, ipaddrptr) \
-do { \
- struct nlattr *__nested = ipset_nest_start(skb, type); \
- \
- if (!__nested) \
- goto nla_put_failure; \
- NLA_PUT(skb, IPSET_ATTR_IPADDR_IPV6, \
- sizeof(struct in6_addr), ipaddrptr); \
- ipset_nest_end(skb, __nested); \
-} while (0)
+ if (!__nested)
+ return -EMSGSIZE;
+ ret = nla_put_net32(skb, IPSET_ATTR_IPADDR_IPV4, ipaddr);
+ if (!ret)
+ ipset_nest_end(skb, __nested);
+ return ret;
+}
+
+static inline int nla_put_ipaddr6(struct sk_buff *skb, int type, const struct in6_addr *ipaddrptr)
+{
+ struct nlattr *__nested = ipset_nest_start(skb, type);
+ int ret;
+
+ if (!__nested)
+ return -EMSGSIZE;
+ ret = nla_put(skb, IPSET_ATTR_IPADDR_IPV6,
+ sizeof(struct in6_addr), ipaddrptr);
+ if (!ret)
+ ipset_nest_end(skb, __nested);
+ return ret;
+}
/* Get address from skbuff */
static inline __be32
diff --git a/include/linux/netfilter/ipset/ip_set_ahash.h b/include/linux/netfilter/ipset/ip_set_ahash.h
index 05a5d72..289b62d 100644
--- a/include/linux/netfilter/ipset/ip_set_ahash.h
+++ b/include/linux/netfilter/ipset/ip_set_ahash.h
@@ -594,17 +594,20 @@
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested)
goto nla_put_failure;
- NLA_PUT_NET32(skb, IPSET_ATTR_HASHSIZE,
- htonl(jhash_size(h->table->htable_bits)));
- NLA_PUT_NET32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem));
+ if (nla_put_net32(skb, IPSET_ATTR_HASHSIZE,
+ htonl(jhash_size(h->table->htable_bits))) ||
+ nla_put_net32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem)))
+ goto nla_put_failure;
#ifdef IP_SET_HASH_WITH_NETMASK
- if (h->netmask != HOST_MASK)
- NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, h->netmask);
+ if (h->netmask != HOST_MASK &&
+ nla_put_u8(skb, IPSET_ATTR_NETMASK, h->netmask))
+ goto nla_put_failure;
#endif
- NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
- NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize));
- if (with_timeout(h->timeout))
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout));
+ if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
+ nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
+ (with_timeout(h->timeout) &&
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout))))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
return 0;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 6fe0a37..f092032 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -412,6 +412,9 @@
/* Clears up any memory if needed */
void (*remove)(struct phy_device *phydev);
+ /* Handles ethtool queries for hardware time stamping. */
+ int (*ts_info)(struct phy_device *phydev, struct ethtool_ts_info *ti);
+
/* Handles SIOCSHWTSTAMP ioctl for hardware time stamping. */
int (*hwtstamp)(struct phy_device *phydev, struct ifreq *ifr);
diff --git a/include/linux/platform_data/wiznet.h b/include/linux/platform_data/wiznet.h
new file mode 100644
index 0000000..b5d8c19
--- /dev/null
+++ b/include/linux/platform_data/wiznet.h
@@ -0,0 +1,24 @@
+/*
+ * Ethernet driver for the WIZnet W5x00 chip.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef PLATFORM_DATA_WIZNET_H
+#define PLATFORM_DATA_WIZNET_H
+
+#include <linux/if_ether.h>
+
+struct wiznet_platform_data {
+ int link_gpio;
+ u8 mac_addr[ETH_ALEN];
+};
+
+#ifndef CONFIG_WIZNET_BUS_SHIFT
+#define CONFIG_WIZNET_BUS_SHIFT 0
+#endif
+
+#define W5100_BUS_DIRECT_SIZE (0x8000 << CONFIG_WIZNET_BUS_SHIFT)
+#define W5300_BUS_DIRECT_SIZE (0x0400 << CONFIG_WIZNET_BUS_SHIFT)
+
+#endif /* PLATFORM_DATA_WIZNET_H */
diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h
index dd2e44f..945704c 100644
--- a/include/linux/ptp_clock_kernel.h
+++ b/include/linux/ptp_clock_kernel.h
@@ -136,4 +136,12 @@
extern void ptp_clock_event(struct ptp_clock *ptp,
struct ptp_clock_event *event);
+/**
+ * ptp_clock_index() - obtain the device index of a PTP clock
+ *
+ * @ptp: The clock obtained from ptp_clock_register().
+ */
+
+extern int ptp_clock_index(struct ptp_clock *ptp);
+
#endif
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 0dddc9e..cf64031 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -28,6 +28,51 @@
#include <linux/platform_device.h>
+#define STMMAC_RX_COE_NONE 0
+#define STMMAC_RX_COE_TYPE1 1
+#define STMMAC_RX_COE_TYPE2 2
+
+/* Define the macros for CSR clock range parameters to be passed by
+ * platform code.
+ * This could also be configured at run time using CPU freq framework. */
+
+/* MDC Clock Selection define*/
+#define STMMAC_CSR_60_100M 0x0 /* MDC = clk_scr_i/42 */
+#define STMMAC_CSR_100_150M 0x1 /* MDC = clk_scr_i/62 */
+#define STMMAC_CSR_20_35M 0x2 /* MDC = clk_scr_i/16 */
+#define STMMAC_CSR_35_60M 0x3 /* MDC = clk_scr_i/26 */
+#define STMMAC_CSR_150_250M 0x4 /* MDC = clk_scr_i/102 */
+#define STMMAC_CSR_250_300M 0x5 /* MDC = clk_scr_i/122 */
+
+/* The MDC clock could be set higher than the IEEE 802.3
+ * specified frequency limit 0f 2.5 MHz, by programming a clock divider
+ * of value different than the above defined values. The resultant MDIO
+ * clock frequency of 12.5 MHz is applicable for the interfacing chips
+ * supporting higher MDC clocks.
+ * The MDC clock selection macros need to be defined for MDC clock rate
+ * of 12.5 MHz, corresponding to the following selection.
+ */
+#define STMMAC_CSR_I_4 0x8 /* clk_csr_i/4 */
+#define STMMAC_CSR_I_6 0x9 /* clk_csr_i/6 */
+#define STMMAC_CSR_I_8 0xA /* clk_csr_i/8 */
+#define STMMAC_CSR_I_10 0xB /* clk_csr_i/10 */
+#define STMMAC_CSR_I_12 0xC /* clk_csr_i/12 */
+#define STMMAC_CSR_I_14 0xD /* clk_csr_i/14 */
+#define STMMAC_CSR_I_16 0xE /* clk_csr_i/16 */
+#define STMMAC_CSR_I_18 0xF /* clk_csr_i/18 */
+
+/* AXI DMA Burst length suported */
+#define DMA_AXI_BLEN_4 (1 << 1)
+#define DMA_AXI_BLEN_8 (1 << 2)
+#define DMA_AXI_BLEN_16 (1 << 3)
+#define DMA_AXI_BLEN_32 (1 << 4)
+#define DMA_AXI_BLEN_64 (1 << 5)
+#define DMA_AXI_BLEN_128 (1 << 6)
+#define DMA_AXI_BLEN_256 (1 << 7)
+#define DMA_AXI_BLEN_ALL (DMA_AXI_BLEN_4 | DMA_AXI_BLEN_8 | DMA_AXI_BLEN_16 \
+ | DMA_AXI_BLEN_32 | DMA_AXI_BLEN_64 \
+ | DMA_AXI_BLEN_128 | DMA_AXI_BLEN_256)
+
/* Platfrom data for platform device structure's platform_data field */
struct stmmac_mdio_bus_data {
@@ -38,16 +83,24 @@
int probed_phy_irq;
};
+struct stmmac_dma_cfg {
+ int pbl;
+ int fixed_burst;
+ int burst_len;
+};
+
struct plat_stmmacenet_data {
+ char *phy_bus_name;
int bus_id;
int phy_addr;
int interface;
struct stmmac_mdio_bus_data *mdio_bus_data;
- int pbl;
+ struct stmmac_dma_cfg *dma_cfg;
int clk_csr;
int has_gmac;
int enh_desc;
int tx_coe;
+ int rx_coe;
int bugged_jumbo;
int pmt;
int force_sf_dma_mode;
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h
index f55c980..fc5d5dc 100644
--- a/include/net/dcbnl.h
+++ b/include/net/dcbnl.h
@@ -48,6 +48,8 @@
/* IEEE 802.1Qaz std */
int (*ieee_getets) (struct net_device *, struct ieee_ets *);
int (*ieee_setets) (struct net_device *, struct ieee_ets *);
+ int (*ieee_getmaxrate) (struct net_device *, struct ieee_maxrate *);
+ int (*ieee_setmaxrate) (struct net_device *, struct ieee_maxrate *);
int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *);
int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *);
int (*ieee_getapp) (struct net_device *, struct dcb_app *);
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 75d6156..ce70a58 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -41,7 +41,6 @@
extern void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info);
extern int icmp_rcv(struct sk_buff *skb);
-extern int icmp_ioctl(struct sock *sk, int cmd, unsigned long arg);
extern int icmp_init(void);
extern void icmp_out_count(struct net *net, unsigned char type);
diff --git a/include/net/netlink.h b/include/net/netlink.h
index f394fe5..785f37a 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -102,20 +102,6 @@
* nla_put_flag(skb, type) add flag attribute to skb
* nla_put_msecs(skb, type, jiffies) add msecs attribute to skb
*
- * Exceptions Based Attribute Construction:
- * NLA_PUT(skb, type, len, data) add attribute to skb
- * NLA_PUT_U8(skb, type, value) add u8 attribute to skb
- * NLA_PUT_U16(skb, type, value) add u16 attribute to skb
- * NLA_PUT_U32(skb, type, value) add u32 attribute to skb
- * NLA_PUT_U64(skb, type, value) add u64 attribute to skb
- * NLA_PUT_STRING(skb, type, str) add string attribute to skb
- * NLA_PUT_FLAG(skb, type) add flag attribute to skb
- * NLA_PUT_MSECS(skb, type, jiffies) add msecs attribute to skb
- *
- * The meaning of these functions is equal to their lower case
- * variants but they jump to the label nla_put_failure in case
- * of a failure.
- *
* Nested Attributes Construction:
* nla_nest_start(skb, type) start a nested attribute
* nla_nest_end(skb, nla) finalize a nested attribute
@@ -772,6 +758,39 @@
}
/**
+ * nla_put_be16 - Add a __be16 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
+{
+ return nla_put(skb, attrtype, sizeof(__be16), &value);
+}
+
+/**
+ * nla_put_net16 - Add 16-bit network byte order netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 value)
+{
+ return nla_put_be16(skb, attrtype | NLA_F_NET_BYTEORDER, value);
+}
+
+/**
+ * nla_put_le16 - Add a __le16 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value)
+{
+ return nla_put(skb, attrtype, sizeof(__le16), &value);
+}
+
+/**
* nla_put_u32 - Add a u32 netlink attribute to a socket buffer
* @skb: socket buffer to add attribute to
* @attrtype: attribute type
@@ -783,7 +802,40 @@
}
/**
- * nla_put_64 - Add a u64 netlink attribute to a socket buffer
+ * nla_put_be32 - Add a __be32 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
+{
+ return nla_put(skb, attrtype, sizeof(__be32), &value);
+}
+
+/**
+ * nla_put_net32 - Add 32-bit network byte order netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value)
+{
+ return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, value);
+}
+
+/**
+ * nla_put_le32 - Add a __le32 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value)
+{
+ return nla_put(skb, attrtype, sizeof(__le32), &value);
+}
+
+/**
+ * nla_put_u64 - Add a u64 netlink attribute to a socket buffer
* @skb: socket buffer to add attribute to
* @attrtype: attribute type
* @value: numeric value
@@ -794,6 +846,39 @@
}
/**
+ * nla_put_be64 - Add a __be64 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value)
+{
+ return nla_put(skb, attrtype, sizeof(__be64), &value);
+}
+
+/**
+ * nla_put_net64 - Add 64-bit network byte order netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value)
+{
+ return nla_put_be64(skb, attrtype | NLA_F_NET_BYTEORDER, value);
+}
+
+/**
+ * nla_put_le64 - Add a __le64 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: numeric value
+ */
+static inline int nla_put_le64(struct sk_buff *skb, int attrtype, __le64 value)
+{
+ return nla_put(skb, attrtype, sizeof(__le64), &value);
+}
+
+/**
* nla_put_string - Add a string netlink attribute to a socket buffer
* @skb: socket buffer to add attribute to
* @attrtype: attribute type
@@ -828,60 +913,6 @@
return nla_put(skb, attrtype, sizeof(u64), &tmp);
}
-#define NLA_PUT(skb, attrtype, attrlen, data) \
- do { \
- if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \
- goto nla_put_failure; \
- } while(0)
-
-#define NLA_PUT_TYPE(skb, type, attrtype, value) \
- do { \
- type __tmp = value; \
- NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
- } while(0)
-
-#define NLA_PUT_U8(skb, attrtype, value) \
- NLA_PUT_TYPE(skb, u8, attrtype, value)
-
-#define NLA_PUT_U16(skb, attrtype, value) \
- NLA_PUT_TYPE(skb, u16, attrtype, value)
-
-#define NLA_PUT_LE16(skb, attrtype, value) \
- NLA_PUT_TYPE(skb, __le16, attrtype, value)
-
-#define NLA_PUT_BE16(skb, attrtype, value) \
- NLA_PUT_TYPE(skb, __be16, attrtype, value)
-
-#define NLA_PUT_NET16(skb, attrtype, value) \
- NLA_PUT_BE16(skb, attrtype | NLA_F_NET_BYTEORDER, value)
-
-#define NLA_PUT_U32(skb, attrtype, value) \
- NLA_PUT_TYPE(skb, u32, attrtype, value)
-
-#define NLA_PUT_BE32(skb, attrtype, value) \
- NLA_PUT_TYPE(skb, __be32, attrtype, value)
-
-#define NLA_PUT_NET32(skb, attrtype, value) \
- NLA_PUT_BE32(skb, attrtype | NLA_F_NET_BYTEORDER, value)
-
-#define NLA_PUT_U64(skb, attrtype, value) \
- NLA_PUT_TYPE(skb, u64, attrtype, value)
-
-#define NLA_PUT_BE64(skb, attrtype, value) \
- NLA_PUT_TYPE(skb, __be64, attrtype, value)
-
-#define NLA_PUT_NET64(skb, attrtype, value) \
- NLA_PUT_BE64(skb, attrtype | NLA_F_NET_BYTEORDER, value)
-
-#define NLA_PUT_STRING(skb, attrtype, value) \
- NLA_PUT(skb, attrtype, strlen(value) + 1, value)
-
-#define NLA_PUT_FLAG(skb, attrtype) \
- NLA_PUT(skb, attrtype, 0, NULL)
-
-#define NLA_PUT_MSECS(skb, attrtype, jiffies) \
- NLA_PUT_U64(skb, attrtype, jiffies_to_msecs(jiffies))
-
/**
* nla_get_u32 - return payload of u32 attribute
* @nla: u32 netlink attribute
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 96239e7..1cb32bf 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1682,8 +1682,9 @@
static inline int xfrm_mark_put(struct sk_buff *skb, const struct xfrm_mark *m)
{
- if (m->m | m->v)
- NLA_PUT(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m);
+ if ((m->m | m->v) &&
+ nla_put(skb, XFRMA_MARK, sizeof(struct xfrm_mark), m))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index 5071136..708c80e 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -166,11 +166,13 @@
struct nlattr *nest;
unsigned int i;
- NLA_PUT_U16(skb, IFLA_VLAN_ID, vlan_dev_priv(dev)->vlan_id);
+ if (nla_put_u16(skb, IFLA_VLAN_ID, vlan_dev_priv(dev)->vlan_id))
+ goto nla_put_failure;
if (vlan->flags) {
f.flags = vlan->flags;
f.mask = ~0;
- NLA_PUT(skb, IFLA_VLAN_FLAGS, sizeof(f), &f);
+ if (nla_put(skb, IFLA_VLAN_FLAGS, sizeof(f), &f))
+ goto nla_put_failure;
}
if (vlan->nr_ingress_mappings) {
nest = nla_nest_start(skb, IFLA_VLAN_INGRESS_QOS);
@@ -183,8 +185,9 @@
m.from = i;
m.to = vlan->ingress_priority_map[i];
- NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING,
- sizeof(m), &m);
+ if (nla_put(skb, IFLA_VLAN_QOS_MAPPING,
+ sizeof(m), &m))
+ goto nla_put_failure;
}
nla_nest_end(skb, nest);
}
@@ -202,8 +205,9 @@
m.from = pm->priority;
m.to = (pm->vlan_qos >> 13) & 0x7;
- NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING,
- sizeof(m), &m);
+ if (nla_put(skb, IFLA_VLAN_QOS_MAPPING,
+ sizeof(m), &m))
+ goto nla_put_failure;
}
}
nla_nest_end(skb, nest);
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index bfa9ab9..0301b32 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -63,7 +63,7 @@
#include <net/tcp_states.h>
#include <net/route.h>
#include <linux/atalk.h>
-#include "../core/kmap_skb.h"
+#include <linux/highmem.h>
struct datalink_proto *ddp_dl, *aarp_dl;
static const struct proto_ops atalk_dgram_ops;
@@ -960,10 +960,10 @@
if (copy > len)
copy = len;
- vaddr = kmap_skb_frag(frag);
+ vaddr = kmap_atomic(skb_frag_page(frag));
sum = atalk_sum_partial(vaddr + frag->page_offset +
offset - start, copy, sum);
- kunmap_skb_frag(vaddr);
+ kunmap_atomic(vaddr);
if (!(len -= copy))
return sum;
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index 5ba0c84..80dbce4 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -487,14 +487,14 @@
ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex;
ndm->ndm_state = fdb_to_nud(fdb);
- NLA_PUT(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr);
-
+ if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr))
+ goto nla_put_failure;
ci.ndm_used = jiffies_to_clock_t(now - fdb->used);
ci.ndm_confirmed = 0;
ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated);
ci.ndm_refcnt = 0;
- NLA_PUT(skb, NDA_CACHEINFO, sizeof(ci), &ci);
-
+ if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
nla_put_failure:
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index a1daf82..346b368 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -60,20 +60,17 @@
hdr->ifi_flags = dev_get_flags(dev);
hdr->ifi_change = 0;
- NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
- NLA_PUT_U32(skb, IFLA_MASTER, br->dev->ifindex);
- NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
- NLA_PUT_U8(skb, IFLA_OPERSTATE, operstate);
-
- if (dev->addr_len)
- NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
-
- if (dev->ifindex != dev->iflink)
- NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
-
- if (event == RTM_NEWLINK)
- NLA_PUT_U8(skb, IFLA_PROTINFO, port->state);
-
+ if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
+ nla_put_u32(skb, IFLA_MASTER, br->dev->ifindex) ||
+ nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
+ nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
+ (dev->addr_len &&
+ nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
+ (dev->ifindex != dev->iflink &&
+ nla_put_u32(skb, IFLA_LINK, dev->iflink)) ||
+ (event == RTM_NEWLINK &&
+ nla_put_u8(skb, IFLA_PROTINFO, port->state)))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
nla_put_failure:
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
index 20618dd..93e9c6d 100644
--- a/net/caif/chnl_net.c
+++ b/net/caif/chnl_net.c
@@ -421,14 +421,14 @@
struct chnl_net *priv;
u8 loop;
priv = netdev_priv(dev);
- NLA_PUT_U32(skb, IFLA_CAIF_IPV4_CONNID,
- priv->conn_req.sockaddr.u.dgm.connection_id);
- NLA_PUT_U32(skb, IFLA_CAIF_IPV6_CONNID,
- priv->conn_req.sockaddr.u.dgm.connection_id);
+ if (nla_put_u32(skb, IFLA_CAIF_IPV4_CONNID,
+ priv->conn_req.sockaddr.u.dgm.connection_id) ||
+ nla_put_u32(skb, IFLA_CAIF_IPV6_CONNID,
+ priv->conn_req.sockaddr.u.dgm.connection_id))
+ goto nla_put_failure;
loop = priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP;
- NLA_PUT_U8(skb, IFLA_CAIF_LOOPBACK, loop);
-
-
+ if (nla_put_u8(skb, IFLA_CAIF_LOOPBACK, loop))
+ goto nla_put_failure;
return 0;
nla_put_failure:
return -EMSGSIZE;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 6d6d7d2..beacdd9 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -17,6 +17,8 @@
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
+#include <linux/net_tstamp.h>
+#include <linux/phy.h>
#include <linux/bitops.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
@@ -36,6 +38,17 @@
}
EXPORT_SYMBOL(ethtool_op_get_link);
+int ethtool_op_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
+{
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE;
+ info->phc_index = -1;
+ return 0;
+}
+EXPORT_SYMBOL(ethtool_op_get_ts_info);
+
/* Handlers for each ethtool command */
#define ETHTOOL_DEV_FEATURE_WORDS ((NETDEV_FEATURE_COUNT + 31) / 32)
@@ -1278,6 +1291,40 @@
return ret;
}
+static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr)
+{
+ int err = 0;
+ struct ethtool_ts_info info;
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+ struct phy_device *phydev = dev->phydev;
+
+ memset(&info, 0, sizeof(info));
+ info.cmd = ETHTOOL_GET_TS_INFO;
+
+ if (phydev && phydev->drv && phydev->drv->ts_info) {
+
+ err = phydev->drv->ts_info(phydev, &info);
+
+ } else if (dev->ethtool_ops && dev->ethtool_ops->get_ts_info) {
+
+ err = ops->get_ts_info(dev, &info);
+
+ } else {
+ info.so_timestamping =
+ SOF_TIMESTAMPING_RX_SOFTWARE |
+ SOF_TIMESTAMPING_SOFTWARE;
+ info.phc_index = -1;
+ }
+
+ if (err)
+ return err;
+
+ if (copy_to_user(useraddr, &info, sizeof(info)))
+ err = -EFAULT;
+
+ return err;
+}
+
/* The main entry point in this file. Called from net/core/dev.c */
int dev_ethtool(struct net *net, struct ifreq *ifr)
@@ -1295,11 +1342,13 @@
return -EFAULT;
if (!dev->ethtool_ops) {
- /* ETHTOOL_GDRVINFO does not require any driver support.
- * It is also unprivileged and does not change anything,
- * so we can take a shortcut to it. */
+ /* A few commands do not require any driver support,
+ * are unprivileged, and do not change anything, so we
+ * can take a shortcut to them. */
if (ethcmd == ETHTOOL_GDRVINFO)
return ethtool_get_drvinfo(dev, useraddr);
+ else if (ethcmd == ETHTOOL_GET_TS_INFO)
+ return ethtool_get_ts_info(dev, useraddr);
else
return -EOPNOTSUPP;
}
@@ -1330,6 +1379,7 @@
case ETHTOOL_GRXCLSRULE:
case ETHTOOL_GRXCLSRLALL:
case ETHTOOL_GFEATURES:
+ case ETHTOOL_GET_TS_INFO:
break;
default:
if (!capable(CAP_NET_ADMIN))
@@ -1496,6 +1546,9 @@
case ETHTOOL_GET_DUMP_DATA:
rc = ethtool_get_dump_data(dev, useraddr);
break;
+ case ETHTOOL_GET_TS_INFO:
+ rc = ethtool_get_ts_info(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index c02e63c..72cceb7 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -542,7 +542,8 @@
frh = nlmsg_data(nlh);
frh->family = ops->family;
frh->table = rule->table;
- NLA_PUT_U32(skb, FRA_TABLE, rule->table);
+ if (nla_put_u32(skb, FRA_TABLE, rule->table))
+ goto nla_put_failure;
frh->res1 = 0;
frh->res2 = 0;
frh->action = rule->action;
@@ -553,31 +554,28 @@
frh->flags |= FIB_RULE_UNRESOLVED;
if (rule->iifname[0]) {
- NLA_PUT_STRING(skb, FRA_IIFNAME, rule->iifname);
-
+ if (nla_put_string(skb, FRA_IIFNAME, rule->iifname))
+ goto nla_put_failure;
if (rule->iifindex == -1)
frh->flags |= FIB_RULE_IIF_DETACHED;
}
if (rule->oifname[0]) {
- NLA_PUT_STRING(skb, FRA_OIFNAME, rule->oifname);
-
+ if (nla_put_string(skb, FRA_OIFNAME, rule->oifname))
+ goto nla_put_failure;
if (rule->oifindex == -1)
frh->flags |= FIB_RULE_OIF_DETACHED;
}
- if (rule->pref)
- NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref);
-
- if (rule->mark)
- NLA_PUT_U32(skb, FRA_FWMARK, rule->mark);
-
- if (rule->mark_mask || rule->mark)
- NLA_PUT_U32(skb, FRA_FWMASK, rule->mark_mask);
-
- if (rule->target)
- NLA_PUT_U32(skb, FRA_GOTO, rule->target);
-
+ if ((rule->pref &&
+ nla_put_u32(skb, FRA_PRIORITY, rule->pref)) ||
+ (rule->mark &&
+ nla_put_u32(skb, FRA_FWMARK, rule->mark)) ||
+ ((rule->mark_mask || rule->mark) &&
+ nla_put_u32(skb, FRA_FWMASK, rule->mark_mask)) ||
+ (rule->target &&
+ nla_put_u32(skb, FRA_GOTO, rule->target)))
+ goto nla_put_failure;
if (ops->fill(rule, skb, frh) < 0)
goto nla_put_failure;
diff --git a/net/core/filter.c b/net/core/filter.c
index 6f755cc..95d05a6 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -317,6 +317,9 @@
case BPF_S_ANC_CPU:
A = raw_smp_processor_id();
continue;
+ case BPF_S_ANC_ALU_XOR_X:
+ A ^= X;
+ continue;
case BPF_S_ANC_NLATTR: {
struct nlattr *nla;
@@ -561,6 +564,7 @@
ANCILLARY(HATYPE);
ANCILLARY(RXHASH);
ANCILLARY(CPU);
+ ANCILLARY(ALU_XOR_X);
}
}
ftest->code = code;
@@ -589,6 +593,67 @@
}
EXPORT_SYMBOL(sk_filter_release_rcu);
+static int __sk_prepare_filter(struct sk_filter *fp)
+{
+ int err;
+
+ fp->bpf_func = sk_run_filter;
+
+ err = sk_chk_filter(fp->insns, fp->len);
+ if (err)
+ return err;
+
+ bpf_jit_compile(fp);
+ return 0;
+}
+
+/**
+ * sk_unattached_filter_create - create an unattached filter
+ * @fprog: the filter program
+ * @sk: the socket to use
+ *
+ * Create a filter independent ofr any socket. We first run some
+ * sanity checks on it to make sure it does not explode on us later.
+ * If an error occurs or there is insufficient memory for the filter
+ * a negative errno code is returned. On success the return is zero.
+ */
+int sk_unattached_filter_create(struct sk_filter **pfp,
+ struct sock_fprog *fprog)
+{
+ struct sk_filter *fp;
+ unsigned int fsize = sizeof(struct sock_filter) * fprog->len;
+ int err;
+
+ /* Make sure new filter is there and in the right amounts. */
+ if (fprog->filter == NULL)
+ return -EINVAL;
+
+ fp = kmalloc(fsize + sizeof(*fp), GFP_KERNEL);
+ if (!fp)
+ return -ENOMEM;
+ memcpy(fp->insns, fprog->filter, fsize);
+
+ atomic_set(&fp->refcnt, 1);
+ fp->len = fprog->len;
+
+ err = __sk_prepare_filter(fp);
+ if (err)
+ goto free_mem;
+
+ *pfp = fp;
+ return 0;
+free_mem:
+ kfree(fp);
+ return err;
+}
+EXPORT_SYMBOL_GPL(sk_unattached_filter_create);
+
+void sk_unattached_filter_destroy(struct sk_filter *fp)
+{
+ sk_filter_release(fp);
+}
+EXPORT_SYMBOL_GPL(sk_unattached_filter_destroy);
+
/**
* sk_attach_filter - attach a socket filter
* @fprog: the filter program
@@ -619,16 +684,13 @@
atomic_set(&fp->refcnt, 1);
fp->len = fprog->len;
- fp->bpf_func = sk_run_filter;
- err = sk_chk_filter(fp->insns, fp->len);
+ err = __sk_prepare_filter(fp);
if (err) {
sk_filter_uncharge(sk, fp);
return err;
}
- bpf_jit_compile(fp);
-
old_fp = rcu_dereference_protected(sk->sk_filter,
sock_owned_by_user(sk));
rcu_assign_pointer(sk->sk_filter, fp);
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c
index 0452eb2..ddedf21 100644
--- a/net/core/gen_stats.c
+++ b/net/core/gen_stats.c
@@ -27,7 +27,8 @@
static inline int
gnet_stats_copy(struct gnet_dump *d, int type, void *buf, int size)
{
- NLA_PUT(d->skb, type, size, buf);
+ if (nla_put(d->skb, type, size, buf))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/core/kmap_skb.h b/net/core/kmap_skb.h
deleted file mode 100644
index 52d0a44..0000000
--- a/net/core/kmap_skb.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <linux/highmem.h>
-
-static inline void *kmap_skb_frag(const skb_frag_t *frag)
-{
-#ifdef CONFIG_HIGHMEM
- BUG_ON(in_irq());
-
- local_bh_disable();
-#endif
- return kmap_atomic(skb_frag_page(frag));
-}
-
-static inline void kunmap_skb_frag(void *vaddr)
-{
- kunmap_atomic(vaddr);
-#ifdef CONFIG_HIGHMEM
- local_bh_enable();
-#endif
-}
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 0a68045..ac71765 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1768,29 +1768,29 @@
if (nest == NULL)
return -ENOBUFS;
- if (parms->dev)
- NLA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex);
-
- NLA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt));
- NLA_PUT_U32(skb, NDTPA_QUEUE_LENBYTES, parms->queue_len_bytes);
- /* approximative value for deprecated QUEUE_LEN (in packets) */
- NLA_PUT_U32(skb, NDTPA_QUEUE_LEN,
- DIV_ROUND_UP(parms->queue_len_bytes,
- SKB_TRUESIZE(ETH_FRAME_LEN)));
- NLA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen);
- NLA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes);
- NLA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes);
- NLA_PUT_U32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes);
- NLA_PUT_MSECS(skb, NDTPA_REACHABLE_TIME, parms->reachable_time);
- NLA_PUT_MSECS(skb, NDTPA_BASE_REACHABLE_TIME,
- parms->base_reachable_time);
- NLA_PUT_MSECS(skb, NDTPA_GC_STALETIME, parms->gc_staletime);
- NLA_PUT_MSECS(skb, NDTPA_DELAY_PROBE_TIME, parms->delay_probe_time);
- NLA_PUT_MSECS(skb, NDTPA_RETRANS_TIME, parms->retrans_time);
- NLA_PUT_MSECS(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay);
- NLA_PUT_MSECS(skb, NDTPA_PROXY_DELAY, parms->proxy_delay);
- NLA_PUT_MSECS(skb, NDTPA_LOCKTIME, parms->locktime);
-
+ if ((parms->dev &&
+ nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) ||
+ nla_put_u32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)) ||
+ nla_put_u32(skb, NDTPA_QUEUE_LENBYTES, parms->queue_len_bytes) ||
+ /* approximative value for deprecated QUEUE_LEN (in packets) */
+ nla_put_u32(skb, NDTPA_QUEUE_LEN,
+ DIV_ROUND_UP(parms->queue_len_bytes,
+ SKB_TRUESIZE(ETH_FRAME_LEN))) ||
+ nla_put_u32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen) ||
+ nla_put_u32(skb, NDTPA_APP_PROBES, parms->app_probes) ||
+ nla_put_u32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes) ||
+ nla_put_u32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes) ||
+ nla_put_msecs(skb, NDTPA_REACHABLE_TIME, parms->reachable_time) ||
+ nla_put_msecs(skb, NDTPA_BASE_REACHABLE_TIME,
+ parms->base_reachable_time) ||
+ nla_put_msecs(skb, NDTPA_GC_STALETIME, parms->gc_staletime) ||
+ nla_put_msecs(skb, NDTPA_DELAY_PROBE_TIME,
+ parms->delay_probe_time) ||
+ nla_put_msecs(skb, NDTPA_RETRANS_TIME, parms->retrans_time) ||
+ nla_put_msecs(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay) ||
+ nla_put_msecs(skb, NDTPA_PROXY_DELAY, parms->proxy_delay) ||
+ nla_put_msecs(skb, NDTPA_LOCKTIME, parms->locktime))
+ goto nla_put_failure;
return nla_nest_end(skb, nest);
nla_put_failure:
@@ -1815,12 +1815,12 @@
ndtmsg->ndtm_pad1 = 0;
ndtmsg->ndtm_pad2 = 0;
- NLA_PUT_STRING(skb, NDTA_NAME, tbl->id);
- NLA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval);
- NLA_PUT_U32(skb, NDTA_THRESH1, tbl->gc_thresh1);
- NLA_PUT_U32(skb, NDTA_THRESH2, tbl->gc_thresh2);
- NLA_PUT_U32(skb, NDTA_THRESH3, tbl->gc_thresh3);
-
+ if (nla_put_string(skb, NDTA_NAME, tbl->id) ||
+ nla_put_msecs(skb, NDTA_GC_INTERVAL, tbl->gc_interval) ||
+ nla_put_u32(skb, NDTA_THRESH1, tbl->gc_thresh1) ||
+ nla_put_u32(skb, NDTA_THRESH2, tbl->gc_thresh2) ||
+ nla_put_u32(skb, NDTA_THRESH3, tbl->gc_thresh3))
+ goto nla_put_failure;
{
unsigned long now = jiffies;
unsigned int flush_delta = now - tbl->last_flush;
@@ -1841,7 +1841,8 @@
ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1);
rcu_read_unlock_bh();
- NLA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc);
+ if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc))
+ goto nla_put_failure;
}
{
@@ -1866,7 +1867,8 @@
ndst.ndts_forced_gc_runs += st->forced_gc_runs;
}
- NLA_PUT(skb, NDTA_STATS, sizeof(ndst), &ndst);
+ if (nla_put(skb, NDTA_STATS, sizeof(ndst), &ndst))
+ goto nla_put_failure;
}
BUG_ON(tbl->parms.dev);
@@ -2137,7 +2139,8 @@
ndm->ndm_type = neigh->type;
ndm->ndm_ifindex = neigh->dev->ifindex;
- NLA_PUT(skb, NDA_DST, neigh->tbl->key_len, neigh->primary_key);
+ if (nla_put(skb, NDA_DST, neigh->tbl->key_len, neigh->primary_key))
+ goto nla_put_failure;
read_lock_bh(&neigh->lock);
ndm->ndm_state = neigh->nud_state;
@@ -2157,8 +2160,9 @@
ci.ndm_refcnt = atomic_read(&neigh->refcnt) - 1;
read_unlock_bh(&neigh->lock);
- NLA_PUT_U32(skb, NDA_PROBES, atomic_read(&neigh->probes));
- NLA_PUT(skb, NDA_CACHEINFO, sizeof(ci), &ci);
+ if (nla_put_u32(skb, NDA_PROBES, atomic_read(&neigh->probes)) ||
+ nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
@@ -2187,7 +2191,8 @@
ndm->ndm_ifindex = pn->dev->ifindex;
ndm->ndm_state = NUD_NONE;
- NLA_PUT(skb, NDA_DST, tbl->key_len, pn->key);
+ if (nla_put(skb, NDA_DST, tbl->key_len, pn->key))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 90430b7..545a969 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -607,7 +607,8 @@
for (i = 0; i < RTAX_MAX; i++) {
if (metrics[i]) {
valid++;
- NLA_PUT_U32(skb, i+1, metrics[i]);
+ if (nla_put_u32(skb, i+1, metrics[i]))
+ goto nla_put_failure;
}
}
@@ -782,6 +783,7 @@
+ nla_total_size(4) /* IFLA_MTU */
+ nla_total_size(4) /* IFLA_LINK */
+ nla_total_size(4) /* IFLA_MASTER */
+ + nla_total_size(4) /* IFLA_PROMISCUITY */
+ nla_total_size(1) /* IFLA_OPERSTATE */
+ nla_total_size(1) /* IFLA_LINKMODE */
+ nla_total_size(ext_filter_mask
@@ -807,7 +809,8 @@
vf_port = nla_nest_start(skb, IFLA_VF_PORT);
if (!vf_port)
goto nla_put_failure;
- NLA_PUT_U32(skb, IFLA_PORT_VF, vf);
+ if (nla_put_u32(skb, IFLA_PORT_VF, vf))
+ goto nla_put_failure;
err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb);
if (err == -EMSGSIZE)
goto nla_put_failure;
@@ -891,25 +894,23 @@
ifm->ifi_flags = dev_get_flags(dev);
ifm->ifi_change = change;
- NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
- NLA_PUT_U32(skb, IFLA_TXQLEN, dev->tx_queue_len);
- NLA_PUT_U8(skb, IFLA_OPERSTATE,
- netif_running(dev) ? dev->operstate : IF_OPER_DOWN);
- NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode);
- NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
- NLA_PUT_U32(skb, IFLA_GROUP, dev->group);
-
- if (dev->ifindex != dev->iflink)
- NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
-
- if (dev->master)
- NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
-
- if (dev->qdisc)
- NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc->ops->id);
-
- if (dev->ifalias)
- NLA_PUT_STRING(skb, IFLA_IFALIAS, dev->ifalias);
+ if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
+ nla_put_u32(skb, IFLA_TXQLEN, dev->tx_queue_len) ||
+ nla_put_u8(skb, IFLA_OPERSTATE,
+ netif_running(dev) ? dev->operstate : IF_OPER_DOWN) ||
+ nla_put_u8(skb, IFLA_LINKMODE, dev->link_mode) ||
+ nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
+ nla_put_u32(skb, IFLA_GROUP, dev->group) ||
+ nla_put_u32(skb, IFLA_PROMISCUITY, dev->promiscuity) ||
+ (dev->ifindex != dev->iflink &&
+ nla_put_u32(skb, IFLA_LINK, dev->iflink)) ||
+ (dev->master &&
+ nla_put_u32(skb, IFLA_MASTER, dev->master->ifindex)) ||
+ (dev->qdisc &&
+ nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
+ (dev->ifalias &&
+ nla_put_string(skb, IFLA_IFALIAS, dev->ifalias)))
+ goto nla_put_failure;
if (1) {
struct rtnl_link_ifmap map = {
@@ -920,12 +921,14 @@
.dma = dev->dma,
.port = dev->if_port,
};
- NLA_PUT(skb, IFLA_MAP, sizeof(map), &map);
+ if (nla_put(skb, IFLA_MAP, sizeof(map), &map))
+ goto nla_put_failure;
}
if (dev->addr_len) {
- NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
- NLA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast);
+ if (nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr) ||
+ nla_put(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast))
+ goto nla_put_failure;
}
attr = nla_reserve(skb, IFLA_STATS,
@@ -942,8 +945,9 @@
goto nla_put_failure;
copy_rtnl_link_stats64(nla_data(attr), stats);
- if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF))
- NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
+ if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF) &&
+ nla_put_u32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent)))
+ goto nla_put_failure;
if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent
&& (ext_filter_mask & RTEXT_FILTER_VF)) {
@@ -986,12 +990,13 @@
nla_nest_cancel(skb, vfinfo);
goto nla_put_failure;
}
- NLA_PUT(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac);
- NLA_PUT(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan);
- NLA_PUT(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
- &vf_tx_rate);
- NLA_PUT(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
- &vf_spoofchk);
+ if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) ||
+ nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) ||
+ nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
+ &vf_tx_rate) ||
+ nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
+ &vf_spoofchk))
+ goto nla_put_failure;
nla_nest_end(skb, vf);
}
nla_nest_end(skb, vfinfo);
@@ -1113,6 +1118,7 @@
[IFLA_PORT_SELF] = { .type = NLA_NESTED },
[IFLA_AF_SPEC] = { .type = NLA_NESTED },
[IFLA_EXT_MASK] = { .type = NLA_U32 },
+ [IFLA_PROMISCUITY] = { .type = NLA_U32 },
};
EXPORT_SYMBOL(ifla_policy);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index baf8d28..a396a69 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -67,8 +67,7 @@
#include <asm/uaccess.h>
#include <trace/events/skb.h>
-
-#include "kmap_skb.h"
+#include <linux/highmem.h>
static struct kmem_cache *skbuff_head_cache __read_mostly;
static struct kmem_cache *skbuff_fclone_cache __read_mostly;
@@ -707,10 +706,10 @@
}
return -ENOMEM;
}
- vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
+ vaddr = kmap_atomic(skb_frag_page(f));
memcpy(page_address(page),
vaddr + f->page_offset, skb_frag_size(f));
- kunmap_skb_frag(vaddr);
+ kunmap_atomic(vaddr);
page->private = (unsigned long)head;
head = page;
}
@@ -1485,21 +1484,22 @@
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
int end;
+ skb_frag_t *f = &skb_shinfo(skb)->frags[i];
WARN_ON(start > offset + len);
- end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]);
+ end = start + skb_frag_size(f);
if ((copy = end - offset) > 0) {
u8 *vaddr;
if (copy > len)
copy = len;
- vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
+ vaddr = kmap_atomic(skb_frag_page(f));
memcpy(to,
- vaddr + skb_shinfo(skb)->frags[i].page_offset+
- offset - start, copy);
- kunmap_skb_frag(vaddr);
+ vaddr + f->page_offset + offset - start,
+ copy);
+ kunmap_atomic(vaddr);
if ((len -= copy) == 0)
return 0;
@@ -1804,10 +1804,10 @@
if (copy > len)
copy = len;
- vaddr = kmap_skb_frag(frag);
+ vaddr = kmap_atomic(skb_frag_page(frag));
memcpy(vaddr + frag->page_offset + offset - start,
from, copy);
- kunmap_skb_frag(vaddr);
+ kunmap_atomic(vaddr);
if ((len -= copy) == 0)
return 0;
@@ -1867,21 +1867,21 @@
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
int end;
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
WARN_ON(start > offset + len);
- end = start + skb_frag_size(&skb_shinfo(skb)->frags[i]);
+ end = start + skb_frag_size(frag);
if ((copy = end - offset) > 0) {
__wsum csum2;
u8 *vaddr;
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
if (copy > len)
copy = len;
- vaddr = kmap_skb_frag(frag);
+ vaddr = kmap_atomic(skb_frag_page(frag));
csum2 = csum_partial(vaddr + frag->page_offset +
offset - start, copy, 0);
- kunmap_skb_frag(vaddr);
+ kunmap_atomic(vaddr);
csum = csum_block_add(csum, csum2, pos);
if (!(len -= copy))
return csum;
@@ -1953,12 +1953,12 @@
if (copy > len)
copy = len;
- vaddr = kmap_skb_frag(frag);
+ vaddr = kmap_atomic(skb_frag_page(frag));
csum2 = csum_partial_copy_nocheck(vaddr +
frag->page_offset +
offset - start, to,
copy, 0);
- kunmap_skb_frag(vaddr);
+ kunmap_atomic(vaddr);
csum = csum_block_add(csum, csum2, pos);
if (!(len -= copy))
return csum;
@@ -2478,7 +2478,7 @@
if (abs_offset < block_limit) {
if (!st->frag_data)
- st->frag_data = kmap_skb_frag(frag);
+ st->frag_data = kmap_atomic(skb_frag_page(frag));
*data = (u8 *) st->frag_data + frag->page_offset +
(abs_offset - st->stepped_offset);
@@ -2487,7 +2487,7 @@
}
if (st->frag_data) {
- kunmap_skb_frag(st->frag_data);
+ kunmap_atomic(st->frag_data);
st->frag_data = NULL;
}
@@ -2496,7 +2496,7 @@
}
if (st->frag_data) {
- kunmap_skb_frag(st->frag_data);
+ kunmap_atomic(st->frag_data);
st->frag_data = NULL;
}
@@ -2524,7 +2524,7 @@
void skb_abort_seq_read(struct skb_seq_state *st)
{
if (st->frag_data)
- kunmap_skb_frag(st->frag_data);
+ kunmap_atomic(st->frag_data);
}
EXPORT_SYMBOL(skb_abort_seq_read);
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index d860530..8dfa1da 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -178,6 +178,7 @@
[DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)},
[DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)},
[DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED},
+ [DCB_ATTR_IEEE_MAXRATE] = {.len = sizeof(struct ieee_maxrate)},
};
static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = {
@@ -1205,13 +1206,15 @@
if (!app)
goto nla_put_failure;
- if (app_info_type)
- NLA_PUT(skb, app_info_type, sizeof(info), &info);
+ if (app_info_type &&
+ nla_put(skb, app_info_type, sizeof(info), &info))
+ goto nla_put_failure;
- for (i = 0; i < app_count; i++)
- NLA_PUT(skb, app_entry_type, sizeof(struct dcb_app),
- &table[i]);
-
+ for (i = 0; i < app_count; i++) {
+ if (nla_put(skb, app_entry_type, sizeof(struct dcb_app),
+ &table[i]))
+ goto nla_put_failure;
+ }
nla_nest_end(skb, app);
}
err = 0;
@@ -1230,8 +1233,8 @@
int dcbx;
int err = -EMSGSIZE;
- NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name);
-
+ if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name))
+ goto nla_put_failure;
ieee = nla_nest_start(skb, DCB_ATTR_IEEE);
if (!ieee)
goto nla_put_failure;
@@ -1239,15 +1242,28 @@
if (ops->ieee_getets) {
struct ieee_ets ets;
err = ops->ieee_getets(netdev, &ets);
- if (!err)
- NLA_PUT(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets);
+ if (!err &&
+ nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets))
+ goto nla_put_failure;
+ }
+
+ if (ops->ieee_getmaxrate) {
+ struct ieee_maxrate maxrate;
+ err = ops->ieee_getmaxrate(netdev, &maxrate);
+ if (!err) {
+ err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE,
+ sizeof(maxrate), &maxrate);
+ if (err)
+ goto nla_put_failure;
+ }
}
if (ops->ieee_getpfc) {
struct ieee_pfc pfc;
err = ops->ieee_getpfc(netdev, &pfc);
- if (!err)
- NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc);
+ if (!err &&
+ nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc))
+ goto nla_put_failure;
}
app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE);
@@ -1278,15 +1294,17 @@
if (ops->ieee_peer_getets) {
struct ieee_ets ets;
err = ops->ieee_peer_getets(netdev, &ets);
- if (!err)
- NLA_PUT(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets);
+ if (!err &&
+ nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets))
+ goto nla_put_failure;
}
if (ops->ieee_peer_getpfc) {
struct ieee_pfc pfc;
err = ops->ieee_peer_getpfc(netdev, &pfc);
- if (!err)
- NLA_PUT(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc);
+ if (!err &&
+ nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc))
+ goto nla_put_failure;
}
if (ops->peer_getappinfo && ops->peer_getapptable) {
@@ -1340,10 +1358,11 @@
ops->getpgtccfgtx(dev, i - DCB_PG_ATTR_TC_0,
&prio, &pgid, &tc_pct, &up_map);
- NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_PGID, pgid);
- NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map);
- NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio);
- NLA_PUT_U8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct);
+ if (nla_put_u8(skb, DCB_TC_ATTR_PARAM_PGID, pgid) ||
+ nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map) ||
+ nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio) ||
+ nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct))
+ goto nla_put_failure;
nla_nest_end(skb, tc_nest);
}
@@ -1356,7 +1375,8 @@
else
ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0,
&tc_pct);
- NLA_PUT_U8(skb, i, tc_pct);
+ if (nla_put_u8(skb, i, tc_pct))
+ goto nla_put_failure;
}
nla_nest_end(skb, pg);
return 0;
@@ -1373,8 +1393,8 @@
int dcbx, i, err = -EMSGSIZE;
u8 value;
- NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name);
-
+ if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name))
+ goto nla_put_failure;
cee = nla_nest_start(skb, DCB_ATTR_CEE);
if (!cee)
goto nla_put_failure;
@@ -1401,7 +1421,8 @@
for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) {
ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, &value);
- NLA_PUT_U8(skb, i, value);
+ if (nla_put_u8(skb, i, value))
+ goto nla_put_failure;
}
nla_nest_end(skb, pfc_nest);
}
@@ -1454,8 +1475,9 @@
for (i = DCB_FEATCFG_ATTR_ALL + 1; i <= DCB_FEATCFG_ATTR_MAX;
i++)
- if (!ops->getfeatcfg(netdev, i, &value))
- NLA_PUT_U8(skb, i, value);
+ if (!ops->getfeatcfg(netdev, i, &value) &&
+ nla_put_u8(skb, i, value))
+ goto nla_put_failure;
nla_nest_end(skb, feat);
}
@@ -1464,15 +1486,17 @@
if (ops->cee_peer_getpg) {
struct cee_pg pg;
err = ops->cee_peer_getpg(netdev, &pg);
- if (!err)
- NLA_PUT(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg);
+ if (!err &&
+ nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg))
+ goto nla_put_failure;
}
if (ops->cee_peer_getpfc) {
struct cee_pfc pfc;
err = ops->cee_peer_getpfc(netdev, &pfc);
- if (!err)
- NLA_PUT(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc);
+ if (!err &&
+ nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc))
+ goto nla_put_failure;
}
if (ops->peer_getappinfo && ops->peer_getapptable) {
@@ -1589,6 +1613,14 @@
goto err;
}
+ if (ieee[DCB_ATTR_IEEE_MAXRATE] && ops->ieee_setmaxrate) {
+ struct ieee_maxrate *maxrate =
+ nla_data(ieee[DCB_ATTR_IEEE_MAXRATE]);
+ err = ops->ieee_setmaxrate(netdev, maxrate);
+ if (err)
+ goto err;
+ }
+
if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) {
struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]);
err = ops->ieee_setpfc(netdev, pfc);
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index c00e307..a4aecb0 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -694,13 +694,13 @@
ifm->ifa_scope = ifa->ifa_scope;
ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
- if (ifa->ifa_address)
- NLA_PUT_LE16(skb, IFA_ADDRESS, ifa->ifa_address);
- if (ifa->ifa_local)
- NLA_PUT_LE16(skb, IFA_LOCAL, ifa->ifa_local);
- if (ifa->ifa_label[0])
- NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label);
-
+ if ((ifa->ifa_address &&
+ nla_put_le16(skb, IFA_ADDRESS, ifa->ifa_address)) ||
+ (ifa->ifa_local &&
+ nla_put_le16(skb, IFA_LOCAL, ifa->ifa_local)) ||
+ (ifa->ifa_label[0] &&
+ nla_put_string(skb, IFA_LABEL, ifa->ifa_label)))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
nla_put_failure:
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index f65c9dd..7399e3d 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -204,11 +204,11 @@
frh->src_len = r->src_len;
frh->tos = 0;
- if (r->dst_len)
- NLA_PUT_LE16(skb, FRA_DST, r->dst);
- if (r->src_len)
- NLA_PUT_LE16(skb, FRA_SRC, r->src);
-
+ if ((r->dst_len &&
+ nla_put_le16(skb, FRA_DST, r->dst)) ||
+ (r->src_len &&
+ nla_put_le16(skb, FRA_SRC, r->src)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index adaf462..ca92587 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -63,15 +63,14 @@
if (!msg)
return -ENOBUFS;
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
- addr->hwaddr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap);
+ if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
+ nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
+ nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+ dev->dev_addr) ||
+ nla_put(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
+ addr->hwaddr) ||
+ nla_put_u8(msg, IEEE802154_ATTR_CAPABILITY, cap))
+ goto nla_put_failure;
return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
@@ -92,14 +91,13 @@
if (!msg)
return -ENOBUFS;
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr);
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
-
+ if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
+ nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
+ nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+ dev->dev_addr) ||
+ nla_put_u16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) ||
+ nla_put_u8(msg, IEEE802154_ATTR_STATUS, status))
+ goto nla_put_failure;
return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
@@ -119,20 +117,22 @@
if (!msg)
return -ENOBUFS;
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- if (addr->addr_type == IEEE802154_ADDR_LONG)
- NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
- addr->hwaddr);
- else
- NLA_PUT_U16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR,
- addr->short_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason);
-
+ if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
+ nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
+ nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+ dev->dev_addr))
+ goto nla_put_failure;
+ if (addr->addr_type == IEEE802154_ADDR_LONG) {
+ if (nla_put(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
+ addr->hwaddr))
+ goto nla_put_failure;
+ } else {
+ if (nla_put_u16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR,
+ addr->short_addr))
+ goto nla_put_failure;
+ }
+ if (nla_put_u8(msg, IEEE802154_ATTR_REASON, reason))
+ goto nla_put_failure;
return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
@@ -151,13 +151,12 @@
if (!msg)
return -ENOBUFS;
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
-
+ if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
+ nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
+ nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+ dev->dev_addr) ||
+ nla_put_u8(msg, IEEE802154_ATTR_STATUS, status))
+ goto nla_put_failure;
return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
@@ -177,13 +176,13 @@
if (!msg)
return -ENOBUFS;
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
- NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr);
- NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid);
-
+ if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
+ nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
+ nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+ dev->dev_addr) ||
+ nla_put_u16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr) ||
+ nla_put_u16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid))
+ goto nla_put_failure;
return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
@@ -204,19 +203,17 @@
if (!msg)
return -ENOBUFS;
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
- NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type);
- NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned);
- NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, page);
-
- if (edl)
- NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl);
-
+ if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
+ nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
+ nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+ dev->dev_addr) ||
+ nla_put_u8(msg, IEEE802154_ATTR_STATUS, status) ||
+ nla_put_u8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type) ||
+ nla_put_u32(msg, IEEE802154_ATTR_CHANNELS, unscanned) ||
+ nla_put_u8(msg, IEEE802154_ATTR_PAGE, page) ||
+ (edl &&
+ nla_put(msg, IEEE802154_ATTR_ED_LIST, 27, edl)))
+ goto nla_put_failure;
return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
@@ -235,13 +232,12 @@
if (!msg)
return -ENOBUFS;
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
-
+ if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
+ nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
+ nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+ dev->dev_addr) ||
+ nla_put_u8(msg, IEEE802154_ATTR_STATUS, status))
+ goto nla_put_failure;
return ieee802154_nl_mcast(msg, ieee802154_coord_mcgrp.id);
nla_put_failure:
@@ -266,16 +262,16 @@
phy = ieee802154_mlme_ops(dev)->get_phy(dev);
BUG_ON(!phy);
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
- NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
- NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
-
- NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
- dev->dev_addr);
- NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR,
- ieee802154_mlme_ops(dev)->get_short_addr(dev));
- NLA_PUT_U16(msg, IEEE802154_ATTR_PAN_ID,
- ieee802154_mlme_ops(dev)->get_pan_id(dev));
+ if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) ||
+ nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
+ nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) ||
+ nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+ dev->dev_addr) ||
+ nla_put_u16(msg, IEEE802154_ATTR_SHORT_ADDR,
+ ieee802154_mlme_ops(dev)->get_short_addr(dev)) ||
+ nla_put_u16(msg, IEEE802154_ATTR_PAN_ID,
+ ieee802154_mlme_ops(dev)->get_pan_id(dev)))
+ goto nla_put_failure;
wpan_phy_put(phy);
return genlmsg_end(msg, hdr);
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index c64a38d..3bdc430 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -53,18 +53,18 @@
goto out;
mutex_lock(&phy->pib_lock);
- NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
-
- NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, phy->current_page);
- NLA_PUT_U8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel);
+ if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
+ nla_put_u8(msg, IEEE802154_ATTR_PAGE, phy->current_page) ||
+ nla_put_u8(msg, IEEE802154_ATTR_CHANNEL, phy->current_channel))
+ goto nla_put_failure;
for (i = 0; i < 32; i++) {
if (phy->channels_supported[i])
buf[pages++] = phy->channels_supported[i] | (i << 27);
}
- if (pages)
- NLA_PUT(msg, IEEE802154_ATTR_CHANNEL_PAGE_LIST,
- pages * sizeof(uint32_t), buf);
-
+ if (pages &&
+ nla_put(msg, IEEE802154_ATTR_CHANNEL_PAGE_LIST,
+ pages * sizeof(uint32_t), buf))
+ goto nla_put_failure;
mutex_unlock(&phy->pib_lock);
kfree(buf);
return genlmsg_end(msg, hdr);
@@ -245,9 +245,9 @@
goto dev_unregister;
}
- NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
-
+ if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
+ nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name))
+ goto nla_put_failure;
dev_put(dev);
wpan_phy_put(phy);
@@ -333,10 +333,9 @@
rtnl_unlock();
-
- NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
- NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, name);
-
+ if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) ||
+ nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, name))
+ goto nla_put_failure;
wpan_phy_put(phy);
return ieee802154_nl_reply(msg, info);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 6e447ff..7ba2196 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1266,17 +1266,15 @@
ifm->ifa_scope = ifa->ifa_scope;
ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
- if (ifa->ifa_address)
- NLA_PUT_BE32(skb, IFA_ADDRESS, ifa->ifa_address);
-
- if (ifa->ifa_local)
- NLA_PUT_BE32(skb, IFA_LOCAL, ifa->ifa_local);
-
- if (ifa->ifa_broadcast)
- NLA_PUT_BE32(skb, IFA_BROADCAST, ifa->ifa_broadcast);
-
- if (ifa->ifa_label[0])
- NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label);
+ if ((ifa->ifa_address &&
+ nla_put_be32(skb, IFA_ADDRESS, ifa->ifa_address)) ||
+ (ifa->ifa_local &&
+ nla_put_be32(skb, IFA_LOCAL, ifa->ifa_local)) ||
+ (ifa->ifa_broadcast &&
+ nla_put_be32(skb, IFA_BROADCAST, ifa->ifa_broadcast)) ||
+ (ifa->ifa_label[0] &&
+ nla_put_string(skb, IFA_LABEL, ifa->ifa_label)))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 799fc79..2d043f7 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -221,15 +221,15 @@
frh->src_len = rule4->src_len;
frh->tos = rule4->tos;
- if (rule4->dst_len)
- NLA_PUT_BE32(skb, FRA_DST, rule4->dst);
-
- if (rule4->src_len)
- NLA_PUT_BE32(skb, FRA_SRC, rule4->src);
-
+ if ((rule4->dst_len &&
+ nla_put_be32(skb, FRA_DST, rule4->dst)) ||
+ (rule4->src_len &&
+ nla_put_be32(skb, FRA_SRC, rule4->src)))
+ goto nla_put_failure;
#ifdef CONFIG_IP_ROUTE_CLASSID
- if (rule4->tclassid)
- NLA_PUT_U32(skb, FRA_FLOW, rule4->tclassid);
+ if (rule4->tclassid &&
+ nla_put_u32(skb, FRA_FLOW, rule4->tclassid))
+ goto nla_put_failure;
#endif
return 0;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 5063fa3..a8bdf740 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -931,33 +931,36 @@
rtm->rtm_table = tb_id;
else
rtm->rtm_table = RT_TABLE_COMPAT;
- NLA_PUT_U32(skb, RTA_TABLE, tb_id);
+ if (nla_put_u32(skb, RTA_TABLE, tb_id))
+ goto nla_put_failure;
rtm->rtm_type = type;
rtm->rtm_flags = fi->fib_flags;
rtm->rtm_scope = fi->fib_scope;
rtm->rtm_protocol = fi->fib_protocol;
- if (rtm->rtm_dst_len)
- NLA_PUT_BE32(skb, RTA_DST, dst);
-
- if (fi->fib_priority)
- NLA_PUT_U32(skb, RTA_PRIORITY, fi->fib_priority);
-
+ if (rtm->rtm_dst_len &&
+ nla_put_be32(skb, RTA_DST, dst))
+ goto nla_put_failure;
+ if (fi->fib_priority &&
+ nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority))
+ goto nla_put_failure;
if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
goto nla_put_failure;
- if (fi->fib_prefsrc)
- NLA_PUT_BE32(skb, RTA_PREFSRC, fi->fib_prefsrc);
-
+ if (fi->fib_prefsrc &&
+ nla_put_be32(skb, RTA_PREFSRC, fi->fib_prefsrc))
+ goto nla_put_failure;
if (fi->fib_nhs == 1) {
- if (fi->fib_nh->nh_gw)
- NLA_PUT_BE32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw);
-
- if (fi->fib_nh->nh_oif)
- NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif);
+ if (fi->fib_nh->nh_gw &&
+ nla_put_be32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw))
+ goto nla_put_failure;
+ if (fi->fib_nh->nh_oif &&
+ nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif))
+ goto nla_put_failure;
#ifdef CONFIG_IP_ROUTE_CLASSID
- if (fi->fib_nh[0].nh_tclassid)
- NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid);
+ if (fi->fib_nh[0].nh_tclassid &&
+ nla_put_u32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid))
+ goto nla_put_failure;
#endif
}
#ifdef CONFIG_IP_ROUTE_MULTIPATH
@@ -978,11 +981,13 @@
rtnh->rtnh_hops = nh->nh_weight - 1;
rtnh->rtnh_ifindex = nh->nh_oif;
- if (nh->nh_gw)
- NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw);
+ if (nh->nh_gw &&
+ nla_put_be32(skb, RTA_GATEWAY, nh->nh_gw))
+ goto nla_put_failure;
#ifdef CONFIG_IP_ROUTE_CLASSID
- if (nh->nh_tclassid)
- NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid);
+ if (nh->nh_tclassid &&
+ nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid))
+ goto nla_put_failure;
#endif
/* length of rtnetlink header + attributes */
rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *) rtnh;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 5dfecfd..ceaac24 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -774,7 +774,7 @@
if (psf->sf_count[MCAST_INCLUDE] ||
pmc->sfcount[MCAST_EXCLUDE] !=
psf->sf_count[MCAST_EXCLUDE])
- continue;
+ break;
if (srcs[i] == psf->sf_inaddr) {
scount++;
break;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index b57532d..02d07c6 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1654,17 +1654,18 @@
struct ip_tunnel *t = netdev_priv(dev);
struct ip_tunnel_parm *p = &t->parms;
- NLA_PUT_U32(skb, IFLA_GRE_LINK, p->link);
- NLA_PUT_BE16(skb, IFLA_GRE_IFLAGS, p->i_flags);
- NLA_PUT_BE16(skb, IFLA_GRE_OFLAGS, p->o_flags);
- NLA_PUT_BE32(skb, IFLA_GRE_IKEY, p->i_key);
- NLA_PUT_BE32(skb, IFLA_GRE_OKEY, p->o_key);
- NLA_PUT_BE32(skb, IFLA_GRE_LOCAL, p->iph.saddr);
- NLA_PUT_BE32(skb, IFLA_GRE_REMOTE, p->iph.daddr);
- NLA_PUT_U8(skb, IFLA_GRE_TTL, p->iph.ttl);
- NLA_PUT_U8(skb, IFLA_GRE_TOS, p->iph.tos);
- NLA_PUT_U8(skb, IFLA_GRE_PMTUDISC, !!(p->iph.frag_off & htons(IP_DF)));
-
+ if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
+ nla_put_be16(skb, IFLA_GRE_IFLAGS, p->i_flags) ||
+ nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) ||
+ nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) ||
+ nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) ||
+ nla_put_be32(skb, IFLA_GRE_LOCAL, p->iph.saddr) ||
+ nla_put_be32(skb, IFLA_GRE_REMOTE, p->iph.daddr) ||
+ nla_put_u8(skb, IFLA_GRE_TTL, p->iph.ttl) ||
+ nla_put_u8(skb, IFLA_GRE_TOS, p->iph.tos) ||
+ nla_put_u8(skb, IFLA_GRE_PMTUDISC,
+ !!(p->iph.frag_off & htons(IP_DF))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 960fbfc3..5bef604 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -2119,15 +2119,16 @@
rtm->rtm_src_len = 32;
rtm->rtm_tos = 0;
rtm->rtm_table = mrt->id;
- NLA_PUT_U32(skb, RTA_TABLE, mrt->id);
+ if (nla_put_u32(skb, RTA_TABLE, mrt->id))
+ goto nla_put_failure;
rtm->rtm_type = RTN_MULTICAST;
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
rtm->rtm_protocol = RTPROT_UNSPEC;
rtm->rtm_flags = 0;
- NLA_PUT_BE32(skb, RTA_SRC, c->mfc_origin);
- NLA_PUT_BE32(skb, RTA_DST, c->mfc_mcastgrp);
-
+ if (nla_put_be32(skb, RTA_SRC, c->mfc_origin) ||
+ nla_put_be32(skb, RTA_DST, c->mfc_mcastgrp))
+ goto nla_put_failure;
if (__ipmr_fill_mroute(mrt, skb, c, rtm) < 0)
goto nla_put_failure;
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index de9da21..5c45e30 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -303,8 +303,9 @@
static int ipv4_tuple_to_nlattr(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple)
{
- NLA_PUT_BE32(skb, CTA_IP_V4_SRC, tuple->src.u3.ip);
- NLA_PUT_BE32(skb, CTA_IP_V4_DST, tuple->dst.u3.ip);
+ if (nla_put_be32(skb, CTA_IP_V4_SRC, tuple->src.u3.ip) ||
+ nla_put_be32(skb, CTA_IP_V4_DST, tuple->dst.u3.ip))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 7cbe9cb..0847e37 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -228,10 +228,10 @@
static int icmp_tuple_to_nlattr(struct sk_buff *skb,
const struct nf_conntrack_tuple *t)
{
- NLA_PUT_BE16(skb, CTA_PROTO_ICMP_ID, t->src.u.icmp.id);
- NLA_PUT_U8(skb, CTA_PROTO_ICMP_TYPE, t->dst.u.icmp.type);
- NLA_PUT_U8(skb, CTA_PROTO_ICMP_CODE, t->dst.u.icmp.code);
-
+ if (nla_put_be16(skb, CTA_PROTO_ICMP_ID, t->src.u.icmp.id) ||
+ nla_put_u8(skb, CTA_PROTO_ICMP_TYPE, t->dst.u.icmp.type) ||
+ nla_put_u8(skb, CTA_PROTO_ICMP_CODE, t->dst.u.icmp.code))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -293,8 +293,8 @@
{
const unsigned int *timeout = data;
- NLA_PUT_BE32(skb, CTA_TIMEOUT_ICMP_TIMEOUT, htonl(*timeout / HZ));
-
+ if (nla_put_be32(skb, CTA_TIMEOUT_ICMP_TIMEOUT, htonl(*timeout / HZ)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 167ea10..e4d18f2 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -229,7 +229,7 @@
TC_PRIO_INTERACTIVE_BULK,
ECN_OR_COST(INTERACTIVE_BULK)
};
-
+EXPORT_SYMBOL(ip_tos2prio);
/*
* Route cache.
@@ -2972,7 +2972,8 @@
r->rtm_src_len = 0;
r->rtm_tos = rt->rt_key_tos;
r->rtm_table = RT_TABLE_MAIN;
- NLA_PUT_U32(skb, RTA_TABLE, RT_TABLE_MAIN);
+ if (nla_put_u32(skb, RTA_TABLE, RT_TABLE_MAIN))
+ goto nla_put_failure;
r->rtm_type = rt->rt_type;
r->rtm_scope = RT_SCOPE_UNIVERSE;
r->rtm_protocol = RTPROT_UNSPEC;
@@ -2980,31 +2981,38 @@
if (rt->rt_flags & RTCF_NOTIFY)
r->rtm_flags |= RTM_F_NOTIFY;
- NLA_PUT_BE32(skb, RTA_DST, rt->rt_dst);
-
+ if (nla_put_be32(skb, RTA_DST, rt->rt_dst))
+ goto nla_put_failure;
if (rt->rt_key_src) {
r->rtm_src_len = 32;
- NLA_PUT_BE32(skb, RTA_SRC, rt->rt_key_src);
+ if (nla_put_be32(skb, RTA_SRC, rt->rt_key_src))
+ goto nla_put_failure;
}
- if (rt->dst.dev)
- NLA_PUT_U32(skb, RTA_OIF, rt->dst.dev->ifindex);
+ if (rt->dst.dev &&
+ nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex))
+ goto nla_put_failure;
#ifdef CONFIG_IP_ROUTE_CLASSID
- if (rt->dst.tclassid)
- NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid);
+ if (rt->dst.tclassid &&
+ nla_put_u32(skb, RTA_FLOW, rt->dst.tclassid))
+ goto nla_put_failure;
#endif
- if (rt_is_input_route(rt))
- NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
- else if (rt->rt_src != rt->rt_key_src)
- NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src);
-
- if (rt->rt_dst != rt->rt_gateway)
- NLA_PUT_BE32(skb, RTA_GATEWAY, rt->rt_gateway);
+ if (rt_is_input_route(rt)) {
+ if (nla_put_be32(skb, RTA_PREFSRC, rt->rt_spec_dst))
+ goto nla_put_failure;
+ } else if (rt->rt_src != rt->rt_key_src) {
+ if (nla_put_be32(skb, RTA_PREFSRC, rt->rt_src))
+ goto nla_put_failure;
+ }
+ if (rt->rt_dst != rt->rt_gateway &&
+ nla_put_be32(skb, RTA_GATEWAY, rt->rt_gateway))
+ goto nla_put_failure;
if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
goto nla_put_failure;
- if (rt->rt_mark)
- NLA_PUT_BE32(skb, RTA_MARK, rt->rt_mark);
+ if (rt->rt_mark &&
+ nla_put_be32(skb, RTA_MARK, rt->rt_mark))
+ goto nla_put_failure;
error = rt->dst.error;
if (peer) {
@@ -3045,7 +3053,8 @@
}
} else
#endif
- NLA_PUT_U32(skb, RTA_IIF, rt->rt_iif);
+ if (nla_put_u32(skb, RTA_IIF, rt->rt_iif))
+ goto nla_put_failure;
}
if (rtnl_put_cacheinfo(skb, &rt->dst, id, ts, tsage,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6a3bb60..fcd230a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -336,10 +336,9 @@
snmp6_free_dev(idev);
kfree_rcu(idev, rcu);
}
-
EXPORT_SYMBOL(in6_dev_finish_destroy);
-static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
+static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
{
struct inet6_dev *ndev;
@@ -441,7 +440,7 @@
return ndev;
}
-static struct inet6_dev * ipv6_find_idev(struct net_device *dev)
+static struct inet6_dev *ipv6_find_idev(struct net_device *dev)
{
struct inet6_dev *idev;
@@ -1333,7 +1332,6 @@
rcu_read_unlock();
return onlink;
}
-
EXPORT_SYMBOL(ipv6_chk_prefix);
struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr,
@@ -1523,7 +1521,7 @@
if (dev->addr_len != ARCNET_ALEN)
return -1;
memset(eui, 0, 7);
- eui[7] = *(u8*)dev->dev_addr;
+ eui[7] = *(u8 *)dev->dev_addr;
return 0;
}
@@ -1668,7 +1666,8 @@
in6_dev_put(idev);
}
-static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr) {
+static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr)
+{
int ret = 0;
if (tmpaddr && memcmp(idev->rndid, &tmpaddr->s6_addr[8], 8) == 0)
@@ -1911,7 +1910,7 @@
/* Try to figure out our local address for this prefix */
if (pinfo->autoconf && in6_dev->cnf.autoconf) {
- struct inet6_ifaddr * ifp;
+ struct inet6_ifaddr *ifp;
struct in6_addr addr;
int create = 0, update_lft = 0;
@@ -2365,9 +2364,9 @@
}
for_each_netdev(net, dev) {
- struct in_device * in_dev = __in_dev_get_rtnl(dev);
+ struct in_device *in_dev = __in_dev_get_rtnl(dev);
if (in_dev && (dev->flags & IFF_UP)) {
- struct in_ifaddr * ifa;
+ struct in_ifaddr *ifa;
int flag = scope;
@@ -2413,7 +2412,7 @@
static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr)
{
- struct inet6_ifaddr * ifp;
+ struct inet6_ifaddr *ifp;
u32 addr_flags = IFA_F_PERMANENT;
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
@@ -2434,7 +2433,7 @@
static void addrconf_dev_config(struct net_device *dev)
{
struct in6_addr addr;
- struct inet6_dev * idev;
+ struct inet6_dev *idev;
ASSERT_RTNL();
@@ -2570,7 +2569,7 @@
}
static int addrconf_notify(struct notifier_block *this, unsigned long event,
- void * data)
+ void *data)
{
struct net_device *dev = (struct net_device *) data;
struct inet6_dev *idev = __in6_dev_get(dev);
@@ -3794,7 +3793,7 @@
return inet6_dump_addr(skb, cb, type);
}
-static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
+static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr *nlh,
void *arg)
{
struct net *net = sock_net(in_skb->sk);
@@ -3989,14 +3988,14 @@
struct nlattr *nla;
struct ifla_cacheinfo ci;
- NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
-
+ if (nla_put_u32(skb, IFLA_INET6_FLAGS, idev->if_flags))
+ goto nla_put_failure;
ci.max_reasm_len = IPV6_MAXPLEN;
ci.tstamp = cstamp_delta(idev->tstamp);
ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time);
- NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
-
+ if (nla_put(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci))
+ goto nla_put_failure;
nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
if (nla == NULL)
goto nla_put_failure;
@@ -4061,15 +4060,13 @@
hdr->ifi_flags = dev_get_flags(dev);
hdr->ifi_change = 0;
- NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
-
- if (dev->addr_len)
- NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
-
- NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
- if (dev->ifindex != dev->iflink)
- NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
-
+ if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
+ (dev->addr_len &&
+ nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
+ nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
+ (dev->ifindex != dev->iflink &&
+ nla_put_u32(skb, IFLA_LINK, dev->iflink)))
+ goto nla_put_failure;
protoinfo = nla_nest_start(skb, IFLA_PROTINFO);
if (protoinfo == NULL)
goto nla_put_failure;
@@ -4182,12 +4179,12 @@
if (pinfo->autoconf)
pmsg->prefix_flags |= IF_PREFIX_AUTOCONF;
- NLA_PUT(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix);
-
+ if (nla_put(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix))
+ goto nla_put_failure;
ci.preferred_time = ntohl(pinfo->prefered);
ci.valid_time = ntohl(pinfo->valid);
- NLA_PUT(skb, PREFIX_CACHEINFO, sizeof(ci), &ci);
-
+ if (nla_put(skb, PREFIX_CACHEINFO, sizeof(ci), &ci))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
nla_put_failure:
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c
index 399287e..7981bde 100644
--- a/net/ipv6/addrconf_core.c
+++ b/net/ipv6/addrconf_core.c
@@ -10,7 +10,7 @@
static inline unsigned ipv6_addr_scope2type(unsigned scope)
{
- switch(scope) {
+ switch (scope) {
case IPV6_ADDR_SCOPE_NODELOCAL:
return (IPV6_ADDR_SCOPE_TYPE(IPV6_ADDR_SCOPE_NODELOCAL) |
IPV6_ADDR_LOOPBACK);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 76832c8..f6210d6 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -98,7 +98,7 @@
sin.sin_port = usin->sin6_port;
err = ip4_datagram_connect(sk,
- (struct sockaddr*) &sin,
+ (struct sockaddr *) &sin,
sizeof(sin));
ipv4_connected:
@@ -518,7 +518,7 @@
unsigned len;
u8 *ptr = nh + off;
- switch(nexthdr) {
+ switch (nexthdr) {
case IPPROTO_DSTOPTS:
nexthdr = ptr[0];
len = (ptr[1] + 1) << 3;
@@ -827,9 +827,8 @@
int tc;
err = -EINVAL;
- if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
goto exit_f;
- }
tc = *(int *)CMSG_DATA(cmsg);
if (tc < -1 || tc > 0xff)
@@ -846,9 +845,8 @@
int df;
err = -EINVAL;
- if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
goto exit_f;
- }
df = *(int *)CMSG_DATA(cmsg);
if (df < 0 || df > 1)
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 3d641b6..c486b8e 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -722,7 +722,6 @@
if (opt->hopopt)
ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
}
-
EXPORT_SYMBOL(ipv6_push_nfrag_opts);
void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
@@ -738,20 +737,19 @@
opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
if (opt2) {
- long dif = (char*)opt2 - (char*)opt;
+ long dif = (char *)opt2 - (char *)opt;
memcpy(opt2, opt, opt->tot_len);
if (opt2->hopopt)
- *((char**)&opt2->hopopt) += dif;
+ *((char **)&opt2->hopopt) += dif;
if (opt2->dst0opt)
- *((char**)&opt2->dst0opt) += dif;
+ *((char **)&opt2->dst0opt) += dif;
if (opt2->dst1opt)
- *((char**)&opt2->dst1opt) += dif;
+ *((char **)&opt2->dst1opt) += dif;
if (opt2->srcrt)
- *((char**)&opt2->srcrt) += dif;
+ *((char **)&opt2->srcrt) += dif;
}
return opt2;
}
-
EXPORT_SYMBOL_GPL(ipv6_dup_options);
static int ipv6_renew_option(void *ohdr,
@@ -892,5 +890,4 @@
fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr;
return orig;
}
-
EXPORT_SYMBOL_GPL(fl6_update_dst);
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index 72957f4..7b1a884 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -21,6 +21,7 @@
(nexthdr == NEXTHDR_NONE) ||
(nexthdr == NEXTHDR_DEST);
}
+EXPORT_SYMBOL(ipv6_ext_hdr);
/*
* Skip any extension headers. This is used by the ICMP module.
@@ -109,6 +110,4 @@
*nexthdrp = nexthdr;
return start;
}
-
-EXPORT_SYMBOL(ipv6_ext_hdr);
EXPORT_SYMBOL(ipv6_skip_exthdr);
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index b6c5731..0ff1cfd 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -22,8 +22,7 @@
#include <net/ip6_route.h>
#include <net/netlink.h>
-struct fib6_rule
-{
+struct fib6_rule {
struct fib_rule common;
struct rt6key src;
struct rt6key dst;
@@ -215,14 +214,13 @@
frh->src_len = rule6->src.plen;
frh->tos = rule6->tclass;
- if (rule6->dst.plen)
- NLA_PUT(skb, FRA_DST, sizeof(struct in6_addr),
- &rule6->dst.addr);
-
- if (rule6->src.plen)
- NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr),
- &rule6->src.addr);
-
+ if ((rule6->dst.plen &&
+ nla_put(skb, FRA_DST, sizeof(struct in6_addr),
+ &rule6->dst.addr)) ||
+ (rule6->src.plen &&
+ nla_put(skb, FRA_SRC, sizeof(struct in6_addr),
+ &rule6->src.addr)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 27ac95a..cc079d8 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -498,7 +498,7 @@
err = ip6_append_data(sk, icmpv6_getfrag, &msg,
len + sizeof(struct icmp6hdr),
sizeof(struct icmp6hdr), hlimit,
- np->tclass, NULL, &fl6, (struct rt6_info*)dst,
+ np->tclass, NULL, &fl6, (struct rt6_info *)dst,
MSG_DONTWAIT, np->dontfrag);
if (err) {
ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
@@ -579,7 +579,7 @@
err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl6,
- (struct rt6_info*)dst, MSG_DONTWAIT,
+ (struct rt6_info *)dst, MSG_DONTWAIT,
np->dontfrag);
if (err) {
@@ -950,7 +950,6 @@
return fatal;
}
-
EXPORT_SYMBOL(icmpv6_err_convert);
#ifdef CONFIG_SYSCTL
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 8110362..efc0098 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -2215,14 +2215,15 @@
rtm->rtm_src_len = 128;
rtm->rtm_tos = 0;
rtm->rtm_table = mrt->id;
- NLA_PUT_U32(skb, RTA_TABLE, mrt->id);
+ if (nla_put_u32(skb, RTA_TABLE, mrt->id))
+ goto nla_put_failure;
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
rtm->rtm_protocol = RTPROT_UNSPEC;
rtm->rtm_flags = 0;
- NLA_PUT(skb, RTA_SRC, 16, &c->mf6c_origin);
- NLA_PUT(skb, RTA_DST, 16, &c->mf6c_mcastgrp);
-
+ if (nla_put(skb, RTA_SRC, 16, &c->mf6c_origin) ||
+ nla_put(skb, RTA_DST, 16, &c->mf6c_mcastgrp))
+ goto nla_put_failure;
if (__ip6mr_fill_mroute(mrt, skb, c, rtm) < 0)
goto nla_put_failure;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index b2869ca..7dfb89f 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1061,7 +1061,7 @@
if (psf->sf_count[MCAST_INCLUDE] ||
pmc->mca_sfcount[MCAST_EXCLUDE] !=
psf->sf_count[MCAST_EXCLUDE])
- continue;
+ break;
if (ipv6_addr_equal(&srcs[i], &psf->sf_addr)) {
scount++;
break;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 3dcdb81..1d6fb0c 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1099,8 +1099,9 @@
memcpy(ndmsg + 1, opt, opt->nd_opt_len << 3);
- NLA_PUT(skb, NDUSEROPT_SRCADDR, sizeof(struct in6_addr),
- &ipv6_hdr(ra)->saddr);
+ if (nla_put(skb, NDUSEROPT_SRCADDR, sizeof(struct in6_addr),
+ &ipv6_hdr(ra)->saddr))
+ goto nla_put_failure;
nlmsg_end(skb, nlh);
rtnl_notify(skb, net, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 4111050..fe925e4 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -278,10 +278,11 @@
static int ipv6_tuple_to_nlattr(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple)
{
- NLA_PUT(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4,
- &tuple->src.u3.ip6);
- NLA_PUT(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4,
- &tuple->dst.u3.ip6);
+ if (nla_put(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4,
+ &tuple->src.u3.ip6) ||
+ nla_put(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4,
+ &tuple->dst.u3.ip6))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 92cc9f2..3e81904 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -234,10 +234,10 @@
static int icmpv6_tuple_to_nlattr(struct sk_buff *skb,
const struct nf_conntrack_tuple *t)
{
- NLA_PUT_BE16(skb, CTA_PROTO_ICMPV6_ID, t->src.u.icmp.id);
- NLA_PUT_U8(skb, CTA_PROTO_ICMPV6_TYPE, t->dst.u.icmp.type);
- NLA_PUT_U8(skb, CTA_PROTO_ICMPV6_CODE, t->dst.u.icmp.code);
-
+ if (nla_put_be16(skb, CTA_PROTO_ICMPV6_ID, t->src.u.icmp.id) ||
+ nla_put_u8(skb, CTA_PROTO_ICMPV6_TYPE, t->dst.u.icmp.type) ||
+ nla_put_u8(skb, CTA_PROTO_ICMPV6_CODE, t->dst.u.icmp.code))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -300,8 +300,8 @@
{
const unsigned int *timeout = data;
- NLA_PUT_BE32(skb, CTA_TIMEOUT_ICMPV6_TIMEOUT, htonl(*timeout / HZ));
-
+ if (nla_put_be32(skb, CTA_TIMEOUT_ICMPV6_TIMEOUT, htonl(*timeout / HZ)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 3992e26..8c5df6f 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2413,7 +2413,8 @@
else
table = RT6_TABLE_UNSPEC;
rtm->rtm_table = table;
- NLA_PUT_U32(skb, RTA_TABLE, table);
+ if (nla_put_u32(skb, RTA_TABLE, table))
+ goto nla_put_failure;
if (rt->rt6i_flags & RTF_REJECT)
rtm->rtm_type = RTN_UNREACHABLE;
else if (rt->rt6i_flags & RTF_LOCAL)
@@ -2436,16 +2437,20 @@
rtm->rtm_flags |= RTM_F_CLONED;
if (dst) {
- NLA_PUT(skb, RTA_DST, 16, dst);
+ if (nla_put(skb, RTA_DST, 16, dst))
+ goto nla_put_failure;
rtm->rtm_dst_len = 128;
} else if (rtm->rtm_dst_len)
- NLA_PUT(skb, RTA_DST, 16, &rt->rt6i_dst.addr);
+ if (nla_put(skb, RTA_DST, 16, &rt->rt6i_dst.addr))
+ goto nla_put_failure;
#ifdef CONFIG_IPV6_SUBTREES
if (src) {
- NLA_PUT(skb, RTA_SRC, 16, src);
+ if (nla_put(skb, RTA_SRC, 16, src))
+ goto nla_put_failure;
rtm->rtm_src_len = 128;
- } else if (rtm->rtm_src_len)
- NLA_PUT(skb, RTA_SRC, 16, &rt->rt6i_src.addr);
+ } else if (rtm->rtm_src_len &&
+ nla_put(skb, RTA_SRC, 16, &rt->rt6i_src.addr))
+ goto nla_put_failure;
#endif
if (iif) {
#ifdef CONFIG_IPV6_MROUTE
@@ -2463,17 +2468,20 @@
}
} else
#endif
- NLA_PUT_U32(skb, RTA_IIF, iif);
+ if (nla_put_u32(skb, RTA_IIF, iif))
+ goto nla_put_failure;
} else if (dst) {
struct in6_addr saddr_buf;
- if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0)
- NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
+ if (ip6_route_get_saddr(net, rt, dst, 0, &saddr_buf) == 0 &&
+ nla_put(skb, RTA_PREFSRC, 16, &saddr_buf))
+ goto nla_put_failure;
}
if (rt->rt6i_prefsrc.plen) {
struct in6_addr saddr_buf;
saddr_buf = rt->rt6i_prefsrc.addr;
- NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
+ if (nla_put(skb, RTA_PREFSRC, 16, &saddr_buf))
+ goto nla_put_failure;
}
if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0)
@@ -2489,11 +2497,11 @@
}
rcu_read_unlock();
- if (rt->dst.dev)
- NLA_PUT_U32(skb, RTA_OIF, rt->dst.dev->ifindex);
-
- NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
-
+ if (rt->dst.dev &&
+ nla_put_u32(skb, RTA_OIF, rt->dst.dev->ifindex))
+ goto nla_put_failure;
+ if (nla_put_u32(skb, RTA_PRIORITY, rt->rt6i_metric))
+ goto nla_put_failure;
if (!(rt->rt6i_flags & RTF_EXPIRES))
expires = 0;
else if (rt->dst.expires - jiffies < INT_MAX)
@@ -2598,6 +2606,7 @@
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
if (!skb) {
+ dst_release(&rt->dst);
err = -ENOBUFS;
goto errout;
}
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index c4ffd17..f9608db 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -115,7 +115,7 @@
/*
* Must be invoked with rcu_read_lock
*/
-static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
+static struct ip_tunnel *ipip6_tunnel_lookup(struct net *net,
struct net_device *dev, __be32 remote, __be32 local)
{
unsigned int h0 = HASH(remote);
@@ -691,7 +691,7 @@
goto tx_error;
}
- addr6 = (const struct in6_addr*)&neigh->primary_key;
+ addr6 = (const struct in6_addr *)&neigh->primary_key;
addr_type = ipv6_addr_type(addr6);
if ((addr_type & IPV6_ADDR_UNICAST) &&
@@ -721,7 +721,7 @@
goto tx_error;
}
- addr6 = (const struct in6_addr*)&neigh->primary_key;
+ addr6 = (const struct in6_addr *)&neigh->primary_key;
addr_type = ipv6_addr_type(addr6);
if (addr_type == IPV6_ADDR_ANY) {
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 93a41a0..bc8c334 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -231,24 +231,28 @@
if (IS_ERR(hdr))
return PTR_ERR(hdr);
- NLA_PUT_U8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version);
- NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id);
- NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id);
- NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, tunnel->debug);
- NLA_PUT_U16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap);
+ if (nla_put_u8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version) ||
+ nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) ||
+ nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) ||
+ nla_put_u32(skb, L2TP_ATTR_DEBUG, tunnel->debug) ||
+ nla_put_u16(skb, L2TP_ATTR_ENCAP_TYPE, tunnel->encap))
+ goto nla_put_failure;
nest = nla_nest_start(skb, L2TP_ATTR_STATS);
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, tunnel->stats.tx_packets);
- NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, tunnel->stats.tx_bytes);
- NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, tunnel->stats.tx_errors);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, tunnel->stats.rx_packets);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, tunnel->stats.rx_bytes);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, tunnel->stats.rx_seq_discards);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, tunnel->stats.rx_oos_packets);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, tunnel->stats.rx_errors);
+ if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS, tunnel->stats.tx_packets) ||
+ nla_put_u64(skb, L2TP_ATTR_TX_BYTES, tunnel->stats.tx_bytes) ||
+ nla_put_u64(skb, L2TP_ATTR_TX_ERRORS, tunnel->stats.tx_errors) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_PACKETS, tunnel->stats.rx_packets) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_BYTES, tunnel->stats.rx_bytes) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_SEQ_DISCARDS,
+ tunnel->stats.rx_seq_discards) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_OOS_PACKETS,
+ tunnel->stats.rx_oos_packets) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_ERRORS, tunnel->stats.rx_errors))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
sk = tunnel->sock;
@@ -259,13 +263,16 @@
switch (tunnel->encap) {
case L2TP_ENCAPTYPE_UDP:
- NLA_PUT_U16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport));
- NLA_PUT_U16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport));
- NLA_PUT_U8(skb, L2TP_ATTR_UDP_CSUM, (sk->sk_no_check != UDP_CSUM_NOXMIT));
+ if (nla_put_u16(skb, L2TP_ATTR_UDP_SPORT, ntohs(inet->inet_sport)) ||
+ nla_put_u16(skb, L2TP_ATTR_UDP_DPORT, ntohs(inet->inet_dport)) ||
+ nla_put_u8(skb, L2TP_ATTR_UDP_CSUM,
+ (sk->sk_no_check != UDP_CSUM_NOXMIT)))
+ goto nla_put_failure;
/* NOBREAK */
case L2TP_ENCAPTYPE_IP:
- NLA_PUT_BE32(skb, L2TP_ATTR_IP_SADDR, inet->inet_saddr);
- NLA_PUT_BE32(skb, L2TP_ATTR_IP_DADDR, inet->inet_daddr);
+ if (nla_put_be32(skb, L2TP_ATTR_IP_SADDR, inet->inet_saddr) ||
+ nla_put_be32(skb, L2TP_ATTR_IP_DADDR, inet->inet_daddr))
+ goto nla_put_failure;
break;
}
@@ -563,43 +570,50 @@
if (IS_ERR(hdr))
return PTR_ERR(hdr);
- NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id);
- NLA_PUT_U32(skb, L2TP_ATTR_SESSION_ID, session->session_id);
- NLA_PUT_U32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id);
- NLA_PUT_U32(skb, L2TP_ATTR_PEER_SESSION_ID, session->peer_session_id);
- NLA_PUT_U32(skb, L2TP_ATTR_DEBUG, session->debug);
- NLA_PUT_U16(skb, L2TP_ATTR_PW_TYPE, session->pwtype);
- NLA_PUT_U16(skb, L2TP_ATTR_MTU, session->mtu);
- if (session->mru)
- NLA_PUT_U16(skb, L2TP_ATTR_MRU, session->mru);
+ if (nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) ||
+ nla_put_u32(skb, L2TP_ATTR_SESSION_ID, session->session_id) ||
+ nla_put_u32(skb, L2TP_ATTR_PEER_CONN_ID, tunnel->peer_tunnel_id) ||
+ nla_put_u32(skb, L2TP_ATTR_PEER_SESSION_ID,
+ session->peer_session_id) ||
+ nla_put_u32(skb, L2TP_ATTR_DEBUG, session->debug) ||
+ nla_put_u16(skb, L2TP_ATTR_PW_TYPE, session->pwtype) ||
+ nla_put_u16(skb, L2TP_ATTR_MTU, session->mtu) ||
+ (session->mru &&
+ nla_put_u16(skb, L2TP_ATTR_MRU, session->mru)))
+ goto nla_put_failure;
- if (session->ifname && session->ifname[0])
- NLA_PUT_STRING(skb, L2TP_ATTR_IFNAME, session->ifname);
- if (session->cookie_len)
- NLA_PUT(skb, L2TP_ATTR_COOKIE, session->cookie_len, &session->cookie[0]);
- if (session->peer_cookie_len)
- NLA_PUT(skb, L2TP_ATTR_PEER_COOKIE, session->peer_cookie_len, &session->peer_cookie[0]);
- NLA_PUT_U8(skb, L2TP_ATTR_RECV_SEQ, session->recv_seq);
- NLA_PUT_U8(skb, L2TP_ATTR_SEND_SEQ, session->send_seq);
- NLA_PUT_U8(skb, L2TP_ATTR_LNS_MODE, session->lns_mode);
+ if ((session->ifname && session->ifname[0] &&
+ nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) ||
+ (session->cookie_len &&
+ nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len,
+ &session->cookie[0])) ||
+ (session->peer_cookie_len &&
+ nla_put(skb, L2TP_ATTR_PEER_COOKIE, session->peer_cookie_len,
+ &session->peer_cookie[0])) ||
+ nla_put_u8(skb, L2TP_ATTR_RECV_SEQ, session->recv_seq) ||
+ nla_put_u8(skb, L2TP_ATTR_SEND_SEQ, session->send_seq) ||
+ nla_put_u8(skb, L2TP_ATTR_LNS_MODE, session->lns_mode) ||
#ifdef CONFIG_XFRM
- if ((sk) && (sk->sk_policy[0] || sk->sk_policy[1]))
- NLA_PUT_U8(skb, L2TP_ATTR_USING_IPSEC, 1);
+ (((sk) && (sk->sk_policy[0] || sk->sk_policy[1])) &&
+ nla_put_u8(skb, L2TP_ATTR_USING_IPSEC, 1)) ||
#endif
- if (session->reorder_timeout)
- NLA_PUT_MSECS(skb, L2TP_ATTR_RECV_TIMEOUT, session->reorder_timeout);
-
+ (session->reorder_timeout &&
+ nla_put_msecs(skb, L2TP_ATTR_RECV_TIMEOUT, session->reorder_timeout)))
+ goto nla_put_failure;
nest = nla_nest_start(skb, L2TP_ATTR_STATS);
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U64(skb, L2TP_ATTR_TX_PACKETS, session->stats.tx_packets);
- NLA_PUT_U64(skb, L2TP_ATTR_TX_BYTES, session->stats.tx_bytes);
- NLA_PUT_U64(skb, L2TP_ATTR_TX_ERRORS, session->stats.tx_errors);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_PACKETS, session->stats.rx_packets);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_BYTES, session->stats.rx_bytes);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_SEQ_DISCARDS, session->stats.rx_seq_discards);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_OOS_PACKETS, session->stats.rx_oos_packets);
- NLA_PUT_U64(skb, L2TP_ATTR_RX_ERRORS, session->stats.rx_errors);
+ if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS, session->stats.tx_packets) ||
+ nla_put_u64(skb, L2TP_ATTR_TX_BYTES, session->stats.tx_bytes) ||
+ nla_put_u64(skb, L2TP_ATTR_TX_ERRORS, session->stats.tx_errors) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_PACKETS, session->stats.rx_packets) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_BYTES, session->stats.rx_bytes) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_SEQ_DISCARDS,
+ session->stats.rx_seq_discards) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_OOS_PACKETS,
+ session->stats.rx_oos_packets) ||
+ nla_put_u64(skb, L2TP_ATTR_RX_ERRORS, session->stats.rx_errors))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
return genlmsg_end(skb, hdr);
diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c
index a72a4df..7e1b061 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ip.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ip.c
@@ -109,8 +109,9 @@
} else
goto nla_put_failure;
}
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP,
- htonl(map->first_ip + id * map->hosts));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
+ htonl(map->first_ip + id * map->hosts)))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
}
ipset_nest_end(skb, atd);
@@ -194,10 +195,11 @@
} else
goto nla_put_failure;
}
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP,
- htonl(map->first_ip + id * map->hosts));
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(members[id])));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
+ htonl(map->first_ip + id * map->hosts)) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(members[id]))))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
}
ipset_nest_end(skb, adt);
@@ -334,15 +336,16 @@
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested)
goto nla_put_failure;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip));
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
- if (map->netmask != 32)
- NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, map->netmask);
- NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
- NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
- htonl(sizeof(*map) + map->memsize));
- if (with_timeout(map->timeout))
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
+ nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)) ||
+ (map->netmask != 32 &&
+ nla_put_u8(skb, IPSET_ATTR_NETMASK, map->netmask)) ||
+ nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
+ nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
+ htonl(sizeof(*map) + map->memsize)) ||
+ (with_timeout(map->timeout) &&
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
return 0;
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
index 81324c1..0bb16c46 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
@@ -186,11 +186,12 @@
} else
goto nla_put_failure;
}
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP,
- htonl(map->first_ip + id));
- if (elem->match == MAC_FILLED)
- NLA_PUT(skb, IPSET_ATTR_ETHER, ETH_ALEN,
- elem->ether);
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
+ htonl(map->first_ip + id)) ||
+ (elem->match == MAC_FILLED &&
+ nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN,
+ elem->ether)))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
}
ipset_nest_end(skb, atd);
@@ -314,14 +315,16 @@
} else
goto nla_put_failure;
}
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP,
- htonl(map->first_ip + id));
- if (elem->match == MAC_FILLED)
- NLA_PUT(skb, IPSET_ATTR_ETHER, ETH_ALEN,
- elem->ether);
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
+ htonl(map->first_ip + id)) ||
+ (elem->match == MAC_FILLED &&
+ nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN,
+ elem->ether)))
+ goto nla_put_failure;
timeout = elem->match == MAC_UNSET ? elem->timeout
: ip_set_timeout_get(elem->timeout);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(timeout));
+ if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(timeout)))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
}
ipset_nest_end(skb, atd);
@@ -438,14 +441,16 @@
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested)
goto nla_put_failure;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip));
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
- NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
- NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
- htonl(sizeof(*map)
- + (map->last_ip - map->first_ip + 1) * map->dsize));
- if (with_timeout(map->timeout))
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
+ nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)) ||
+ nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
+ nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
+ htonl(sizeof(*map) +
+ ((map->last_ip - map->first_ip + 1) *
+ map->dsize))) ||
+ (with_timeout(map->timeout) &&
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
return 0;
diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c
index 382ec28..b9f1fce 100644
--- a/net/netfilter/ipset/ip_set_bitmap_port.c
+++ b/net/netfilter/ipset/ip_set_bitmap_port.c
@@ -96,8 +96,9 @@
} else
goto nla_put_failure;
}
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT,
- htons(map->first_port + id));
+ if (nla_put_net16(skb, IPSET_ATTR_PORT,
+ htons(map->first_port + id)))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
}
ipset_nest_end(skb, atd);
@@ -183,10 +184,11 @@
} else
goto nla_put_failure;
}
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT,
- htons(map->first_port + id));
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(members[id])));
+ if (nla_put_net16(skb, IPSET_ATTR_PORT,
+ htons(map->first_port + id)) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(members[id]))))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
}
ipset_nest_end(skb, adt);
@@ -320,13 +322,14 @@
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested)
goto nla_put_failure;
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, htons(map->first_port));
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port));
- NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
- NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
- htonl(sizeof(*map) + map->memsize));
- if (with_timeout(map->timeout))
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout));
+ if (nla_put_net16(skb, IPSET_ATTR_PORT, htons(map->first_port)) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port)) ||
+ nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
+ nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
+ htonl(sizeof(*map) + map->memsize)) ||
+ (with_timeout(map->timeout) &&
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
return 0;
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index e6c1c96..eb66b97 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1092,19 +1092,21 @@
ret = -EMSGSIZE;
goto release_refcount;
}
- NLA_PUT_U8(skb, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL);
- NLA_PUT_STRING(skb, IPSET_ATTR_SETNAME, set->name);
+ if (nla_put_u8(skb, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL) ||
+ nla_put_string(skb, IPSET_ATTR_SETNAME, set->name))
+ goto nla_put_failure;
if (dump_flags & IPSET_FLAG_LIST_SETNAME)
goto next_set;
switch (cb->args[2]) {
case 0:
/* Core header data */
- NLA_PUT_STRING(skb, IPSET_ATTR_TYPENAME,
- set->type->name);
- NLA_PUT_U8(skb, IPSET_ATTR_FAMILY,
- set->family);
- NLA_PUT_U8(skb, IPSET_ATTR_REVISION,
- set->revision);
+ if (nla_put_string(skb, IPSET_ATTR_TYPENAME,
+ set->type->name) ||
+ nla_put_u8(skb, IPSET_ATTR_FAMILY,
+ set->family) ||
+ nla_put_u8(skb, IPSET_ATTR_REVISION,
+ set->revision))
+ goto nla_put_failure;
ret = set->variant->head(set, skb);
if (ret < 0)
goto release_refcount;
@@ -1410,11 +1412,12 @@
IPSET_CMD_HEADER);
if (!nlh2)
goto nlmsg_failure;
- NLA_PUT_U8(skb2, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL);
- NLA_PUT_STRING(skb2, IPSET_ATTR_SETNAME, set->name);
- NLA_PUT_STRING(skb2, IPSET_ATTR_TYPENAME, set->type->name);
- NLA_PUT_U8(skb2, IPSET_ATTR_FAMILY, set->family);
- NLA_PUT_U8(skb2, IPSET_ATTR_REVISION, set->revision);
+ if (nla_put_u8(skb2, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL) ||
+ nla_put_string(skb2, IPSET_ATTR_SETNAME, set->name) ||
+ nla_put_string(skb2, IPSET_ATTR_TYPENAME, set->type->name) ||
+ nla_put_u8(skb2, IPSET_ATTR_FAMILY, set->family) ||
+ nla_put_u8(skb2, IPSET_ATTR_REVISION, set->revision))
+ goto nla_put_failure;
nlmsg_end(skb2, nlh2);
ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
@@ -1469,11 +1472,12 @@
IPSET_CMD_TYPE);
if (!nlh2)
goto nlmsg_failure;
- NLA_PUT_U8(skb2, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL);
- NLA_PUT_STRING(skb2, IPSET_ATTR_TYPENAME, typename);
- NLA_PUT_U8(skb2, IPSET_ATTR_FAMILY, family);
- NLA_PUT_U8(skb2, IPSET_ATTR_REVISION, max);
- NLA_PUT_U8(skb2, IPSET_ATTR_REVISION_MIN, min);
+ if (nla_put_u8(skb2, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL) ||
+ nla_put_string(skb2, IPSET_ATTR_TYPENAME, typename) ||
+ nla_put_u8(skb2, IPSET_ATTR_FAMILY, family) ||
+ nla_put_u8(skb2, IPSET_ATTR_REVISION, max) ||
+ nla_put_u8(skb2, IPSET_ATTR_REVISION_MIN, min))
+ goto nla_put_failure;
nlmsg_end(skb2, nlh2);
pr_debug("Send TYPE, nlmsg_len: %u\n", nlh2->nlmsg_len);
@@ -1517,7 +1521,8 @@
IPSET_CMD_PROTOCOL);
if (!nlh2)
goto nlmsg_failure;
- NLA_PUT_U8(skb2, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL);
+ if (nla_put_u8(skb2, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL))
+ goto nla_put_failure;
nlmsg_end(skb2, nlh2);
ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
index 5139dea..507fe93 100644
--- a/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -81,7 +81,8 @@
static inline bool
hash_ip4_data_list(struct sk_buff *skb, const struct hash_ip4_elem *data)
{
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -94,9 +95,10 @@
const struct hash_ip4_telem *tdata =
(const struct hash_ip4_telem *)data;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(tdata->timeout)));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(tdata->timeout))))
+ goto nla_put_failure;
return 0;
@@ -262,7 +264,8 @@
static bool
hash_ip6_data_list(struct sk_buff *skb, const struct hash_ip6_elem *data)
{
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -275,9 +278,10 @@
const struct hash_ip6_telem *e =
(const struct hash_ip6_telem *)data;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(e->timeout)));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(e->timeout))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
index 9c27e24..68f284c 100644
--- a/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -93,9 +93,10 @@
hash_ipport4_data_list(struct sk_buff *skb,
const struct hash_ipport4_elem *data)
{
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -109,12 +110,12 @@
const struct hash_ipport4_telem *tdata =
(const struct hash_ipport4_telem *)data;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(tdata->timeout)));
-
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, tdata->port) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(tdata->timeout))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -308,9 +309,10 @@
hash_ipport6_data_list(struct sk_buff *skb,
const struct hash_ipport6_elem *data)
{
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -324,11 +326,12 @@
const struct hash_ipport6_telem *e =
(const struct hash_ipport6_telem *)data;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(e->timeout)));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(e->timeout))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
index 9134057..1eec4b9 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -94,10 +94,11 @@
hash_ipportip4_data_list(struct sk_buff *skb,
const struct hash_ipportip4_elem *data)
{
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP2, data->ip2);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
+ nla_put_ipaddr4(skb, IPSET_ATTR_IP2, data->ip2) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -111,13 +112,13 @@
const struct hash_ipportip4_telem *tdata =
(const struct hash_ipportip4_telem *)data;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip);
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP2, tdata->ip2);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(tdata->timeout)));
-
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
+ nla_put_ipaddr4(skb, IPSET_ATTR_IP2, tdata->ip2) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, tdata->port) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(tdata->timeout))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -319,10 +320,11 @@
hash_ipportip6_data_list(struct sk_buff *skb,
const struct hash_ipportip6_elem *data)
{
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP2, &data->ip2);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
+ nla_put_ipaddr6(skb, IPSET_ATTR_IP2, &data->ip2.in6) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -336,12 +338,13 @@
const struct hash_ipportip6_telem *e =
(const struct hash_ipportip6_telem *)data;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP2, &data->ip2);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(e->timeout)));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
+ nla_put_ipaddr6(skb, IPSET_ATTR_IP2, &data->ip2.in6) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(e->timeout))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
index 5d05e69..62d66ec 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -124,13 +124,14 @@
{
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP2, data->ip2);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR2, data->cidr + 1);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
+ nla_put_ipaddr4(skb, IPSET_ATTR_IP2, data->ip2) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr + 1) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -145,16 +146,16 @@
(const struct hash_ipportnet4_telem *)data;
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip);
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP2, tdata->ip2);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR2, data->cidr + 1);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(tdata->timeout)));
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
-
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
+ nla_put_ipaddr4(skb, IPSET_ATTR_IP2, tdata->ip2) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, tdata->port) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr + 1) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(tdata->timeout))) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -436,13 +437,14 @@
{
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP2, &data->ip2);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR2, data->cidr + 1);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
+ nla_put_ipaddr6(skb, IPSET_ATTR_IP2, &data->ip2.in6) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr + 1) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -457,15 +459,16 @@
(const struct hash_ipportnet6_telem *)data;
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP2, &data->ip2);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR2, data->cidr + 1);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(e->timeout)));
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
+ nla_put_ipaddr6(skb, IPSET_ATTR_IP2, &data->ip2.in6) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr + 1) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(e->timeout))) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
index 7c3d945..6607a81 100644
--- a/net/netfilter/ipset/ip_set_hash_net.c
+++ b/net/netfilter/ipset/ip_set_hash_net.c
@@ -111,10 +111,11 @@
{
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -128,13 +129,13 @@
(const struct hash_net4_telem *)data;
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, tdata->cidr);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(tdata->timeout)));
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
-
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, tdata->cidr) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(tdata->timeout))) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -339,10 +340,11 @@
{
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -356,12 +358,13 @@
(const struct hash_net6_telem *)data;
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, e->cidr);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(e->timeout)));
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, e->cidr) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(e->timeout))) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index f24037f..6093f3d 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -252,11 +252,12 @@
if (data->nomatch)
flags |= IPSET_FLAG_NOMATCH;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
- NLA_PUT_STRING(skb, IPSET_ATTR_IFACE, data->iface);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
+ nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -273,13 +274,14 @@
if (data->nomatch)
flags |= IPSET_FLAG_NOMATCH;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
- NLA_PUT_STRING(skb, IPSET_ATTR_IFACE, data->iface);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(tdata->timeout)));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
+ nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(tdata->timeout))))
+ goto nla_put_failure;
return 0;
@@ -555,11 +557,12 @@
if (data->nomatch)
flags |= IPSET_FLAG_NOMATCH;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
- NLA_PUT_STRING(skb, IPSET_ATTR_IFACE, data->iface);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
+ nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -576,13 +579,14 @@
if (data->nomatch)
flags |= IPSET_FLAG_NOMATCH;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr);
- NLA_PUT_STRING(skb, IPSET_ATTR_IFACE, data->iface);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(e->timeout)));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
+ nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(e->timeout))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
index ce2e771..ae3c644 100644
--- a/net/netfilter/ipset/ip_set_hash_netport.c
+++ b/net/netfilter/ipset/ip_set_hash_netport.c
@@ -124,12 +124,13 @@
{
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, data->ip);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr + 1);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -144,15 +145,15 @@
(const struct hash_netport4_telem *)data;
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, tdata->ip);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, tdata->port);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr + 1);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(tdata->timeout)));
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
-
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, tdata->port) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(tdata->timeout))) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -402,12 +403,13 @@
{
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &data->ip);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr + 1);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -422,14 +424,15 @@
(const struct hash_netport6_telem *)data;
u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
- NLA_PUT_IPADDR6(skb, IPSET_ATTR_IP, &e->ip);
- NLA_PUT_NET16(skb, IPSET_ATTR_PORT, data->port);
- NLA_PUT_U8(skb, IPSET_ATTR_CIDR, data->cidr + 1);
- NLA_PUT_U8(skb, IPSET_ATTR_PROTO, data->proto);
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(e->timeout)));
- if (flags)
- NLA_PUT_NET32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags));
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
+ nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
+ nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
+ nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
+ htonl(ip_set_timeout_get(e->timeout))) ||
+ (flags &&
+ nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
index 7e095f9..6cb1225 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -402,12 +402,13 @@
nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested)
goto nla_put_failure;
- NLA_PUT_NET32(skb, IPSET_ATTR_SIZE, htonl(map->size));
- if (with_timeout(map->timeout))
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout));
- NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
- NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
- htonl(sizeof(*map) + map->size * map->dsize));
+ if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) ||
+ (with_timeout(map->timeout) &&
+ nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) ||
+ nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
+ nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
+ htonl(sizeof(*map) + map->size * map->dsize)))
+ goto nla_put_failure;
ipset_nest_end(skb, nested);
return 0;
@@ -442,13 +443,15 @@
} else
goto nla_put_failure;
}
- NLA_PUT_STRING(skb, IPSET_ATTR_NAME,
- ip_set_name_byindex(e->id));
+ if (nla_put_string(skb, IPSET_ATTR_NAME,
+ ip_set_name_byindex(e->id)))
+ goto nla_put_failure;
if (with_timeout(map->timeout)) {
const struct set_telem *te =
(const struct set_telem *) e;
- NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT,
- htonl(ip_set_timeout_get(te->timeout)));
+ __be32 to = htonl(ip_set_timeout_get(te->timeout));
+ if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT, to))
+ goto nla_put_failure;
}
ipset_nest_end(skb, nested);
}
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index b3afe18..964d426 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -2816,17 +2816,17 @@
ip_vs_copy_stats(&ustats, stats);
- NLA_PUT_U32(skb, IPVS_STATS_ATTR_CONNS, ustats.conns);
- NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPKTS, ustats.inpkts);
- NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPKTS, ustats.outpkts);
- NLA_PUT_U64(skb, IPVS_STATS_ATTR_INBYTES, ustats.inbytes);
- NLA_PUT_U64(skb, IPVS_STATS_ATTR_OUTBYTES, ustats.outbytes);
- NLA_PUT_U32(skb, IPVS_STATS_ATTR_CPS, ustats.cps);
- NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPPS, ustats.inpps);
- NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPPS, ustats.outpps);
- NLA_PUT_U32(skb, IPVS_STATS_ATTR_INBPS, ustats.inbps);
- NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTBPS, ustats.outbps);
-
+ if (nla_put_u32(skb, IPVS_STATS_ATTR_CONNS, ustats.conns) ||
+ nla_put_u32(skb, IPVS_STATS_ATTR_INPKTS, ustats.inpkts) ||
+ nla_put_u32(skb, IPVS_STATS_ATTR_OUTPKTS, ustats.outpkts) ||
+ nla_put_u64(skb, IPVS_STATS_ATTR_INBYTES, ustats.inbytes) ||
+ nla_put_u64(skb, IPVS_STATS_ATTR_OUTBYTES, ustats.outbytes) ||
+ nla_put_u32(skb, IPVS_STATS_ATTR_CPS, ustats.cps) ||
+ nla_put_u32(skb, IPVS_STATS_ATTR_INPPS, ustats.inpps) ||
+ nla_put_u32(skb, IPVS_STATS_ATTR_OUTPPS, ustats.outpps) ||
+ nla_put_u32(skb, IPVS_STATS_ATTR_INBPS, ustats.inbps) ||
+ nla_put_u32(skb, IPVS_STATS_ATTR_OUTBPS, ustats.outbps))
+ goto nla_put_failure;
nla_nest_end(skb, nl_stats);
return 0;
@@ -2847,23 +2847,25 @@
if (!nl_service)
return -EMSGSIZE;
- NLA_PUT_U16(skb, IPVS_SVC_ATTR_AF, svc->af);
-
+ if (nla_put_u16(skb, IPVS_SVC_ATTR_AF, svc->af))
+ goto nla_put_failure;
if (svc->fwmark) {
- NLA_PUT_U32(skb, IPVS_SVC_ATTR_FWMARK, svc->fwmark);
+ if (nla_put_u32(skb, IPVS_SVC_ATTR_FWMARK, svc->fwmark))
+ goto nla_put_failure;
} else {
- NLA_PUT_U16(skb, IPVS_SVC_ATTR_PROTOCOL, svc->protocol);
- NLA_PUT(skb, IPVS_SVC_ATTR_ADDR, sizeof(svc->addr), &svc->addr);
- NLA_PUT_U16(skb, IPVS_SVC_ATTR_PORT, svc->port);
+ if (nla_put_u16(skb, IPVS_SVC_ATTR_PROTOCOL, svc->protocol) ||
+ nla_put(skb, IPVS_SVC_ATTR_ADDR, sizeof(svc->addr), &svc->addr) ||
+ nla_put_u16(skb, IPVS_SVC_ATTR_PORT, svc->port))
+ goto nla_put_failure;
}
- NLA_PUT_STRING(skb, IPVS_SVC_ATTR_SCHED_NAME, svc->scheduler->name);
- if (svc->pe)
- NLA_PUT_STRING(skb, IPVS_SVC_ATTR_PE_NAME, svc->pe->name);
- NLA_PUT(skb, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags);
- NLA_PUT_U32(skb, IPVS_SVC_ATTR_TIMEOUT, svc->timeout / HZ);
- NLA_PUT_U32(skb, IPVS_SVC_ATTR_NETMASK, svc->netmask);
-
+ if (nla_put_string(skb, IPVS_SVC_ATTR_SCHED_NAME, svc->scheduler->name) ||
+ (svc->pe &&
+ nla_put_string(skb, IPVS_SVC_ATTR_PE_NAME, svc->pe->name)) ||
+ nla_put(skb, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags) ||
+ nla_put_u32(skb, IPVS_SVC_ATTR_TIMEOUT, svc->timeout / HZ) ||
+ nla_put_u32(skb, IPVS_SVC_ATTR_NETMASK, svc->netmask))
+ goto nla_put_failure;
if (ip_vs_genl_fill_stats(skb, IPVS_SVC_ATTR_STATS, &svc->stats))
goto nla_put_failure;
@@ -3038,21 +3040,22 @@
if (!nl_dest)
return -EMSGSIZE;
- NLA_PUT(skb, IPVS_DEST_ATTR_ADDR, sizeof(dest->addr), &dest->addr);
- NLA_PUT_U16(skb, IPVS_DEST_ATTR_PORT, dest->port);
-
- NLA_PUT_U32(skb, IPVS_DEST_ATTR_FWD_METHOD,
- atomic_read(&dest->conn_flags) & IP_VS_CONN_F_FWD_MASK);
- NLA_PUT_U32(skb, IPVS_DEST_ATTR_WEIGHT, atomic_read(&dest->weight));
- NLA_PUT_U32(skb, IPVS_DEST_ATTR_U_THRESH, dest->u_threshold);
- NLA_PUT_U32(skb, IPVS_DEST_ATTR_L_THRESH, dest->l_threshold);
- NLA_PUT_U32(skb, IPVS_DEST_ATTR_ACTIVE_CONNS,
- atomic_read(&dest->activeconns));
- NLA_PUT_U32(skb, IPVS_DEST_ATTR_INACT_CONNS,
- atomic_read(&dest->inactconns));
- NLA_PUT_U32(skb, IPVS_DEST_ATTR_PERSIST_CONNS,
- atomic_read(&dest->persistconns));
-
+ if (nla_put(skb, IPVS_DEST_ATTR_ADDR, sizeof(dest->addr), &dest->addr) ||
+ nla_put_u16(skb, IPVS_DEST_ATTR_PORT, dest->port) ||
+ nla_put_u32(skb, IPVS_DEST_ATTR_FWD_METHOD,
+ (atomic_read(&dest->conn_flags) &
+ IP_VS_CONN_F_FWD_MASK)) ||
+ nla_put_u32(skb, IPVS_DEST_ATTR_WEIGHT,
+ atomic_read(&dest->weight)) ||
+ nla_put_u32(skb, IPVS_DEST_ATTR_U_THRESH, dest->u_threshold) ||
+ nla_put_u32(skb, IPVS_DEST_ATTR_L_THRESH, dest->l_threshold) ||
+ nla_put_u32(skb, IPVS_DEST_ATTR_ACTIVE_CONNS,
+ atomic_read(&dest->activeconns)) ||
+ nla_put_u32(skb, IPVS_DEST_ATTR_INACT_CONNS,
+ atomic_read(&dest->inactconns)) ||
+ nla_put_u32(skb, IPVS_DEST_ATTR_PERSIST_CONNS,
+ atomic_read(&dest->persistconns)))
+ goto nla_put_failure;
if (ip_vs_genl_fill_stats(skb, IPVS_DEST_ATTR_STATS, &dest->stats))
goto nla_put_failure;
@@ -3181,10 +3184,10 @@
if (!nl_daemon)
return -EMSGSIZE;
- NLA_PUT_U32(skb, IPVS_DAEMON_ATTR_STATE, state);
- NLA_PUT_STRING(skb, IPVS_DAEMON_ATTR_MCAST_IFN, mcast_ifn);
- NLA_PUT_U32(skb, IPVS_DAEMON_ATTR_SYNC_ID, syncid);
-
+ if (nla_put_u32(skb, IPVS_DAEMON_ATTR_STATE, state) ||
+ nla_put_string(skb, IPVS_DAEMON_ATTR_MCAST_IFN, mcast_ifn) ||
+ nla_put_u32(skb, IPVS_DAEMON_ATTR_SYNC_ID, syncid))
+ goto nla_put_failure;
nla_nest_end(skb, nl_daemon);
return 0;
@@ -3473,21 +3476,26 @@
__ip_vs_get_timeouts(net, &t);
#ifdef CONFIG_IP_VS_PROTO_TCP
- NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP, t.tcp_timeout);
- NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP_FIN,
- t.tcp_fin_timeout);
+ if (nla_put_u32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP,
+ t.tcp_timeout) ||
+ nla_put_u32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP_FIN,
+ t.tcp_fin_timeout))
+ goto nla_put_failure;
#endif
#ifdef CONFIG_IP_VS_PROTO_UDP
- NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_UDP, t.udp_timeout);
+ if (nla_put_u32(msg, IPVS_CMD_ATTR_TIMEOUT_UDP, t.udp_timeout))
+ goto nla_put_failure;
#endif
break;
}
case IPVS_CMD_GET_INFO:
- NLA_PUT_U32(msg, IPVS_INFO_ATTR_VERSION, IP_VS_VERSION_CODE);
- NLA_PUT_U32(msg, IPVS_INFO_ATTR_CONN_TAB_SIZE,
- ip_vs_conn_tab_size);
+ if (nla_put_u32(msg, IPVS_INFO_ATTR_VERSION,
+ IP_VS_VERSION_CODE) ||
+ nla_put_u32(msg, IPVS_INFO_ATTR_CONN_TAB_SIZE,
+ ip_vs_conn_tab_size))
+ goto nla_put_failure;
break;
}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 3cc4487..6cd8e32 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1152,8 +1152,9 @@
int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple)
{
- NLA_PUT_BE16(skb, CTA_PROTO_SRC_PORT, tuple->src.u.tcp.port);
- NLA_PUT_BE16(skb, CTA_PROTO_DST_PORT, tuple->dst.u.tcp.port);
+ if (nla_put_be16(skb, CTA_PROTO_SRC_PORT, tuple->src.u.tcp.port) ||
+ nla_put_be16(skb, CTA_PROTO_DST_PORT, tuple->dst.u.tcp.port))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index ca7e835..462ec2d 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -66,7 +66,8 @@
nest_parms = nla_nest_start(skb, CTA_TUPLE_PROTO | NLA_F_NESTED);
if (!nest_parms)
goto nla_put_failure;
- NLA_PUT_U8(skb, CTA_PROTO_NUM, tuple->dst.protonum);
+ if (nla_put_u8(skb, CTA_PROTO_NUM, tuple->dst.protonum))
+ goto nla_put_failure;
if (likely(l4proto->tuple_to_nlattr))
ret = l4proto->tuple_to_nlattr(skb, tuple);
@@ -126,7 +127,8 @@
static inline int
ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
{
- NLA_PUT_BE32(skb, CTA_STATUS, htonl(ct->status));
+ if (nla_put_be32(skb, CTA_STATUS, htonl(ct->status)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -141,7 +143,8 @@
if (timeout < 0)
timeout = 0;
- NLA_PUT_BE32(skb, CTA_TIMEOUT, htonl(timeout));
+ if (nla_put_be32(skb, CTA_TIMEOUT, htonl(timeout)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -190,7 +193,8 @@
nest_helper = nla_nest_start(skb, CTA_HELP | NLA_F_NESTED);
if (!nest_helper)
goto nla_put_failure;
- NLA_PUT_STRING(skb, CTA_HELP_NAME, helper->name);
+ if (nla_put_string(skb, CTA_HELP_NAME, helper->name))
+ goto nla_put_failure;
if (helper->to_nlattr)
helper->to_nlattr(skb, ct);
@@ -214,8 +218,9 @@
if (!nest_count)
goto nla_put_failure;
- NLA_PUT_BE64(skb, CTA_COUNTERS_PACKETS, cpu_to_be64(pkts));
- NLA_PUT_BE64(skb, CTA_COUNTERS_BYTES, cpu_to_be64(bytes));
+ if (nla_put_be64(skb, CTA_COUNTERS_PACKETS, cpu_to_be64(pkts)) ||
+ nla_put_be64(skb, CTA_COUNTERS_BYTES, cpu_to_be64(bytes)))
+ goto nla_put_failure;
nla_nest_end(skb, nest_count);
@@ -260,11 +265,10 @@
if (!nest_count)
goto nla_put_failure;
- NLA_PUT_BE64(skb, CTA_TIMESTAMP_START, cpu_to_be64(tstamp->start));
- if (tstamp->stop != 0) {
- NLA_PUT_BE64(skb, CTA_TIMESTAMP_STOP,
- cpu_to_be64(tstamp->stop));
- }
+ if (nla_put_be64(skb, CTA_TIMESTAMP_START, cpu_to_be64(tstamp->start)) ||
+ (tstamp->stop != 0 && nla_put_be64(skb, CTA_TIMESTAMP_STOP,
+ cpu_to_be64(tstamp->stop))))
+ goto nla_put_failure;
nla_nest_end(skb, nest_count);
return 0;
@@ -277,7 +281,8 @@
static inline int
ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
{
- NLA_PUT_BE32(skb, CTA_MARK, htonl(ct->mark));
+ if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -304,7 +309,8 @@
if (!nest_secctx)
goto nla_put_failure;
- NLA_PUT_STRING(skb, CTA_SECCTX_NAME, secctx);
+ if (nla_put_string(skb, CTA_SECCTX_NAME, secctx))
+ goto nla_put_failure;
nla_nest_end(skb, nest_secctx);
ret = 0;
@@ -349,12 +355,13 @@
if (!nest_parms)
goto nla_put_failure;
- NLA_PUT_BE32(skb, CTA_NAT_SEQ_CORRECTION_POS,
- htonl(natseq->correction_pos));
- NLA_PUT_BE32(skb, CTA_NAT_SEQ_OFFSET_BEFORE,
- htonl(natseq->offset_before));
- NLA_PUT_BE32(skb, CTA_NAT_SEQ_OFFSET_AFTER,
- htonl(natseq->offset_after));
+ if (nla_put_be32(skb, CTA_NAT_SEQ_CORRECTION_POS,
+ htonl(natseq->correction_pos)) ||
+ nla_put_be32(skb, CTA_NAT_SEQ_OFFSET_BEFORE,
+ htonl(natseq->offset_before)) ||
+ nla_put_be32(skb, CTA_NAT_SEQ_OFFSET_AFTER,
+ htonl(natseq->offset_after)))
+ goto nla_put_failure;
nla_nest_end(skb, nest_parms);
@@ -390,7 +397,8 @@
static inline int
ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
{
- NLA_PUT_BE32(skb, CTA_ID, htonl((unsigned long)ct));
+ if (nla_put_be32(skb, CTA_ID, htonl((unsigned long)ct)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -400,7 +408,8 @@
static inline int
ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
{
- NLA_PUT_BE32(skb, CTA_USE, htonl(atomic_read(&ct->ct_general.use)));
+ if (nla_put_be32(skb, CTA_USE, htonl(atomic_read(&ct->ct_general.use))))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -440,8 +449,9 @@
goto nla_put_failure;
nla_nest_end(skb, nest_parms);
- if (nf_ct_zone(ct))
- NLA_PUT_BE16(skb, CTA_ZONE, htons(nf_ct_zone(ct)));
+ if (nf_ct_zone(ct) &&
+ nla_put_be16(skb, CTA_ZONE, htons(nf_ct_zone(ct))))
+ goto nla_put_failure;
if (ctnetlink_dump_status(skb, ct) < 0 ||
ctnetlink_dump_timeout(skb, ct) < 0 ||
@@ -617,8 +627,9 @@
goto nla_put_failure;
nla_nest_end(skb, nest_parms);
- if (nf_ct_zone(ct))
- NLA_PUT_BE16(skb, CTA_ZONE, htons(nf_ct_zone(ct)));
+ if (nf_ct_zone(ct) &&
+ nla_put_be16(skb, CTA_ZONE, htons(nf_ct_zone(ct))))
+ goto nla_put_failure;
if (ctnetlink_dump_id(skb, ct) < 0)
goto nla_put_failure;
@@ -1705,7 +1716,8 @@
if (!nest_parms)
goto nla_put_failure;
- NLA_PUT_BE32(skb, CTA_EXPECT_NAT_DIR, htonl(exp->dir));
+ if (nla_put_be32(skb, CTA_EXPECT_NAT_DIR, htonl(exp->dir)))
+ goto nla_put_failure;
nat_tuple.src.l3num = nf_ct_l3num(master);
nat_tuple.src.u3.ip = exp->saved_ip;
@@ -1718,21 +1730,24 @@
nla_nest_end(skb, nest_parms);
}
#endif
- NLA_PUT_BE32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout));
- NLA_PUT_BE32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp));
- NLA_PUT_BE32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags));
- NLA_PUT_BE32(skb, CTA_EXPECT_CLASS, htonl(exp->class));
+ if (nla_put_be32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)) ||
+ nla_put_be32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp)) ||
+ nla_put_be32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)) ||
+ nla_put_be32(skb, CTA_EXPECT_CLASS, htonl(exp->class)))
+ goto nla_put_failure;
help = nfct_help(master);
if (help) {
struct nf_conntrack_helper *helper;
helper = rcu_dereference(help->helper);
- if (helper)
- NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name);
+ if (helper &&
+ nla_put_string(skb, CTA_EXPECT_HELP_NAME, helper->name))
+ goto nla_put_failure;
}
expfn = nf_ct_helper_expectfn_find_by_symbol(exp->expectfn);
- if (expfn != NULL)
- NLA_PUT_STRING(skb, CTA_EXPECT_FN, expfn->name);
+ if (expfn != NULL &&
+ nla_put_string(skb, CTA_EXPECT_FN, expfn->name))
+ goto nla_put_failure;
return 0;
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index 24fdce2..a58998d 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -643,11 +643,12 @@
nest_parms = nla_nest_start(skb, CTA_PROTOINFO_DCCP | NLA_F_NESTED);
if (!nest_parms)
goto nla_put_failure;
- NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state);
- NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_ROLE,
- ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]);
- NLA_PUT_BE64(skb, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
- cpu_to_be64(ct->proto.dccp.handshake_seq));
+ if (nla_put_u8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state) ||
+ nla_put_u8(skb, CTA_PROTOINFO_DCCP_ROLE,
+ ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]) ||
+ nla_put_be64(skb, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
+ cpu_to_be64(ct->proto.dccp.handshake_seq)))
+ goto nla_put_failure;
nla_nest_end(skb, nest_parms);
spin_unlock_bh(&ct->lock);
return 0;
@@ -739,9 +740,10 @@
const unsigned int *timeouts = data;
int i;
- for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++)
- NLA_PUT_BE32(skb, i, htonl(timeouts[i] / HZ));
-
+ for (i=CTA_TIMEOUT_DCCP_UNSPEC+1; i<CTA_TIMEOUT_DCCP_MAX+1; i++) {
+ if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
+ goto nla_put_failure;
+ }
return 0;
nla_put_failure:
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index 835e24c..d8923d5 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -90,7 +90,8 @@
{
const unsigned int *timeout = data;
- NLA_PUT_BE32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ));
+ if (nla_put_be32(skb, CTA_TIMEOUT_GENERIC_TIMEOUT, htonl(*timeout / HZ)))
+ goto nla_put_failure;
return 0;
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 659648c..4bf6b4e 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -321,10 +321,11 @@
{
const unsigned int *timeouts = data;
- NLA_PUT_BE32(skb, CTA_TIMEOUT_GRE_UNREPLIED,
- htonl(timeouts[GRE_CT_UNREPLIED] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_GRE_REPLIED,
- htonl(timeouts[GRE_CT_REPLIED] / HZ));
+ if (nla_put_be32(skb, CTA_TIMEOUT_GRE_UNREPLIED,
+ htonl(timeouts[GRE_CT_UNREPLIED] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_GRE_REPLIED,
+ htonl(timeouts[GRE_CT_REPLIED] / HZ)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 72b5088..996db2f 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -482,15 +482,12 @@
if (!nest_parms)
goto nla_put_failure;
- NLA_PUT_U8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state);
-
- NLA_PUT_BE32(skb,
- CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
- ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]);
-
- NLA_PUT_BE32(skb,
- CTA_PROTOINFO_SCTP_VTAG_REPLY,
- ct->proto.sctp.vtag[IP_CT_DIR_REPLY]);
+ if (nla_put_u8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state) ||
+ nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
+ ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]) ||
+ nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_REPLY,
+ ct->proto.sctp.vtag[IP_CT_DIR_REPLY]))
+ goto nla_put_failure;
spin_unlock_bh(&ct->lock);
@@ -578,9 +575,10 @@
const unsigned int *timeouts = data;
int i;
- for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++)
- NLA_PUT_BE32(skb, i, htonl(timeouts[i] / HZ));
-
+ for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
+ if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
+ goto nla_put_failure;
+ }
return 0;
nla_put_failure:
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 361eade..cc558162 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1147,21 +1147,22 @@
if (!nest_parms)
goto nla_put_failure;
- NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_STATE, ct->proto.tcp.state);
-
- NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
- ct->proto.tcp.seen[0].td_scale);
-
- NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY,
- ct->proto.tcp.seen[1].td_scale);
+ if (nla_put_u8(skb, CTA_PROTOINFO_TCP_STATE, ct->proto.tcp.state) ||
+ nla_put_u8(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
+ ct->proto.tcp.seen[0].td_scale) ||
+ nla_put_u8(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY,
+ ct->proto.tcp.seen[1].td_scale))
+ goto nla_put_failure;
tmp.flags = ct->proto.tcp.seen[0].flags;
- NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
- sizeof(struct nf_ct_tcp_flags), &tmp);
+ if (nla_put(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
+ sizeof(struct nf_ct_tcp_flags), &tmp))
+ goto nla_put_failure;
tmp.flags = ct->proto.tcp.seen[1].flags;
- NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
- sizeof(struct nf_ct_tcp_flags), &tmp);
+ if (nla_put(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
+ sizeof(struct nf_ct_tcp_flags), &tmp))
+ goto nla_put_failure;
spin_unlock_bh(&ct->lock);
nla_nest_end(skb, nest_parms);
@@ -1310,28 +1311,29 @@
{
const unsigned int *timeouts = data;
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_SYN_SENT,
- htonl(timeouts[TCP_CONNTRACK_SYN_SENT] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_SYN_RECV,
- htonl(timeouts[TCP_CONNTRACK_SYN_RECV] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_ESTABLISHED,
- htonl(timeouts[TCP_CONNTRACK_ESTABLISHED] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_FIN_WAIT,
- htonl(timeouts[TCP_CONNTRACK_FIN_WAIT] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_CLOSE_WAIT,
- htonl(timeouts[TCP_CONNTRACK_CLOSE_WAIT] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_LAST_ACK,
- htonl(timeouts[TCP_CONNTRACK_LAST_ACK] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_TIME_WAIT,
- htonl(timeouts[TCP_CONNTRACK_TIME_WAIT] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_CLOSE,
- htonl(timeouts[TCP_CONNTRACK_CLOSE] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_SYN_SENT2,
- htonl(timeouts[TCP_CONNTRACK_SYN_SENT2] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_RETRANS,
- htonl(timeouts[TCP_CONNTRACK_RETRANS] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_TCP_UNACK,
- htonl(timeouts[TCP_CONNTRACK_UNACK] / HZ));
+ if (nla_put_be32(skb, CTA_TIMEOUT_TCP_SYN_SENT,
+ htonl(timeouts[TCP_CONNTRACK_SYN_SENT] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_SYN_RECV,
+ htonl(timeouts[TCP_CONNTRACK_SYN_RECV] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_ESTABLISHED,
+ htonl(timeouts[TCP_CONNTRACK_ESTABLISHED] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_FIN_WAIT,
+ htonl(timeouts[TCP_CONNTRACK_FIN_WAIT] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_CLOSE_WAIT,
+ htonl(timeouts[TCP_CONNTRACK_CLOSE_WAIT] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_LAST_ACK,
+ htonl(timeouts[TCP_CONNTRACK_LAST_ACK] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_TIME_WAIT,
+ htonl(timeouts[TCP_CONNTRACK_TIME_WAIT] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_CLOSE,
+ htonl(timeouts[TCP_CONNTRACK_CLOSE] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_SYN_SENT2,
+ htonl(timeouts[TCP_CONNTRACK_SYN_SENT2] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_RETRANS,
+ htonl(timeouts[TCP_CONNTRACK_RETRANS] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_TCP_UNACK,
+ htonl(timeouts[TCP_CONNTRACK_UNACK] / HZ)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index a9073dc..7259a6b 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -181,10 +181,11 @@
{
const unsigned int *timeouts = data;
- NLA_PUT_BE32(skb, CTA_TIMEOUT_UDP_UNREPLIED,
- htonl(timeouts[UDP_CT_UNREPLIED] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_UDP_REPLIED,
- htonl(timeouts[UDP_CT_REPLIED] / HZ));
+ if (nla_put_be32(skb, CTA_TIMEOUT_UDP_UNREPLIED,
+ htonl(timeouts[UDP_CT_UNREPLIED] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_UDP_REPLIED,
+ htonl(timeouts[UDP_CT_REPLIED] / HZ)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index e060639..4d60a53 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -185,10 +185,11 @@
{
const unsigned int *timeouts = data;
- NLA_PUT_BE32(skb, CTA_TIMEOUT_UDPLITE_UNREPLIED,
- htonl(timeouts[UDPLITE_CT_UNREPLIED] / HZ));
- NLA_PUT_BE32(skb, CTA_TIMEOUT_UDPLITE_REPLIED,
- htonl(timeouts[UDPLITE_CT_REPLIED] / HZ));
+ if (nla_put_be32(skb, CTA_TIMEOUT_UDPLITE_UNREPLIED,
+ htonl(timeouts[UDPLITE_CT_UNREPLIED] / HZ)) ||
+ nla_put_be32(skb, CTA_TIMEOUT_UDPLITE_REPLIED,
+ htonl(timeouts[UDPLITE_CT_REPLIED] / HZ)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index d98c868..b2e7310 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -109,7 +109,8 @@
nfmsg->version = NFNETLINK_V0;
nfmsg->res_id = 0;
- NLA_PUT_STRING(skb, NFACCT_NAME, acct->name);
+ if (nla_put_string(skb, NFACCT_NAME, acct->name))
+ goto nla_put_failure;
if (type == NFNL_MSG_ACCT_GET_CTRZERO) {
pkts = atomic64_xchg(&acct->pkts, 0);
@@ -118,9 +119,10 @@
pkts = atomic64_read(&acct->pkts);
bytes = atomic64_read(&acct->bytes);
}
- NLA_PUT_BE64(skb, NFACCT_PKTS, cpu_to_be64(pkts));
- NLA_PUT_BE64(skb, NFACCT_BYTES, cpu_to_be64(bytes));
- NLA_PUT_BE32(skb, NFACCT_USE, htonl(atomic_read(&acct->refcnt)));
+ if (nla_put_be64(skb, NFACCT_PKTS, cpu_to_be64(pkts)) ||
+ nla_put_be64(skb, NFACCT_BYTES, cpu_to_be64(bytes)) ||
+ nla_put_be32(skb, NFACCT_USE, htonl(atomic_read(&acct->refcnt))))
+ goto nla_put_failure;
nlmsg_end(skb, nlh);
return skb->len;
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 2b9e79f..3e65528 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -170,11 +170,12 @@
nfmsg->version = NFNETLINK_V0;
nfmsg->res_id = 0;
- NLA_PUT_STRING(skb, CTA_TIMEOUT_NAME, timeout->name);
- NLA_PUT_BE16(skb, CTA_TIMEOUT_L3PROTO, htons(timeout->l3num));
- NLA_PUT_U8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4proto->l4proto);
- NLA_PUT_BE32(skb, CTA_TIMEOUT_USE,
- htonl(atomic_read(&timeout->refcnt)));
+ if (nla_put_string(skb, CTA_TIMEOUT_NAME, timeout->name) ||
+ nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(timeout->l3num)) ||
+ nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, timeout->l4proto->l4proto) ||
+ nla_put_be32(skb, CTA_TIMEOUT_USE,
+ htonl(atomic_read(&timeout->refcnt))))
+ goto nla_put_failure;
if (likely(l4proto->ctnl_timeout.obj_to_nlattr)) {
struct nlattr *nest_parms;
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 66b2c54..3c3cfc0 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -391,67 +391,78 @@
pmsg.hw_protocol = skb->protocol;
pmsg.hook = hooknum;
- NLA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg);
+ if (nla_put(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg))
+ goto nla_put_failure;
- if (prefix)
- NLA_PUT(inst->skb, NFULA_PREFIX, plen, prefix);
+ if (prefix &&
+ nla_put(inst->skb, NFULA_PREFIX, plen, prefix))
+ goto nla_put_failure;
if (indev) {
#ifndef CONFIG_BRIDGE_NETFILTER
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV,
- htonl(indev->ifindex));
+ if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
+ htonl(indev->ifindex)))
+ goto nla_put_failure;
#else
if (pf == PF_BRIDGE) {
/* Case 1: outdev is physical input device, we need to
* look for bridge group (when called from
* netfilter_bridge) */
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
- htonl(indev->ifindex));
+ if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
+ htonl(indev->ifindex)) ||
/* this is the bridge group "brX" */
/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV,
- htonl(br_port_get_rcu(indev)->br->dev->ifindex));
+ nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
+ htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
+ goto nla_put_failure;
} else {
/* Case 2: indev is bridge group, we need to look for
* physical device (when called from ipv4) */
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV,
- htonl(indev->ifindex));
- if (skb->nf_bridge && skb->nf_bridge->physindev)
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
- htonl(skb->nf_bridge->physindev->ifindex));
+ if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV,
+ htonl(indev->ifindex)))
+ goto nla_put_failure;
+ if (skb->nf_bridge && skb->nf_bridge->physindev &&
+ nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
+ htonl(skb->nf_bridge->physindev->ifindex)))
+ goto nla_put_failure;
}
#endif
}
if (outdev) {
#ifndef CONFIG_BRIDGE_NETFILTER
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
- htonl(outdev->ifindex));
+ if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
+ htonl(outdev->ifindex)))
+ goto nla_put_failure;
#else
if (pf == PF_BRIDGE) {
/* Case 1: outdev is physical output device, we need to
* look for bridge group (when called from
* netfilter_bridge) */
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
- htonl(outdev->ifindex));
+ if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
+ htonl(outdev->ifindex)) ||
/* this is the bridge group "brX" */
/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
- htonl(br_port_get_rcu(outdev)->br->dev->ifindex));
+ nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
+ htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
+ goto nla_put_failure;
} else {
/* Case 2: indev is a bridge group, we need to look
* for physical device (when called from ipv4) */
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
- htonl(outdev->ifindex));
- if (skb->nf_bridge && skb->nf_bridge->physoutdev)
- NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
- htonl(skb->nf_bridge->physoutdev->ifindex));
+ if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV,
+ htonl(outdev->ifindex)))
+ goto nla_put_failure;
+ if (skb->nf_bridge && skb->nf_bridge->physoutdev &&
+ nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
+ htonl(skb->nf_bridge->physoutdev->ifindex)))
+ goto nla_put_failure;
}
#endif
}
- if (skb->mark)
- NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark));
+ if (skb->mark &&
+ nla_put_be32(inst->skb, NFULA_MARK, htonl(skb->mark)))
+ goto nla_put_failure;
if (indev && skb->dev &&
skb->mac_header != skb->network_header) {
@@ -459,16 +470,18 @@
int len = dev_parse_header(skb, phw.hw_addr);
if (len > 0) {
phw.hw_addrlen = htons(len);
- NLA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw);
+ if (nla_put(inst->skb, NFULA_HWADDR, sizeof(phw), &phw))
+ goto nla_put_failure;
}
}
if (indev && skb_mac_header_was_set(skb)) {
- NLA_PUT_BE16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type));
- NLA_PUT_BE16(inst->skb, NFULA_HWLEN,
- htons(skb->dev->hard_header_len));
- NLA_PUT(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len,
- skb_mac_header(skb));
+ if (nla_put_be32(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) ||
+ nla_put_be16(inst->skb, NFULA_HWLEN,
+ htons(skb->dev->hard_header_len)) ||
+ nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len,
+ skb_mac_header(skb)))
+ goto nla_put_failure;
}
if (skb->tstamp.tv64) {
@@ -477,7 +490,8 @@
ts.sec = cpu_to_be64(tv.tv_sec);
ts.usec = cpu_to_be64(tv.tv_usec);
- NLA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts);
+ if (nla_put(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts))
+ goto nla_put_failure;
}
/* UID */
@@ -487,22 +501,24 @@
struct file *file = skb->sk->sk_socket->file;
__be32 uid = htonl(file->f_cred->fsuid);
__be32 gid = htonl(file->f_cred->fsgid);
- /* need to unlock here since NLA_PUT may goto */
read_unlock_bh(&skb->sk->sk_callback_lock);
- NLA_PUT_BE32(inst->skb, NFULA_UID, uid);
- NLA_PUT_BE32(inst->skb, NFULA_GID, gid);
+ if (nla_put_be32(inst->skb, NFULA_UID, uid) ||
+ nla_put_be32(inst->skb, NFULA_GID, gid))
+ goto nla_put_failure;
} else
read_unlock_bh(&skb->sk->sk_callback_lock);
}
/* local sequence number */
- if (inst->flags & NFULNL_CFG_F_SEQ)
- NLA_PUT_BE32(inst->skb, NFULA_SEQ, htonl(inst->seq++));
+ if ((inst->flags & NFULNL_CFG_F_SEQ) &&
+ nla_put_be32(inst->skb, NFULA_SEQ, htonl(inst->seq++)))
+ goto nla_put_failure;
/* global sequence number */
- if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
- NLA_PUT_BE32(inst->skb, NFULA_SEQ_GLOBAL,
- htonl(atomic_inc_return(&global_seq)));
+ if ((inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) &&
+ nla_put_be32(inst->skb, NFULA_SEQ_GLOBAL,
+ htonl(atomic_inc_return(&global_seq))))
+ goto nla_put_failure;
if (data_len) {
struct nlattr *nla;
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index a80b0cb..8d6bcf3 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -288,58 +288,67 @@
indev = entry->indev;
if (indev) {
#ifndef CONFIG_BRIDGE_NETFILTER
- NLA_PUT_BE32(skb, NFQA_IFINDEX_INDEV, htonl(indev->ifindex));
+ if (nla_put_be32(skb, NFQA_IFINDEX_INDEV, htonl(indev->ifindex)))
+ goto nla_put_failure;
#else
if (entry->pf == PF_BRIDGE) {
/* Case 1: indev is physical input device, we need to
* look for bridge group (when called from
* netfilter_bridge) */
- NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSINDEV,
- htonl(indev->ifindex));
+ if (nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
+ htonl(indev->ifindex)) ||
/* this is the bridge group "brX" */
/* rcu_read_lock()ed by __nf_queue */
- NLA_PUT_BE32(skb, NFQA_IFINDEX_INDEV,
- htonl(br_port_get_rcu(indev)->br->dev->ifindex));
+ nla_put_be32(skb, NFQA_IFINDEX_INDEV,
+ htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
+ goto nla_put_failure;
} else {
/* Case 2: indev is bridge group, we need to look for
* physical device (when called from ipv4) */
- NLA_PUT_BE32(skb, NFQA_IFINDEX_INDEV,
- htonl(indev->ifindex));
- if (entskb->nf_bridge && entskb->nf_bridge->physindev)
- NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSINDEV,
- htonl(entskb->nf_bridge->physindev->ifindex));
+ if (nla_put_be32(skb, NFQA_IFINDEX_INDEV,
+ htonl(indev->ifindex)))
+ goto nla_put_failure;
+ if (entskb->nf_bridge && entskb->nf_bridge->physindev &&
+ nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
+ htonl(entskb->nf_bridge->physindev->ifindex)))
+ goto nla_put_failure;
}
#endif
}
if (outdev) {
#ifndef CONFIG_BRIDGE_NETFILTER
- NLA_PUT_BE32(skb, NFQA_IFINDEX_OUTDEV, htonl(outdev->ifindex));
+ if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV, htonl(outdev->ifindex)))
+ goto nla_put_failure;
#else
if (entry->pf == PF_BRIDGE) {
/* Case 1: outdev is physical output device, we need to
* look for bridge group (when called from
* netfilter_bridge) */
- NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSOUTDEV,
- htonl(outdev->ifindex));
+ if (nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
+ htonl(outdev->ifindex)) ||
/* this is the bridge group "brX" */
/* rcu_read_lock()ed by __nf_queue */
- NLA_PUT_BE32(skb, NFQA_IFINDEX_OUTDEV,
- htonl(br_port_get_rcu(outdev)->br->dev->ifindex));
+ nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
+ htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
+ goto nla_put_failure;
} else {
/* Case 2: outdev is bridge group, we need to look for
* physical output device (when called from ipv4) */
- NLA_PUT_BE32(skb, NFQA_IFINDEX_OUTDEV,
- htonl(outdev->ifindex));
- if (entskb->nf_bridge && entskb->nf_bridge->physoutdev)
- NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSOUTDEV,
- htonl(entskb->nf_bridge->physoutdev->ifindex));
+ if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
+ htonl(outdev->ifindex)))
+ goto nla_put_failure;
+ if (entskb->nf_bridge && entskb->nf_bridge->physoutdev &&
+ nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
+ htonl(entskb->nf_bridge->physoutdev->ifindex)))
+ goto nla_put_failure;
}
#endif
}
- if (entskb->mark)
- NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark));
+ if (entskb->mark &&
+ nla_put_be32(skb, NFQA_MARK, htonl(entskb->mark)))
+ goto nla_put_failure;
if (indev && entskb->dev &&
entskb->mac_header != entskb->network_header) {
@@ -347,7 +356,8 @@
int len = dev_parse_header(entskb, phw.hw_addr);
if (len) {
phw.hw_addrlen = htons(len);
- NLA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
+ if (nla_put(skb, NFQA_HWADDR, sizeof(phw), &phw))
+ goto nla_put_failure;
}
}
@@ -357,7 +367,8 @@
ts.sec = cpu_to_be64(tv.tv_sec);
ts.usec = cpu_to_be64(tv.tv_usec);
- NLA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
+ if (nla_put(skb, NFQA_TIMESTAMP, sizeof(ts), &ts))
+ goto nla_put_failure;
}
if (data_len) {
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 9f40441..8340ace 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -635,11 +635,12 @@
if (hdr == NULL)
return -1;
- NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name);
- NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id);
- NLA_PUT_U32(skb, CTRL_ATTR_VERSION, family->version);
- NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize);
- NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr);
+ if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) ||
+ nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id) ||
+ nla_put_u32(skb, CTRL_ATTR_VERSION, family->version) ||
+ nla_put_u32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize) ||
+ nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr))
+ goto nla_put_failure;
if (!list_empty(&family->ops_list)) {
struct nlattr *nla_ops;
@@ -657,8 +658,9 @@
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd);
- NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags);
+ if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) ||
+ nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, ops->flags))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
}
@@ -682,9 +684,10 @@
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id);
- NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME,
- grp->name);
+ if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) ||
+ nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
+ grp->name))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
}
@@ -710,8 +713,9 @@
if (hdr == NULL)
return -1;
- NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name);
- NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id);
+ if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name) ||
+ nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id))
+ goto nla_put_failure;
nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
if (nla_grps == NULL)
@@ -721,9 +725,10 @@
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id);
- NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME,
- grp->name);
+ if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id) ||
+ nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
+ grp->name))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
nla_nest_end(skb, nla_grps);
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 6404052..8937664 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -63,19 +63,23 @@
genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
- NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target->idx);
- NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols);
- NLA_PUT_U16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res);
- NLA_PUT_U8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res);
- if (target->nfcid1_len > 0)
- NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
- target->nfcid1);
- if (target->sensb_res_len > 0)
- NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
- target->sensb_res);
- if (target->sensf_res_len > 0)
- NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
- target->sensf_res);
+ if (nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target->idx) ||
+ nla_put_u32(msg, NFC_ATTR_PROTOCOLS, target->supported_protocols) ||
+ nla_put_u16(msg, NFC_ATTR_TARGET_SENS_RES, target->sens_res) ||
+ nla_put_u8(msg, NFC_ATTR_TARGET_SEL_RES, target->sel_res))
+ goto nla_put_failure;
+ if (target->nfcid1_len > 0 &&
+ nla_put(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
+ target->nfcid1))
+ goto nla_put_failure;
+ if (target->sensb_res_len > 0 &&
+ nla_put(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
+ target->sensb_res))
+ goto nla_put_failure;
+ if (target->sensf_res_len > 0 &&
+ nla_put(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
+ target->sensf_res))
+ goto nla_put_failure;
return genlmsg_end(msg, hdr);
@@ -170,7 +174,8 @@
if (!hdr)
goto free_msg;
- NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
+ if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -197,10 +202,11 @@
if (!hdr)
goto free_msg;
- NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
- NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
- NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
- NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);
+ if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
+ nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
+ nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
+ nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -229,7 +235,8 @@
if (!hdr)
goto free_msg;
- NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
+ if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -259,10 +266,11 @@
if (cb)
genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
- NLA_PUT_STRING(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev));
- NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
- NLA_PUT_U32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols);
- NLA_PUT_U8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up);
+ if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
+ nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
+ nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
+ nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
+ goto nla_put_failure;
return genlmsg_end(msg, hdr);
@@ -339,11 +347,14 @@
if (!hdr)
goto free_msg;
- NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
- if (rf_mode == NFC_RF_INITIATOR)
- NLA_PUT_U32(msg, NFC_ATTR_TARGET_INDEX, target_idx);
- NLA_PUT_U8(msg, NFC_ATTR_COMM_MODE, comm_mode);
- NLA_PUT_U8(msg, NFC_ATTR_RF_MODE, rf_mode);
+ if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
+ goto nla_put_failure;
+ if (rf_mode == NFC_RF_INITIATOR &&
+ nla_put_u32(msg, NFC_ATTR_TARGET_INDEX, target_idx))
+ goto nla_put_failure;
+ if (nla_put_u8(msg, NFC_ATTR_COMM_MODE, comm_mode) ||
+ nla_put_u8(msg, NFC_ATTR_RF_MODE, rf_mode))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -376,7 +387,8 @@
if (!hdr)
goto free_msg;
- NLA_PUT_U32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx);
+ if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index e44e631..f86de29 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -778,15 +778,18 @@
tcp_flags = flow->tcp_flags;
spin_unlock_bh(&flow->lock);
- if (used)
- NLA_PUT_U64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used));
+ if (used &&
+ nla_put_u64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used)))
+ goto nla_put_failure;
- if (stats.n_packets)
- NLA_PUT(skb, OVS_FLOW_ATTR_STATS,
- sizeof(struct ovs_flow_stats), &stats);
+ if (stats.n_packets &&
+ nla_put(skb, OVS_FLOW_ATTR_STATS,
+ sizeof(struct ovs_flow_stats), &stats))
+ goto nla_put_failure;
- if (tcp_flags)
- NLA_PUT_U8(skb, OVS_FLOW_ATTR_TCP_FLAGS, tcp_flags);
+ if (tcp_flags &&
+ nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, tcp_flags))
+ goto nla_put_failure;
/* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if
* this is the first flow to be dumped into 'skb'. This is unusual for
@@ -1168,7 +1171,8 @@
goto nla_put_failure;
get_dp_stats(dp, &dp_stats);
- NLA_PUT(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats), &dp_stats);
+ if (nla_put(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats), &dp_stats))
+ goto nla_put_failure;
return genlmsg_end(skb, ovs_header);
@@ -1468,14 +1472,16 @@
ovs_header->dp_ifindex = get_dpifindex(vport->dp);
- NLA_PUT_U32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no);
- NLA_PUT_U32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type);
- NLA_PUT_STRING(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport));
- NLA_PUT_U32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_pid);
+ if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) ||
+ nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) ||
+ nla_put_string(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport)) ||
+ nla_put_u32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_pid))
+ goto nla_put_failure;
ovs_vport_get_stats(vport, &vport_stats);
- NLA_PUT(skb, OVS_VPORT_ATTR_STATS, sizeof(struct ovs_vport_stats),
- &vport_stats);
+ if (nla_put(skb, OVS_VPORT_ATTR_STATS, sizeof(struct ovs_vport_stats),
+ &vport_stats))
+ goto nla_put_failure;
err = ovs_vport_get_options(vport, skb);
if (err == -EMSGSIZE)
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 1252c30..7cb4163 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -1174,11 +1174,13 @@
struct ovs_key_ethernet *eth_key;
struct nlattr *nla, *encap;
- if (swkey->phy.priority)
- NLA_PUT_U32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority);
+ if (swkey->phy.priority &&
+ nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority))
+ goto nla_put_failure;
- if (swkey->phy.in_port != USHRT_MAX)
- NLA_PUT_U32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port);
+ if (swkey->phy.in_port != USHRT_MAX &&
+ nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port))
+ goto nla_put_failure;
nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));
if (!nla)
@@ -1188,8 +1190,9 @@
memcpy(eth_key->eth_dst, swkey->eth.dst, ETH_ALEN);
if (swkey->eth.tci || swkey->eth.type == htons(ETH_P_8021Q)) {
- NLA_PUT_BE16(skb, OVS_KEY_ATTR_ETHERTYPE, htons(ETH_P_8021Q));
- NLA_PUT_BE16(skb, OVS_KEY_ATTR_VLAN, swkey->eth.tci);
+ if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, htons(ETH_P_8021Q)) ||
+ nla_put_be16(skb, OVS_KEY_ATTR_VLAN, swkey->eth.tci))
+ goto nla_put_failure;
encap = nla_nest_start(skb, OVS_KEY_ATTR_ENCAP);
if (!swkey->eth.tci)
goto unencap;
@@ -1200,7 +1203,8 @@
if (swkey->eth.type == htons(ETH_P_802_2))
goto unencap;
- NLA_PUT_BE16(skb, OVS_KEY_ATTR_ETHERTYPE, swkey->eth.type);
+ if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, swkey->eth.type))
+ goto nla_put_failure;
if (swkey->eth.type == htons(ETH_P_IP)) {
struct ovs_key_ipv4 *ipv4_key;
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index d61f676..cfdf135 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -116,7 +116,8 @@
ifm->ifa_flags = IFA_F_PERMANENT;
ifm->ifa_scope = RT_SCOPE_LINK;
ifm->ifa_index = dev->ifindex;
- NLA_PUT_U8(skb, IFA_LOCAL, addr);
+ if (nla_put_u8(skb, IFA_LOCAL, addr))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
nla_put_failure:
@@ -183,8 +184,9 @@
rtm->rtm_scope = RT_SCOPE_UNIVERSE;
rtm->rtm_type = RTN_UNICAST;
rtm->rtm_flags = 0;
- NLA_PUT_U8(skb, RTA_DST, dst);
- NLA_PUT_U32(skb, RTA_OIF, dev->ifindex);
+ if (nla_put_u8(skb, RTA_DST, dst) ||
+ nla_put_u32(skb, RTA_OIF, dev->ifindex))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
nla_put_failure:
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 93fdf13..5cfb160 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -127,7 +127,8 @@
nest = nla_nest_start(skb, a->order);
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
+ if (nla_put_string(skb, TCA_KIND, a->ops->kind))
+ goto nla_put_failure;
for (i = 0; i < (hinfo->hmask + 1); i++) {
p = hinfo->htab[tcf_hash(i, hinfo->hmask)];
@@ -139,7 +140,8 @@
p = s_p;
}
}
- NLA_PUT_U32(skb, TCA_FCNT, n_i);
+ if (nla_put_u32(skb, TCA_FCNT, n_i))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
return n_i;
@@ -437,7 +439,8 @@
if (a->ops == NULL || a->ops->dump == NULL)
return err;
- NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
+ if (nla_put_string(skb, TCA_KIND, a->ops->kind))
+ goto nla_put_failure;
if (tcf_action_copy_stats(skb, a, 0))
goto nla_put_failure;
nest = nla_nest_start(skb, TCA_OPTIONS);
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
index 453a734..882124ceb 100644
--- a/net/sched/act_csum.c
+++ b/net/sched/act_csum.c
@@ -550,11 +550,13 @@
};
struct tcf_t t;
- NLA_PUT(skb, TCA_CSUM_PARMS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_CSUM_PARMS, sizeof(opt), &opt))
+ goto nla_put_failure;
t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
- NLA_PUT(skb, TCA_CSUM_TM, sizeof(t), &t);
+ if (nla_put(skb, TCA_CSUM_TM, sizeof(t), &t))
+ goto nla_put_failure;
return skb->len;
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index b77f5a0..f10fb82 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -162,7 +162,8 @@
};
struct tcf_t t;
- NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_GACT_PARMS, sizeof(opt), &opt))
+ goto nla_put_failure;
#ifdef CONFIG_GACT_PROB
if (gact->tcfg_ptype) {
struct tc_gact_p p_opt = {
@@ -171,13 +172,15 @@
.ptype = gact->tcfg_ptype,
};
- NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
+ if (nla_put(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt))
+ goto nla_put_failure;
}
#endif
t.install = jiffies_to_clock_t(jiffies - gact->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - gact->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(gact->tcf_tm.expires);
- NLA_PUT(skb, TCA_GACT_TM, sizeof(t), &t);
+ if (nla_put(skb, TCA_GACT_TM, sizeof(t), &t))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 60f8f61..0beba0e 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -267,15 +267,17 @@
c.refcnt = ipt->tcf_refcnt - ref;
strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name);
- NLA_PUT(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t);
- NLA_PUT_U32(skb, TCA_IPT_INDEX, ipt->tcf_index);
- NLA_PUT_U32(skb, TCA_IPT_HOOK, ipt->tcfi_hook);
- NLA_PUT(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c);
- NLA_PUT_STRING(skb, TCA_IPT_TABLE, ipt->tcfi_tname);
+ if (nla_put(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t) ||
+ nla_put_u32(skb, TCA_IPT_INDEX, ipt->tcf_index) ||
+ nla_put_u32(skb, TCA_IPT_HOOK, ipt->tcfi_hook) ||
+ nla_put(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c) ||
+ nla_put_string(skb, TCA_IPT_TABLE, ipt->tcfi_tname))
+ goto nla_put_failure;
tm.install = jiffies_to_clock_t(jiffies - ipt->tcf_tm.install);
tm.lastuse = jiffies_to_clock_t(jiffies - ipt->tcf_tm.lastuse);
tm.expires = jiffies_to_clock_t(ipt->tcf_tm.expires);
- NLA_PUT(skb, TCA_IPT_TM, sizeof (tm), &tm);
+ if (nla_put(skb, TCA_IPT_TM, sizeof (tm), &tm))
+ goto nla_put_failure;
kfree(t);
return skb->len;
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index e051398..d583aea 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -227,11 +227,13 @@
};
struct tcf_t t;
- NLA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt))
+ goto nla_put_failure;
t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(m->tcf_tm.expires);
- NLA_PUT(skb, TCA_MIRRED_TM, sizeof(t), &t);
+ if (nla_put(skb, TCA_MIRRED_TM, sizeof(t), &t))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index 001d1b3..b5d029e 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -284,11 +284,13 @@
};
struct tcf_t t;
- NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_NAT_PARMS, sizeof(opt), &opt))
+ goto nla_put_failure;
t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
- NLA_PUT(skb, TCA_NAT_TM, sizeof(t), &t);
+ if (nla_put(skb, TCA_NAT_TM, sizeof(t), &t))
+ goto nla_put_failure;
return skb->len;
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 10d3aed..26aa2f6 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -215,11 +215,13 @@
opt->refcnt = p->tcf_refcnt - ref;
opt->bindcnt = p->tcf_bindcnt - bind;
- NLA_PUT(skb, TCA_PEDIT_PARMS, s, opt);
+ if (nla_put(skb, TCA_PEDIT_PARMS, s, opt))
+ goto nla_put_failure;
t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
- NLA_PUT(skb, TCA_PEDIT_TM, sizeof(t), &t);
+ if (nla_put(skb, TCA_PEDIT_TM, sizeof(t), &t))
+ goto nla_put_failure;
kfree(opt);
return skb->len;
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 6fb3f5a..a9de232 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -356,11 +356,14 @@
opt.rate = police->tcfp_R_tab->rate;
if (police->tcfp_P_tab)
opt.peakrate = police->tcfp_P_tab->rate;
- NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt);
- if (police->tcfp_result)
- NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result);
- if (police->tcfp_ewma_rate)
- NLA_PUT_U32(skb, TCA_POLICE_AVRATE, police->tcfp_ewma_rate);
+ if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt))
+ goto nla_put_failure;
+ if (police->tcfp_result &&
+ nla_put_u32(skb, TCA_POLICE_RESULT, police->tcfp_result))
+ goto nla_put_failure;
+ if (police->tcfp_ewma_rate &&
+ nla_put_u32(skb, TCA_POLICE_AVRATE, police->tcfp_ewma_rate))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 73e0a3a..3922f2a 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -172,12 +172,14 @@
};
struct tcf_t t;
- NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
- NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
+ if (nla_put(skb, TCA_DEF_PARMS, sizeof(opt), &opt) ||
+ nla_put_string(skb, TCA_DEF_DATA, d->tcfd_defdata))
+ goto nla_put_failure;
t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(d->tcf_tm.expires);
- NLA_PUT(skb, TCA_DEF_TM, sizeof(t), &t);
+ if (nla_put(skb, TCA_DEF_TM, sizeof(t), &t))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index 35dbbe9..476e0fa 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -166,20 +166,25 @@
};
struct tcf_t t;
- NLA_PUT(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt);
- if (d->flags & SKBEDIT_F_PRIORITY)
- NLA_PUT(skb, TCA_SKBEDIT_PRIORITY, sizeof(d->priority),
- &d->priority);
- if (d->flags & SKBEDIT_F_QUEUE_MAPPING)
- NLA_PUT(skb, TCA_SKBEDIT_QUEUE_MAPPING,
- sizeof(d->queue_mapping), &d->queue_mapping);
- if (d->flags & SKBEDIT_F_MARK)
- NLA_PUT(skb, TCA_SKBEDIT_MARK, sizeof(d->mark),
- &d->mark);
+ if (nla_put(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt))
+ goto nla_put_failure;
+ if ((d->flags & SKBEDIT_F_PRIORITY) &&
+ nla_put(skb, TCA_SKBEDIT_PRIORITY, sizeof(d->priority),
+ &d->priority))
+ goto nla_put_failure;
+ if ((d->flags & SKBEDIT_F_QUEUE_MAPPING) &&
+ nla_put(skb, TCA_SKBEDIT_QUEUE_MAPPING,
+ sizeof(d->queue_mapping), &d->queue_mapping))
+ goto nla_put_failure;
+ if ((d->flags & SKBEDIT_F_MARK) &&
+ nla_put(skb, TCA_SKBEDIT_MARK, sizeof(d->mark),
+ &d->mark))
+ goto nla_put_failure;
t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(d->tcf_tm.expires);
- NLA_PUT(skb, TCA_SKBEDIT_TM, sizeof(t), &t);
+ if (nla_put(skb, TCA_SKBEDIT_TM, sizeof(t), &t))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index a69d44f..f452f69 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -357,7 +357,8 @@
tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex;
tcm->tcm_parent = tp->classid;
tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
- NLA_PUT_STRING(skb, TCA_KIND, tp->ops->kind);
+ if (nla_put_string(skb, TCA_KIND, tp->ops->kind))
+ goto nla_put_failure;
tcm->tcm_handle = fh;
if (RTM_DELTFILTER != event) {
tcm->tcm_handle = 0;
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index ea1f70b..590960a 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -257,8 +257,9 @@
if (nest == NULL)
goto nla_put_failure;
- if (f->res.classid)
- NLA_PUT_U32(skb, TCA_BASIC_CLASSID, f->res.classid);
+ if (f->res.classid &&
+ nla_put_u32(skb, TCA_BASIC_CLASSID, f->res.classid))
+ goto nla_put_failure;
if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 ||
tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 1d8bd0d..ccd08c8 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -572,25 +572,32 @@
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, TCA_FLOW_KEYS, f->keymask);
- NLA_PUT_U32(skb, TCA_FLOW_MODE, f->mode);
+ if (nla_put_u32(skb, TCA_FLOW_KEYS, f->keymask) ||
+ nla_put_u32(skb, TCA_FLOW_MODE, f->mode))
+ goto nla_put_failure;
if (f->mask != ~0 || f->xor != 0) {
- NLA_PUT_U32(skb, TCA_FLOW_MASK, f->mask);
- NLA_PUT_U32(skb, TCA_FLOW_XOR, f->xor);
+ if (nla_put_u32(skb, TCA_FLOW_MASK, f->mask) ||
+ nla_put_u32(skb, TCA_FLOW_XOR, f->xor))
+ goto nla_put_failure;
}
- if (f->rshift)
- NLA_PUT_U32(skb, TCA_FLOW_RSHIFT, f->rshift);
- if (f->addend)
- NLA_PUT_U32(skb, TCA_FLOW_ADDEND, f->addend);
+ if (f->rshift &&
+ nla_put_u32(skb, TCA_FLOW_RSHIFT, f->rshift))
+ goto nla_put_failure;
+ if (f->addend &&
+ nla_put_u32(skb, TCA_FLOW_ADDEND, f->addend))
+ goto nla_put_failure;
- if (f->divisor)
- NLA_PUT_U32(skb, TCA_FLOW_DIVISOR, f->divisor);
- if (f->baseclass)
- NLA_PUT_U32(skb, TCA_FLOW_BASECLASS, f->baseclass);
+ if (f->divisor &&
+ nla_put_u32(skb, TCA_FLOW_DIVISOR, f->divisor))
+ goto nla_put_failure;
+ if (f->baseclass &&
+ nla_put_u32(skb, TCA_FLOW_BASECLASS, f->baseclass))
+ goto nla_put_failure;
- if (f->perturb_period)
- NLA_PUT_U32(skb, TCA_FLOW_PERTURB, f->perturb_period / HZ);
+ if (f->perturb_period &&
+ nla_put_u32(skb, TCA_FLOW_PERTURB, f->perturb_period / HZ))
+ goto nla_put_failure;
if (tcf_exts_dump(skb, &f->exts, &flow_ext_map) < 0)
goto nla_put_failure;
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 389af15..8384a47 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -346,14 +346,17 @@
if (nest == NULL)
goto nla_put_failure;
- if (f->res.classid)
- NLA_PUT_U32(skb, TCA_FW_CLASSID, f->res.classid);
+ if (f->res.classid &&
+ nla_put_u32(skb, TCA_FW_CLASSID, f->res.classid))
+ goto nla_put_failure;
#ifdef CONFIG_NET_CLS_IND
- if (strlen(f->indev))
- NLA_PUT_STRING(skb, TCA_FW_INDEV, f->indev);
+ if (strlen(f->indev) &&
+ nla_put_string(skb, TCA_FW_INDEV, f->indev))
+ goto nla_put_failure;
#endif /* CONFIG_NET_CLS_IND */
- if (head->mask != 0xFFFFFFFF)
- NLA_PUT_U32(skb, TCA_FW_MASK, head->mask);
+ if (head->mask != 0xFFFFFFFF &&
+ nla_put_u32(skb, TCA_FW_MASK, head->mask))
+ goto nla_put_failure;
if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0)
goto nla_put_failure;
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 13ab66e..36fec42 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -571,17 +571,21 @@
if (!(f->handle & 0x8000)) {
id = f->id & 0xFF;
- NLA_PUT_U32(skb, TCA_ROUTE4_TO, id);
+ if (nla_put_u32(skb, TCA_ROUTE4_TO, id))
+ goto nla_put_failure;
}
if (f->handle & 0x80000000) {
- if ((f->handle >> 16) != 0xFFFF)
- NLA_PUT_U32(skb, TCA_ROUTE4_IIF, f->iif);
+ if ((f->handle >> 16) != 0xFFFF &&
+ nla_put_u32(skb, TCA_ROUTE4_IIF, f->iif))
+ goto nla_put_failure;
} else {
id = f->id >> 16;
- NLA_PUT_U32(skb, TCA_ROUTE4_FROM, id);
+ if (nla_put_u32(skb, TCA_ROUTE4_FROM, id))
+ goto nla_put_failure;
}
- if (f->res.classid)
- NLA_PUT_U32(skb, TCA_ROUTE4_CLASSID, f->res.classid);
+ if (f->res.classid &&
+ nla_put_u32(skb, TCA_ROUTE4_CLASSID, f->res.classid))
+ goto nla_put_failure;
if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0)
goto nla_put_failure;
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index b014279..18ab93e 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -615,18 +615,22 @@
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst);
+ if (nla_put(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst))
+ goto nla_put_failure;
pinfo.dpi = s->dpi;
pinfo.spi = f->spi;
pinfo.protocol = s->protocol;
pinfo.tunnelid = s->tunnelid;
pinfo.tunnelhdr = f->tunnelhdr;
pinfo.pad = 0;
- NLA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo);
- if (f->res.classid)
- NLA_PUT_U32(skb, TCA_RSVP_CLASSID, f->res.classid);
- if (((f->handle >> 8) & 0xFF) != 16)
- NLA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src);
+ if (nla_put(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo))
+ goto nla_put_failure;
+ if (f->res.classid &&
+ nla_put_u32(skb, TCA_RSVP_CLASSID, f->res.classid))
+ goto nla_put_failure;
+ if (((f->handle >> 8) & 0xFF) != 16 &&
+ nla_put(skb, TCA_RSVP_SRC, sizeof(f->src), f->src))
+ goto nla_put_failure;
if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0)
goto nla_put_failure;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index dbe1992..fe29420 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -438,10 +438,11 @@
if (!fh) {
t->tcm_handle = ~0; /* whatever ... */
- NLA_PUT_U32(skb, TCA_TCINDEX_HASH, p->hash);
- NLA_PUT_U16(skb, TCA_TCINDEX_MASK, p->mask);
- NLA_PUT_U32(skb, TCA_TCINDEX_SHIFT, p->shift);
- NLA_PUT_U32(skb, TCA_TCINDEX_FALL_THROUGH, p->fall_through);
+ if (nla_put_u32(skb, TCA_TCINDEX_HASH, p->hash) ||
+ nla_put_u16(skb, TCA_TCINDEX_MASK, p->mask) ||
+ nla_put_u32(skb, TCA_TCINDEX_SHIFT, p->shift) ||
+ nla_put_u32(skb, TCA_TCINDEX_FALL_THROUGH, p->fall_through))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
} else {
if (p->perfect) {
@@ -460,8 +461,9 @@
}
}
pr_debug("handle = %d\n", t->tcm_handle);
- if (r->res.class)
- NLA_PUT_U32(skb, TCA_TCINDEX_CLASSID, r->res.classid);
+ if (r->res.class &&
+ nla_put_u32(skb, TCA_TCINDEX_CLASSID, r->res.classid))
+ goto nla_put_failure;
if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0)
goto nla_put_failure;
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 939b627..591b006 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -733,36 +733,44 @@
struct tc_u_hnode *ht = (struct tc_u_hnode *)fh;
u32 divisor = ht->divisor + 1;
- NLA_PUT_U32(skb, TCA_U32_DIVISOR, divisor);
+ if (nla_put_u32(skb, TCA_U32_DIVISOR, divisor))
+ goto nla_put_failure;
} else {
- NLA_PUT(skb, TCA_U32_SEL,
- sizeof(n->sel) + n->sel.nkeys*sizeof(struct tc_u32_key),
- &n->sel);
+ if (nla_put(skb, TCA_U32_SEL,
+ sizeof(n->sel) + n->sel.nkeys*sizeof(struct tc_u32_key),
+ &n->sel))
+ goto nla_put_failure;
if (n->ht_up) {
u32 htid = n->handle & 0xFFFFF000;
- NLA_PUT_U32(skb, TCA_U32_HASH, htid);
+ if (nla_put_u32(skb, TCA_U32_HASH, htid))
+ goto nla_put_failure;
}
- if (n->res.classid)
- NLA_PUT_U32(skb, TCA_U32_CLASSID, n->res.classid);
- if (n->ht_down)
- NLA_PUT_U32(skb, TCA_U32_LINK, n->ht_down->handle);
+ if (n->res.classid &&
+ nla_put_u32(skb, TCA_U32_CLASSID, n->res.classid))
+ goto nla_put_failure;
+ if (n->ht_down &&
+ nla_put_u32(skb, TCA_U32_LINK, n->ht_down->handle))
+ goto nla_put_failure;
#ifdef CONFIG_CLS_U32_MARK
- if (n->mark.val || n->mark.mask)
- NLA_PUT(skb, TCA_U32_MARK, sizeof(n->mark), &n->mark);
+ if ((n->mark.val || n->mark.mask) &&
+ nla_put(skb, TCA_U32_MARK, sizeof(n->mark), &n->mark))
+ goto nla_put_failure;
#endif
if (tcf_exts_dump(skb, &n->exts, &u32_ext_map) < 0)
goto nla_put_failure;
#ifdef CONFIG_NET_CLS_IND
- if (strlen(n->indev))
- NLA_PUT_STRING(skb, TCA_U32_INDEV, n->indev);
+ if (strlen(n->indev) &&
+ nla_put_string(skb, TCA_U32_INDEV, n->indev))
+ goto nla_put_failure;
#endif
#ifdef CONFIG_CLS_U32_PERF
- NLA_PUT(skb, TCA_U32_PCNT,
- sizeof(struct tc_u32_pcnt) + n->sel.nkeys*sizeof(u64),
- n->pf);
+ if (nla_put(skb, TCA_U32_PCNT,
+ sizeof(struct tc_u32_pcnt) + n->sel.nkeys*sizeof(u64),
+ n->pf))
+ goto nla_put_failure;
#endif
}
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 1363bf1..4790c69 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -585,8 +585,9 @@
static int meta_var_dump(struct sk_buff *skb, struct meta_value *v, int tlv)
{
- if (v->val && v->len)
- NLA_PUT(skb, tlv, v->len, (void *) v->val);
+ if (v->val && v->len &&
+ nla_put(skb, tlv, v->len, (void *) v->val))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -636,10 +637,13 @@
static int meta_int_dump(struct sk_buff *skb, struct meta_value *v, int tlv)
{
- if (v->len == sizeof(unsigned long))
- NLA_PUT(skb, tlv, sizeof(unsigned long), &v->val);
- else if (v->len == sizeof(u32))
- NLA_PUT_U32(skb, tlv, v->val);
+ if (v->len == sizeof(unsigned long)) {
+ if (nla_put(skb, tlv, sizeof(unsigned long), &v->val))
+ goto nla_put_failure;
+ } else if (v->len == sizeof(u32)) {
+ if (nla_put_u32(skb, tlv, v->val))
+ goto nla_put_failure;
+ }
return 0;
@@ -831,7 +835,8 @@
memcpy(&hdr.left, &meta->lvalue.hdr, sizeof(hdr.left));
memcpy(&hdr.right, &meta->rvalue.hdr, sizeof(hdr.right));
- NLA_PUT(skb, TCA_EM_META_HDR, sizeof(hdr), &hdr);
+ if (nla_put(skb, TCA_EM_META_HDR, sizeof(hdr), &hdr))
+ goto nla_put_failure;
ops = meta_type_ops(&meta->lvalue);
if (ops->dump(skb, &meta->lvalue, TCA_EM_META_LVALUE) < 0 ||
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 88d93eb..aca233c 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -441,7 +441,8 @@
if (top_start == NULL)
goto nla_put_failure;
- NLA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr);
+ if (nla_put(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr))
+ goto nla_put_failure;
list_start = nla_nest_start(skb, TCA_EMATCH_TREE_LIST);
if (list_start == NULL)
@@ -457,7 +458,8 @@
.flags = em->flags
};
- NLA_PUT(skb, i + 1, sizeof(em_hdr), &em_hdr);
+ if (nla_put(skb, i + 1, sizeof(em_hdr), &em_hdr))
+ goto nla_put_failure;
if (em->ops && em->ops->dump) {
if (em->ops->dump(skb, em) < 0)
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 3d8981f..d2daefc 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -426,7 +426,8 @@
nest = nla_nest_start(skb, TCA_STAB);
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT(skb, TCA_STAB_BASE, sizeof(stab->szopts), &stab->szopts);
+ if (nla_put(skb, TCA_STAB_BASE, sizeof(stab->szopts), &stab->szopts))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
return skb->len;
@@ -1201,7 +1202,8 @@
tcm->tcm_parent = clid;
tcm->tcm_handle = q->handle;
tcm->tcm_info = atomic_read(&q->refcnt);
- NLA_PUT_STRING(skb, TCA_KIND, q->ops->id);
+ if (nla_put_string(skb, TCA_KIND, q->ops->id))
+ goto nla_put_failure;
if (q->ops->dump && q->ops->dump(q, skb) < 0)
goto nla_put_failure;
q->qstats.qlen = q->q.qlen;
@@ -1505,7 +1507,8 @@
tcm->tcm_parent = q->handle;
tcm->tcm_handle = q->handle;
tcm->tcm_info = 0;
- NLA_PUT_STRING(skb, TCA_KIND, q->ops->id);
+ if (nla_put_string(skb, TCA_KIND, q->ops->id))
+ goto nla_put_failure;
if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0)
goto nla_put_failure;
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index e25e490..a77a4fb 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -601,7 +601,8 @@
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT(skb, TCA_ATM_HDR, flow->hdr_len, flow->hdr);
+ if (nla_put(skb, TCA_ATM_HDR, flow->hdr_len, flow->hdr))
+ goto nla_put_failure;
if (flow->vcc) {
struct sockaddr_atmpvc pvc;
int state;
@@ -610,15 +611,19 @@
pvc.sap_addr.itf = flow->vcc->dev ? flow->vcc->dev->number : -1;
pvc.sap_addr.vpi = flow->vcc->vpi;
pvc.sap_addr.vci = flow->vcc->vci;
- NLA_PUT(skb, TCA_ATM_ADDR, sizeof(pvc), &pvc);
+ if (nla_put(skb, TCA_ATM_ADDR, sizeof(pvc), &pvc))
+ goto nla_put_failure;
state = ATM_VF2VS(flow->vcc->flags);
- NLA_PUT_U32(skb, TCA_ATM_STATE, state);
+ if (nla_put_u32(skb, TCA_ATM_STATE, state))
+ goto nla_put_failure;
}
- if (flow->excess)
- NLA_PUT_U32(skb, TCA_ATM_EXCESS, flow->classid);
- else
- NLA_PUT_U32(skb, TCA_ATM_EXCESS, 0);
-
+ if (flow->excess) {
+ if (nla_put_u32(skb, TCA_ATM_EXCESS, flow->classid))
+ goto nla_put_failure;
+ } else {
+ if (nla_put_u32(skb, TCA_ATM_EXCESS, 0))
+ goto nla_put_failure;
+ }
nla_nest_end(skb, nest);
return skb->len;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 24d94c0..6aabd77 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1425,7 +1425,8 @@
{
unsigned char *b = skb_tail_pointer(skb);
- NLA_PUT(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate);
+ if (nla_put(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
@@ -1450,7 +1451,8 @@
opt.minidle = (u32)(-cl->minidle);
opt.offtime = cl->offtime;
opt.change = ~0;
- NLA_PUT(skb, TCA_CBQ_LSSOPT, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_CBQ_LSSOPT, sizeof(opt), &opt))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
@@ -1468,7 +1470,8 @@
opt.priority = cl->priority + 1;
opt.cpriority = cl->cpriority + 1;
opt.weight = cl->weight;
- NLA_PUT(skb, TCA_CBQ_WRROPT, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_CBQ_WRROPT, sizeof(opt), &opt))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
@@ -1485,7 +1488,8 @@
opt.priority2 = cl->priority2 + 1;
opt.pad = 0;
opt.penalty = cl->penalty;
- NLA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
@@ -1502,7 +1506,8 @@
opt.split = cl->split ? cl->split->common.classid : 0;
opt.defmap = cl->defmap;
opt.defchange = ~0;
- NLA_PUT(skb, TCA_CBQ_FOPT, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_CBQ_FOPT, sizeof(opt), &opt))
+ goto nla_put_failure;
}
return skb->len;
@@ -1521,7 +1526,8 @@
opt.police = cl->police;
opt.__res1 = 0;
opt.__res2 = 0;
- NLA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_CBQ_POLICE, sizeof(opt), &opt))
+ goto nla_put_failure;
}
return skb->len;
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index 7e267d7..81445cc 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -515,8 +515,9 @@
if (opts == NULL)
goto nla_put_failure;
- NLA_PUT(skb, TCA_CHOKE_PARMS, sizeof(opt), &opt);
- NLA_PUT_U32(skb, TCA_CHOKE_MAX_P, q->parms.max_P);
+ if (nla_put(skb, TCA_CHOKE_PARMS, sizeof(opt), &opt) ||
+ nla_put_u32(skb, TCA_CHOKE_MAX_P, q->parms.max_P))
+ goto nla_put_failure;
return nla_nest_end(skb, opts);
nla_put_failure:
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 6b7fe4a..c218987 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -260,7 +260,8 @@
nest = nla_nest_start(skb, TCA_OPTIONS);
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, TCA_DRR_QUANTUM, cl->quantum);
+ if (nla_put_u32(skb, TCA_DRR_QUANTUM, cl->quantum))
+ goto nla_put_failure;
return nla_nest_end(skb, nest);
nla_put_failure:
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 2c79020..389b856 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -429,8 +429,9 @@
opts = nla_nest_start(skb, TCA_OPTIONS);
if (opts == NULL)
goto nla_put_failure;
- NLA_PUT_U8(skb, TCA_DSMARK_MASK, p->mask[cl - 1]);
- NLA_PUT_U8(skb, TCA_DSMARK_VALUE, p->value[cl - 1]);
+ if (nla_put_u8(skb, TCA_DSMARK_MASK, p->mask[cl - 1]) ||
+ nla_put_u8(skb, TCA_DSMARK_VALUE, p->value[cl - 1]))
+ goto nla_put_failure;
return nla_nest_end(skb, opts);
@@ -447,13 +448,16 @@
opts = nla_nest_start(skb, TCA_OPTIONS);
if (opts == NULL)
goto nla_put_failure;
- NLA_PUT_U16(skb, TCA_DSMARK_INDICES, p->indices);
+ if (nla_put_u16(skb, TCA_DSMARK_INDICES, p->indices))
+ goto nla_put_failure;
- if (p->default_index != NO_DEFAULT_INDEX)
- NLA_PUT_U16(skb, TCA_DSMARK_DEFAULT_INDEX, p->default_index);
+ if (p->default_index != NO_DEFAULT_INDEX &&
+ nla_put_u16(skb, TCA_DSMARK_DEFAULT_INDEX, p->default_index))
+ goto nla_put_failure;
- if (p->set_tc_index)
- NLA_PUT_FLAG(skb, TCA_DSMARK_SET_TC_INDEX);
+ if (p->set_tc_index &&
+ nla_put_flag(skb, TCA_DSMARK_SET_TC_INDEX))
+ goto nla_put_failure;
return nla_nest_end(skb, opts);
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 66effe2..e15a9eb 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -85,7 +85,8 @@
{
struct tc_fifo_qopt opt = { .limit = sch->limit };
- NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 67fc573..0eb1202 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -512,7 +512,8 @@
struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS };
memcpy(&opt.priomap, prio2band, TC_PRIO_MAX + 1);
- NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index 0b15236..55e3310 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -521,14 +521,16 @@
opts = nla_nest_start(skb, TCA_OPTIONS);
if (opts == NULL)
goto nla_put_failure;
- NLA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt);
+ if (nla_put(skb, TCA_GRED_DPS, sizeof(sopt), &sopt))
+ goto nla_put_failure;
for (i = 0; i < MAX_DPs; i++) {
struct gred_sched_data *q = table->tab[i];
max_p[i] = q ? q->parms.max_P : 0;
}
- NLA_PUT(skb, TCA_GRED_MAX_P, sizeof(max_p), max_p);
+ if (nla_put(skb, TCA_GRED_MAX_P, sizeof(max_p), max_p))
+ goto nla_put_failure;
parms = nla_nest_start(skb, TCA_GRED_PARMS);
if (parms == NULL)
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 9bdca2e..8db3e2c 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1305,7 +1305,8 @@
tsc.m1 = sm2m(sc->sm1);
tsc.d = dx2d(sc->dx);
tsc.m2 = sm2m(sc->sm2);
- NLA_PUT(skb, attr, sizeof(tsc), &tsc);
+ if (nla_put(skb, attr, sizeof(tsc), &tsc))
+ goto nla_put_failure;
return skb->len;
@@ -1573,7 +1574,8 @@
}
qopt.defcls = q->defcls;
- NLA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt);
+ if (nla_put(skb, TCA_OPTIONS, sizeof(qopt), &qopt))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 29b942c..2ea6f19 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1051,7 +1051,8 @@
nest = nla_nest_start(skb, TCA_OPTIONS);
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
+ if (nla_put(skb, TCA_HTB_INIT, sizeof(gopt), &gopt))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
spin_unlock_bh(root_lock);
@@ -1090,7 +1091,8 @@
opt.quantum = cl->quantum;
opt.prio = cl->prio;
opt.level = cl->level;
- NLA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_HTB_PARMS, sizeof(opt), &opt))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
spin_unlock_bh(root_lock);
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 28de430..d1831ca 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -247,7 +247,8 @@
opt.offset[i] = dev->tc_to_txq[i].offset;
}
- NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
+ goto nla_put_failure;
return skb->len;
nla_put_failure:
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 49131d7..2a2b096 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -284,7 +284,8 @@
opt.bands = q->bands;
opt.max_bands = q->max_bands;
- NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
+ goto nla_put_failure;
return skb->len;
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 5da548f..1109731 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -834,7 +834,8 @@
.p23 = q->clg.a5,
};
- NLA_PUT(skb, NETEM_LOSS_GI, sizeof(gi), &gi);
+ if (nla_put(skb, NETEM_LOSS_GI, sizeof(gi), &gi))
+ goto nla_put_failure;
break;
}
case CLG_GILB_ELL: {
@@ -845,7 +846,8 @@
.k1 = q->clg.a4,
};
- NLA_PUT(skb, NETEM_LOSS_GE, sizeof(ge), &ge);
+ if (nla_put(skb, NETEM_LOSS_GE, sizeof(ge), &ge))
+ goto nla_put_failure;
break;
}
}
@@ -874,26 +876,31 @@
qopt.loss = q->loss;
qopt.gap = q->gap;
qopt.duplicate = q->duplicate;
- NLA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt);
+ if (nla_put(skb, TCA_OPTIONS, sizeof(qopt), &qopt))
+ goto nla_put_failure;
cor.delay_corr = q->delay_cor.rho;
cor.loss_corr = q->loss_cor.rho;
cor.dup_corr = q->dup_cor.rho;
- NLA_PUT(skb, TCA_NETEM_CORR, sizeof(cor), &cor);
+ if (nla_put(skb, TCA_NETEM_CORR, sizeof(cor), &cor))
+ goto nla_put_failure;
reorder.probability = q->reorder;
reorder.correlation = q->reorder_cor.rho;
- NLA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
+ if (nla_put(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder))
+ goto nla_put_failure;
corrupt.probability = q->corrupt;
corrupt.correlation = q->corrupt_cor.rho;
- NLA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
+ if (nla_put(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt))
+ goto nla_put_failure;
rate.rate = q->rate;
rate.packet_overhead = q->packet_overhead;
rate.cell_size = q->cell_size;
rate.cell_overhead = q->cell_overhead;
- NLA_PUT(skb, TCA_NETEM_RATE, sizeof(rate), &rate);
+ if (nla_put(skb, TCA_NETEM_RATE, sizeof(rate), &rate))
+ goto nla_put_failure;
if (dump_loss_model(q, skb) != 0)
goto nla_put_failure;
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index b5d56a2..79359b6 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -247,7 +247,8 @@
opt.bands = q->bands;
memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX + 1);
- NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
+ goto nla_put_failure;
return skb->len;
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index e68cb44..9af01f3 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -429,8 +429,9 @@
nest = nla_nest_start(skb, TCA_OPTIONS);
if (nest == NULL)
goto nla_put_failure;
- NLA_PUT_U32(skb, TCA_QFQ_WEIGHT, ONE_FP/cl->inv_w);
- NLA_PUT_U32(skb, TCA_QFQ_LMAX, cl->lmax);
+ if (nla_put_u32(skb, TCA_QFQ_WEIGHT, ONE_FP/cl->inv_w) ||
+ nla_put_u32(skb, TCA_QFQ_LMAX, cl->lmax))
+ goto nla_put_failure;
return nla_nest_end(skb, nest);
nla_put_failure:
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index a5cc301..633e32d 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -272,8 +272,9 @@
opts = nla_nest_start(skb, TCA_OPTIONS);
if (opts == NULL)
goto nla_put_failure;
- NLA_PUT(skb, TCA_RED_PARMS, sizeof(opt), &opt);
- NLA_PUT_U32(skb, TCA_RED_MAX_P, q->parms.max_P);
+ if (nla_put(skb, TCA_RED_PARMS, sizeof(opt), &opt) ||
+ nla_put_u32(skb, TCA_RED_MAX_P, q->parms.max_P))
+ goto nla_put_failure;
return nla_nest_end(skb, opts);
nla_put_failure:
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index d7eea99..74305c8 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -570,7 +570,8 @@
sch->qstats.backlog = q->qdisc->qstats.backlog;
opts = nla_nest_start(skb, TCA_OPTIONS);
- NLA_PUT(skb, TCA_SFB_PARMS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_SFB_PARMS, sizeof(opt), &opt))
+ goto nla_put_failure;
return nla_nest_end(skb, opts);
nla_put_failure:
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 02a21ab..d3a1bc2 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -812,7 +812,8 @@
memcpy(&opt.stats, &q->stats, sizeof(opt.stats));
opt.flags = q->flags;
- NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
+ goto nla_put_failure;
return skb->len;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index b8e1563..4b056c15 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -359,7 +359,8 @@
memset(&opt.peakrate, 0, sizeof(opt.peakrate));
opt.mtu = q->mtu;
opt.buffer = q->buffer;
- NLA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt);
+ if (nla_put(skb, TCA_TBF_PARMS, sizeof(opt), &opt))
+ goto nla_put_failure;
nla_nest_end(skb, nest);
return skb->len;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index d510353..eadb902 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1442,6 +1442,7 @@
long timeo;
struct scm_cookie tmp_scm;
int max_level;
+ int data_len = 0;
if (NULL == siocb->scm)
siocb->scm = &tmp_scm;
@@ -1475,7 +1476,13 @@
if (len > sk->sk_sndbuf - 32)
goto out;
- skb = sock_alloc_send_skb(sk, len, msg->msg_flags&MSG_DONTWAIT, &err);
+ if (len > SKB_MAX_ALLOC)
+ data_len = min_t(size_t,
+ len - SKB_MAX_ALLOC,
+ MAX_SKB_FRAGS * PAGE_SIZE);
+
+ skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
+ msg->msg_flags & MSG_DONTWAIT, &err);
if (skb == NULL)
goto out;
@@ -1485,8 +1492,10 @@
max_level = err + 1;
unix_get_secdata(siocb->scm, skb);
- skb_reset_transport_header(skb);
- err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+ skb_put(skb, len - data_len);
+ skb->data_len = data_len;
+ skb->len = len;
+ err = skb_copy_datagram_from_iovec(skb, 0, msg->msg_iov, 0, len);
if (err)
goto out_free;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e49da27..a4aab1d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -356,20 +356,26 @@
static int nl80211_msg_put_channel(struct sk_buff *msg,
struct ieee80211_channel *chan)
{
- NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
- chan->center_freq);
+ if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
+ chan->center_freq))
+ goto nla_put_failure;
- if (chan->flags & IEEE80211_CHAN_DISABLED)
- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
- if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
- if (chan->flags & IEEE80211_CHAN_NO_IBSS)
- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
- if (chan->flags & IEEE80211_CHAN_RADAR)
- NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
+ if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
+ goto nla_put_failure;
+ if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN))
+ goto nla_put_failure;
+ if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
+ goto nla_put_failure;
+ if ((chan->flags & IEEE80211_CHAN_RADAR) &&
+ nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
+ goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
- DBM_TO_MBM(chan->max_power));
+ if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
+ DBM_TO_MBM(chan->max_power)))
+ goto nla_put_failure;
return 0;
@@ -621,8 +627,8 @@
i = 0;
while (ifmodes) {
- if (ifmodes & 1)
- NLA_PUT_FLAG(msg, i);
+ if ((ifmodes & 1) && nla_put_flag(msg, i))
+ goto nla_put_failure;
ifmodes >>= 1;
i++;
}
@@ -665,8 +671,9 @@
nl_limit = nla_nest_start(msg, j + 1);
if (!nl_limit)
goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_IFACE_LIMIT_MAX,
- c->limits[j].max);
+ if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
+ c->limits[j].max))
+ goto nla_put_failure;
if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
c->limits[j].types))
goto nla_put_failure;
@@ -675,13 +682,14 @@
nla_nest_end(msg, nl_limits);
- if (c->beacon_int_infra_match)
- NLA_PUT_FLAG(msg,
- NL80211_IFACE_COMB_STA_AP_BI_MATCH);
- NLA_PUT_U32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
- c->num_different_channels);
- NLA_PUT_U32(msg, NL80211_IFACE_COMB_MAXNUM,
- c->max_interfaces);
+ if (c->beacon_int_infra_match &&
+ nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
+ goto nla_put_failure;
+ if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
+ c->num_different_channels) ||
+ nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
+ c->max_interfaces))
+ goto nla_put_failure;
nla_nest_end(msg, nl_combi);
}
@@ -712,64 +720,74 @@
if (!hdr)
return -1;
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
- NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) ||
+ nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)) ||
+ nla_put_u32(msg, NL80211_ATTR_GENERATION,
+ cfg80211_rdev_list_generation) ||
+ nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
+ dev->wiphy.retry_short) ||
+ nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
+ dev->wiphy.retry_long) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+ dev->wiphy.frag_threshold) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
+ dev->wiphy.rts_threshold) ||
+ nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
+ dev->wiphy.coverage_class) ||
+ nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
+ dev->wiphy.max_scan_ssids) ||
+ nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
+ dev->wiphy.max_sched_scan_ssids) ||
+ nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
+ dev->wiphy.max_scan_ie_len) ||
+ nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
+ dev->wiphy.max_sched_scan_ie_len) ||
+ nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
+ dev->wiphy.max_match_sets))
+ goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION,
- cfg80211_rdev_list_generation);
+ if ((dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
+ nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
+ goto nla_put_failure;
+ if ((dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
+ nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
+ goto nla_put_failure;
+ if ((dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
+ nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
+ goto nla_put_failure;
+ if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
+ nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
+ goto nla_put_failure;
+ if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
+ nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
+ goto nla_put_failure;
+ if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
+ nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
+ goto nla_put_failure;
- NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
- dev->wiphy.retry_short);
- NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
- dev->wiphy.retry_long);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
- dev->wiphy.frag_threshold);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
- dev->wiphy.rts_threshold);
- NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
- dev->wiphy.coverage_class);
- NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
- dev->wiphy.max_scan_ssids);
- NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
- dev->wiphy.max_sched_scan_ssids);
- NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
- dev->wiphy.max_scan_ie_len);
- NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
- dev->wiphy.max_sched_scan_ie_len);
- NLA_PUT_U8(msg, NL80211_ATTR_MAX_MATCH_SETS,
- dev->wiphy.max_match_sets);
+ if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
+ sizeof(u32) * dev->wiphy.n_cipher_suites,
+ dev->wiphy.cipher_suites))
+ goto nla_put_failure;
- if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)
- NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
- if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH)
- NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
- if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD)
- NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD);
- if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)
- NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT);
- if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS)
- NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_SUPPORT);
- if (dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)
- NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP);
+ if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
+ dev->wiphy.max_num_pmkids))
+ goto nla_put_failure;
- NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
- sizeof(u32) * dev->wiphy.n_cipher_suites,
- dev->wiphy.cipher_suites);
+ if ((dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
+ nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
+ goto nla_put_failure;
- NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
- dev->wiphy.max_num_pmkids);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
+ dev->wiphy.available_antennas_tx) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
+ dev->wiphy.available_antennas_rx))
+ goto nla_put_failure;
- if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
- NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE);
-
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
- dev->wiphy.available_antennas_tx);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
- dev->wiphy.available_antennas_rx);
-
- if (dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD)
- NLA_PUT_U32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
- dev->wiphy.probe_resp_offload);
+ if ((dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
+ nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
+ dev->wiphy.probe_resp_offload))
+ goto nla_put_failure;
if ((dev->wiphy.available_antennas_tx ||
dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) {
@@ -777,8 +795,11 @@
int res;
res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant);
if (!res) {
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX,
+ tx_ant) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX,
+ rx_ant))
+ goto nla_put_failure;
}
}
@@ -799,17 +820,17 @@
goto nla_put_failure;
/* add HT info */
- if (dev->wiphy.bands[band]->ht_cap.ht_supported) {
- NLA_PUT(msg, NL80211_BAND_ATTR_HT_MCS_SET,
- sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
- &dev->wiphy.bands[band]->ht_cap.mcs);
- NLA_PUT_U16(msg, NL80211_BAND_ATTR_HT_CAPA,
- dev->wiphy.bands[band]->ht_cap.cap);
- NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
- dev->wiphy.bands[band]->ht_cap.ampdu_factor);
- NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
- dev->wiphy.bands[band]->ht_cap.ampdu_density);
- }
+ if (dev->wiphy.bands[band]->ht_cap.ht_supported &&
+ (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
+ sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
+ &dev->wiphy.bands[band]->ht_cap.mcs) ||
+ nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
+ dev->wiphy.bands[band]->ht_cap.cap) ||
+ nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+ dev->wiphy.bands[band]->ht_cap.ampdu_factor) ||
+ nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+ dev->wiphy.bands[band]->ht_cap.ampdu_density)))
+ goto nla_put_failure;
/* add frequencies */
nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
@@ -842,11 +863,13 @@
goto nla_put_failure;
rate = &dev->wiphy.bands[band]->bitrates[i];
- NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
- rate->bitrate);
- if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
- NLA_PUT_FLAG(msg,
- NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
+ if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
+ rate->bitrate))
+ goto nla_put_failure;
+ if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
+ nla_put_flag(msg,
+ NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
+ goto nla_put_failure;
nla_nest_end(msg, nl_rate);
}
@@ -866,7 +889,8 @@
do { \
if (dev->ops->op) { \
i++; \
- NLA_PUT_U32(msg, i, NL80211_CMD_ ## n); \
+ if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
+ goto nla_put_failure; \
} \
} while (0)
@@ -894,7 +918,8 @@
CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
i++;
- NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
+ if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
+ goto nla_put_failure;
}
CMD(set_channel, SET_CHANNEL);
CMD(set_wds_peer, SET_WDS_PEER);
@@ -908,7 +933,8 @@
CMD(set_noack_map, SET_NOACK_MAP);
if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
i++;
- NLA_PUT_U32(msg, i, NL80211_CMD_REGISTER_BEACONS);
+ if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
+ goto nla_put_failure;
}
#ifdef CONFIG_NL80211_TESTMODE
@@ -919,23 +945,27 @@
if (dev->ops->connect || dev->ops->auth) {
i++;
- NLA_PUT_U32(msg, i, NL80211_CMD_CONNECT);
+ if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
+ goto nla_put_failure;
}
if (dev->ops->disconnect || dev->ops->deauth) {
i++;
- NLA_PUT_U32(msg, i, NL80211_CMD_DISCONNECT);
+ if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
+ goto nla_put_failure;
}
nla_nest_end(msg, nl_cmds);
if (dev->ops->remain_on_channel &&
- dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
- NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
- dev->wiphy.max_remain_on_channel_duration);
+ (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
+ nla_put_u32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
+ dev->wiphy.max_remain_on_channel_duration))
+ goto nla_put_failure;
- if (dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)
- NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
+ if ((dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
+ nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
+ goto nla_put_failure;
if (mgmt_stypes) {
u16 stypes;
@@ -953,9 +983,10 @@
i = 0;
stypes = mgmt_stypes[ift].tx;
while (stypes) {
- if (stypes & 1)
- NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE,
- (i << 4) | IEEE80211_FTYPE_MGMT);
+ if ((stypes & 1) &&
+ nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
+ (i << 4) | IEEE80211_FTYPE_MGMT))
+ goto nla_put_failure;
stypes >>= 1;
i++;
}
@@ -975,9 +1006,10 @@
i = 0;
stypes = mgmt_stypes[ift].rx;
while (stypes) {
- if (stypes & 1)
- NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE,
- (i << 4) | IEEE80211_FTYPE_MGMT);
+ if ((stypes & 1) &&
+ nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
+ (i << 4) | IEEE80211_FTYPE_MGMT))
+ goto nla_put_failure;
stypes >>= 1;
i++;
}
@@ -994,22 +1026,23 @@
if (!nl_wowlan)
goto nla_put_failure;
- if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
- if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
- if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
- if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED);
- if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
- if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
- if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
- if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
+ if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
+ ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
+ ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
+ ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
+ ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
+ ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
+ ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
+ ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
+ goto nla_put_failure;
if (dev->wiphy.wowlan.n_patterns) {
struct nl80211_wowlan_pattern_support pat = {
.max_patterns = dev->wiphy.wowlan.n_patterns,
@@ -1018,8 +1051,9 @@
.max_pattern_len =
dev->wiphy.wowlan.pattern_max_len,
};
- NLA_PUT(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
- sizeof(pat), &pat);
+ if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
+ sizeof(pat), &pat))
+ goto nla_put_failure;
}
nla_nest_end(msg, nl_wowlan);
@@ -1032,16 +1066,20 @@
if (nl80211_put_iface_combinations(&dev->wiphy, msg))
goto nla_put_failure;
- if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME)
- NLA_PUT_U32(msg, NL80211_ATTR_DEVICE_AP_SME,
- dev->wiphy.ap_sme_capa);
+ if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
+ nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
+ dev->wiphy.ap_sme_capa))
+ goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_ATTR_FEATURE_FLAGS, dev->wiphy.features);
+ if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS,
+ dev->wiphy.features))
+ goto nla_put_failure;
- if (dev->wiphy.ht_capa_mod_mask)
- NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
- sizeof(*dev->wiphy.ht_capa_mod_mask),
- dev->wiphy.ht_capa_mod_mask);
+ if (dev->wiphy.ht_capa_mod_mask &&
+ nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
+ sizeof(*dev->wiphy.ht_capa_mod_mask),
+ dev->wiphy.ht_capa_mod_mask))
+ goto nla_put_failure;
return genlmsg_end(msg, hdr);
@@ -1484,14 +1522,15 @@
if (!hdr)
return -1;
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
- NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
-
- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION,
- rdev->devlist_generation ^
- (cfg80211_rdev_list_generation << 2));
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name) ||
+ nla_put_u32(msg, NL80211_ATTR_IFTYPE,
+ dev->ieee80211_ptr->iftype) ||
+ nla_put_u32(msg, NL80211_ATTR_GENERATION,
+ rdev->devlist_generation ^
+ (cfg80211_rdev_list_generation << 2)))
+ goto nla_put_failure;
return genlmsg_end(msg, hdr);
@@ -1789,35 +1828,34 @@
struct nlattr *key;
struct get_key_cookie *cookie = c;
- if (params->key)
- NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
- params->key_len, params->key);
-
- if (params->seq)
- NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
- params->seq_len, params->seq);
-
- if (params->cipher)
- NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
- params->cipher);
+ if ((params->key &&
+ nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
+ params->key_len, params->key)) ||
+ (params->seq &&
+ nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
+ params->seq_len, params->seq)) ||
+ (params->cipher &&
+ nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
+ params->cipher)))
+ goto nla_put_failure;
key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
if (!key)
goto nla_put_failure;
- if (params->key)
- NLA_PUT(cookie->msg, NL80211_KEY_DATA,
- params->key_len, params->key);
+ if ((params->key &&
+ nla_put(cookie->msg, NL80211_KEY_DATA,
+ params->key_len, params->key)) ||
+ (params->seq &&
+ nla_put(cookie->msg, NL80211_KEY_SEQ,
+ params->seq_len, params->seq)) ||
+ (params->cipher &&
+ nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
+ params->cipher)))
+ goto nla_put_failure;
- if (params->seq)
- NLA_PUT(cookie->msg, NL80211_KEY_SEQ,
- params->seq_len, params->seq);
-
- if (params->cipher)
- NLA_PUT_U32(cookie->msg, NL80211_KEY_CIPHER,
- params->cipher);
-
- NLA_PUT_U8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx);
+ if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx))
+ goto nla_put_failure;
nla_nest_end(cookie->msg, key);
@@ -1875,10 +1913,12 @@
cookie.msg = msg;
cookie.idx = key_idx;
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
- NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
- if (mac_addr)
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
+ goto nla_put_failure;
+ if (mac_addr &&
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
+ goto nla_put_failure;
if (pairwise && mac_addr &&
!(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
@@ -2368,15 +2408,15 @@
/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
bitrate = cfg80211_calculate_bitrate(info);
- if (bitrate > 0)
- NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
-
- if (info->flags & RATE_INFO_FLAGS_MCS)
- NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS, info->mcs);
- if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
- NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
- if (info->flags & RATE_INFO_FLAGS_SHORT_GI)
- NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
+ if ((bitrate > 0 &&
+ nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate)) ||
+ ((info->flags & RATE_INFO_FLAGS_MCS) &&
+ nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) ||
+ ((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) &&
+ nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) ||
+ ((info->flags & RATE_INFO_FLAGS_SHORT_GI) &&
+ nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)))
+ goto nla_put_failure;
nla_nest_end(msg, rate);
return true;
@@ -2398,43 +2438,50 @@
if (!hdr)
return -1;
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
-
- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, sinfo->generation);
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
+ nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
+ goto nla_put_failure;
sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
if (!sinfoattr)
goto nla_put_failure;
- if (sinfo->filled & STATION_INFO_CONNECTED_TIME)
- NLA_PUT_U32(msg, NL80211_STA_INFO_CONNECTED_TIME,
- sinfo->connected_time);
- if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
- NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
- sinfo->inactive_time);
- if (sinfo->filled & STATION_INFO_RX_BYTES)
- NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES,
- sinfo->rx_bytes);
- if (sinfo->filled & STATION_INFO_TX_BYTES)
- NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES,
- sinfo->tx_bytes);
- if (sinfo->filled & STATION_INFO_LLID)
- NLA_PUT_U16(msg, NL80211_STA_INFO_LLID,
- sinfo->llid);
- if (sinfo->filled & STATION_INFO_PLID)
- NLA_PUT_U16(msg, NL80211_STA_INFO_PLID,
- sinfo->plid);
- if (sinfo->filled & STATION_INFO_PLINK_STATE)
- NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
- sinfo->plink_state);
+ if ((sinfo->filled & STATION_INFO_CONNECTED_TIME) &&
+ nla_put_u32(msg, NL80211_STA_INFO_CONNECTED_TIME,
+ sinfo->connected_time))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_INACTIVE_TIME) &&
+ nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME,
+ sinfo->inactive_time))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_RX_BYTES) &&
+ nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
+ sinfo->rx_bytes))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_TX_BYTES) &&
+ nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
+ sinfo->tx_bytes))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_LLID) &&
+ nla_put_u16(msg, NL80211_STA_INFO_LLID, sinfo->llid))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_PLID) &&
+ nla_put_u16(msg, NL80211_STA_INFO_PLID, sinfo->plid))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_PLINK_STATE) &&
+ nla_put_u8(msg, NL80211_STA_INFO_PLINK_STATE,
+ sinfo->plink_state))
+ goto nla_put_failure;
switch (rdev->wiphy.signal_type) {
case CFG80211_SIGNAL_TYPE_MBM:
- if (sinfo->filled & STATION_INFO_SIGNAL)
- NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
- sinfo->signal);
- if (sinfo->filled & STATION_INFO_SIGNAL_AVG)
- NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG,
- sinfo->signal_avg);
+ if ((sinfo->filled & STATION_INFO_SIGNAL) &&
+ nla_put_u8(msg, NL80211_STA_INFO_SIGNAL,
+ sinfo->signal))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_SIGNAL_AVG) &&
+ nla_put_u8(msg, NL80211_STA_INFO_SIGNAL_AVG,
+ sinfo->signal_avg))
+ goto nla_put_failure;
break;
default:
break;
@@ -2449,49 +2496,56 @@
NL80211_STA_INFO_RX_BITRATE))
goto nla_put_failure;
}
- if (sinfo->filled & STATION_INFO_RX_PACKETS)
- NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS,
- sinfo->rx_packets);
- if (sinfo->filled & STATION_INFO_TX_PACKETS)
- NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS,
- sinfo->tx_packets);
- if (sinfo->filled & STATION_INFO_TX_RETRIES)
- NLA_PUT_U32(msg, NL80211_STA_INFO_TX_RETRIES,
- sinfo->tx_retries);
- if (sinfo->filled & STATION_INFO_TX_FAILED)
- NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED,
- sinfo->tx_failed);
- if (sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT)
- NLA_PUT_U32(msg, NL80211_STA_INFO_BEACON_LOSS,
- sinfo->beacon_loss_count);
+ if ((sinfo->filled & STATION_INFO_RX_PACKETS) &&
+ nla_put_u32(msg, NL80211_STA_INFO_RX_PACKETS,
+ sinfo->rx_packets))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_TX_PACKETS) &&
+ nla_put_u32(msg, NL80211_STA_INFO_TX_PACKETS,
+ sinfo->tx_packets))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_TX_RETRIES) &&
+ nla_put_u32(msg, NL80211_STA_INFO_TX_RETRIES,
+ sinfo->tx_retries))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_TX_FAILED) &&
+ nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED,
+ sinfo->tx_failed))
+ goto nla_put_failure;
+ if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) &&
+ nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS,
+ sinfo->beacon_loss_count))
+ goto nla_put_failure;
if (sinfo->filled & STATION_INFO_BSS_PARAM) {
bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
if (!bss_param)
goto nla_put_failure;
- if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT)
- NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_CTS_PROT);
- if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE)
- NLA_PUT_FLAG(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE);
- if (sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME)
- NLA_PUT_FLAG(msg,
- NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME);
- NLA_PUT_U8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
- sinfo->bss_param.dtim_period);
- NLA_PUT_U16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
- sinfo->bss_param.beacon_interval);
+ if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
+ nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
+ ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
+ nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
+ ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
+ nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
+ nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
+ sinfo->bss_param.dtim_period) ||
+ nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
+ sinfo->bss_param.beacon_interval))
+ goto nla_put_failure;
nla_nest_end(msg, bss_param);
}
- if (sinfo->filled & STATION_INFO_STA_FLAGS)
- NLA_PUT(msg, NL80211_STA_INFO_STA_FLAGS,
- sizeof(struct nl80211_sta_flag_update),
- &sinfo->sta_flags);
+ if ((sinfo->filled & STATION_INFO_STA_FLAGS) &&
+ nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
+ sizeof(struct nl80211_sta_flag_update),
+ &sinfo->sta_flags))
+ goto nla_put_failure;
nla_nest_end(msg, sinfoattr);
- if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
- NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
- sinfo->assoc_req_ies);
+ if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) &&
+ nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
+ sinfo->assoc_req_ies))
+ goto nla_put_failure;
return genlmsg_end(msg, hdr);
@@ -2913,36 +2967,37 @@
if (!hdr)
return -1;
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
- NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
-
- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, pinfo->generation);
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
+ nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
+ nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
+ goto nla_put_failure;
pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
if (!pinfoattr)
goto nla_put_failure;
- if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
- NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
- pinfo->frame_qlen);
- if (pinfo->filled & MPATH_INFO_SN)
- NLA_PUT_U32(msg, NL80211_MPATH_INFO_SN,
- pinfo->sn);
- if (pinfo->filled & MPATH_INFO_METRIC)
- NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
- pinfo->metric);
- if (pinfo->filled & MPATH_INFO_EXPTIME)
- NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME,
- pinfo->exptime);
- if (pinfo->filled & MPATH_INFO_FLAGS)
- NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS,
- pinfo->flags);
- if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT)
- NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
- pinfo->discovery_timeout);
- if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES)
- NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
- pinfo->discovery_retries);
+ if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
+ nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
+ pinfo->frame_qlen))
+ goto nla_put_failure;
+ if (((pinfo->filled & MPATH_INFO_SN) &&
+ nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
+ ((pinfo->filled & MPATH_INFO_METRIC) &&
+ nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
+ pinfo->metric)) ||
+ ((pinfo->filled & MPATH_INFO_EXPTIME) &&
+ nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
+ pinfo->exptime)) ||
+ ((pinfo->filled & MPATH_INFO_FLAGS) &&
+ nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
+ pinfo->flags)) ||
+ ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
+ nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
+ pinfo->discovery_timeout)) ||
+ ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
+ nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
+ pinfo->discovery_retries)))
+ goto nla_put_failure;
nla_nest_end(msg, pinfoattr);
@@ -3268,47 +3323,48 @@
pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
if (!pinfoattr)
goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
- NLA_PUT_U16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
- cur_params.dot11MeshRetryTimeout);
- NLA_PUT_U16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
- cur_params.dot11MeshConfirmTimeout);
- NLA_PUT_U16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
- cur_params.dot11MeshHoldingTimeout);
- NLA_PUT_U16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
- cur_params.dot11MeshMaxPeerLinks);
- NLA_PUT_U8(msg, NL80211_MESHCONF_MAX_RETRIES,
- cur_params.dot11MeshMaxRetries);
- NLA_PUT_U8(msg, NL80211_MESHCONF_TTL,
- cur_params.dot11MeshTTL);
- NLA_PUT_U8(msg, NL80211_MESHCONF_ELEMENT_TTL,
- cur_params.element_ttl);
- NLA_PUT_U8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
- cur_params.auto_open_plinks);
- NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
- cur_params.dot11MeshHWMPmaxPREQretries);
- NLA_PUT_U32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
- cur_params.path_refresh_time);
- NLA_PUT_U16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
- cur_params.min_discovery_timeout);
- NLA_PUT_U32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
- cur_params.dot11MeshHWMPactivePathTimeout);
- NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
- cur_params.dot11MeshHWMPpreqMinInterval);
- NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
- cur_params.dot11MeshHWMPperrMinInterval);
- NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
- cur_params.dot11MeshHWMPnetDiameterTraversalTime);
- NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
- cur_params.dot11MeshHWMPRootMode);
- NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
- cur_params.dot11MeshHWMPRannInterval);
- NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
- cur_params.dot11MeshGateAnnouncementProtocol);
- NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING,
- cur_params.dot11MeshForwarding);
- NLA_PUT_U32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
- cur_params.rssi_threshold);
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
+ cur_params.dot11MeshRetryTimeout) ||
+ nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
+ cur_params.dot11MeshConfirmTimeout) ||
+ nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
+ cur_params.dot11MeshHoldingTimeout) ||
+ nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
+ cur_params.dot11MeshMaxPeerLinks) ||
+ nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
+ cur_params.dot11MeshMaxRetries) ||
+ nla_put_u8(msg, NL80211_MESHCONF_TTL,
+ cur_params.dot11MeshTTL) ||
+ nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
+ cur_params.element_ttl) ||
+ nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
+ cur_params.auto_open_plinks) ||
+ nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+ cur_params.dot11MeshHWMPmaxPREQretries) ||
+ nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
+ cur_params.path_refresh_time) ||
+ nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+ cur_params.min_discovery_timeout) ||
+ nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+ cur_params.dot11MeshHWMPactivePathTimeout) ||
+ nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+ cur_params.dot11MeshHWMPpreqMinInterval) ||
+ nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
+ cur_params.dot11MeshHWMPperrMinInterval) ||
+ nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+ cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
+ nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
+ cur_params.dot11MeshHWMPRootMode) ||
+ nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
+ cur_params.dot11MeshHWMPRannInterval) ||
+ nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
+ cur_params.dot11MeshGateAnnouncementProtocol) ||
+ nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
+ cur_params.dot11MeshForwarding) ||
+ nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
+ cur_params.rssi_threshold))
+ goto nla_put_failure;
nla_nest_end(msg, pinfoattr);
genlmsg_end(msg, hdr);
return genlmsg_reply(msg, info);
@@ -3539,11 +3595,12 @@
if (!hdr)
goto put_failure;
- NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2,
- cfg80211_regdomain->alpha2);
- if (cfg80211_regdomain->dfs_region)
- NLA_PUT_U8(msg, NL80211_ATTR_DFS_REGION,
- cfg80211_regdomain->dfs_region);
+ if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
+ cfg80211_regdomain->alpha2) ||
+ (cfg80211_regdomain->dfs_region &&
+ nla_put_u8(msg, NL80211_ATTR_DFS_REGION,
+ cfg80211_regdomain->dfs_region)))
+ goto nla_put_failure;
nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
if (!nl_reg_rules)
@@ -3563,18 +3620,19 @@
if (!nl_reg_rule)
goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_ATTR_REG_RULE_FLAGS,
- reg_rule->flags);
- NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_START,
- freq_range->start_freq_khz);
- NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_END,
- freq_range->end_freq_khz);
- NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
- freq_range->max_bandwidth_khz);
- NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
- power_rule->max_antenna_gain);
- NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
- power_rule->max_eirp);
+ if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
+ reg_rule->flags) ||
+ nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
+ freq_range->start_freq_khz) ||
+ nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
+ freq_range->end_freq_khz) ||
+ nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
+ freq_range->max_bandwidth_khz) ||
+ nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
+ power_rule->max_antenna_gain) ||
+ nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
+ power_rule->max_eirp))
+ goto nla_put_failure;
nla_nest_end(msg, nl_reg_rule);
}
@@ -4145,37 +4203,44 @@
genl_dump_check_consistent(cb, hdr, &nl80211_fam);
- NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex);
+ if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
+ goto nla_put_failure;
bss = nla_nest_start(msg, NL80211_ATTR_BSS);
if (!bss)
goto nla_put_failure;
- if (!is_zero_ether_addr(res->bssid))
- NLA_PUT(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid);
- if (res->information_elements && res->len_information_elements)
- NLA_PUT(msg, NL80211_BSS_INFORMATION_ELEMENTS,
- res->len_information_elements,
- res->information_elements);
- if (res->beacon_ies && res->len_beacon_ies &&
- res->beacon_ies != res->information_elements)
- NLA_PUT(msg, NL80211_BSS_BEACON_IES,
- res->len_beacon_ies, res->beacon_ies);
- if (res->tsf)
- NLA_PUT_U64(msg, NL80211_BSS_TSF, res->tsf);
- if (res->beacon_interval)
- NLA_PUT_U16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval);
- NLA_PUT_U16(msg, NL80211_BSS_CAPABILITY, res->capability);
- NLA_PUT_U32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq);
- NLA_PUT_U32(msg, NL80211_BSS_SEEN_MS_AGO,
- jiffies_to_msecs(jiffies - intbss->ts));
+ if ((!is_zero_ether_addr(res->bssid) &&
+ nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)) ||
+ (res->information_elements && res->len_information_elements &&
+ nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
+ res->len_information_elements,
+ res->information_elements)) ||
+ (res->beacon_ies && res->len_beacon_ies &&
+ res->beacon_ies != res->information_elements &&
+ nla_put(msg, NL80211_BSS_BEACON_IES,
+ res->len_beacon_ies, res->beacon_ies)))
+ goto nla_put_failure;
+ if (res->tsf &&
+ nla_put_u64(msg, NL80211_BSS_TSF, res->tsf))
+ goto nla_put_failure;
+ if (res->beacon_interval &&
+ nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
+ goto nla_put_failure;
+ if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
+ nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
+ nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
+ jiffies_to_msecs(jiffies - intbss->ts)))
+ goto nla_put_failure;
switch (rdev->wiphy.signal_type) {
case CFG80211_SIGNAL_TYPE_MBM:
- NLA_PUT_U32(msg, NL80211_BSS_SIGNAL_MBM, res->signal);
+ if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
+ goto nla_put_failure;
break;
case CFG80211_SIGNAL_TYPE_UNSPEC:
- NLA_PUT_U8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal);
+ if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
+ goto nla_put_failure;
break;
default:
break;
@@ -4184,14 +4249,16 @@
switch (wdev->iftype) {
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
- if (intbss == wdev->current_bss)
- NLA_PUT_U32(msg, NL80211_BSS_STATUS,
- NL80211_BSS_STATUS_ASSOCIATED);
+ if (intbss == wdev->current_bss &&
+ nla_put_u32(msg, NL80211_BSS_STATUS,
+ NL80211_BSS_STATUS_ASSOCIATED))
+ goto nla_put_failure;
break;
case NL80211_IFTYPE_ADHOC:
- if (intbss == wdev->current_bss)
- NLA_PUT_U32(msg, NL80211_BSS_STATUS,
- NL80211_BSS_STATUS_IBSS_JOINED);
+ if (intbss == wdev->current_bss &&
+ nla_put_u32(msg, NL80211_BSS_STATUS,
+ NL80211_BSS_STATUS_IBSS_JOINED))
+ goto nla_put_failure;
break;
default:
break;
@@ -4260,34 +4327,43 @@
if (!hdr)
return -ENOMEM;
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
+ goto nla_put_failure;
infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
if (!infoattr)
goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_SURVEY_INFO_FREQUENCY,
- survey->channel->center_freq);
- if (survey->filled & SURVEY_INFO_NOISE_DBM)
- NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE,
- survey->noise);
- if (survey->filled & SURVEY_INFO_IN_USE)
- NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
- if (survey->filled & SURVEY_INFO_CHANNEL_TIME)
- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
- survey->channel_time);
- if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
- survey->channel_time_busy);
- if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
- survey->channel_time_ext_busy);
- if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX)
- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
- survey->channel_time_rx);
- if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX)
- NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
- survey->channel_time_tx);
+ if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
+ survey->channel->center_freq))
+ goto nla_put_failure;
+
+ if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
+ nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
+ goto nla_put_failure;
+ if ((survey->filled & SURVEY_INFO_IN_USE) &&
+ nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
+ goto nla_put_failure;
+ if ((survey->filled & SURVEY_INFO_CHANNEL_TIME) &&
+ nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
+ survey->channel_time))
+ goto nla_put_failure;
+ if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) &&
+ nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
+ survey->channel_time_busy))
+ goto nla_put_failure;
+ if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) &&
+ nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
+ survey->channel_time_ext_busy))
+ goto nla_put_failure;
+ if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) &&
+ nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
+ survey->channel_time_rx))
+ goto nla_put_failure;
+ if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) &&
+ nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
+ survey->channel_time_tx))
+ goto nla_put_failure;
nla_nest_end(msg, infoattr);
@@ -4968,7 +5044,7 @@
NL80211_CMD_TESTMODE);
struct nlattr *tmdata;
- if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx) < 0) {
+ if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
genlmsg_cancel(skb, hdr);
break;
}
@@ -5019,7 +5095,8 @@
return NULL;
}
- NLA_PUT_U32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
+ goto nla_put_failure;
data = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
((void **)skb->cb)[0] = rdev;
@@ -5398,7 +5475,8 @@
if (err)
goto free_msg;
- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
+ if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -5685,7 +5763,8 @@
goto free_msg;
if (msg) {
- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
+ if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
return genlmsg_reply(msg, info);
@@ -5790,7 +5869,8 @@
else
ps_state = NL80211_PS_DISABLED;
- NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state);
+ if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
return genlmsg_reply(msg, info);
@@ -5937,20 +6017,21 @@
if (!nl_wowlan)
goto nla_put_failure;
- if (rdev->wowlan->any)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
- if (rdev->wowlan->disconnect)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
- if (rdev->wowlan->magic_pkt)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
- if (rdev->wowlan->gtk_rekey_failure)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
- if (rdev->wowlan->eap_identity_req)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
- if (rdev->wowlan->four_way_handshake)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
- if (rdev->wowlan->rfkill_release)
- NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
+ if ((rdev->wowlan->any &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
+ (rdev->wowlan->disconnect &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
+ (rdev->wowlan->magic_pkt &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
+ (rdev->wowlan->gtk_rekey_failure &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
+ (rdev->wowlan->eap_identity_req &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
+ (rdev->wowlan->four_way_handshake &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
+ (rdev->wowlan->rfkill_release &&
+ nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
+ goto nla_put_failure;
if (rdev->wowlan->n_patterns) {
struct nlattr *nl_pats, *nl_pat;
int i, pat_len;
@@ -5965,12 +6046,13 @@
if (!nl_pat)
goto nla_put_failure;
pat_len = rdev->wowlan->patterns[i].pattern_len;
- NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_MASK,
- DIV_ROUND_UP(pat_len, 8),
- rdev->wowlan->patterns[i].mask);
- NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
- pat_len,
- rdev->wowlan->patterns[i].pattern);
+ if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
+ DIV_ROUND_UP(pat_len, 8),
+ rdev->wowlan->patterns[i].mask) ||
+ nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
+ pat_len,
+ rdev->wowlan->patterns[i].pattern))
+ goto nla_put_failure;
nla_nest_end(msg, nl_pat);
}
nla_nest_end(msg, nl_pats);
@@ -6243,7 +6325,8 @@
if (err)
goto free_msg;
- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
+ if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -6911,19 +6994,24 @@
nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
if (!nest)
goto nla_put_failure;
- for (i = 0; i < req->n_ssids; i++)
- NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid);
+ for (i = 0; i < req->n_ssids; i++) {
+ if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
+ goto nla_put_failure;
+ }
nla_nest_end(msg, nest);
nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
if (!nest)
goto nla_put_failure;
- for (i = 0; i < req->n_channels; i++)
- NLA_PUT_U32(msg, i, req->channels[i]->center_freq);
+ for (i = 0; i < req->n_channels; i++) {
+ if (nla_put_u32(msg, i, req->channels[i]->center_freq))
+ goto nla_put_failure;
+ }
nla_nest_end(msg, nest);
- if (req->ie)
- NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie);
+ if (req->ie &&
+ nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
+ goto nla_put_failure;
return 0;
nla_put_failure:
@@ -6942,8 +7030,9 @@
if (!hdr)
return -1;
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
+ goto nla_put_failure;
/* ignore errors and send incomplete event anyway */
nl80211_add_scan_req(msg, rdev);
@@ -6967,8 +7056,9 @@
if (!hdr)
return -1;
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
+ goto nla_put_failure;
return genlmsg_end(msg, hdr);
@@ -7091,26 +7181,33 @@
}
/* Userspace can always count this one always being set */
- NLA_PUT_U8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator);
+ if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
+ goto nla_put_failure;
- if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
- NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
- NL80211_REGDOM_TYPE_WORLD);
- else if (request->alpha2[0] == '9' && request->alpha2[1] == '9')
- NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
- NL80211_REGDOM_TYPE_CUSTOM_WORLD);
- else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
- request->intersect)
- NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
- NL80211_REGDOM_TYPE_INTERSECTION);
- else {
- NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
- NL80211_REGDOM_TYPE_COUNTRY);
- NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, request->alpha2);
+ if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
+ if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
+ NL80211_REGDOM_TYPE_WORLD))
+ goto nla_put_failure;
+ } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
+ if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
+ NL80211_REGDOM_TYPE_CUSTOM_WORLD))
+ goto nla_put_failure;
+ } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
+ request->intersect) {
+ if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
+ NL80211_REGDOM_TYPE_INTERSECTION))
+ goto nla_put_failure;
+ } else {
+ if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
+ NL80211_REGDOM_TYPE_COUNTRY) ||
+ nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
+ request->alpha2))
+ goto nla_put_failure;
}
- if (wiphy_idx_valid(request->wiphy_idx))
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx);
+ if (wiphy_idx_valid(request->wiphy_idx) &&
+ nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7144,9 +7241,10 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_FRAME, len, buf))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7224,10 +7322,11 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7275,15 +7374,15 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- if (bssid)
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
- NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status);
- if (req_ie)
- NLA_PUT(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie);
- if (resp_ie)
- NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) ||
+ nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status) ||
+ (req_ie &&
+ nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
+ (resp_ie &&
+ nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7315,13 +7414,14 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
- if (req_ie)
- NLA_PUT(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie);
- if (resp_ie)
- NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
+ (req_ie &&
+ nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
+ (resp_ie &&
+ nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7352,14 +7452,14 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- if (from_ap && reason)
- NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason);
- if (from_ap)
- NLA_PUT_FLAG(msg, NL80211_ATTR_DISCONNECTED_BY_AP);
- if (ie)
- NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ (from_ap && reason &&
+ nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
+ (from_ap &&
+ nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
+ (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7390,9 +7490,10 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7423,11 +7524,12 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr);
- if (ie_len && ie)
- NLA_PUT(msg, NL80211_ATTR_IE, ie_len , ie);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr) ||
+ (ie_len && ie &&
+ nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7458,15 +7560,14 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- if (addr)
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
- if (key_id != -1)
- NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
- if (tsc)
- NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
+ nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
+ (key_id != -1 &&
+ nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
+ (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7501,7 +7602,8 @@
* Since we are applying the beacon hint to a wiphy we know its
* wiphy_idx is valid
*/
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
+ goto nla_put_failure;
/* Before */
nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
@@ -7553,14 +7655,16 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type);
- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type) ||
+ nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
+ goto nla_put_failure;
- if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL)
- NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
+ if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
+ nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7631,8 +7735,9 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7668,9 +7773,10 @@
return true;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
+ goto nla_put_failure;
err = genlmsg_end(msg, hdr);
if (err < 0) {
@@ -7719,12 +7825,13 @@
return -ENOMEM;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
- if (sig_dbm)
- NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm);
- NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
+ (sig_dbm &&
+ nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
+ nla_put(msg, NL80211_ATTR_FRAME, len, buf))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7754,12 +7861,12 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
- if (ack)
- NLA_PUT_FLAG(msg, NL80211_ATTR_ACK);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
+ nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
+ (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -7791,15 +7898,17 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
+ goto nla_put_failure;
pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
if (!pinfoattr)
goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
- rssi_event);
+ if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
+ rssi_event))
+ goto nla_put_failure;
nla_nest_end(msg, pinfoattr);
@@ -7832,16 +7941,18 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
+ goto nla_put_failure;
rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
if (!rekey_attr)
goto nla_put_failure;
- NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR,
- NL80211_REPLAY_CTR_LEN, replay_ctr);
+ if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
+ NL80211_REPLAY_CTR_LEN, replay_ctr))
+ goto nla_put_failure;
nla_nest_end(msg, rekey_attr);
@@ -7874,17 +7985,19 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
+ goto nla_put_failure;
attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
if (!attr)
goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index);
- NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid);
- if (preauth)
- NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH);
+ if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
+ nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
+ (preauth &&
+ nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
+ goto nla_put_failure;
nla_nest_end(msg, attr);
@@ -7918,15 +8031,17 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer))
+ goto nla_put_failure;
pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
if (!pinfoattr)
goto nla_put_failure;
- NLA_PUT_U32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets);
+ if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
+ goto nla_put_failure;
nla_nest_end(msg, pinfoattr);
@@ -7960,12 +8075,12 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
- NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
- NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
- if (acked)
- NLA_PUT_FLAG(msg, NL80211_ATTR_ACK);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
+ nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
+ (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
+ goto nla_put_failure;
err = genlmsg_end(msg, hdr);
if (err < 0) {
@@ -8005,12 +8120,13 @@
return;
}
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
- if (freq)
- NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
- if (sig_dbm)
- NLA_PUT_U32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm);
- NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame);
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ (freq &&
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
+ (sig_dbm &&
+ nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
+ nla_put(msg, NL80211_ATTR_FRAME, len, frame))
+ goto nla_put_failure;
genlmsg_end(msg, hdr);
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index 0af7f54..9f544c9 100644
--- a/net/wireless/wext-core.c
+++ b/net/wireless/wext-core.c
@@ -402,7 +402,8 @@
r->ifi_flags = dev_get_flags(dev);
r->ifi_change = 0; /* Wireless changes don't affect those flags */
- NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
+ if (nla_put_string(skb, IFLA_IFNAME, dev->name))
+ goto nla_put_failure;
return nlh;
nla_put_failure:
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 7128dde..44293b3 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -756,40 +756,50 @@
{
copy_to_user_state(x, p);
- if (x->coaddr)
- NLA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);
+ if (x->coaddr &&
+ nla_put(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr))
+ goto nla_put_failure;
- if (x->lastused)
- NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused);
+ if (x->lastused &&
+ nla_put_u64(skb, XFRMA_LASTUSED, x->lastused))
+ goto nla_put_failure;
- if (x->aead)
- NLA_PUT(skb, XFRMA_ALG_AEAD, aead_len(x->aead), x->aead);
- if (x->aalg) {
- if (copy_to_user_auth(x->aalg, skb))
- goto nla_put_failure;
+ if (x->aead &&
+ nla_put(skb, XFRMA_ALG_AEAD, aead_len(x->aead), x->aead))
+ goto nla_put_failure;
- NLA_PUT(skb, XFRMA_ALG_AUTH_TRUNC,
- xfrm_alg_auth_len(x->aalg), x->aalg);
- }
- if (x->ealg)
- NLA_PUT(skb, XFRMA_ALG_CRYPT, xfrm_alg_len(x->ealg), x->ealg);
- if (x->calg)
- NLA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
+ if (x->aalg &&
+ (copy_to_user_auth(x->aalg, skb) ||
+ nla_put(skb, XFRMA_ALG_AUTH_TRUNC,
+ xfrm_alg_auth_len(x->aalg), x->aalg)))
+ goto nla_put_failure;
- if (x->encap)
- NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
+ if (x->ealg &&
+ nla_put(skb, XFRMA_ALG_CRYPT, xfrm_alg_len(x->ealg), x->ealg))
+ goto nla_put_failure;
- if (x->tfcpad)
- NLA_PUT_U32(skb, XFRMA_TFCPAD, x->tfcpad);
+ if (x->calg &&
+ nla_put(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg))
+ goto nla_put_failure;
+
+ if (x->encap &&
+ nla_put(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap))
+ goto nla_put_failure;
+
+ if (x->tfcpad &&
+ nla_put_u32(skb, XFRMA_TFCPAD, x->tfcpad))
+ goto nla_put_failure;
if (xfrm_mark_put(skb, &x->mark))
goto nla_put_failure;
- if (x->replay_esn)
- NLA_PUT(skb, XFRMA_REPLAY_ESN_VAL,
- xfrm_replay_state_esn_len(x->replay_esn), x->replay_esn);
+ if (x->replay_esn &&
+ nla_put(skb, XFRMA_REPLAY_ESN_VAL,
+ xfrm_replay_state_esn_len(x->replay_esn),
+ x->replay_esn))
+ goto nla_put_failure;
- if (x->security && copy_sec_ctx(x->security, skb) < 0)
+ if (x->security && copy_sec_ctx(x->security, skb))
goto nla_put_failure;
return 0;
@@ -912,8 +922,9 @@
sph.spdhcnt = si.spdhcnt;
sph.spdhmcnt = si.spdhmcnt;
- NLA_PUT(skb, XFRMA_SPD_INFO, sizeof(spc), &spc);
- NLA_PUT(skb, XFRMA_SPD_HINFO, sizeof(sph), &sph);
+ if (nla_put(skb, XFRMA_SPD_INFO, sizeof(spc), &spc) ||
+ nla_put(skb, XFRMA_SPD_HINFO, sizeof(sph), &sph))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
@@ -967,8 +978,9 @@
sh.sadhmcnt = si.sadhmcnt;
sh.sadhcnt = si.sadhcnt;
- NLA_PUT_U32(skb, XFRMA_SAD_CNT, si.sadcnt);
- NLA_PUT(skb, XFRMA_SAD_HINFO, sizeof(sh), &sh);
+ if (nla_put_u32(skb, XFRMA_SAD_CNT, si.sadcnt) ||
+ nla_put(skb, XFRMA_SAD_HINFO, sizeof(sh), &sh))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);
@@ -1690,21 +1702,27 @@
id->reqid = x->props.reqid;
id->flags = c->data.aevent;
- if (x->replay_esn)
- NLA_PUT(skb, XFRMA_REPLAY_ESN_VAL,
- xfrm_replay_state_esn_len(x->replay_esn),
- x->replay_esn);
- else
- NLA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay);
+ if (x->replay_esn) {
+ if (nla_put(skb, XFRMA_REPLAY_ESN_VAL,
+ xfrm_replay_state_esn_len(x->replay_esn),
+ x->replay_esn))
+ goto nla_put_failure;
+ } else {
+ if (nla_put(skb, XFRMA_REPLAY_VAL, sizeof(x->replay),
+ &x->replay))
+ goto nla_put_failure;
+ }
+ if (nla_put(skb, XFRMA_LTIME_VAL, sizeof(x->curlft), &x->curlft))
+ goto nla_put_failure;
- NLA_PUT(skb, XFRMA_LTIME_VAL, sizeof(x->curlft), &x->curlft);
+ if ((id->flags & XFRM_AE_RTHR) &&
+ nla_put_u32(skb, XFRMA_REPLAY_THRESH, x->replay_maxdiff))
+ goto nla_put_failure;
- if (id->flags & XFRM_AE_RTHR)
- NLA_PUT_U32(skb, XFRMA_REPLAY_THRESH, x->replay_maxdiff);
-
- if (id->flags & XFRM_AE_ETHR)
- NLA_PUT_U32(skb, XFRMA_ETIMER_THRESH,
- x->replay_maxage * 10 / HZ);
+ if ((id->flags & XFRM_AE_ETHR) &&
+ nla_put_u32(skb, XFRMA_ETIMER_THRESH,
+ x->replay_maxage * 10 / HZ))
+ goto nla_put_failure;
if (xfrm_mark_put(skb, &x->mark))
goto nla_put_failure;
@@ -2835,8 +2853,9 @@
ur->proto = proto;
memcpy(&ur->sel, sel, sizeof(ur->sel));
- if (addr)
- NLA_PUT(skb, XFRMA_COADDR, sizeof(*addr), addr);
+ if (addr &&
+ nla_put(skb, XFRMA_COADDR, sizeof(*addr), addr))
+ goto nla_put_failure;
return nlmsg_end(skb, nlh);