* Re: [PATCH] sis900: Fix mem leak in sis900_rx error path
From: David Miller @ 2011-02-06 2:09 UTC (permalink / raw)
To: jj; +Cc: venza, netdev, linux-kernel
In-Reply-To: <alpine.LNX.2.00.1102052139150.12305@swampdragon.chaosbits.net>
From: Jesper Juhl <jj@chaosbits.net>
Date: Sat, 5 Feb 2011 21:41:53 +0100 (CET)
> Fix memory leak in error path of sis900_rx(). If we don't do this we'll
> leak the skb we dev_alloc_skb()'ed just a few lines above when the
> variable goes out of scope.
>
> Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Applied, thanks Jesper.
^ permalink raw reply
* Re: [PATCH] tcp: Increase the initial congestion window to 10.
From: David Miller @ 2011-02-06 2:14 UTC (permalink / raw)
To: alexander.zimmermann; +Cc: netdev, dccp, therbert
In-Reply-To: <C9A0E70E-D1DB-45CF-ABB1-8CF9A9D03144@comsys.rwth-aachen.de>
From: Alexander Zimmermann <alexander.zimmermann@comsys.rwth-aachen.de>
Date: Fri, 04 Feb 2011 09:38:34 +0100
> Could you add a reference to draft?
>
>> +/* TCP initial congestion window */
>> +#define TCP_INIT_CWND 10
>> +
>> extern struct inet_timewait_death_row tcp_death_row;
Sure, done.
--------------------
tcp: Add reference to initial CWND ietf draft.
Suggested by Alexander Zimmermann
Signed-off-by: David S. Miller <davem@davemloft.net>
---
include/net/tcp.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 7118668..adfe6db 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -196,7 +196,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
/* TCP thin-stream limits */
#define TCP_THIN_LINEAR_RETRIES 6 /* After 6 linear retries, do exp. backoff */
-/* TCP initial congestion window */
+/* TCP initial congestion window as per draft-hkchu-tcpm-initcwnd-01 */
#define TCP_INIT_CWND 10
extern struct inet_timewait_death_row tcp_death_row;
--
1.7.4
^ permalink raw reply related
* RE: [net-next-2.6 4/5] enic: Clean up: Remove support for an older version of hardware
From: Vasanthy Kolluri (vkolluri) @ 2011-02-06 3:13 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20110205.175702.226777511.davem@davemloft.net>
This hardware was never shipped to customers. So we are safe removing
it.
Thanks
Vasanthy
-----Original Message-----
From: David Miller [mailto:davem@davemloft.net]
Sent: Saturday, February 05, 2011 5:57 PM
To: Vasanthy Kolluri (vkolluri)
Cc: netdev@vger.kernel.org
Subject: Re: [net-next-2.6 4/5] enic: Clean up: Remove support for an
older version of hardware
If this hardware ever shipped to any customers, you cannot
simply remove support for it.
Such code must be retained.
^ permalink raw reply
* re: tlan: Code cleanup: checkpatch.pl is relatively happy now.
From: Dan Carpenter @ 2011-02-06 10:43 UTC (permalink / raw)
To: Sakari Ailus; +Cc: netdev
Commit c659c38b279657 "tlan: Code cleanup: checkpatch.pl is relatively
happy now." includes the following change without explanation.
- if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
+ if (head_list->c_stat & TLAN_CSTAT_READY) {
Was this a bug fix or a bug introduce?
regards,
dan carpenter
^ permalink raw reply
* [PATCH 4/4] m68k/atari: ARAnyM - Add support for network access
From: Geert Uytterhoeven @ 2011-02-06 10:51 UTC (permalink / raw)
To: linux-m68k, linux-kernel, cz-bobek-lists-aranym
Cc: Michael Schmitz, Geert Uytterhoeven, Petr Stehlik, Milan Jurik,
netdev
In-Reply-To: <1296989469-7844-1-git-send-email-geert@linux-m68k.org>
From: Michael Schmitz <schmitz@opal.biophys.uni-duesseldorf.de>
Should be signed off by Milan and Petr, really.
[geert] Cleanups and updates
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Petr Stehlik <pstehlik@sophics.cz>
Cc: Milan Jurik <M.Jurik@sh.cvut.cz>
Cc: netdev@vger.kernel.org
---
Changelog:
- Convert to net_device_ops,
- nfeth doesn't need obsolete <net/ieee80211.h>,
- Convert print_mac to %pM,
- Break too long lines,
- Make needlessly global functions static,
- Make version[] const,
- Use pr_*(),
- Use net_device_stats from struct net_device instead of our own,
- Propagate error code from request_irq(),
- Remove unused variable "handled".
---
arch/m68k/Kconfig | 8 ++
arch/m68k/emu/Makefile | 1 +
arch/m68k/emu/nfeth.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 281 insertions(+), 0 deletions(-)
create mode 100644 arch/m68k/emu/nfeth.c
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 6719c56..80df6ee 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -263,6 +263,14 @@ config NFCON
which allows the console output to be redirected to the stderr
output of ARAnyM.
+config NFETH
+ tristate "NatFeat Ethernet support"
+ depends on NET_ETHERNET && NATFEAT
+ help
+ Say Y to include support for the ARAnyM NatFeat network device
+ which will emulate a regular ethernet device while presenting an
+ ethertap device to the host system.
+
comment "Processor type"
config M68020
diff --git a/arch/m68k/emu/Makefile b/arch/m68k/emu/Makefile
index a83ef1e..7dc2010 100644
--- a/arch/m68k/emu/Makefile
+++ b/arch/m68k/emu/Makefile
@@ -6,3 +6,4 @@ obj-y += natfeat.o
obj-$(CONFIG_NFBLOCK) += nfblock.o
obj-$(CONFIG_NFCON) += nfcon.o
+obj-$(CONFIG_NFETH) += nfeth.o
diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c
new file mode 100644
index 0000000..5b2a33d
--- /dev/null
+++ b/arch/m68k/emu/nfeth.c
@@ -0,0 +1,272 @@
+/*
+ * atari_nfeth.c - ARAnyM ethernet card driver for GNU/Linux
+ *
+ * Copyright (c) 2005 Milan Jurik, Petr Stehlik of ARAnyM dev team
+ *
+ * Based on ARAnyM driver for FreeMiNT written by Standa Opichal
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <asm/natfeat.h>
+#include <asm/virtconvert.h>
+
+enum {
+ GET_VERSION = 0,/* no parameters, return NFAPI_VERSION in d0 */
+ XIF_INTLEVEL, /* no parameters, return Interrupt Level in d0 */
+ XIF_IRQ, /* acknowledge interrupt from host */
+ XIF_START, /* (ethX), called on 'ifup', start receiver thread */
+ XIF_STOP, /* (ethX), called on 'ifdown', stop the thread */
+ XIF_READLENGTH, /* (ethX), return size of network data block to read */
+ XIF_READBLOCK, /* (ethX, buffer, size), read block of network data */
+ XIF_WRITEBLOCK, /* (ethX, buffer, size), write block of network data */
+ XIF_GET_MAC, /* (ethX, buffer, size), return MAC HW addr in buffer */
+ XIF_GET_IPHOST, /* (ethX, buffer, size), return IP address of host */
+ XIF_GET_IPATARI,/* (ethX, buffer, size), return IP address of atari */
+ XIF_GET_NETMASK /* (ethX, buffer, size), return IP netmask */
+};
+
+#define DRV_NAME "nfeth"
+#define DRV_VERSION "0.3"
+#define DRV_RELDATE "10/12/2005"
+
+#define MAX_UNIT 8
+
+/* These identify the driver base version and may not be removed. */
+static const char version[] __devinitdata =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
+ " S.Opichal, M.Jurik, P.Stehlik\n"
+ KERN_INFO " http://aranym.atari.org/\n";
+
+MODULE_AUTHOR("Milan Jurik");
+MODULE_DESCRIPTION("Atari NFeth driver");
+MODULE_LICENSE("GPL");
+/*
+MODULE_PARM(nfeth_debug, "i");
+MODULE_PARM_DESC(nfeth_debug, "nfeth_debug level (1-2)");
+*/
+
+
+static long nfEtherID;
+static int nfEtherIRQ;
+
+struct nfeth_private {
+ int ethX;
+};
+
+static struct net_device *nfeth_dev[MAX_UNIT];
+
+static int nfeth_open(struct net_device *dev)
+{
+ struct nfeth_private *priv = netdev_priv(dev);
+ int res;
+
+ res = nf_call(nfEtherID + XIF_START, priv->ethX);
+
+ pr_debug(DRV_NAME ": open %d\n", res);
+
+ /* Ready for data */
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+static int nfeth_stop(struct net_device *dev)
+{
+ struct nfeth_private *priv = netdev_priv(dev);
+
+ /* No more data */
+ netif_stop_queue(dev);
+
+ nf_call(nfEtherID + XIF_STOP, priv->ethX);
+
+ return 0;
+}
+
+/*
+ * Read a packet out of the adapter and pass it to the upper layers
+ */
+static inline void recv_packet(struct net_device *dev)
+{
+ struct nfeth_private *priv = netdev_priv(dev);
+ unsigned short pktlen;
+ struct sk_buff *skb;
+
+ /* read packet length (excluding 32 bit crc) */
+ pktlen = nf_call(nfEtherID + XIF_READLENGTH, priv->ethX);
+
+ pr_debug(DRV_NAME ": recv_packet: %i\n", pktlen);
+
+ if (!pktlen) {
+ pr_debug(DRV_NAME ": recv_packet: pktlen == 0\n");
+ dev->stats.rx_errors++;
+ return;
+ }
+
+ skb = dev_alloc_skb(pktlen + 2);
+ if (!skb) {
+ pr_debug(DRV_NAME
+ ": recv_packet: out of mem (buf_alloc failed)\n");
+ dev->stats.rx_dropped++;
+ return;
+ }
+
+ skb->dev = dev;
+ skb_reserve(skb, 2); /* 16 Byte align */
+ skb_put(skb, pktlen); /* make room */
+ nf_call(nfEtherID + XIF_READBLOCK, priv->ethX, virt_to_phys(skb->data),
+ pktlen);
+
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ dev->last_rx = jiffies;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pktlen;
+
+ /* and enqueue packet */
+ return;
+}
+
+static irqreturn_t nfeth_interrupt(int irq, void *dev_id)
+{
+ int i, m, mask;
+
+ mask = nf_call(nfEtherID + XIF_IRQ, 0);
+ for (i = 0, m = 1; i < MAX_UNIT; m <<= 1, i++) {
+ if (mask & m && nfeth_dev[i]) {
+ recv_packet(nfeth_dev[i]);
+ nf_call(nfEtherID + XIF_IRQ, m);
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static int nfeth_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ int len;
+ char *data, shortpkt[ETH_ZLEN];
+ struct nfeth_private *priv = netdev_priv(dev);
+
+ data = skb->data;
+ len = skb->len;
+ if (len < ETH_ZLEN) {
+ memset(shortpkt, 0, ETH_ZLEN);
+ memcpy(shortpkt, data, len);
+ data = shortpkt;
+ len = ETH_ZLEN;
+ }
+
+ dev->trans_start = jiffies;
+
+ pr_debug(DRV_NAME ": send %d bytes\n", len);
+ nf_call(nfEtherID + XIF_WRITEBLOCK, priv->ethX, virt_to_phys(data),
+ len);
+
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += len;
+
+ dev_kfree_skb(skb);
+ return 0;
+}
+
+static void nfeth_tx_timeout(struct net_device *dev)
+{
+ dev->stats.tx_errors++;
+ netif_wake_queue(dev);
+}
+
+static const struct net_device_ops nfeth_netdev_ops = {
+ .ndo_open = nfeth_open,
+ .ndo_stop = nfeth_stop,
+ .ndo_start_xmit = nfeth_xmit,
+ .ndo_tx_timeout = nfeth_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
+static struct net_device * __init nfeth_probe(int unit)
+{
+ struct net_device *dev;
+ struct nfeth_private *priv;
+ char mac[ETH_ALEN], host_ip[32], local_ip[32];
+ int err;
+
+ if (!nf_call(nfEtherID + XIF_GET_MAC, unit, mac, ETH_ALEN))
+ return NULL;
+
+ dev = alloc_etherdev(sizeof(struct nfeth_private));
+ if (!dev)
+ return NULL;
+
+ dev->irq = nfEtherIRQ;
+ dev->netdev_ops = &nfeth_netdev_ops;
+
+ dev->flags |= NETIF_F_NO_CSUM;
+ memcpy(dev->dev_addr, mac, ETH_ALEN);
+
+ priv = netdev_priv(dev);
+ priv->ethX = unit;
+
+ err = register_netdev(dev);
+ if (err) {
+ free_netdev(dev);
+ return NULL;
+ }
+
+ nf_call(nfEtherID + XIF_GET_IPHOST, unit,
+ host_ip, sizeof(host_ip));
+ nf_call(nfEtherID + XIF_GET_IPATARI, unit,
+ local_ip, sizeof(local_ip));
+
+ pr_info("%s: nfeth addr:%s (%s) HWaddr:%pM\n", dev->name, host_ip,
+ local_ip, mac);
+
+ return dev;
+}
+
+static int __init nfeth_init(void)
+{
+ long ver;
+ int error, i;
+
+ nfEtherID = nf_get_id("ETHERNET");
+ if (!nfEtherID)
+ return -ENODEV;
+
+ ver = nf_call(nfEtherID + GET_VERSION);
+ pr_info("nfeth API %lu\n", ver);
+
+ nfEtherIRQ = nf_call(nfEtherID + XIF_INTLEVEL);
+ error = request_irq(nfEtherIRQ, nfeth_interrupt, IRQF_SHARED,
+ "eth emu", nfeth_interrupt);
+ if (error) {
+ pr_err("nfeth: request for irq %d failed", nfEtherIRQ);
+ return error;
+ }
+
+ for (i = 0; i < MAX_UNIT; i++)
+ nfeth_dev[i] = nfeth_probe(i);
+
+ return 0;
+}
+
+static void __exit nfeth_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_UNIT; i++) {
+ if (nfeth_dev[i]) {
+ unregister_netdev(nfeth_dev[0]);
+ free_netdev(nfeth_dev[0]);
+ }
+ }
+ free_irq(nfEtherIRQ, nfeth_interrupt);
+}
+
+module_init(nfeth_init);
+module_exit(nfeth_cleanup);
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 4/4] m68k/atari: ARAnyM - Add support for network access
From: Petr Stehlik @ 2011-02-06 12:30 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-m68k, linux-kernel, cz-bobek-lists-aranym, Michael Schmitz,
Milan Jurik, netdev
In-Reply-To: <1296989469-7844-5-git-send-email-geert@linux-m68k.org>
Geert Uytterhoeven píše v Ne 06. 02. 2011 v 11:51 +0100:
> From: Michael Schmitz <schmitz@opal.biophys.uni-duesseldorf.de>
>
> Should be signed off by Milan and Petr, really.
>
> [geert] Cleanups and updates
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Petr Stehlik <pstehlik@sophics.cz>
Signed-off-by: Petr Stehlik <pstehlik@sophics.cz>
Petr
P.S. you might want to update the URL - ARAnyM got its own domain:
> + " S.Opichal, M.Jurik, P.Stehlik\n"
> + KERN_INFO " http://aranym.atari.org/\n";
+ KERN_INFO " http://aranym.org/\n";
^ permalink raw reply
* [PATCH net-next] bnx2x: MTU for FCoE L2 ring
From: Vladislav Zolotarov @ 2011-02-06 12:49 UTC (permalink / raw)
To: Dave Miller; +Cc: netdev list, Eilon Greenstein
Always configure an FCoE L2 ring with a mini-jumbo MTU size (2500).
To do that we had to move the rx_buf_size parameter from per
function level to a per ring level.
Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x/bnx2x.h | 7 ++++-
drivers/net/bnx2x/bnx2x_cmn.c | 53 +++++++++++++++++++++++++++----------
drivers/net/bnx2x/bnx2x_cmn.h | 6 ++--
drivers/net/bnx2x/bnx2x_ethtool.c | 2 +-
drivers/net/bnx2x/bnx2x_main.c | 10 +++++-
5 files changed, 57 insertions(+), 21 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index ff87ec3..c29b37e 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -341,6 +341,8 @@ struct bnx2x_fastpath {
/* chip independed shortcut into rx_prods_offset memory */
u32 ustorm_rx_prods_offset;
+ u32 rx_buf_size;
+
dma_addr_t status_blk_mapping;
struct sw_tx_bd *tx_buf_ring;
@@ -428,6 +430,10 @@ struct bnx2x_fastpath {
};
#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var)
+
+/* Use 2500 as a mini-jumbo MTU for FCoE */
+#define BNX2X_FCOE_MINI_JUMBO_MTU 2500
+
#ifdef BCM_CNIC
/* FCoE L2 `fastpath' is right after the eth entries */
#define FCOE_IDX BNX2X_NUM_ETH_QUEUES(bp)
@@ -911,7 +917,6 @@ struct bnx2x {
int tx_ring_size;
u32 rx_csum;
- u32 rx_buf_size;
/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
#define ETH_MIN_PACKET_SIZE 60
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 710ce5d..844afce 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -232,7 +232,7 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
/* move empty skb from pool to prod and map it */
prod_rx_buf->skb = fp->tpa_pool[queue].skb;
mapping = dma_map_single(&bp->pdev->dev, fp->tpa_pool[queue].skb->data,
- bp->rx_buf_size, DMA_FROM_DEVICE);
+ fp->rx_buf_size, DMA_FROM_DEVICE);
dma_unmap_addr_set(prod_rx_buf, mapping, mapping);
/* move partial skb from cons to pool (don't unmap yet) */
@@ -333,13 +333,13 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
struct sw_rx_bd *rx_buf = &fp->tpa_pool[queue];
struct sk_buff *skb = rx_buf->skb;
/* alloc new skb */
- struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+ struct sk_buff *new_skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size);
/* Unmap skb in the pool anyway, as we are going to change
pool entry status to BNX2X_TPA_STOP even if new skb allocation
fails. */
dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size, DMA_FROM_DEVICE);
+ fp->rx_buf_size, DMA_FROM_DEVICE);
if (likely(new_skb)) {
/* fix ip xsum and give it to the stack */
@@ -349,10 +349,10 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
prefetch(((char *)(skb)) + L1_CACHE_BYTES);
#ifdef BNX2X_STOP_ON_ERROR
- if (pad + len > bp->rx_buf_size) {
+ if (pad + len > fp->rx_buf_size) {
BNX2X_ERR("skb_put is about to fail... "
"pad %d len %d rx_buf_size %d\n",
- pad, len, bp->rx_buf_size);
+ pad, len, fp->rx_buf_size);
bnx2x_panic();
return;
}
@@ -582,7 +582,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) {
dma_unmap_single(&bp->pdev->dev,
dma_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size,
+ fp->rx_buf_size,
DMA_FROM_DEVICE);
skb_reserve(skb, pad);
skb_put(skb, len);
@@ -821,19 +821,16 @@ void bnx2x_init_rx_rings(struct bnx2x *bp)
u16 ring_prod;
int i, j;
- bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN +
- IP_HEADER_ALIGNMENT_PADDING;
-
- DP(NETIF_MSG_IFUP,
- "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size);
-
for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
+ DP(NETIF_MSG_IFUP,
+ "mtu %d rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size);
+
if (!fp->disable_tpa) {
for (i = 0; i < max_agg_queues; i++) {
fp->tpa_pool[i].skb =
- netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+ netdev_alloc_skb(bp->dev, fp->rx_buf_size);
if (!fp->tpa_pool[i].skb) {
BNX2X_ERR("Failed to allocate TPA "
"skb pool for queue[%d] - "
@@ -941,7 +938,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
dma_unmap_single(&bp->pdev->dev,
dma_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size, DMA_FROM_DEVICE);
+ fp->rx_buf_size, DMA_FROM_DEVICE);
rx_buf->skb = NULL;
dev_kfree_skb(skb);
@@ -1249,6 +1246,31 @@ static inline int bnx2x_set_real_num_queues(struct bnx2x *bp)
return rc;
}
+static inline void bnx2x_set_rx_buf_size(struct bnx2x *bp)
+{
+ int i;
+
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ /* Always use a mini-jumbo MTU for the FCoE L2 ring */
+ if (IS_FCOE_IDX(i))
+ /*
+ * Although there are no IP frames expected to arrive to
+ * this ring we still want to add an
+ * IP_HEADER_ALIGNMENT_PADDING to prevent a buffer
+ * overrun attack.
+ */
+ fp->rx_buf_size =
+ BNX2X_FCOE_MINI_JUMBO_MTU + ETH_OVREHEAD +
+ BNX2X_RX_ALIGN + IP_HEADER_ALIGNMENT_PADDING;
+ else
+ fp->rx_buf_size =
+ bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN +
+ IP_HEADER_ALIGNMENT_PADDING;
+ }
+}
+
/* must be called with rtnl_lock */
int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
{
@@ -1272,6 +1294,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
/* must be called before memory allocation and HW init */
bnx2x_ilt_set_info(bp);
+ /* Set the receive queues buffer size */
+ bnx2x_set_rx_buf_size(bp);
+
if (bnx2x_alloc_mem(bp))
return -ENOMEM;
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index 03eb4d6..f062d5d 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -822,11 +822,11 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index];
dma_addr_t mapping;
- skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+ skb = netdev_alloc_skb(bp->dev, fp->rx_buf_size);
if (unlikely(skb == NULL))
return -ENOMEM;
- mapping = dma_map_single(&bp->pdev->dev, skb->data, bp->rx_buf_size,
+ mapping = dma_map_single(&bp->pdev->dev, skb->data, fp->rx_buf_size,
DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
dev_kfree_skb(skb);
@@ -892,7 +892,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
if (fp->tpa_state[i] == BNX2X_TPA_START)
dma_unmap_single(&bp->pdev->dev,
dma_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size, DMA_FROM_DEVICE);
+ fp->rx_buf_size, DMA_FROM_DEVICE);
dev_kfree_skb(skb);
rx_buf->skb = NULL;
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 5b44a8b..816fef6 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -1618,7 +1618,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
/* prepare the loopback packet */
pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ?
bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN);
- skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+ skb = netdev_alloc_skb(bp->dev, fp_rx->rx_buf_size);
if (!skb) {
rc = -ENOMEM;
goto test_loopback_exit;
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index ae8d20a..4b2cc1f 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -2478,8 +2478,14 @@ static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp,
rxq_init->sge_map = fp->rx_sge_mapping;
rxq_init->rcq_map = fp->rx_comp_mapping;
rxq_init->rcq_np_map = fp->rx_comp_mapping + BCM_PAGE_SIZE;
- rxq_init->mtu = bp->dev->mtu;
- rxq_init->buf_sz = bp->rx_buf_size;
+
+ /* Always use mini-jumbo MTU for FCoE L2 ring */
+ if (IS_FCOE_FP(fp))
+ rxq_init->mtu = BNX2X_FCOE_MINI_JUMBO_MTU;
+ else
+ rxq_init->mtu = bp->dev->mtu;
+
+ rxq_init->buf_sz = fp->rx_buf_size;
rxq_init->cl_qzone_id = fp->cl_qzone_id;
rxq_init->cl_id = fp->cl_id;
rxq_init->spcl_id = fp->cl_id;
--
1.7.0.4
^ permalink raw reply related
* Re: [Aranym-dev] [PATCH 4/4] m68k/atari: ARAnyM - Add support for network access
From: Milan Jurik @ 2011-02-06 12:52 UTC (permalink / raw)
To: aranym
Cc: linux-m68k, linux-kernel, cz-bobek-lists-aranym, Milan Jurik,
Michael Schmitz, netdev, Geert Uytterhoeven
In-Reply-To: <1296989469-7844-5-git-send-email-geert@linux-m68k.org>
Hi,
Signed-off-by: Milan Jurik <milan.jurik@xylab.cz>
The original e-mail address is dead for some time.
Best regards,
Milan
Geert Uytterhoeven píše v ne 06. 02. 2011 v 11:51 +0100:
> From: Michael Schmitz <schmitz@opal.biophys.uni-duesseldorf.de>
>
> Should be signed off by Milan and Petr, really.
>
> [geert] Cleanups and updates
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Petr Stehlik <pstehlik@sophics.cz>
> Cc: Milan Jurik <M.Jurik@sh.cvut.cz>
> Cc: netdev@vger.kernel.org
>
> ---
> Changelog:
> - Convert to net_device_ops,
> - nfeth doesn't need obsolete <net/ieee80211.h>,
> - Convert print_mac to %pM,
> - Break too long lines,
> - Make needlessly global functions static,
> - Make version[] const,
> - Use pr_*(),
> - Use net_device_stats from struct net_device instead of our own,
> - Propagate error code from request_irq(),
> - Remove unused variable "handled".
> ---
> arch/m68k/Kconfig | 8 ++
> arch/m68k/emu/Makefile | 1 +
> arch/m68k/emu/nfeth.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 281 insertions(+), 0 deletions(-)
> create mode 100644 arch/m68k/emu/nfeth.c
>
> diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
> index 6719c56..80df6ee 100644
> --- a/arch/m68k/Kconfig
> +++ b/arch/m68k/Kconfig
> @@ -263,6 +263,14 @@ config NFCON
> which allows the console output to be redirected to the stderr
> output of ARAnyM.
>
> +config NFETH
> + tristate "NatFeat Ethernet support"
> + depends on NET_ETHERNET && NATFEAT
> + help
> + Say Y to include support for the ARAnyM NatFeat network device
> + which will emulate a regular ethernet device while presenting an
> + ethertap device to the host system.
> +
> comment "Processor type"
>
> config M68020
> diff --git a/arch/m68k/emu/Makefile b/arch/m68k/emu/Makefile
> index a83ef1e..7dc2010 100644
> --- a/arch/m68k/emu/Makefile
> +++ b/arch/m68k/emu/Makefile
> @@ -6,3 +6,4 @@ obj-y += natfeat.o
>
> obj-$(CONFIG_NFBLOCK) += nfblock.o
> obj-$(CONFIG_NFCON) += nfcon.o
> +obj-$(CONFIG_NFETH) += nfeth.o
> diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c
> new file mode 100644
> index 0000000..5b2a33d
> --- /dev/null
> +++ b/arch/m68k/emu/nfeth.c
> @@ -0,0 +1,272 @@
> +/*
> + * atari_nfeth.c - ARAnyM ethernet card driver for GNU/Linux
> + *
> + * Copyright (c) 2005 Milan Jurik, Petr Stehlik of ARAnyM dev team
> + *
> + * Based on ARAnyM driver for FreeMiNT written by Standa Opichal
> + *
> + * This software may be used and distributed according to the terms of
> + * the GNU General Public License (GPL), incorporated herein by reference.
> + */
> +
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
> +#include <linux/module.h>
> +#include <asm/natfeat.h>
> +#include <asm/virtconvert.h>
> +
> +enum {
> + GET_VERSION = 0,/* no parameters, return NFAPI_VERSION in d0 */
> + XIF_INTLEVEL, /* no parameters, return Interrupt Level in d0 */
> + XIF_IRQ, /* acknowledge interrupt from host */
> + XIF_START, /* (ethX), called on 'ifup', start receiver thread */
> + XIF_STOP, /* (ethX), called on 'ifdown', stop the thread */
> + XIF_READLENGTH, /* (ethX), return size of network data block to read */
> + XIF_READBLOCK, /* (ethX, buffer, size), read block of network data */
> + XIF_WRITEBLOCK, /* (ethX, buffer, size), write block of network data */
> + XIF_GET_MAC, /* (ethX, buffer, size), return MAC HW addr in buffer */
> + XIF_GET_IPHOST, /* (ethX, buffer, size), return IP address of host */
> + XIF_GET_IPATARI,/* (ethX, buffer, size), return IP address of atari */
> + XIF_GET_NETMASK /* (ethX, buffer, size), return IP netmask */
> +};
> +
> +#define DRV_NAME "nfeth"
> +#define DRV_VERSION "0.3"
> +#define DRV_RELDATE "10/12/2005"
> +
> +#define MAX_UNIT 8
> +
> +/* These identify the driver base version and may not be removed. */
> +static const char version[] __devinitdata =
> + KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
> + " S.Opichal, M.Jurik, P.Stehlik\n"
> + KERN_INFO " http://aranym.atari.org/\n";
> +
> +MODULE_AUTHOR("Milan Jurik");
> +MODULE_DESCRIPTION("Atari NFeth driver");
> +MODULE_LICENSE("GPL");
> +/*
> +MODULE_PARM(nfeth_debug, "i");
> +MODULE_PARM_DESC(nfeth_debug, "nfeth_debug level (1-2)");
> +*/
> +
> +
> +static long nfEtherID;
> +static int nfEtherIRQ;
> +
> +struct nfeth_private {
> + int ethX;
> +};
> +
> +static struct net_device *nfeth_dev[MAX_UNIT];
> +
> +static int nfeth_open(struct net_device *dev)
> +{
> + struct nfeth_private *priv = netdev_priv(dev);
> + int res;
> +
> + res = nf_call(nfEtherID + XIF_START, priv->ethX);
> +
> + pr_debug(DRV_NAME ": open %d\n", res);
> +
> + /* Ready for data */
> + netif_start_queue(dev);
> +
> + return 0;
> +}
> +
> +static int nfeth_stop(struct net_device *dev)
> +{
> + struct nfeth_private *priv = netdev_priv(dev);
> +
> + /* No more data */
> + netif_stop_queue(dev);
> +
> + nf_call(nfEtherID + XIF_STOP, priv->ethX);
> +
> + return 0;
> +}
> +
> +/*
> + * Read a packet out of the adapter and pass it to the upper layers
> + */
> +static inline void recv_packet(struct net_device *dev)
> +{
> + struct nfeth_private *priv = netdev_priv(dev);
> + unsigned short pktlen;
> + struct sk_buff *skb;
> +
> + /* read packet length (excluding 32 bit crc) */
> + pktlen = nf_call(nfEtherID + XIF_READLENGTH, priv->ethX);
> +
> + pr_debug(DRV_NAME ": recv_packet: %i\n", pktlen);
> +
> + if (!pktlen) {
> + pr_debug(DRV_NAME ": recv_packet: pktlen == 0\n");
> + dev->stats.rx_errors++;
> + return;
> + }
> +
> + skb = dev_alloc_skb(pktlen + 2);
> + if (!skb) {
> + pr_debug(DRV_NAME
> + ": recv_packet: out of mem (buf_alloc failed)\n");
> + dev->stats.rx_dropped++;
> + return;
> + }
> +
> + skb->dev = dev;
> + skb_reserve(skb, 2); /* 16 Byte align */
> + skb_put(skb, pktlen); /* make room */
> + nf_call(nfEtherID + XIF_READBLOCK, priv->ethX, virt_to_phys(skb->data),
> + pktlen);
> +
> + skb->protocol = eth_type_trans(skb, dev);
> + netif_rx(skb);
> + dev->last_rx = jiffies;
> + dev->stats.rx_packets++;
> + dev->stats.rx_bytes += pktlen;
> +
> + /* and enqueue packet */
> + return;
> +}
> +
> +static irqreturn_t nfeth_interrupt(int irq, void *dev_id)
> +{
> + int i, m, mask;
> +
> + mask = nf_call(nfEtherID + XIF_IRQ, 0);
> + for (i = 0, m = 1; i < MAX_UNIT; m <<= 1, i++) {
> + if (mask & m && nfeth_dev[i]) {
> + recv_packet(nfeth_dev[i]);
> + nf_call(nfEtherID + XIF_IRQ, m);
> + }
> + }
> + return IRQ_HANDLED;
> +}
> +
> +static int nfeth_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> + int len;
> + char *data, shortpkt[ETH_ZLEN];
> + struct nfeth_private *priv = netdev_priv(dev);
> +
> + data = skb->data;
> + len = skb->len;
> + if (len < ETH_ZLEN) {
> + memset(shortpkt, 0, ETH_ZLEN);
> + memcpy(shortpkt, data, len);
> + data = shortpkt;
> + len = ETH_ZLEN;
> + }
> +
> + dev->trans_start = jiffies;
> +
> + pr_debug(DRV_NAME ": send %d bytes\n", len);
> + nf_call(nfEtherID + XIF_WRITEBLOCK, priv->ethX, virt_to_phys(data),
> + len);
> +
> + dev->stats.tx_packets++;
> + dev->stats.tx_bytes += len;
> +
> + dev_kfree_skb(skb);
> + return 0;
> +}
> +
> +static void nfeth_tx_timeout(struct net_device *dev)
> +{
> + dev->stats.tx_errors++;
> + netif_wake_queue(dev);
> +}
> +
> +static const struct net_device_ops nfeth_netdev_ops = {
> + .ndo_open = nfeth_open,
> + .ndo_stop = nfeth_stop,
> + .ndo_start_xmit = nfeth_xmit,
> + .ndo_tx_timeout = nfeth_tx_timeout,
> + .ndo_validate_addr = eth_validate_addr,
> + .ndo_change_mtu = eth_change_mtu,
> + .ndo_set_mac_address = eth_mac_addr,
> +};
> +
> +static struct net_device * __init nfeth_probe(int unit)
> +{
> + struct net_device *dev;
> + struct nfeth_private *priv;
> + char mac[ETH_ALEN], host_ip[32], local_ip[32];
> + int err;
> +
> + if (!nf_call(nfEtherID + XIF_GET_MAC, unit, mac, ETH_ALEN))
> + return NULL;
> +
> + dev = alloc_etherdev(sizeof(struct nfeth_private));
> + if (!dev)
> + return NULL;
> +
> + dev->irq = nfEtherIRQ;
> + dev->netdev_ops = &nfeth_netdev_ops;
> +
> + dev->flags |= NETIF_F_NO_CSUM;
> + memcpy(dev->dev_addr, mac, ETH_ALEN);
> +
> + priv = netdev_priv(dev);
> + priv->ethX = unit;
> +
> + err = register_netdev(dev);
> + if (err) {
> + free_netdev(dev);
> + return NULL;
> + }
> +
> + nf_call(nfEtherID + XIF_GET_IPHOST, unit,
> + host_ip, sizeof(host_ip));
> + nf_call(nfEtherID + XIF_GET_IPATARI, unit,
> + local_ip, sizeof(local_ip));
> +
> + pr_info("%s: nfeth addr:%s (%s) HWaddr:%pM\n", dev->name, host_ip,
> + local_ip, mac);
> +
> + return dev;
> +}
> +
> +static int __init nfeth_init(void)
> +{
> + long ver;
> + int error, i;
> +
> + nfEtherID = nf_get_id("ETHERNET");
> + if (!nfEtherID)
> + return -ENODEV;
> +
> + ver = nf_call(nfEtherID + GET_VERSION);
> + pr_info("nfeth API %lu\n", ver);
> +
> + nfEtherIRQ = nf_call(nfEtherID + XIF_INTLEVEL);
> + error = request_irq(nfEtherIRQ, nfeth_interrupt, IRQF_SHARED,
> + "eth emu", nfeth_interrupt);
> + if (error) {
> + pr_err("nfeth: request for irq %d failed", nfEtherIRQ);
> + return error;
> + }
> +
> + for (i = 0; i < MAX_UNIT; i++)
> + nfeth_dev[i] = nfeth_probe(i);
> +
> + return 0;
> +}
> +
> +static void __exit nfeth_cleanup(void)
> +{
> + int i;
> +
> + for (i = 0; i < MAX_UNIT; i++) {
> + if (nfeth_dev[i]) {
> + unregister_netdev(nfeth_dev[0]);
> + free_netdev(nfeth_dev[0]);
> + }
> + }
> + free_irq(nfEtherIRQ, nfeth_interrupt);
> +}
> +
> +module_init(nfeth_init);
> +module_exit(nfeth_cleanup);
^ permalink raw reply
* [PATCH net-2.6] bnx2x: Duplication in promisc mode
From: Vladislav Zolotarov @ 2011-02-06 13:14 UTC (permalink / raw)
To: Dave Miller; +Cc: netdev list, Eilon Greenstein
Prevent packets duplication for frames targeting FCoE L2 ring:
packets were arriving to stack from both L2 RSS and from FCoE
L2 in a promiscuous mode.
Configure FCoE L2 ring to DROP_ALL rx mode, when interface is
configured to PROMISC, and to accept only unicast frames, when
interface is configured to ALL_MULTI.
Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x/bnx2x_main.c | 32 +++++++++++++++++++++++---------
1 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index ae8d20a..84608c8 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -4281,9 +4281,12 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST |
BNX2X_ACCEPT_MULTICAST;
#ifdef BCM_CNIC
- cl_id = bnx2x_fcoe(bp, cl_id);
- bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
- BNX2X_ACCEPT_MULTICAST);
+ if (!NO_FCOE(bp)) {
+ cl_id = bnx2x_fcoe(bp, cl_id);
+ bnx2x_rxq_set_mac_filters(bp, cl_id,
+ BNX2X_ACCEPT_UNICAST |
+ BNX2X_ACCEPT_MULTICAST);
+ }
#endif
break;
@@ -4291,18 +4294,29 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST |
BNX2X_ACCEPT_ALL_MULTICAST;
#ifdef BCM_CNIC
- cl_id = bnx2x_fcoe(bp, cl_id);
- bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
- BNX2X_ACCEPT_MULTICAST);
+ /*
+ * Prevent duplication of multicast packets by configuring FCoE
+ * L2 Client to receive only matched unicast frames.
+ */
+ if (!NO_FCOE(bp)) {
+ cl_id = bnx2x_fcoe(bp, cl_id);
+ bnx2x_rxq_set_mac_filters(bp, cl_id,
+ BNX2X_ACCEPT_UNICAST);
+ }
#endif
break;
case BNX2X_RX_MODE_PROMISC:
def_q_filters |= BNX2X_PROMISCUOUS_MODE;
#ifdef BCM_CNIC
- cl_id = bnx2x_fcoe(bp, cl_id);
- bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST |
- BNX2X_ACCEPT_MULTICAST);
+ /*
+ * Prevent packets duplication by configuring DROP_ALL for FCoE
+ * L2 Client.
+ */
+ if (!NO_FCOE(bp)) {
+ cl_id = bnx2x_fcoe(bp, cl_id);
+ bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE);
+ }
#endif
/* pass management unicast packets as well */
llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST;
--
1.7.0.4
^ permalink raw reply related
* Re: tlan: Code cleanup: checkpatch.pl is relatively happy now.
From: Sakari Ailus @ 2011-02-06 13:24 UTC (permalink / raw)
To: Dan Carpenter; +Cc: netdev
In-Reply-To: <20110206104330.GA4384@bicker>
Hi Dan,
Dan Carpenter wrote:
> Commit c659c38b279657 "tlan: Code cleanup: checkpatch.pl is relatively
> happy now." includes the following change without explanation.
>
> - if ( ( head_list->cStat& TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
> + if (head_list->c_stat& TLAN_CSTAT_READY) {
>
> Was this a bug fix or a bug introduce?
Ouch. Introduce in this case, unfortunately. I *thought*
TLAN_CSTAT_READY would have been a single bit instead of a bit mask. I
should have actually checked it, and still put that change into a
separate patch.
This might not be the one and only place where this kind of shortcut was
made --- for 80 characters per line compliance. There are very few,
anyway, in similar places.
I'll recheck the patch and provide a correction, in the coming days likely.
Many thanks for finding this!
--
Sakari Ailus
sakari.ailus@iki.fi
^ permalink raw reply
* [PATCH net-next] bnx2x: Proper netdev->ndo_set_rx_mode() implementation.
From: Vlad Zolotarov @ 2011-02-06 16:50 UTC (permalink / raw)
To: Dave Miller; +Cc: netdev@vger.kernel.org, Eilon Greenstein
Completed the bnx2x_set_rx_mode() to a proper netdev->ndo_set_rx_mode
implementation:
- Added a missing configuration of a unicast MAC addresses list.
- Changed bp->dma_lock from being a mutex to a spinlock as long as it's taken
under netdev->addr_list_lock now.
Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x/bnx2x.h | 13 +-
drivers/net/bnx2x/bnx2x_cmn.c | 17 +-
drivers/net/bnx2x/bnx2x_main.c | 444 +++++++++++++++++++++++++++++++---------
3 files changed, 369 insertions(+), 105 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 8e41837..9821bd9 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -129,6 +129,7 @@ void bnx2x_panic_dump(struct bnx2x *bp);
#endif
#define bnx2x_mc_addr(ha) ((ha)->addr)
+#define bnx2x_uc_addr(ha) ((ha)->addr)
#define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff)
#define U64_HI(x) (u32)(((u64)(x)) >> 32)
@@ -810,6 +811,7 @@ struct bnx2x_slowpath {
struct eth_stats_query fw_stats;
struct mac_configuration_cmd mac_config;
struct mac_configuration_cmd mcast_config;
+ struct mac_configuration_cmd uc_mac_config;
struct client_init_ramrod_data client_init_data;
/* used by dmae command executer */
@@ -939,7 +941,7 @@ struct bnx2x {
struct eth_spe *spq_prod_bd;
struct eth_spe *spq_last_bd;
__le16 *dsb_sp_prod;
- atomic_t spq_left; /* serialize spq */
+ atomic_t cq_spq_left; /* ETH_XXX ramrods credit */
/* used to synchronize spq accesses */
spinlock_t spq_lock;
@@ -949,6 +951,7 @@ struct bnx2x {
u16 eq_prod;
u16 eq_cons;
__le16 *eq_cons_sb;
+ atomic_t eq_spq_left; /* COMMON_XXX ramrods credit */
/* Flags for marking that there is a STAT_QUERY or
SET_MAC ramrod pending */
@@ -1131,7 +1134,7 @@ struct bnx2x {
int dmae_ready;
/* used to synchronize dmae accesses */
- struct mutex dmae_mutex;
+ spinlock_t dmae_lock;
/* used to protect the FW mail box */
struct mutex fw_mb_mutex;
@@ -1447,6 +1450,12 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param);
void bnx2x_calc_fc_adv(struct bnx2x *bp);
int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
u32 data_hi, u32 data_lo, int common);
+
+/* Clears multicast and unicast list configuration in the chip. */
+void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp);
+void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp);
+void bnx2x_invalidate_uc_list(struct bnx2x *bp);
+
void bnx2x_update_coalesce(struct bnx2x *bp);
int bnx2x_get_link_cfg_idx(struct bnx2x *bp);
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 710ce5d..ae98f7d 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -1427,28 +1427,35 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bnx2x_set_eth_mac(bp, 1);
+ /* Clear MC configuration */
+ if (CHIP_IS_E1(bp))
+ bnx2x_invalidate_e1_mc_list(bp);
+ else
+ bnx2x_invalidate_e1h_mc_list(bp);
+
+ /* Clear UC lists configuration */
+ bnx2x_invalidate_uc_list(bp);
+
if (bp->port.pmf)
bnx2x_initial_phy_init(bp, load_mode);
+ /* Initialize Rx filtering */
+ bnx2x_set_rx_mode(bp->dev);
+
/* Start fast path */
switch (load_mode) {
case LOAD_NORMAL:
/* Tx queue should be only reenabled */
netif_tx_wake_all_queues(bp->dev);
/* Initialize the receive filter. */
- bnx2x_set_rx_mode(bp->dev);
break;
case LOAD_OPEN:
netif_tx_start_all_queues(bp->dev);
smp_mb__after_clear_bit();
- /* Initialize the receive filter. */
- bnx2x_set_rx_mode(bp->dev);
break;
case LOAD_DIAG:
- /* Initialize the receive filter. */
- bnx2x_set_rx_mode(bp->dev);
bp->state = BNX2X_STATE_DIAG;
break;
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 8cdcf5b..ea10b26 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -586,7 +586,7 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp,
bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
/* lock the dmae channel */
- mutex_lock(&bp->dmae_mutex);
+ spin_lock_bh(&bp->dmae_lock);
/* reset completion */
*wb_comp = 0;
@@ -617,7 +617,7 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp,
bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
unlock:
- mutex_unlock(&bp->dmae_mutex);
+ spin_unlock_bh(&bp->dmae_lock);
return rc;
}
@@ -1397,7 +1397,7 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp,
}
smp_mb__before_atomic_inc();
- atomic_inc(&bp->spq_left);
+ atomic_inc(&bp->cq_spq_left);
/* push the change in fp->state and towards the memory */
smp_wmb();
@@ -2731,11 +2731,18 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
spin_lock_bh(&bp->spq_lock);
- if (!atomic_read(&bp->spq_left)) {
- BNX2X_ERR("BUG! SPQ ring full!\n");
- spin_unlock_bh(&bp->spq_lock);
- bnx2x_panic();
- return -EBUSY;
+ if (common) {
+ if (!atomic_read(&bp->eq_spq_left)) {
+ BNX2X_ERR("BUG! EQ ring full!\n");
+ spin_unlock_bh(&bp->spq_lock);
+ bnx2x_panic();
+ return -EBUSY;
+ }
+ } else if (!atomic_read(&bp->cq_spq_left)) {
+ BNX2X_ERR("BUG! SPQ ring full!\n");
+ spin_unlock_bh(&bp->spq_lock);
+ bnx2x_panic();
+ return -EBUSY;
}
spe = bnx2x_sp_get_next(bp);
@@ -2766,20 +2773,26 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
spe->data.update_data_addr.lo = cpu_to_le32(data_lo);
/* stats ramrod has it's own slot on the spq */
- if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY)
+ if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY) {
/* It's ok if the actual decrement is issued towards the memory
* somewhere between the spin_lock and spin_unlock. Thus no
* more explict memory barrier is needed.
*/
- atomic_dec(&bp->spq_left);
+ if (common)
+ atomic_dec(&bp->eq_spq_left);
+ else
+ atomic_dec(&bp->cq_spq_left);
+ }
+
DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/,
"SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) "
- "type(0x%x) left %x\n",
+ "type(0x%x) left (ETH, COMMON) (%x,%x)\n",
bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping),
(u32)(U64_LO(bp->spq_mapping) +
(void *)bp->spq_prod_bd - (void *)bp->spq), command,
- HW_CID(bp, cid), data_hi, data_lo, type, atomic_read(&bp->spq_left));
+ HW_CID(bp, cid), data_hi, data_lo, type,
+ atomic_read(&bp->cq_spq_left), atomic_read(&bp->eq_spq_left));
bnx2x_sp_prod_update(bp);
spin_unlock_bh(&bp->spq_lock);
@@ -3691,8 +3704,8 @@ static void bnx2x_eq_int(struct bnx2x *bp)
sw_cons = bp->eq_cons;
sw_prod = bp->eq_prod;
- DP(BNX2X_MSG_SP, "EQ: hw_cons %u sw_cons %u bp->spq_left %u\n",
- hw_cons, sw_cons, atomic_read(&bp->spq_left));
+ DP(BNX2X_MSG_SP, "EQ: hw_cons %u sw_cons %u bp->cq_spq_left %u\n",
+ hw_cons, sw_cons, atomic_read(&bp->eq_spq_left));
for (; sw_cons != hw_cons;
sw_prod = NEXT_EQ_IDX(sw_prod), sw_cons = NEXT_EQ_IDX(sw_cons)) {
@@ -3757,13 +3770,15 @@ static void bnx2x_eq_int(struct bnx2x *bp)
case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_OPEN):
case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_DIAG):
DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
- bp->set_mac_pending = 0;
+ if (elem->message.data.set_mac_event.echo)
+ bp->set_mac_pending = 0;
break;
case (EVENT_RING_OPCODE_SET_MAC |
BNX2X_STATE_CLOSING_WAIT4_HALT):
DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
- bp->set_mac_pending = 0;
+ if (elem->message.data.set_mac_event.echo)
+ bp->set_mac_pending = 0;
break;
default:
/* unknown event log error and continue */
@@ -3775,7 +3790,7 @@ next_spqe:
} /* for */
smp_mb__before_atomic_inc();
- atomic_add(spqe_cnt, &bp->spq_left);
+ atomic_add(spqe_cnt, &bp->eq_spq_left);
bp->eq_cons = sw_cons;
bp->eq_prod = sw_prod;
@@ -4208,7 +4223,7 @@ void bnx2x_update_coalesce(struct bnx2x *bp)
static void bnx2x_init_sp_ring(struct bnx2x *bp)
{
spin_lock_init(&bp->spq_lock);
- atomic_set(&bp->spq_left, MAX_SPQ_PENDING);
+ atomic_set(&bp->cq_spq_left, MAX_SPQ_PENDING);
bp->spq_prod_idx = 0;
bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
@@ -4233,6 +4248,9 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp)
bp->eq_cons = 0;
bp->eq_prod = NUM_EQ_DESC;
bp->eq_cons_sb = BNX2X_EQ_INDEX;
+ /* we want a warning message before it gets rought... */
+ atomic_set(&bp->eq_spq_left,
+ min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1);
}
static void bnx2x_init_ind_table(struct bnx2x *bp)
@@ -5838,7 +5856,7 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
BP_ABS_FUNC(bp), load_code);
bp->dmae_ready = 0;
- mutex_init(&bp->dmae_mutex);
+ spin_lock_init(&bp->dmae_lock);
rc = bnx2x_gunzip_init(bp);
if (rc)
return rc;
@@ -6173,12 +6191,14 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac,
int ramrod_flags = WAIT_RAMROD_COMMON;
bp->set_mac_pending = 1;
- smp_wmb();
config->hdr.length = 1;
config->hdr.offset = cam_offset;
config->hdr.client_id = 0xff;
- config->hdr.reserved1 = 0;
+ /* Mark the single MAC configuration ramrod as opposed to a
+ * UC/MC list configuration).
+ */
+ config->hdr.echo = 1;
/* primary MAC */
config->config_table[0].msb_mac_addr =
@@ -6210,6 +6230,8 @@ static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac,
config->config_table[0].middle_mac_addr,
config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec);
+ mb();
+
bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
U64_HI(bnx2x_sp_mapping(bp, mac_config)),
U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1);
@@ -6274,20 +6296,15 @@ static u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset)
if (CHIP_IS_E1H(bp))
return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp);
else if (CHIP_MODE_IS_4_PORT(bp))
- return BP_FUNC(bp) * 32 + rel_offset;
+ return E2_FUNC_MAX * rel_offset + BP_FUNC(bp);
else
- return BP_VN(bp) * 32 + rel_offset;
+ return E2_FUNC_MAX * rel_offset + BP_VN(bp);
}
/**
* LLH CAM line allocations: currently only iSCSI and ETH macs are
* relevant. In addition, current implementation is tuned for a
* single ETH MAC.
- *
- * When multiple unicast ETH MACs PF configuration in switch
- * independent mode is required (NetQ, multiple netdev MACs,
- * etc.), consider better utilisation of 16 per function MAC
- * entries in the LLH memory.
*/
enum {
LLH_CAM_ISCSI_ETH_LINE = 0,
@@ -6362,14 +6379,37 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set)
bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1);
}
}
-static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset)
+
+static inline u8 bnx2x_e1_cam_mc_offset(struct bnx2x *bp)
+{
+ return CHIP_REV_IS_SLOW(bp) ?
+ (BNX2X_MAX_EMUL_MULTI * (1 + BP_PORT(bp))) :
+ (BNX2X_MAX_MULTICAST * (1 + BP_PORT(bp)));
+}
+
+/* set mc list, do not wait as wait implies sleep and
+ * set_rx_mode can be invoked from non-sleepable context.
+ *
+ * Instead we use the same ramrod data buffer each time we need
+ * to configure a list of addresses, and use the fact that the
+ * list of MACs is changed in an incremental way and that the
+ * function is called under the netif_addr_lock. A temporary
+ * inconsistent CAM configuration (possible in case of a very fast
+ * sequence of add/del/add on the host side) will shortly be
+ * restored by the handler of the last ramrod.
+ */
+static int bnx2x_set_e1_mc_list(struct bnx2x *bp)
{
int i = 0, old;
struct net_device *dev = bp->dev;
+ u8 offset = bnx2x_e1_cam_mc_offset(bp);
struct netdev_hw_addr *ha;
struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config);
dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config);
+ if (netdev_mc_count(dev) > BNX2X_MAX_MULTICAST)
+ return -EINVAL;
+
netdev_for_each_mc_addr(ha, dev) {
/* copy mac */
config_cmd->config_table[i].msb_mac_addr =
@@ -6410,32 +6450,47 @@ static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset)
}
}
+ wmb();
+
config_cmd->hdr.length = i;
config_cmd->hdr.offset = offset;
config_cmd->hdr.client_id = 0xff;
- config_cmd->hdr.reserved1 = 0;
+ /* Mark that this ramrod doesn't use bp->set_mac_pending for
+ * synchronization.
+ */
+ config_cmd->hdr.echo = 0;
- bp->set_mac_pending = 1;
- smp_wmb();
+ mb();
- bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
+ return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
}
-static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp)
+
+void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp)
{
int i;
struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config);
dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config);
int ramrod_flags = WAIT_RAMROD_COMMON;
+ u8 offset = bnx2x_e1_cam_mc_offset(bp);
- bp->set_mac_pending = 1;
- smp_wmb();
-
- for (i = 0; i < config_cmd->hdr.length; i++)
+ for (i = 0; i < BNX2X_MAX_MULTICAST; i++)
SET_FLAG(config_cmd->config_table[i].flags,
MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
T_ETH_MAC_COMMAND_INVALIDATE);
+ wmb();
+
+ config_cmd->hdr.length = BNX2X_MAX_MULTICAST;
+ config_cmd->hdr.offset = offset;
+ config_cmd->hdr.client_id = 0xff;
+ /* We'll wait for a completion this time... */
+ config_cmd->hdr.echo = 1;
+
+ bp->set_mac_pending = 1;
+
+ mb();
+
bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
@@ -6445,6 +6500,44 @@ static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp)
}
+/* Accept one or more multicasts */
+static int bnx2x_set_e1h_mc_list(struct bnx2x *bp)
+{
+ struct net_device *dev = bp->dev;
+ struct netdev_hw_addr *ha;
+ u32 mc_filter[MC_HASH_SIZE];
+ u32 crc, bit, regidx;
+ int i;
+
+ memset(mc_filter, 0, 4 * MC_HASH_SIZE);
+
+ netdev_for_each_mc_addr(ha, dev) {
+ DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n",
+ bnx2x_mc_addr(ha));
+
+ crc = crc32c_le(0, bnx2x_mc_addr(ha),
+ ETH_ALEN);
+ bit = (crc >> 24) & 0xff;
+ regidx = bit >> 5;
+ bit &= 0x1f;
+ mc_filter[regidx] |= (1 << bit);
+ }
+
+ for (i = 0; i < MC_HASH_SIZE; i++)
+ REG_WR(bp, MC_HASH_OFFSET(bp, i),
+ mc_filter[i]);
+
+ return 0;
+}
+
+void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp)
+{
+ int i;
+
+ for (i = 0; i < MC_HASH_SIZE; i++)
+ REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
+}
+
#ifdef BCM_CNIC
/**
* Set iSCSI MAC(s) at the next enties in the CAM after the ETH
@@ -7110,20 +7203,15 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
/* Give HW time to discard old tx messages */
msleep(1);
- if (CHIP_IS_E1(bp)) {
- /* invalidate mc list,
- * wait and poll (interrupts are off)
- */
- bnx2x_invlidate_e1_mc_list(bp);
- bnx2x_set_eth_mac(bp, 0);
-
- } else {
- REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
+ bnx2x_set_eth_mac(bp, 0);
- bnx2x_set_eth_mac(bp, 0);
+ bnx2x_invalidate_uc_list(bp);
- for (i = 0; i < MC_HASH_SIZE; i++)
- REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
+ if (CHIP_IS_E1(bp))
+ bnx2x_invalidate_e1_mc_list(bp);
+ else {
+ bnx2x_invalidate_e1h_mc_list(bp);
+ REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
}
#ifdef BCM_CNIC
@@ -8813,12 +8901,197 @@ static int bnx2x_close(struct net_device *dev)
return 0;
}
+#define E1_MAX_UC_LIST 29
+#define E1H_MAX_UC_LIST 30
+#define E2_MAX_UC_LIST 14
+static inline u8 bnx2x_max_uc_list(struct bnx2x *bp)
+{
+ if (CHIP_IS_E1(bp))
+ return E1_MAX_UC_LIST;
+ else if (CHIP_IS_E1H(bp))
+ return E1H_MAX_UC_LIST;
+ else
+ return E2_MAX_UC_LIST;
+}
+
+
+static inline u8 bnx2x_uc_list_cam_offset(struct bnx2x *bp)
+{
+ if (CHIP_IS_E1(bp))
+ /* CAM Entries for Port0:
+ * 0 - prim ETH MAC
+ * 1 - BCAST MAC
+ * 2 - iSCSI L2 ring ETH MAC
+ * 3-31 - UC MACs
+ *
+ * Port1 entries are allocated the same way starting from
+ * entry 32.
+ */
+ return 3 + 32 * BP_PORT(bp);
+ else if (CHIP_IS_E1H(bp)) {
+ /* CAM Entries:
+ * 0-7 - prim ETH MAC for each function
+ * 8-15 - iSCSI L2 ring ETH MAC for each function
+ * 16 till 255 UC MAC lists for each function
+ *
+ * Remark: There is no FCoE support for E1H, thus FCoE related
+ * MACs are not considered.
+ */
+ return E1H_FUNC_MAX * (CAM_ISCSI_ETH_LINE + 1) +
+ bnx2x_max_uc_list(bp) * BP_FUNC(bp);
+ } else {
+ /* CAM Entries (there is a separate CAM per engine):
+ * 0-4 - prim ETH MAC for each function
+ * 4-7 - iSCSI L2 ring ETH MAC for each function
+ * 8-11 - FIP ucast L2 MAC for each function
+ * 12-15 - ALL_ENODE_MACS mcast MAC for each function
+ * 16 till 71 UC MAC lists for each function
+ */
+ u8 func_idx =
+ (CHIP_MODE_IS_4_PORT(bp) ? BP_FUNC(bp) : BP_VN(bp));
+
+ return E2_FUNC_MAX * (CAM_MAX_PF_LINE + 1) +
+ bnx2x_max_uc_list(bp) * func_idx;
+ }
+}
+
+/* set uc list, do not wait as wait implies sleep and
+ * set_rx_mode can be invoked from non-sleepable context.
+ *
+ * Instead we use the same ramrod data buffer each time we need
+ * to configure a list of addresses, and use the fact that the
+ * list of MACs is changed in an incremental way and that the
+ * function is called under the netif_addr_lock. A temporary
+ * inconsistent CAM configuration (possible in case of very fast
+ * sequence of add/del/add on the host side) will shortly be
+ * restored by the handler of the last ramrod.
+ */
+static int bnx2x_set_uc_list(struct bnx2x *bp)
+{
+ int i = 0, old;
+ struct net_device *dev = bp->dev;
+ u8 offset = bnx2x_uc_list_cam_offset(bp);
+ struct netdev_hw_addr *ha;
+ struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, uc_mac_config);
+ dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, uc_mac_config);
+
+ if (netdev_uc_count(dev) > bnx2x_max_uc_list(bp))
+ return -EINVAL;
+
+ netdev_for_each_uc_addr(ha, dev) {
+ /* copy mac */
+ config_cmd->config_table[i].msb_mac_addr =
+ swab16(*(u16 *)&bnx2x_uc_addr(ha)[0]);
+ config_cmd->config_table[i].middle_mac_addr =
+ swab16(*(u16 *)&bnx2x_uc_addr(ha)[2]);
+ config_cmd->config_table[i].lsb_mac_addr =
+ swab16(*(u16 *)&bnx2x_uc_addr(ha)[4]);
+
+ config_cmd->config_table[i].vlan_id = 0;
+ config_cmd->config_table[i].pf_id = BP_FUNC(bp);
+ config_cmd->config_table[i].clients_bit_vector =
+ cpu_to_le32(1 << BP_L_ID(bp));
+
+ SET_FLAG(config_cmd->config_table[i].flags,
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+ T_ETH_MAC_COMMAND_SET);
+
+ DP(NETIF_MSG_IFUP,
+ "setting UCAST[%d] (%04x:%04x:%04x)\n", i,
+ config_cmd->config_table[i].msb_mac_addr,
+ config_cmd->config_table[i].middle_mac_addr,
+ config_cmd->config_table[i].lsb_mac_addr);
+
+ i++;
+
+ /* Set uc MAC in NIG */
+ bnx2x_set_mac_in_nig(bp, 1, bnx2x_uc_addr(ha),
+ LLH_CAM_ETH_LINE + i);
+ }
+ old = config_cmd->hdr.length;
+ if (old > i) {
+ for (; i < old; i++) {
+ if (CAM_IS_INVALID(config_cmd->
+ config_table[i])) {
+ /* already invalidated */
+ break;
+ }
+ /* invalidate */
+ SET_FLAG(config_cmd->config_table[i].flags,
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+ T_ETH_MAC_COMMAND_INVALIDATE);
+ }
+ }
+
+ wmb();
+
+ config_cmd->hdr.length = i;
+ config_cmd->hdr.offset = offset;
+ config_cmd->hdr.client_id = 0xff;
+ /* Mark that this ramrod doesn't use bp->set_mac_pending for
+ * synchronization.
+ */
+ config_cmd->hdr.echo = 0;
+
+ mb();
+
+ return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
+ U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
+
+}
+
+void bnx2x_invalidate_uc_list(struct bnx2x *bp)
+{
+ int i;
+ struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, uc_mac_config);
+ dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, uc_mac_config);
+ int ramrod_flags = WAIT_RAMROD_COMMON;
+ u8 offset = bnx2x_uc_list_cam_offset(bp);
+ u8 max_list_size = bnx2x_max_uc_list(bp);
+
+ for (i = 0; i < max_list_size; i++) {
+ SET_FLAG(config_cmd->config_table[i].flags,
+ MAC_CONFIGURATION_ENTRY_ACTION_TYPE,
+ T_ETH_MAC_COMMAND_INVALIDATE);
+ bnx2x_set_mac_in_nig(bp, 0, NULL, LLH_CAM_ETH_LINE + 1 + i);
+ }
+
+ wmb();
+
+ config_cmd->hdr.length = max_list_size;
+ config_cmd->hdr.offset = offset;
+ config_cmd->hdr.client_id = 0xff;
+ /* We'll wait for a completion this time... */
+ config_cmd->hdr.echo = 1;
+
+ bp->set_mac_pending = 1;
+
+ mb();
+
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0,
+ U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1);
+
+ /* Wait for a completion */
+ bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending,
+ ramrod_flags);
+
+}
+
+static inline int bnx2x_set_mc_list(struct bnx2x *bp)
+{
+ /* some multicasts */
+ if (CHIP_IS_E1(bp)) {
+ return bnx2x_set_e1_mc_list(bp);
+ } else { /* E1H and newer */
+ return bnx2x_set_e1h_mc_list(bp);
+ }
+}
+
/* called with netif_tx_lock from dev_mcast.c */
void bnx2x_set_rx_mode(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
u32 rx_mode = BNX2X_RX_MODE_NORMAL;
- int port = BP_PORT(bp);
if (bp->state != BNX2X_STATE_OPEN) {
DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
@@ -8829,47 +9102,16 @@ void bnx2x_set_rx_mode(struct net_device *dev)
if (dev->flags & IFF_PROMISC)
rx_mode = BNX2X_RX_MODE_PROMISC;
- else if ((dev->flags & IFF_ALLMULTI) ||
- ((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) &&
- CHIP_IS_E1(bp)))
+ else if (dev->flags & IFF_ALLMULTI)
rx_mode = BNX2X_RX_MODE_ALLMULTI;
- else { /* some multicasts */
- if (CHIP_IS_E1(bp)) {
- /*
- * set mc list, do not wait as wait implies sleep
- * and set_rx_mode can be invoked from non-sleepable
- * context
- */
- u8 offset = (CHIP_REV_IS_SLOW(bp) ?
- BNX2X_MAX_EMUL_MULTI*(1 + port) :
- BNX2X_MAX_MULTICAST*(1 + port));
-
- bnx2x_set_e1_mc_list(bp, offset);
- } else { /* E1H */
- /* Accept one or more multicasts */
- struct netdev_hw_addr *ha;
- u32 mc_filter[MC_HASH_SIZE];
- u32 crc, bit, regidx;
- int i;
-
- memset(mc_filter, 0, 4 * MC_HASH_SIZE);
-
- netdev_for_each_mc_addr(ha, dev) {
- DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n",
- bnx2x_mc_addr(ha));
-
- crc = crc32c_le(0, bnx2x_mc_addr(ha),
- ETH_ALEN);
- bit = (crc >> 24) & 0xff;
- regidx = bit >> 5;
- bit &= 0x1f;
- mc_filter[regidx] |= (1 << bit);
- }
+ else {
+ /* some multicasts */
+ if (bnx2x_set_mc_list(bp))
+ rx_mode = BNX2X_RX_MODE_ALLMULTI;
- for (i = 0; i < MC_HASH_SIZE; i++)
- REG_WR(bp, MC_HASH_OFFSET(bp, i),
- mc_filter[i]);
- }
+ /* some unicasts */
+ if (bnx2x_set_uc_list(bp))
+ rx_mode = BNX2X_RX_MODE_PROMISC;
}
bp->rx_mode = rx_mode;
@@ -8950,7 +9192,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_stop = bnx2x_close,
.ndo_start_xmit = bnx2x_start_xmit,
.ndo_select_queue = bnx2x_select_queue,
- .ndo_set_multicast_list = bnx2x_set_rx_mode,
+ .ndo_set_rx_mode = bnx2x_set_rx_mode,
.ndo_set_mac_address = bnx2x_change_mac_addr,
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = bnx2x_ioctl,
@@ -9776,15 +10018,21 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count)
HW_CID(bp, BNX2X_ISCSI_ETH_CID));
}
- /* There may be not more than 8 L2 and COMMON SPEs and not more
- * than 8 L5 SPEs in the air.
+ /* There may be not more than 8 L2 and not more than 8 L5 SPEs
+ * We also check that the number of outstanding
+ * COMMON ramrods is not more than the EQ and SPQ can
+ * accommodate.
*/
- if ((type == NONE_CONNECTION_TYPE) ||
- (type == ETH_CONNECTION_TYPE)) {
- if (!atomic_read(&bp->spq_left))
+ if (type == ETH_CONNECTION_TYPE) {
+ if (!atomic_read(&bp->cq_spq_left))
+ break;
+ else
+ atomic_dec(&bp->cq_spq_left);
+ } else if (type == NONE_CONNECTION_TYPE) {
+ if (!atomic_read(&bp->eq_spq_left))
break;
else
- atomic_dec(&bp->spq_left);
+ atomic_dec(&bp->eq_spq_left);
} else if ((type == ISCSI_CONNECTION_TYPE) ||
(type == FCOE_CONNECTION_TYPE)) {
if (bp->cnic_spq_pending >=
@@ -9976,7 +10224,7 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
int count = ctl->data.credit.credit_count;
smp_mb__before_atomic_inc();
- atomic_add(count, &bp->spq_left);
+ atomic_add(count, &bp->cq_spq_left);
smp_mb__after_atomic_inc();
break;
}
--
1.7.0.4
^ permalink raw reply related
* Re: 2.6.37 regression: adding main interface to a bridge breaks vlan interface RX
From: Jesse Gross @ 2011-02-06 18:09 UTC (permalink / raw)
To: chriss; +Cc: netdev
In-Reply-To: <loom.20110205T163216-459@post.gmane.org>
On Sat, Feb 5, 2011 at 7:34 AM, chriss <mail_to_chriss@gmx.net> wrote:
> Maciej Rutecki <maciej.rutecki <at> gmail.com> writes:
>
>>
>> On niedziela, 23 stycznia 2011 o 22:29:02 Jesse Gross wrote:
>> > On Sun, Jan 23, 2011 at 9:45 AM, Maciej Rutecki
>> >
>> > <maciej.rutecki <at> gmail.com> wrote:
>> > > I created a Bugzilla entry at
>> > > https://bugzilla.kernel.org/show_bug.cgi?id=27432
>> > > for your bug report, please add your address to the CC list in there,
>> > > thanks!
>> >
>> > This isn't a bug - the change resolved behavior that varied depending
>> > on what NIC was in use.
>>
>> Thanks for the update. Closing.
>>
>> Regards
>
>
> Hi
>
> How am i supposed to put my eth to a bridge and have a seprate vlan besides that
> bridge?
You should either attached a bridge to a vlan device or stack a vlan
device on the bridge port depending on what you are trying to achieve.
The bridge handler takes all packets of the device that it is attached
to, so having a vlan also attached to the same device will not work.
You may get different results on older kernels depending on what NIC
you were using but that was a bug.
^ permalink raw reply
* Re: [PATCH 4/4] m68k/atari: ARAnyM - Add support for network access
From: David Miller @ 2011-02-06 19:17 UTC (permalink / raw)
To: geert
Cc: linux-m68k, linux-kernel, cz-bobek-lists-aranym, schmitz,
pstehlik, M.Jurik, netdev
In-Reply-To: <1296989469-7844-5-git-send-email-geert@linux-m68k.org>
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun, 6 Feb 2011 11:51:09 +0100
> + dev->trans_start = jiffies;
Device drivers no longer make this operation, the generic code
does it (see net/core/dev.c:dev_hard_start_xmit() and how it
invokes txq_trans_update() on ->ndo_start_xmit() success).
Therefore, please remove this line.
> + pr_debug(DRV_NAME ": send %d bytes\n", len);
For consistency with other network drivers, add an appropriate CPP
define for "pr_fmt" and use netdev_info(), netdev_debug(), etc.
In situations where a netdev pointer is not available
(ie. pre-register_netdev()), use "dev_*()" instead.
Thanks.
^ permalink raw reply
* Re: [net-next-2.6 PATCH 0/5] enic: updates to version 2.1.1.6
From: David Miller @ 2011-02-06 19:18 UTC (permalink / raw)
To: vkolluri; +Cc: netdev
In-Reply-To: <20110205021618.8510.34816.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
Date: Fri, 04 Feb 2011 18:17:00 -0800
> The following series implements enic driver updates:
>
> 1/5 - Clean up: Organize devcmd wrapper routines
> 2/5 - Bug Fix: Fix return values of enic_add/del_station_addr routines
> 3/5 - Bug Fix: Reorder firmware devcmds - CMD_INIT and CMD_IG_VLAN_REWRITE_MODE
> 4/5 - Clean up: Remove support for an older version of hardware
> 5/5 - Update MAINTAINERS
>
> Signed-off-by: Christian Benvenuti <benve@cisco.com>
> Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
> Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
> Signed-off-by: David Wang <dwang2@cisco.com>
These patches do not apply cleanly to current net-next-2.6, please
respin them.
Thanks.
^ permalink raw reply
* Re: [PATCH net-next] bnx2x: MTU for FCoE L2 ring
From: David Miller @ 2011-02-06 19:21 UTC (permalink / raw)
To: vladz; +Cc: netdev, eilong
In-Reply-To: <1296996562.16759.9.camel@lb-tlvb-vladz>
From: "Vladislav Zolotarov" <vladz@broadcom.com>
Date: Sun, 6 Feb 2011 14:49:22 +0200
> Always configure an FCoE L2 ring with a mini-jumbo MTU size (2500).
> To do that we had to move the rx_buf_size parameter from per
> function level to a per ring level.
>
> Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-2.6] bnx2x: Duplication in promisc mode
From: David Miller @ 2011-02-06 19:21 UTC (permalink / raw)
To: vladz; +Cc: netdev, eilong
In-Reply-To: <1296998053.16759.25.camel@lb-tlvb-vladz>
From: "Vladislav Zolotarov" <vladz@broadcom.com>
Date: Sun, 6 Feb 2011 15:14:13 +0200
> Prevent packets duplication for frames targeting FCoE L2 ring:
> packets were arriving to stack from both L2 RSS and from FCoE
> L2 in a promiscuous mode.
>
> Configure FCoE L2 ring to DROP_ALL rx mode, when interface is
> configured to PROMISC, and to accept only unicast frames, when
> interface is configured to ALL_MULTI.
>
> Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next] bnx2x: Proper netdev->ndo_set_rx_mode() implementation.
From: David Miller @ 2011-02-06 19:25 UTC (permalink / raw)
To: vladz; +Cc: netdev, eilong
In-Reply-To: <201102061850.40458.vladz@broadcom.com>
From: "Vlad Zolotarov" <vladz@broadcom.com>
Date: Sun, 6 Feb 2011 18:50:40 +0200
> Completed the bnx2x_set_rx_mode() to a proper netdev->ndo_set_rx_mode
> implementation:
> - Added a missing configuration of a unicast MAC addresses list.
> - Changed bp->dma_lock from being a mutex to a spinlock as long as it's taken
> under netdev->addr_list_lock now.
>
> Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Applied, thanks.
^ permalink raw reply
* Re: 2.6.37 regression: adding main interface to a bridge breaks vlan interface RX
From: chriss @ 2011-02-06 19:37 UTC (permalink / raw)
To: netdev
In-Reply-To: <AANLkTi=-+1dnh5ab6nMwjwMx20jpirYyaASZ=dk4OExp@mail.gmail.com>
Jesse Gross <jesse <at> nicira.com> writes:
>
> You should either attached a bridge to a vlan device or stack a vlan
> device on the bridge port depending on what you are trying to achieve.
>
> The bridge handler takes all packets of the device that it is attached
> to, so having a vlan also attached to the same device will not work.
> You may get different results on older kernels depending on what NIC
> you were using but that was a bug.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo <at> vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
Hi and thanks for your reply
I tried that.
I had under 2.6.36.3 following combination:
eth1 in br0 -> all traffic without vlan id
eth1.3 -> traffic with vlan 3
with 2.6.37 i should do the following
eth1 in br0 -> traffic w/o vlans
and br0.3 -> traffic with vlan id 3
But still there is no rx for vlan 3.
Any suggestions? Or am i missing something?
regards
^ permalink raw reply
* Re: x25: possible skb leak on bad facilities
From: David Miller @ 2011-02-07 4:28 UTC (permalink / raw)
To: andrew.hendry; +Cc: apw, john, linux-x25, netdev, linux-kernel, tim.gardner
In-Reply-To: <AANLkTik-ywwtNg2AxAXtsKYJviDp=1zCZ-43JXp9i3g6@mail.gmail.com>
From: Andrew Hendry <andrew.hendry@gmail.com>
Date: Tue, 1 Feb 2011 22:55:13 +1100
> There are two callers, when I was crashing it I don't remember it
> using the backlog path.
> x25_process_rx_frame is called from both x25_backlog_rcv and also
> x25_receive_data (via x25_lapb_receive_frame)
>
> But reviewing that second path now it looks like it will also leak, -1
> would make it skip the kfree_skb there as well.
> So patch looks good to me, when I have some time I'll run it through
> the environment I had setup originally to confirm.
Andrew, have you had a chance to do this yet?
^ permalink raw reply
* Re: x25: possible skb leak on bad facilities
From: Andrew Hendry @ 2011-02-07 6:29 UTC (permalink / raw)
To: David Miller; +Cc: apw, john, linux-x25, netdev, linux-kernel, tim.gardner
In-Reply-To: <20110206.202824.260090071.davem@davemloft.net>
The issue is a bit more complex than Andy's patch, I think I have a full fix.
Burning it in on test system now, if thats OK ill post patch in a few hours.
On Mon, Feb 7, 2011 at 3:28 PM, David Miller <davem@davemloft.net> wrote:
> From: Andrew Hendry <andrew.hendry@gmail.com>
> Date: Tue, 1 Feb 2011 22:55:13 +1100
>
>> There are two callers, when I was crashing it I don't remember it
>> using the backlog path.
>> x25_process_rx_frame is called from both x25_backlog_rcv and also
>> x25_receive_data (via x25_lapb_receive_frame)
>>
>> But reviewing that second path now it looks like it will also leak, -1
>> would make it skip the kfree_skb there as well.
>> So patch looks good to me, when I have some time I'll run it through
>> the environment I had setup originally to confirm.
>
> Andrew, have you had a chance to do this yet?
>
^ permalink raw reply
* iputils license issue
From: Noah Meyerhans @ 2011-02-07 7:38 UTC (permalink / raw)
To: YOSHIFUJI Hideaki; +Cc: netdev
[-- Attachment #1: Type: text/plain, Size: 765 bytes --]
Hello. In ac3fe58b (in the iputils git repo on linux-ipv6.org), code
was added to ping6.c that makes use of some routines from OpenSSL's
libcrypto library. No explicit licensing is attached to this code, so
due to the concerns about mixing GPL code with OpenSSL code, I'm seeking
clarification about the terms under which it may be distributed. The
original heading for ping6.c indicates that the file is licensed under
the BSD license. If the intent is for this new code to also be BSD
licensed, could you state this in the copyright statement in ping6.c?
If the intent was for the code to be licensed under the GPL, would you
be willing to grant an exception similar to the example at
http://lists.debian.org/debian-legal/2002/07/msg00454.html
Thanks.
noah
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [patch] IPVS: precedence bug in ip_vs_sync_switch_mode()
From: Dan Carpenter @ 2011-02-07 8:38 UTC (permalink / raw)
To: Wensong Zhang
Cc: Simon Horman, Julian Anastasov, hans.schillstrom, Patrick McHardy,
David S. Miller, netdev, lvs-devel, netfilter-devel,
kernel-janitors
'!' has higher precedence than '&'. IP_VS_STATE_MASTER is 0x1 so
the original code is equivelent to if (!ipvs->sync_state) ...
Signed-off-by: Dan Carpenter <error27@gmail.com>
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 2a2a836..d1b7298 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -392,7 +392,7 @@ void ip_vs_sync_switch_mode(struct net *net, int mode)
{
struct netns_ipvs *ipvs = net_ipvs(net);
- if (!ipvs->sync_state & IP_VS_STATE_MASTER)
+ if (!(ipvs->sync_state & IP_VS_STATE_MASTER))
return;
if (mode == ipvs->sysctl_sync_ver || !ipvs->sync_buff)
return;
^ permalink raw reply related
* Re: [patch] IPVS: precedence bug in ip_vs_sync_switch_mode()
From: Simon Horman @ 2011-02-07 9:09 UTC (permalink / raw)
To: Dan Carpenter
Cc: Wensong Zhang, Julian Anastasov, hans.schillstrom,
Patrick McHardy, David S. Miller, netdev, lvs-devel,
netfilter-devel, kernel-janitors
In-Reply-To: <20110207083855.GD4384@bicker>
On Mon, Feb 07, 2011 at 11:38:55AM +0300, Dan Carpenter wrote:
> '!' has higher precedence than '&'. IP_VS_STATE_MASTER is 0x1 so
> the original code is equivelent to if (!ipvs->sync_state) ...
Thanks Dan, I'll push this to Patrick ASAP.
For the record, this seems to have been added as part of the
new synchronisation code and as such is only present in
development trees at this time. i.e. its not in .37 nor scheduled for .38.
> Signed-off-by: Dan Carpenter <error27@gmail.com>
>
> diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
> index 2a2a836..d1b7298 100644
> --- a/net/netfilter/ipvs/ip_vs_sync.c
> +++ b/net/netfilter/ipvs/ip_vs_sync.c
> @@ -392,7 +392,7 @@ void ip_vs_sync_switch_mode(struct net *net, int mode)
> {
> struct netns_ipvs *ipvs = net_ipvs(net);
>
> - if (!ipvs->sync_state & IP_VS_STATE_MASTER)
> + if (!(ipvs->sync_state & IP_VS_STATE_MASTER))
> return;
> if (mode == ipvs->sysctl_sync_ver || !ipvs->sync_buff)
> return;
> --
> To unsubscribe from this list: send the line "unsubscribe lvs-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [GIT PULL nf-next-2.6] IPVS
From: Simon Horman @ 2011-02-07 9:19 UTC (permalink / raw)
To: netdev, netfilter-devel, netfilter, lvs-devel
Cc: Julian Anastasov, Hans Schillstrom, Dan Carpenter,
Patrick McHardy
Hi Patrick,
please consider pulling
git://git.kernel.org/pub/scm/linux/kernel/git/horms/lvs-test-2.6.git master
to get a precedence bug fix from Dan Carpenter.
net/netfilter/ipvs/ip_vs_sync.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
^ permalink raw reply
* [PATCH] IPVS: precedence bug in ip_vs_sync_switch_mode()
From: Simon Horman @ 2011-02-07 9:19 UTC (permalink / raw)
To: netdev, netfilter-devel, netfilter, lvs-devel
Cc: Julian Anastasov, Hans Schillstrom, Dan Carpenter,
Patrick McHardy, Simon Horman
In-Reply-To: <1297070381-24377-1-git-send-email-horms@verge.net.au>
From: Dan Carpenter <error27@gmail.com>
'!' has higher precedence than '&'. IP_VS_STATE_MASTER is 0x1 so
the original code is equivelent to if (!ipvs->sync_state) ...
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
net/netfilter/ipvs/ip_vs_sync.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 2a2a836..d1b7298 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -392,7 +392,7 @@ void ip_vs_sync_switch_mode(struct net *net, int mode)
{
struct netns_ipvs *ipvs = net_ipvs(net);
- if (!ipvs->sync_state & IP_VS_STATE_MASTER)
+ if (!(ipvs->sync_state & IP_VS_STATE_MASTER))
return;
if (mode == ipvs->sysctl_sync_ver || !ipvs->sync_buff)
return;
--
1.7.2.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox