* Re: future developments of usbnet
From: Michał Mirosław @ 2011-05-14 10:46 UTC (permalink / raw)
To: Oliver Neukum
Cc: Alan Stern, David Miller, shemminger-ZtmgI6mnKB3QT0dZR+AlfA,
tom.leiming-Re5JQEeQqe8AvxtiuMwx3w, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <201105141201.40265.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org>
2011/5/14 Oliver Neukum <oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org>:
> Am Donnerstag, 12. Mai 2011, 16:37:28 schrieb Alan Stern:
>> Therefore usbnet's poll routine should take the "weight" argument as an
>> indication of how many outstanding rx URBs are allowed. Each time the
>> poll routine is called, it should check to see if any rx URBs have
>> completed since the previous poll. If not then there is no network
>> traffic, so usbnet can take itself out of the poll loop. Otherwise,
>> the number of outstanding URBs should be adjusted (by unlinking some or
>> submitting more -- subject to some fixed maximum limit) to match the
>> new "weight".
> What does happen if we reach the weight 0 ?
Poll callback won't be called with weight 0. If there are more RX
packets after processing 'weight' of them, then the callback will be
called again later.
Best Regards,
Michał Mirosław
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* PATCH: ENC28J60 works with half-duplex DMA
From: Davide Rizzo @ 2011-05-14 12:54 UTC (permalink / raw)
To: netdev
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: enc28j60.c-2.6.38.patch --]
[-- Type: text/x-patch, Size: 5357 bytes --]
This patch modifies SPI access to take advantage of DMA on machines supporting
only half-duplex SPI DMA (like Samsung S3C2410)
Signed-off-by: Davide Rizzo <elpa.rizzo@gmail.com>
---
diff -urNp linux-2.6.38/drivers/net/enc28j60.c linux-2.6.38.elpa/drivers/net/enc28j60.c
--- linux-2.6.38/drivers/net/enc28j60.c 2011-03-15 02:20:32.000000000 +0100
+++ linux-2.6.38.elpa/drivers/net/enc28j60.c 2011-05-14 09:56:05.701797208 +0200
@@ -36,6 +36,8 @@
#define SPI_OPLEN 1
+#define FCLK_MAX 20000000
+
#define ENC28J60_MSG_DEFAULT \
(NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_LINK)
@@ -84,29 +86,33 @@ static struct {
* SPI read buffer
* wait for the SPI transfer and copy received data to destination
*/
-static int
-spi_read_buf(struct enc28j60_net *priv, int len, u8 *data)
+static int spi_read_buf(struct enc28j60_net *priv, int len, u8 *data)
{
- u8 *rx_buf = priv->spi_transfer_buf + 4;
- u8 *tx_buf = priv->spi_transfer_buf;
struct spi_transfer t = {
- .tx_buf = tx_buf,
- .rx_buf = rx_buf,
- .len = SPI_OPLEN + len,
+ .tx_buf = priv->spi_transfer_buf,
+ .rx_buf = NULL,
+ .len = SPI_OPLEN,
+ .cs_change = 0,
+ .speed_hz = FCLK_MAX,
+ };
+ struct spi_transfer r = {
+ .tx_buf = NULL,
+ .rx_buf = data,
+ .len = len,
+ .cs_change = 1,
+ .speed_hz = FCLK_MAX,
};
struct spi_message msg;
int ret;
- tx_buf[0] = ENC28J60_READ_BUF_MEM;
- tx_buf[1] = tx_buf[2] = tx_buf[3] = 0; /* don't care */
+ priv->spi_transfer_buf[0] = ENC28J60_READ_BUF_MEM;
spi_message_init(&msg);
spi_message_add_tail(&t, &msg);
+ spi_message_add_tail(&r, &msg);
ret = spi_sync(priv->spi, &msg);
- if (ret == 0) {
- memcpy(data, &rx_buf[SPI_OPLEN], len);
+ if (ret == 0)
ret = msg.status;
- }
if (ret && netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
__func__, ret);
@@ -114,20 +120,26 @@ spi_read_buf(struct enc28j60_net *priv,
return ret;
}
-/*
- * SPI write buffer
- */
-static int spi_write_buf(struct enc28j60_net *priv, int len,
- const u8 *data)
+static int spi_send(struct enc28j60_net *priv, u8 cmd, int len, const u8 *data)
{
int ret;
+ struct spi_message msg;
+ struct spi_transfer t = {
+ .tx_buf = priv->spi_transfer_buf,
+ .rx_buf = NULL,
+ .len = len + 1,
+ .cs_change = 1,
+ .speed_hz = FCLK_MAX,
+ };
if (len > SPI_TRANSFER_BUF_LEN - 1 || len <= 0)
ret = -EINVAL;
else {
- priv->spi_transfer_buf[0] = ENC28J60_WRITE_BUF_MEM;
+ spi_message_init(&msg);
+ spi_message_add_tail(&t, &msg);
+ priv->spi_transfer_buf[0] = cmd;
memcpy(&priv->spi_transfer_buf[1], data, len);
- ret = spi_write(priv->spi, priv->spi_transfer_buf, len + 1);
+ ret = spi_sync(priv->spi, &msg);
if (ret && netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
__func__, ret);
@@ -136,28 +148,56 @@ static int spi_write_buf(struct enc28j60
}
/*
+ * SPI write buffer
+ */
+static int spi_write_buf(struct enc28j60_net *priv, int len,
+ const u8 *data)
+{
+ return spi_send(priv, ENC28J60_WRITE_BUF_MEM, len, data);
+}
+
+/*
* basic SPI read operation
*/
-static u8 spi_read_op(struct enc28j60_net *priv, u8 op,
- u8 addr)
+static u8 spi_read_op(struct enc28j60_net *priv, u8 op, u8 addr)
{
- u8 tx_buf[2];
- u8 rx_buf[4];
+ u8 tx_buf;
+ u8 rx_buf[SPI_OPLEN + 1];
u8 val = 0;
+ struct spi_transfer t = {
+ .tx_buf = &tx_buf,
+ .rx_buf = NULL,
+ .len = SPI_OPLEN,
+ .cs_change = 0,
+ .speed_hz = FCLK_MAX,
+ };
+ struct spi_transfer r = {
+ .tx_buf = NULL,
+ .rx_buf = rx_buf,
+ .len = SPI_OPLEN,
+ .cs_change = 1,
+ .speed_hz = FCLK_MAX,
+ };
+ struct spi_message msg;
int ret;
- int slen = SPI_OPLEN;
/* do dummy read if needed */
if (addr & SPRD_MASK)
- slen++;
+ r.len++;
+
+ tx_buf = op | (addr & ADDR_MASK);
- tx_buf[0] = op | (addr & ADDR_MASK);
- ret = spi_write_then_read(priv->spi, tx_buf, 1, rx_buf, slen);
- if (ret)
+ spi_message_init(&msg);
+ spi_message_add_tail(&t, &msg);
+ spi_message_add_tail(&r, &msg);
+ ret = spi_sync(priv->spi, &msg);
+ if (ret == 0)
+ ret = msg.status;
+ if (ret && netif_msg_drv(priv))
printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
__func__, ret);
else
- val = rx_buf[slen - 1];
+ val = rx_buf[r.len - 1];
return val;
}
@@ -165,18 +205,9 @@ static u8 spi_read_op(struct enc28j60_ne
/*
* basic SPI write operation
*/
-static int spi_write_op(struct enc28j60_net *priv, u8 op,
- u8 addr, u8 val)
+static int spi_write_op(struct enc28j60_net *priv, u8 op, u8 addr, u8 val)
{
- int ret;
-
- priv->spi_transfer_buf[0] = op | (addr & ADDR_MASK);
- priv->spi_transfer_buf[1] = val;
- ret = spi_write(priv->spi, priv->spi_transfer_buf, 2);
- if (ret && netif_msg_drv(priv))
- printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
- __func__, ret);
- return ret;
+ return spi_send(priv, op | (addr & ADDR_MASK), 1, &val);
}
static void enc28j60_soft_reset(struct enc28j60_net *priv)
@@ -1572,6 +1603,12 @@ static int __devinit enc28j60_probe(stru
dev_set_drvdata(&spi->dev, priv); /* spi to priv reference */
SET_NETDEV_DEV(dev, &spi->dev);
+ /* Configure the SPI bus */
+ spi->mode = SPI_MODE_0;
+ spi->bits_per_word = 8;
+ spi->max_speed_hz = FCLK_MAX;
+ spi_setup(spi);
+
if (!enc28j60_chipset_init(dev)) {
if (netif_msg_probe(priv))
dev_info(&spi->dev, DRV_NAME " chip not found\n");
^ permalink raw reply
* [PATCH] net: ipv6: mcast: Removing invalid check
From: Maxin B John @ 2011-05-14 13:43 UTC (permalink / raw)
To: netdev; +Cc: linux-kernel, kaber, yoshfuji, jmorris, pekkas, kuznet, davem
Since the variable 'first' is assigned to 1, the check
"if (truncate && !first)" will always be false.
Thanks to Coverity for spotting this issue.
Signed-off-by: Maxin B. John <maxin.john@gmail.com>
---
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 76b8937..441c1a4 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1536,8 +1536,6 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
if (AVAILABLE(skb) < sizeof(*psrc) +
first*sizeof(struct mld2_grec)) {
- if (truncate && !first)
- break; /* truncate these */
if (pgr)
pgr->grec_nsrcs = htons(scount);
if (skb)
^ permalink raw reply related
* Re: [PATCH] net: ipv6: mcast: Removing invalid check
From: Eric Dumazet @ 2011-05-14 14:33 UTC (permalink / raw)
To: Maxin B John
Cc: netdev, linux-kernel, kaber, yoshfuji, jmorris, pekkas, kuznet,
davem
In-Reply-To: <20110514134307.GA3603@maxin>
Le samedi 14 mai 2011 à 16:43 +0300, Maxin B John a écrit :
> Since the variable 'first' is assigned to 1, the check
> "if (truncate && !first)" will always be false.
>
> Thanks to Coverity for spotting this issue.
>
> Signed-off-by: Maxin B. John <maxin.john@gmail.com>
> ---
> diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> index 76b8937..441c1a4 100644
> --- a/net/ipv6/mcast.c
> +++ b/net/ipv6/mcast.c
> @@ -1536,8 +1536,6 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
>
> if (AVAILABLE(skb) < sizeof(*psrc) +
> first*sizeof(struct mld2_grec)) {
> - if (truncate && !first)
> - break; /* truncate these */
> if (pgr)
> pgr->grec_nsrcs = htons(scount);
> if (skb)
At a first glance, I would say Coverity is wrong, unless you can explain
why it's right ;)
first can be 0 at this point, we are in a loop.
BTW "Removing invalid check" is a really wrong patch title.
Once you can prove your point, you should use "Remove useless check"
Thanks
^ permalink raw reply
* Re: [PATCH net-next-2.6] net: ping: small changes
From: Vasiliy Kulikov @ 2011-05-14 14:34 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1305363559.3120.54.camel@edumazet-laptop>
On Sat, May 14, 2011 at 10:59 +0200, Eric Dumazet wrote:
> ping_table is not __read_mostly, since it contains one rwlock,
> and is static to ping.c
>
> ping_port_rover & ping_v4_lookup are static
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Acked-by: Vasiliy Kulikov <segoon@openwall.com>
Thanks,
--
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
^ permalink raw reply
* Re: [PATCH] net: ipv6: mcast: Removing invalid check
From: Maxin B John @ 2011-05-14 14:45 UTC (permalink / raw)
To: Eric Dumazet
Cc: netdev, linux-kernel, kaber, yoshfuji, jmorris, pekkas, kuznet,
davem
In-Reply-To: <1305383610.3120.62.camel@edumazet-laptop>
Hi,
> At a first glance, I would say Coverity is wrong, unless you can explain
> why it's right ;)
>
> first can be 0 at this point, we are in a loop.
You are right.
> BTW "Removing invalid check" is a really wrong patch title.
>
> Once you can prove your point, you should use "Remove useless check"
>
I will keep it in mind. Thanks .
Best Regards,
Maxin B John
^ permalink raw reply
* radvd v1.8 released
From: Reuben Hawkins @ 2011-05-14 14:50 UTC (permalink / raw)
To: radvd-announce-l, radvd Development Discussion, netdev
Hi All,
Radvd v1.8 was just released. The release highlights are...
* IgnoreIfMissing now defaults to on
* Timer code replaced with poll
* radvd now listens for interface state changes on a netlink socket
* DecrementLifetimes
* DeprecatePrefix
* FlushRoute
* BugFix in DNSSL parsing
Radvd v1.8 can be downloaded at http://www.litech.org/radvd. Please
report any bugs or problems to radvd-devel-l@litech.org.
Thanks,
Reuben
^ permalink raw reply
* Re: [PATCH net-2.6] ethtool: Remove fallback to old ethtool operations for ETHTOOL_SFEATURES
From: Ben Hutchings @ 2011-05-14 20:08 UTC (permalink / raw)
To: Michał Mirosław; +Cc: David Miller, netdev
In-Reply-To: <20110514095457.GA31970@rere.qmqm.pl>
[Sending this from my home address as solarflare.com mail is under
maintenance and SPF prevents me using that address entirely.]
On Sat, 2011-05-14 at 11:54 +0200, Michał Mirosław wrote:
> On Sat, May 14, 2011 at 02:05:42AM +0100, Ben Hutchings wrote:
> > ethtool_set_feature_compat() squashes the feature mask into a boolean,
> > which is not correct for ethtool_ops::set_flags.
> >
> > We could fix this, but the fallback code for ETHTOOL_SFEATURES actually
> > makes things more complicated for the ethtool utility and any other
> > application using the ethtool API. They will still need to fall back to
> > the old offload control commands in order to support older kernel
> > versions. The fallback code in the kernel adds a third possibility for
> > them to handle. So make ETHTOOL_SFEATURES fail when the driver
> > implements the old offload control operations, and let userland do the
> > fallback.
> >
> > Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
>
> This will disable SFEATURES for drivers which implement changing newer
> features that have no old ethtool ops (e.g. NETIF_F_LOOPBACK), but are
> not converted, yet. This might matter when bisecting.
>
> It's easy to fix this.
Yes, I realise that.
> The code is going away for 2.6.40, though.
> Do you want to get rid of ETHTOOL_F_COMPAT bit before 2.6.39?
Right, I don't want this to ever be in a stable release.
> BTW, what are the complications for userspace?
With 2.6.38 and earlier, ETHTOOL_SFEATURES will fail; ethtool -K will
fall back to the individual operations can can report which of them
failed and why.
With 2.6.39 and a converted driver, ethtool -K can find out exactly
which features are changeable and report whether any of the individual
changes are not supported at all. If there's something wrong with the
combination of features then ETHTOOL_SFEATURES will return
ETHTOOL_F_WISH and it can report that the combination is not supported.
With 2.6.39 and an unconverted driver, ETHTOOL_SFEATURES can return
ETHTOOL_F_COMPAT which just tells us some change failed, but not why.
We can try to guess what went wrong by reading back the features, but
it's unclear. This is particularly problematic with set_flags (again)
where the ethtool core can't tell which flags are settable in an
unconverted driver.
I would much prefer not to have this third case existing in a single
stable release.
> This change misses ethtool_get_features_compat() setting available bits.
Yes, but that is less of a problem in practice.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH net-next 2/4] tulip: Convert printks to netdev_<level>
From: Grant Grundler @ 2011-05-14 20:30 UTC (permalink / raw)
To: Joe Perches; +Cc: Tobias Ringstrom, netdev, linux-kernel
In-Reply-To: <1305176371.6124.29.camel@Joe-Laptop>
On Wed, May 11, 2011 at 09:59:31PM -0700, Joe Perches wrote:
> On Wed, 2011-05-11 at 22:09 -0600, Grant Grundler wrote:
> > Some additional clean ups to consider in a future patch:
> > o replace "if (skb == NULL)" with "if (!skb)"
>
> Hey Grant.
>
> I generally don't change those.
> While I prefer (!ptr), others prefer explicit comparisons.
> I do have a script that does the conversion though.
> (de4x5.c is a mess and I didn't change it)
>
> Here's the output with hoisted assigns from if too.
> (and a spelling fix I noticed)
LGTM. :)
Please repost with Signed-off-by, my
"Acked-By: Grant Grundler <grundler@parisc-linux.org>"
and davem can apply.
I can't test these at the moment because I haven't figured out how to
update my parisc machine (parisc was dropped from debian testing).
I'm trying to build a gentoo chroot today though. We'll see.
thanks,
grant
>
> drivers/net/tulip/de2104x.c | 3 ++-
> drivers/net/tulip/dmfe.c | 11 ++++++-----
> drivers/net/tulip/eeprom.c | 6 +++---
> drivers/net/tulip/interrupt.c | 18 +++++++++---------
> drivers/net/tulip/timer.c | 2 +-
> drivers/net/tulip/tulip_core.c | 15 +++++++++------
> drivers/net/tulip/uli526x.c | 15 +++++++--------
> drivers/net/tulip/winbond-840.c | 14 ++++++++------
> drivers/net/tulip/xircom_cb.c | 12 ++++++------
> 9 files changed, 51 insertions(+), 45 deletions(-)
>
> diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
> index e2f6923..45a4843 100644
> --- a/drivers/net/tulip/de2104x.c
> +++ b/drivers/net/tulip/de2104x.c
> @@ -2170,7 +2170,8 @@ static int de_resume (struct pci_dev *pdev)
> goto out;
> if (!netif_running(dev))
> goto out_attach;
> - if ((retval = pci_enable_device(pdev))) {
> + retval = pci_enable_device(pdev);
> + if (retval) {
> netdev_err(dev, "pci_enable_device failed in resume\n");
> goto out;
> }
> diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
> index 4685127..588d6b4 100644
> --- a/drivers/net/tulip/dmfe.c
> +++ b/drivers/net/tulip/dmfe.c
> @@ -400,7 +400,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
>
> /* Init network device */
> dev = alloc_etherdev(sizeof(*db));
> - if (dev == NULL)
> + if (!dev)
> return -ENOMEM;
> SET_NETDEV_DEV(dev, &pdev->dev);
>
> @@ -1009,10 +1009,10 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db)
> db->dm910x_chk_mode = 3;
> } else {
> /* Good packet, send to upper layer */
> - /* Shorst packet used new SKB */
> + /* Short packet used new SKB */
> if ((rxlen < RX_COPY_SIZE) &&
> - ((newskb = dev_alloc_skb(rxlen + 2))
> - != NULL)) {
> + (newskb =
> + dev_alloc_skb(rxlen + 2))) {
>
> skb = newskb;
> /* size less than COPY_SIZE, allocate a rxlen SKB */
> @@ -1561,7 +1561,8 @@ static void allocate_rx_buffer(struct dmfe_board_info *db)
> rxptr = db->rx_insert_ptr;
>
> while(db->rx_avail_cnt < RX_DESC_CNT) {
> - if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )
> + skb = dev_alloc_skb(RX_ALLOC_SIZE);
> + if (!skb)
> break;
> rxptr->rx_skb_ptr = skb; /* FIXME (?) */
> rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data,
> diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
> index fa5eee9..a11eb73 100644
> --- a/drivers/net/tulip/eeprom.c
> +++ b/drivers/net/tulip/eeprom.c
> @@ -123,7 +123,7 @@ static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
> tp->mtable = kmalloc(sizeof(struct mediatable) +
> sizeof(struct medialeaf), GFP_KERNEL);
>
> - if (tp->mtable == NULL)
> + if (!tp->mtable)
> return; /* Horrible, impossible failure. */
>
> tp->mtable->defaultmedia = 0x800;
> @@ -192,7 +192,7 @@ void __devinit tulip_parse_eeprom(struct net_device *dev)
> break;
> }
> }
> - if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
> + if (!eeprom_fixups[i].name) { /* No fixup found. */
> pr_info("%s: Old style EEPROM with no media selection information\n",
> dev->name);
> return;
> @@ -230,7 +230,7 @@ subsequent_board:
> mtable = kmalloc(sizeof(struct mediatable) +
> count * sizeof(struct medialeaf),
> GFP_KERNEL);
> - if (mtable == NULL)
> + if (!mtable)
> return; /* Horrible, impossible failure. */
> last_mediatable = tp->mtable = mtable;
> mtable->defaultmedia = media;
> diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
> index 5350d75..1a1bff5 100644
> --- a/drivers/net/tulip/interrupt.c
> +++ b/drivers/net/tulip/interrupt.c
> @@ -68,12 +68,12 @@ int tulip_refill_rx(struct net_device *dev)
> /* Refill the Rx ring buffers. */
> for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) {
> entry = tp->dirty_rx % RX_RING_SIZE;
> - if (tp->rx_buffers[entry].skb == NULL) {
> + if (!tp->rx_buffers[entry].skb) {
> struct sk_buff *skb;
> dma_addr_t mapping;
>
> skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ);
> - if (skb == NULL)
> + if (!skb)
> break;
>
> mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ,
> @@ -205,7 +205,7 @@ int tulip_poll(struct napi_struct *napi, int budget)
> /* Check if the packet is long enough to accept without copying
> to a minimally-sized skbuff. */
> if (pkt_len < tulip_rx_copybreak &&
> - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
> + (skb = dev_alloc_skb(pkt_len + 2))) {
> skb_reserve(skb, 2); /* 16 byte align the IP header */
> pci_dma_sync_single_for_cpu(tp->pdev,
> tp->rx_buffers[entry].mapping,
> @@ -311,7 +311,7 @@ int tulip_poll(struct napi_struct *napi, int budget)
> tulip_refill_rx(dev);
>
> /* If RX ring is not full we are out of memory. */
> - if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
> + if (!tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb)
> goto oom;
>
> /* Remove us from polling list and enable RX intr. */
> @@ -334,10 +334,10 @@ int tulip_poll(struct napi_struct *napi, int budget)
>
> not_done:
> if (tp->cur_rx - tp->dirty_rx > RX_RING_SIZE/2 ||
> - tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
> + !tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb)
> tulip_refill_rx(dev);
>
> - if (tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb == NULL)
> + if (!tp->rx_buffers[tp->dirty_rx % RX_RING_SIZE].skb)
> goto oom;
>
> return work_done;
> @@ -431,7 +431,7 @@ static int tulip_rx(struct net_device *dev)
> /* Check if the packet is long enough to accept without copying
> to a minimally-sized skbuff. */
> if (pkt_len < tulip_rx_copybreak &&
> - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
> + (skb = dev_alloc_skb(pkt_len + 2))) {
> skb_reserve(skb, 2); /* 16 byte align the IP header */
> pci_dma_sync_single_for_cpu(tp->pdev,
> tp->rx_buffers[entry].mapping,
> @@ -591,7 +591,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
> break; /* It still has not been Txed */
>
> /* Check for Rx filter setup frames. */
> - if (tp->tx_buffers[entry].skb == NULL) {
> + if (!tp->tx_buffers[entry].skb) {
> /* test because dummy frames not mapped */
> if (tp->tx_buffers[entry].mapping)
> pci_unmap_single(tp->pdev,
> @@ -775,7 +775,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
>
> /* check if the card is in suspend mode */
> entry = tp->dirty_rx % RX_RING_SIZE;
> - if (tp->rx_buffers[entry].skb == NULL) {
> + if (!tp->rx_buffers[entry].skb) {
> if (tulip_debug > 1)
> dev_warn(&dev->dev,
> "in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n",
> diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
> index 2017faf..afc5445 100644
> --- a/drivers/net/tulip/timer.c
> +++ b/drivers/net/tulip/timer.c
> @@ -43,7 +43,7 @@ void tulip_media_task(struct work_struct *work)
> default: {
> struct medialeaf *mleaf;
> unsigned char *p;
> - if (tp->mtable == NULL) { /* No EEPROM info, use generic code. */
> + if (!tp->mtable) { /* No EEPROM info, use generic code. */
> /* Not much that can be done.
> Assume this a generic MII or SYM transceiver. */
> next_tick = 60*HZ;
> diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
> index 82f8764..0ab2465 100644
> --- a/drivers/net/tulip/tulip_core.c
> +++ b/drivers/net/tulip/tulip_core.c
> @@ -384,7 +384,7 @@ static void tulip_up(struct net_device *dev)
>
> /* Allow selecting a default media. */
> i = 0;
> - if (tp->mtable == NULL)
> + if (!tp->mtable)
> goto media_picked;
> if (dev->if_port) {
> int looking_for = tulip_media_cap[dev->if_port] & MediaIsMII ? 11 :
> @@ -642,7 +642,7 @@ static void tulip_init_ring(struct net_device *dev)
> use skb_reserve() to align the IP header! */
> struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
> tp->rx_buffers[i].skb = skb;
> - if (skb == NULL)
> + if (!skb)
> break;
> mapping = pci_map_single(tp->pdev, skb->data,
> PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
> @@ -728,7 +728,7 @@ static void tulip_clean_tx_ring(struct tulip_private *tp)
> }
>
> /* Check for Tx filter setup frames. */
> - if (tp->tx_buffers[entry].skb == NULL) {
> + if (!tp->tx_buffers[entry].skb) {
> /* test because dummy frames not mapped */
> if (tp->tx_buffers[entry].mapping)
> pci_unmap_single(tp->pdev,
> @@ -821,7 +821,7 @@ static void tulip_free_ring (struct net_device *dev)
> for (i = 0; i < TX_RING_SIZE; i++) {
> struct sk_buff *skb = tp->tx_buffers[i].skb;
>
> - if (skb != NULL) {
> + if (skb) {
> pci_unmap_single(tp->pdev, tp->tx_buffers[i].mapping,
> skb->len, PCI_DMA_TODEVICE);
> dev_kfree_skb (skb);
> @@ -1900,12 +1900,15 @@ static int tulip_resume(struct pci_dev *pdev)
> if (!netif_running(dev))
> return 0;
>
> - if ((retval = pci_enable_device(pdev))) {
> + retval = pci_enable_device(pdev);
> + if (retval) {
> pr_err("pci_enable_device failed in resume\n");
> return retval;
> }
>
> - if ((retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
> + retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED,
> + dev->name, dev);
> + if (retval) {
> pr_err("request_irq failed in resume\n");
> return retval;
> }
> diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
> index 9e63f40..a6f6a9e 100644
> --- a/drivers/net/tulip/uli526x.c
> +++ b/drivers/net/tulip/uli526x.c
> @@ -286,7 +286,7 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
>
> /* Init network device */
> dev = alloc_etherdev(sizeof(*db));
> - if (dev == NULL)
> + if (!dev)
> return -ENOMEM;
> SET_NETDEV_DEV(dev, &pdev->dev);
>
> @@ -324,14 +324,12 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
>
> /* Allocate Tx/Rx descriptor memory */
> 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)
> - {
> + if (!db->desc_pool_ptr) {
> err = -ENOMEM;
> goto err_out_nomem;
> }
> 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)
> - {
> + if (!db->buf_pool_ptr) {
> err = -ENOMEM;
> goto err_out_nomem;
> }
> @@ -404,7 +402,7 @@ err_out_nomem:
> 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)
> + if (db->buf_pool_ptr)
> pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
> db->buf_pool_ptr, db->buf_pool_dma_ptr);
> err_out_disable:
> @@ -844,7 +842,7 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info
> /* Good packet, send to upper layer */
> /* Shorst packet used new SKB */
> if ((rxlen < RX_COPY_SIZE) &&
> - (((new_skb = dev_alloc_skb(rxlen + 2)) != NULL))) {
> + (new_skb = dev_alloc_skb(rxlen + 2))) {
> skb = new_skb;
> /* size less than COPY_SIZE, allocate a rxlen SKB */
> skb_reserve(skb, 2); /* 16byte align */
> @@ -1440,7 +1438,8 @@ static void allocate_rx_buffer(struct uli526x_board_info *db)
> rxptr = db->rx_insert_ptr;
>
> while(db->rx_avail_cnt < RX_DESC_CNT) {
> - if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )
> + skb = dev_alloc_skb(RX_ALLOC_SIZE);
> + if (!skb)
> break;
> rxptr->rx_skb_ptr = skb; /* FIXME (?) */
> rxptr->rdes2 = cpu_to_le32(pci_map_single(db->pdev,
> diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
> index 862eadf..a957e72 100644
> --- a/drivers/net/tulip/winbond-840.c
> +++ b/drivers/net/tulip/winbond-840.c
> @@ -647,7 +647,8 @@ static int netdev_open(struct net_device *dev)
> if (debug > 1)
> netdev_dbg(dev, "w89c840_open() irq %d\n", dev->irq);
>
> - if((i=alloc_ringdesc(dev)))
> + i = alloc_ringdesc(dev);
> + if (i)
> goto out_err;
>
> spin_lock_irq(&np->lock);
> @@ -817,7 +818,7 @@ static void init_rxtx_rings(struct net_device *dev)
> for (i = 0; i < RX_RING_SIZE; i++) {
> struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
> np->rx_skbuff[i] = skb;
> - if (skb == NULL)
> + if (!skb)
> break;
> np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data,
> np->rx_buf_sz,PCI_DMA_FROMDEVICE);
> @@ -1231,7 +1232,7 @@ static int netdev_rx(struct net_device *dev)
> /* Check if the packet is long enough to accept without copying
> to a minimally-sized skbuff. */
> if (pkt_len < rx_copybreak &&
> - (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
> + (skb = dev_alloc_skb(pkt_len + 2))) {
> skb_reserve(skb, 2); /* 16 byte align the IP header */
> pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
> np->rx_skbuff[entry]->len,
> @@ -1269,10 +1270,10 @@ static int netdev_rx(struct net_device *dev)
> for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {
> struct sk_buff *skb;
> entry = np->dirty_rx % RX_RING_SIZE;
> - if (np->rx_skbuff[entry] == NULL) {
> + if (!np->rx_skbuff[entry]) {
> skb = dev_alloc_skb(np->rx_buf_sz);
> np->rx_skbuff[entry] = skb;
> - if (skb == NULL)
> + if (!skb)
> break; /* Better luck next round. */
> np->rx_addr[entry] = pci_map_single(np->pci_dev,
> skb->data,
> @@ -1618,7 +1619,8 @@ static int w840_resume (struct pci_dev *pdev)
> if (netif_device_present(dev))
> goto out; /* device not suspended */
> if (netif_running(dev)) {
> - if ((retval = pci_enable_device(pdev))) {
> + retval = pci_enable_device(pdev);
> + if (retval) {
> dev_err(&dev->dev,
> "pci_enable_device failed in resume\n");
> goto out;
> diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
> index 988b8eb..1cb7208 100644
> --- a/drivers/net/tulip/xircom_cb.c
> +++ b/drivers/net/tulip/xircom_cb.c
> @@ -230,12 +230,12 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
>
> /* Allocate the send/receive buffers */
> private->rx_buffer = pci_alloc_consistent(pdev,8192,&private->rx_dma_handle);
> - if (private->rx_buffer == NULL) {
> + if (!private->rx_buffer) {
> 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);
> - if (private->tx_buffer == NULL) {
> + if (!private->tx_buffer) {
> pr_err("%s: no memory for tx buffer\n", __func__);
> goto tx_buf_fail;
> }
> @@ -546,8 +546,8 @@ static void setup_descriptors(struct xircom_private *card)
> u32 address;
> int i;
>
> - BUG_ON(card->rx_buffer == NULL);
> - BUG_ON(card->tx_buffer == NULL);
> + BUG_ON(!card->rx_buffer);
> + BUG_ON(!card->tx_buffer);
>
> /* Receive descriptors */
> memset(card->rx_buffer, 0, 128); /* clear the descriptors */
> @@ -1086,7 +1086,7 @@ investigate_read_descriptor(struct net_device *dev, struct xircom_private *card,
> }
>
> skb = dev_alloc_skb(pkt_len + 2);
> - if (skb == NULL) {
> + if (!skb) {
> dev->stats.rx_dropped++;
> goto out;
> }
> @@ -1125,7 +1125,7 @@ investigate_write_descriptor(struct net_device *dev,
> }
> #endif
> if (status > 0) { /* bit 31 is 0 when done */
> - if (card->tx_skb[descnr]!=NULL) {
> + if (card->tx_skb[descnr]) {
> dev->stats.tx_bytes += card->tx_skb[descnr]->len;
> dev_kfree_skb_irq(card->tx_skb[descnr]);
> }
>
> > o in general, HW doesn't return signed integer values. Where possible,
> > I prefer to see "unsigned int status;" and "if (status)".
>
> That one is yours to change if you want.
^ permalink raw reply
* (unknown),
From: Micha Nelissen @ 2011-05-14 20:20 UTC (permalink / raw)
To: netdev
/* Define the friendly delay before and after opening net devices */
-#define CONF_PRE_OPEN 500 /* Before opening: 1/2 second */
-#define CONF_POST_OPEN 1 /* After opening: 1 second */
+#define CONF_POST_OPEN 10 /* After opening: 10 msecs */
+#define CONF_CARRIER_TIMEOUT 120000 /* Wait for carrier timeout */
/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
#define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */
@@ -187,11 +187,22 @@
static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
static struct net_device *ic_dev __initdata = NULL; /* Selected device */
+static int __init ic_is_init_dev(struct net_device *dev)
+{
+ if (dev->flags & IFF_LOOPBACK)
+ return 0;
+ return user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
+ (!(dev->flags & IFF_LOOPBACK) &&
+ (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
+ strncmp(dev->name, "dummy", 5));
+}
+
static int __init ic_open_devs(void)
{
struct ic_device *d, **last;
struct net_device *dev;
unsigned short oflags;
+ unsigned long start;
last = &ic_first_dev;
rtnl_lock();
@@ -205,12 +216,7 @@
}
for_each_netdev(&init_net, dev) {
- if (dev->flags & IFF_LOOPBACK)
- continue;
- if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
- (!(dev->flags & IFF_LOOPBACK) &&
- (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
- strncmp(dev->name, "dummy", 5))) {
+ if (ic_is_init_dev(dev)) {
int able = 0;
if (dev->mtu >= 364)
able |= IC_BOOTP;
@@ -244,6 +250,17 @@
dev->name, able, d->xid));
}
}
+
+ /* wait for a carrier on at least one device */
+ start = jiffies;
+ while (jiffies - start < msecs_to_jiffies(CONF_CARRIER_TIMEOUT)) {
+ for_each_netdev(&init_net, dev)
+ if (ic_is_init_dev(dev) && netif_carrier_ok(dev))
+ goto have_carrier;
+
+ msleep(1);
+ }
+have_carrier:
rtnl_unlock();
*last = NULL;
@@ -1325,15 +1342,12 @@
#ifdef IPCONFIG_DYNAMIC
try_try_again:
#endif
- /* Give hardware a chance to settle */
- msleep(CONF_PRE_OPEN);
-
/* Setup all network devices */
if (ic_open_devs() < 0)
return -1;
/* Give drivers a chance to settle */
- ssleep(CONF_POST_OPEN);
+ msleep(CONF_POST_OPEN);
/*
* If the config information is insufficient (e.g., our IP address or
^ permalink raw reply
* [PATCH] ipconfig wait for carrier
From: Micha Nelissen @ 2011-05-14 20:36 UTC (permalink / raw)
To: netdev
Currently the ip auto configuration has a hardcoded delay of 1 second.
When (ethernet) link takes longer to come up (e.g. more than 3 seconds),
nfs root may not be found.
Remove the hardcoded delay, and wait for carrier on at least one network
device.
Index: atom-linux/net/ipv4/ipconfig.c
===================================================================
--- atom-linux/net/ipv4/ipconfig.c (revision 1445)
+++ atom-linux/net/ipv4/ipconfig.c (working copy)
@@ -86,8 +86,8 @@
#endif
/* Define the friendly delay before and after opening net devices */
-#define CONF_PRE_OPEN 500 /* Before opening: 1/2 second */
-#define CONF_POST_OPEN 1 /* After opening: 1 second */
+#define CONF_POST_OPEN 10 /* After opening: 10 msecs */
+#define CONF_CARRIER_TIMEOUT 120000 /* Wait for carrier timeout */
/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
#define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */
@@ -187,11 +187,22 @@
static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
static struct net_device *ic_dev __initdata = NULL; /* Selected device */
+static int __init ic_is_init_dev(struct net_device *dev)
+{
+ if (dev->flags & IFF_LOOPBACK)
+ return 0;
+ return user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
+ (!(dev->flags & IFF_LOOPBACK) &&
+ (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
+ strncmp(dev->name, "dummy", 5));
+}
+
static int __init ic_open_devs(void)
{
struct ic_device *d, **last;
struct net_device *dev;
unsigned short oflags;
+ unsigned long start;
last = &ic_first_dev;
rtnl_lock();
@@ -205,12 +216,7 @@
}
for_each_netdev(&init_net, dev) {
- if (dev->flags & IFF_LOOPBACK)
- continue;
- if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
- (!(dev->flags & IFF_LOOPBACK) &&
- (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
- strncmp(dev->name, "dummy", 5))) {
+ if (ic_is_init_dev(dev)) {
int able = 0;
if (dev->mtu >= 364)
able |= IC_BOOTP;
@@ -244,6 +250,17 @@
dev->name, able, d->xid));
}
}
+
+ /* wait for a carrier on at least one device */
+ start = jiffies;
+ while (jiffies - start < msecs_to_jiffies(CONF_CARRIER_TIMEOUT)) {
+ for_each_netdev(&init_net, dev)
+ if (ic_is_init_dev(dev) && netif_carrier_ok(dev))
+ goto have_carrier;
+
+ msleep(1);
+ }
+have_carrier:
rtnl_unlock();
*last = NULL;
@@ -1325,15 +1342,12 @@
#ifdef IPCONFIG_DYNAMIC
try_try_again:
#endif
- /* Give hardware a chance to settle */
- msleep(CONF_PRE_OPEN);
-
/* Setup all network devices */
if (ic_open_devs() < 0)
return -1;
/* Give drivers a chance to settle */
- ssleep(CONF_POST_OPEN);
+ msleep(CONF_POST_OPEN);
/*
* If the config information is insufficient (e.g., our IP address or
^ permalink raw reply
* strange code in cdc-ncm
From: Oliver Neukum @ 2011-05-14 20:58 UTC (permalink / raw)
To: linux-usb-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
Alexey Orishko
Hi,
I was looking at this code:
static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
{
struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
struct usb_driver *driver;
if (ctx == NULL)
return; /* no setup */
driver = driver_of(intf);
usb_set_intfdata(ctx->data, NULL);
usb_set_intfdata(ctx->control, NULL);
usb_set_intfdata(ctx->intf, NULL);
/* release interfaces, if any */
if (ctx->data_claimed) {
usb_driver_release_interface(driver, ctx->data);
ctx->data_claimed = 0;
}
if (ctx->control_claimed) {
usb_driver_release_interface(driver, ctx->control);
ctx->control_claimed = 0;
}
It seems a bit strange to me. If you may or may not have claimed an interface,
how can you unconditionally zero out intfdata?
Regards
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] output ipconfig info message as one printk
From: Micha Nelissen @ 2011-05-14 21:45 UTC (permalink / raw)
To: netdev, davem
the "ip-config complete" message with ip address etc is output using
many printks. When using the netconsole, and multiple agents are booting
(and logging their boot) simultaneously, the syslog of the receiving
host gets very messy, as the individual printks are interleaved.
Combining the many printks into one printk improves syslog readability.
Index: atom-linux/net/ipv4/ipconfig.c
===================================================================
--- atom-linux/net/ipv4/ipconfig.c (revision 1493)
+++ atom-linux/net/ipv4/ipconfig.c (revision 1494)
@@ -1363,6 +1363,9 @@
#ifdef IPCONFIG_DYNAMIC
int retries = CONF_OPEN_RETRIES;
#endif
+#ifndef IPCONFIG_SILENT
+ char mtubuf[16];
+#endif
int err;
#ifdef CONFIG_PROC_FS
@@ -1477,19 +1480,17 @@
/*
* Clue in the operator.
*/
- printk("IP-Config: Complete:");
- printk("\n device=%s", ic_dev->name);
- printk(", addr=%pI4", &ic_myaddr);
- printk(", mask=%pI4", &ic_netmask);
- printk(", gw=%pI4", &ic_gateway);
- printk(",\n host=%s, domain=%s, nis-domain=%s",
- utsname()->nodename, ic_domain, utsname()->domainname);
- printk(",\n bootserver=%pI4", &ic_servaddr);
- printk(", rootserver=%pI4", &root_server_addr);
- printk(", rootpath=%s", root_server_path);
if (ic_dev_mtu)
- printk(", mtu=%d", ic_dev_mtu);
- printk("\n");
+ snprintf(mtubuf, sizeof(mtubuf), "mtu=%d, ", ic_dev_mtu);
+ else
+ mtubuf[0] = '\0';
+ printk( "IP-Config: Complete:\n"
+ " device=%s, addr=%pI4, mask=%pI4, gw=%pI4,\n"
+ " %shost=%s, domain=%s, nis-domain=%s,\n"
+ " bootserver=%pI4, rootserver=%pI4, rootpath=%s\n",
+ ic_dev->name, &ic_myaddr, &ic_netmask, &ic_gateway,
+ mtubuf, utsname()->nodename, ic_domain, utsname()->domainname,
+ &ic_servaddr, &root_server_addr, root_server_path);
#endif /* !SILENT */
return 0;
^ permalink raw reply
* pull request: batman-adv 2011-05-14
From: Sven Eckelmann @ 2011-05-14 22:16 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n
Hi,
I would like tp propose following corrections for net-next-2.6/2.6.40.
Both are bug fixes. The first one fixes the regression introduced by
"batman-adv: Make bat_priv->primary_if an rcu protected pointer" which
prevented that the attached net_devices could be destroyed because the
references to them were incorrectly counted.
The second one is a bug which may "filled" the broadcast queue when at
the same time primary_if got changed and a broadcast was initiated. The
queue counter were never reduced because there were no actual packets
attached to the the queue.
thanks,
Sven
The following changes since commit 27aea2128ec09924dfe08e97739b2bf8b15c8619:
batman-adv: remove duplicate code from function is_bidirectional_neigh() (2011-05-08 16:10:42 +0200)
are available in the git repository at:
git://git.open-mesh.org/ecsv/linux-merge.git batman-adv/next
Marek Lindner (1):
batman-adv: reset broadcast flood protection on error
Sven Eckelmann (1):
batman-adv: Add missing hardif_free_ref in forw_packet_free
net/batman-adv/aggregation.c | 14 +++++++++++---
net/batman-adv/send.c | 19 ++++++++++++++++---
2 files changed, 27 insertions(+), 6 deletions(-)
^ permalink raw reply
* [PATCH 1/2] batman-adv: Add missing hardif_free_ref in forw_packet_free
From: Sven Eckelmann @ 2011-05-14 22:16 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Sven Eckelmann
In-Reply-To: <1305411394-28807-1-git-send-email-sven@narfation.org>
add_bcast_packet_to_list increases the refcount for if_incoming but the
reference count is never decreased. The reference count must be
increased for all kinds of forwarded packets which have the primary
interface stored and forw_packet_free must decrease them. Also
purge_outstanding_packets has to invoke forw_packet_free when a work
item was really cancelled.
This regression was introduced in
32ae9b221e788413ce68feaae2ca39e406211a0a.
Reported-by: Antonio Quartulli <ordex@autistici.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
net/batman-adv/aggregation.c | 14 +++++++++++---
net/batman-adv/send.c | 17 +++++++++++++++--
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/net/batman-adv/aggregation.c b/net/batman-adv/aggregation.c
index 9b94590..a8c3203 100644
--- a/net/batman-adv/aggregation.c
+++ b/net/batman-adv/aggregation.c
@@ -23,6 +23,7 @@
#include "aggregation.h"
#include "send.h"
#include "routing.h"
+#include "hard-interface.h"
/* calculate the size of the tt information for a given packet */
static int tt_len(struct batman_packet *batman_packet)
@@ -105,12 +106,15 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
struct forw_packet *forw_packet_aggr;
unsigned char *skb_buff;
+ if (!atomic_inc_not_zero(&if_incoming->refcount))
+ return;
+
/* own packet should always be scheduled */
if (!own_packet) {
if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
bat_dbg(DBG_BATMAN, bat_priv,
"batman packet queue full\n");
- return;
+ goto out;
}
}
@@ -118,7 +122,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
if (!forw_packet_aggr) {
if (!own_packet)
atomic_inc(&bat_priv->batman_queue_left);
- return;
+ goto out;
}
if ((atomic_read(&bat_priv->aggregated_ogms)) &&
@@ -133,7 +137,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
if (!own_packet)
atomic_inc(&bat_priv->batman_queue_left);
kfree(forw_packet_aggr);
- return;
+ goto out;
}
skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr));
@@ -164,6 +168,10 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len,
queue_delayed_work(bat_event_workqueue,
&forw_packet_aggr->delayed_work,
send_time - jiffies);
+
+ return;
+out:
+ hardif_free_ref(if_incoming);
}
/* aggregate a new packet into the existing aggregation */
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index f30d0c6..76daa46 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -377,6 +377,8 @@ static void forw_packet_free(struct forw_packet *forw_packet)
{
if (forw_packet->skb)
kfree_skb(forw_packet->skb);
+ if (forw_packet->if_incoming)
+ hardif_free_ref(forw_packet->if_incoming);
kfree(forw_packet);
}
@@ -539,6 +541,7 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
{
struct forw_packet *forw_packet;
struct hlist_node *tmp_node, *safe_tmp_node;
+ bool pending;
if (hard_iface)
bat_dbg(DBG_BATMAN, bat_priv,
@@ -567,8 +570,13 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
* send_outstanding_bcast_packet() will lock the list to
* delete the item from the list
*/
- cancel_delayed_work_sync(&forw_packet->delayed_work);
+ pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
spin_lock_bh(&bat_priv->forw_bcast_list_lock);
+
+ if (pending) {
+ hlist_del(&forw_packet->list);
+ forw_packet_free(forw_packet);
+ }
}
spin_unlock_bh(&bat_priv->forw_bcast_list_lock);
@@ -591,8 +599,13 @@ void purge_outstanding_packets(struct bat_priv *bat_priv,
* send_outstanding_bat_packet() will lock the list to
* delete the item from the list
*/
- cancel_delayed_work_sync(&forw_packet->delayed_work);
+ pending = cancel_delayed_work_sync(&forw_packet->delayed_work);
spin_lock_bh(&bat_priv->forw_bat_list_lock);
+
+ if (pending) {
+ hlist_del(&forw_packet->list);
+ forw_packet_free(forw_packet);
+ }
}
spin_unlock_bh(&bat_priv->forw_bat_list_lock);
}
--
1.7.5.1
^ permalink raw reply related
* [PATCH 2/2] batman-adv: reset broadcast flood protection on error
From: Sven Eckelmann @ 2011-05-14 22:16 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Marek Lindner, Sven Eckelmann
In-Reply-To: <1305411394-28807-1-git-send-email-sven@narfation.org>
From: Marek Lindner <lindner_marek@yahoo.de>
The broadcast flood protection should be reset to its original value
if the primary interface could not be retrieved.
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
net/batman-adv/send.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 76daa46..3377927 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -421,7 +421,7 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb)
primary_if = primary_if_get_selected(bat_priv);
if (!primary_if)
- goto out;
+ goto out_and_inc;
forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
--
1.7.5.1
^ permalink raw reply related
* 2.6.39-rc7-git7: Reported regressions from 2.6.38
From: Rafael J. Wysocki @ 2011-05-14 22:18 UTC (permalink / raw)
To: Linux Kernel Mailing List
Cc: Maciej Rutecki, Florian Mickler, Andrew Morton, Linus Torvalds,
Kernel Testers List, Network Development, Linux ACPI,
Linux PM List, Linux SCSI List, Linux Wireless List, DRI
This message contains a list of some regressions from 2.6.38,
for which there are no fixes in the mainline known to the tracking team.
If any of them have been fixed already, please let us know.
If you know of any other unresolved regressions from 2.6.38, please let us
know either and we'll add them to the list. Also, please let us know
if any of the entries below are invalid.
Each entry from the list will be sent additionally in an automatic reply
to this message with CCs to the people involved in reporting and handling
the issue.
Listed regressions statistics:
Date Total Pending Unresolved
----------------------------------------
2011-05-15 50 12 11
2011-04-30 38 17 16
2011-04-17 17 11 10
Unresolved regressions
----------------------
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=35062
Subject : Suspend to ram stopped working after commit of " intel-iommu: Unlink domain from iommu "
Submitter : <optiluca@gmail.com>
Date : 2011-05-14 11:08 (1 days old)
First-Bad-Commit: http://git.kernel.org/linus/a97590e56d0d58e1dd262353f7cbd84e81d8e600
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=34952
Subject : 2.6.39-rc6: SATA hangs for a few seconds during boot
Submitter : Tino Keitel <tino.keitel@tikei.de>
Date : 2011-05-09 20:48 (6 days old)
Message-ID : <20110509204801.GA2258@x61.home>
References : http://marc.info/?l=linux-kernel&m=130497409509438&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=34942
Subject : [Bug] Kdump does not work when panic triggered due to MCE
Submitter : K.Prasad <prasad@linux.vnet.ibm.com>
Date : 2011-05-06 16:54 (9 days old)
Message-ID : <20110506165412.GB2719@in.ibm.com>
References : http://marc.info/?l=linux-kernel&m=130470087226270&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=34662
Subject : Warning at block/genhd.c:1556 disk_clear_events
Submitter : Meelis Roos <mroos@linux.ee>
Date : 2011-05-02 9:59 (13 days old)
Message-ID : <alpine.SOC.1.00.1105021255400.6200@math.ut.ee>
References : http://marc.info/?l=linux-kernel&m=130433037002610&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=34492
Subject : [2.6.39-rc4, x86_32] Stall at default_idle()
Submitter : Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Date : 2011-04-27 4:49 (18 days old)
Message-ID : <201104270449.p3R4n54n023453@www262.sakura.ne.jp>
References : http://marc.info/?l=linux-kernel&m=130387977425687&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=34202
Subject : MCEUSB remotes don't work with USB 3.0 ports
Submitter : Aaron Barany <akb825@gmail.com>
Date : 2011-05-01 23:48 (14 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=34002
Subject : [REGRESSION] [2.6.39-rc3] Wrong resolution in framebuffer and X Window
Submitter : Maciej Rutecki <maciej.rutecki@gmail.com>
Date : 2011-04-17 16:04 (28 days old)
Message-ID : <201104171804.04664.maciej.rutecki@gmail.com>
References : http://marc.info/?l=linux-fbdev&m=130305625114863&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=33842
Subject : NULL pointer dereference in ip_fragment
Submitter : Tomas Carnecky <tom@dbservice.com>
Date : 2011-04-23 07:51 (22 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=33792
Subject : lockdep trace when unplugging usb audio (.39rc4)
Submitter : Dave Jones <davej@redhat.com>
Date : 2011-04-19 18:07 (26 days old)
Message-ID : <20110419180745.GA438@redhat.com>
References : http://marc.info/?l=linux-kernel&m=130323648920431&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=33272
Subject : drm related hard-hang
Submitter : Peter Teoh <htmldeveloper@gmail.com>
Date : 2011-04-14 01:29 (31 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=33242
Subject : Lockdep splat in autofs with 2.6.39-rc2
Submitter : Nick Bowler <nbowler@elliptictech.com>
Date : 2011-04-07 19:44 (38 days old)
Message-ID : <20110407194403.GA29404@elliptictech.com>
References : http://marc.info/?l=linux-kernel&m=130220545614682&w=2
Regressions with patches
------------------------
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=33802
Subject : list_del corruption in sd driver since 2.6.39-rc4
Submitter : Christian Casteyde <casteyde.christian@free.fr>
Date : 2011-04-21 21:10 (24 days old)
Handled-By : James Bottomley <James.Bottomley@suse.de>
Patch : http://marc.info/?l=linux-kernel&m=130271409412095
For details, please visit the bug entries and follow the links given in
references.
As you can see, there is a Bugzilla entry for each of the listed regressions.
There also is a Bugzilla entry used for tracking the regressions from 2.6.38,
unresolved as well as resolved, at:
http://bugzilla.kernel.org/show_bug.cgi?id=32012
Please let the tracking team know if there are any Bugzilla entries that
should be added to the list in there.
Thanks!
^ permalink raw reply
* 2.6.39-rc7-git7: Reported regressions 2.6.37 -> 2.6.38
From: Rafael J. Wysocki @ 2011-05-14 22:39 UTC (permalink / raw)
To: Linux Kernel Mailing List
Cc: Maciej Rutecki, Florian Mickler, Andrew Morton, Linus Torvalds,
Kernel Testers List, Network Development, Linux ACPI,
Linux PM List, Linux SCSI List, Linux Wireless List, DRI
[NOTE:
This most likely is the last summary report of post-2.6.37 regressions
introduced during the 2.6.38 development cycle. Please let us know what
the current status of those bugs is, if possible, and thanks for all of
the reports, updates and fixes.]
This message contains a list of some post-2.6.37 regressions introduced before
2.6.38, for which there are no fixes in the mainline known to the tracking team.
If any of them have been fixed already, please let us know.
If you know of any other unresolved post-2.6.37 regressions, please let us know
either and we'll add them to the list. Also, please let us know if any
of the entries below are invalid.
Each entry from the list will be sent additionally in an automatic reply to
this message with CCs to the people involved in reporting and handling the
issue.
Listed regressions statistics:
Date Total Pending Unresolved
----------------------------------------
2011-05-15 107 23 20
2011-04-30 105 29 28
2011-04-17 98 28 28
2011-03-27 88 26 26
2011-03-06 70 27 26
2011-02-21 51 18 17
2011-02-12 39 20 18
2011-02-03 19 11 7
Unresolved regressions
----------------------
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=34992
Subject : Regression with ath5k, cannot find any wireless network
Submitter : Joshua Covington <joshuacov-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
Date : 2011-05-12 11:24 (3 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=33982
Subject : ath9k: regulatory: strange tx power limits
Submitter : Richard Schütz <r.schtz-zqRNUXuvxA0b1SvskN2V4Q@public.gmane.org>
Date : 2011-04-26 18:37 (19 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=33882
Subject : rt2800pci bad performance in 2.6.38
Submitter : Ricardo Graça <r.jpg-8MI2nhFGehw@public.gmane.org>
Date : 2011-04-23 14:35 (22 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=33852
Subject : Regression of AR2413 802.11bg in 2.6.38.4
Submitter : Boris Popov <popov.b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2011-04-23 12:12 (22 days old)
First-Bad-Commit: http://git.kernel.org/linus/42c025f3de9042d9c9abd9a6f6205d1a0f4bcadf
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=33662
Subject : System hangs during X startup (kwin compositing?)
Submitter : Luke-Jr <luke-jr+linuxbugs-LLS2WxOx/a1AfugRpC6u6w@public.gmane.org>
Date : 2011-04-19 04:26 (26 days old)
First-Bad-Commit: http://git.kernel.org/linus/e8616b6ced6137085e6657cc63bc2fe3900b8616
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=32862
Subject : acer_wmi partially crashes ACPI/EC (Aspire 8930G)
Submitter : Hector Martin <hector-eIot3r3D0w+Wd6l5hS35sQ@public.gmane.org>
Date : 2011-04-07 17:44 (38 days old)
Handled-By : Lee, Chun-Yi <jlee-Et1tbQHTxzrQT0dZR+AlfA@public.gmane.org>
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=32522
Subject : drm:i915_hangcheck_ring_idle after suspend/resume cycle
Submitter : <fhimpe-CNXmb7IdZIWZIoH1IeqzKA@public.gmane.org>
Date : 2011-04-02 18:40 (43 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=32202
Subject : 2.6.38 hangs on boot until key is pressed
Submitter : Tvrtko Ursulin <tvrtko-9sj9WOxYP5jR7s880joybQ@public.gmane.org>
Date : 2011-03-27 19:18 (49 days old)
Message-ID : <1301253485.2500.2.camel@deuteros>
References : http://marc.info/?l=linux-kernel&m=130125411116558&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=31922
Subject : ath5k: Decreased throughput in IBSS or 802.11n mode
Submitter : Jeff Cook <jeff-Lrzp875GHuWS7RsuTa25K+qUGfbH9hYC@public.gmane.org>
Date : 2011-03-26 20:06 (50 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=31782
Subject : nouveau: lockdep spew
Submitter : Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
Date : 2011-03-24 09:51 (52 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=31572
Subject : BUG in vb_alloc() - firewire crash at boot
Submitter : Pavel Kysilka <goldenfish-3RRv3fhkseTjAhjy0/KdDg@public.gmane.org>
Date : 2011-03-21 12:40 (55 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=31402
Subject : Diminished brightness at startup
Submitter : Guilherme Salazar <guilhermesalazar-DaQTI0RpDDMAvxtiuMwx3w@public.gmane.org>
Date : 2011-03-18 16:29 (58 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=31322
Subject : 2.6.38-rc echo 3 > /proc/sys/vm/drop_caches repairs mplayer distortions
Submitter : Hans de Bruin <jmdebruin-agH9qYG3oEhmR6Xm/wNWPw@public.gmane.org>
Date : 2011-03-14 21:34 (62 days old)
Message-ID : <4D7E89E7.3080505-agH9qYG3oEhmR6Xm/wNWPw@public.gmane.org>
References : http://marc.info/?l=linux-kernel&m=130014181919827&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=31012
Subject : WARNING: Perf: bad frame pointer = (null), 2.6.38-rc8
Submitter : Chuck Ebbert <cebbert-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Date : 2011-03-12 19:08 (64 days old)
Message-ID : <20110312140851.52420149@katamari>
References : http://marc.info/?l=linux-kernel&m=129995721014931&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=30992
Subject : 2.6.38-rc7: Some strange soft-lockup
Submitter : Dmitry Nezhevenko <dion-Riw6fTKU00peoWH0uzbU5w@public.gmane.org>
Date : 2011-03-06 14:01 (70 days old)
Message-ID : <20110306140104.GA7700-Kfeq/R7O60eE+EvaaNYduQ@public.gmane.org>
References : http://marc.info/?l=linux-kernel&m=129942161205739&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=29992
Subject : boot hang 2.6.37.1 regression w/ intel_idle and CONFIG_NO_HZ=n - asus p7p55d le
Submitter : De Ganseman Amaury <amaury.deganseman-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2011-02-27 10:38 (77 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=29672
Subject : [regression][ALSA][hda-conexant][2.6.38-rcX] external microphone sound too quiet
Submitter : Shawn Starr <shawn.starr-bJEeYj9oJeDQT0dZR+AlfA@public.gmane.org>
Date : 2011-02-19 6:02 (85 days old)
Message-ID : <474630.25335.qm-LGyaPT5kzbjzJNTqFNLFoaJ1FwRQo79cG6kzb5Gsg2M@public.gmane.org>
References : http://marc.info/?l=linux-kernel&m=129809536502092&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=28522
Subject : Unable to mount FAT-formatted floppy on /dev/fd0, plus WARN_ON when using /dev/fd0u1440
Submitter : Alex Villacis Lasso <avillaci-x0m+Mc+nT7uljOmnV8AmnkElSqmLX1BE@public.gmane.org>
Date : 2011-02-07 17:21 (97 days old)
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=28452
Subject : 2.6.38-rc3 regression on parisc: segfaults
Submitter : Meelis Roos <mroos-Y27EyoLml9s@public.gmane.org>
Date : 2011-02-01 22:00 (103 days old)
Message-ID : <alpine.SOC.1.00.1102012342200.25944-ptEonEWSGqKptlylMvRsHA@public.gmane.org>
References : http://marc.info/?l=linux-kernel&m=129659763426600&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=28422
Subject : kref and apparmor panic in 2.6.38-rc2.
Submitter : Tao Ma <tm-d1IQDZat3X0@public.gmane.org>
Date : 2011-01-31 10:06 (104 days old)
Message-ID : <4D46899B.80302-d1IQDZat3X0@public.gmane.org>
References : http://marc.info/?l=linux-kernel&m=129646840303149&w=2
Regressions with patches
------------------------
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=34252
Subject : Unexpected behaviour when switching video cards with vga_switcheroo
Submitter : Igor Murzov <e-mail-YtcMAkmAr8g@public.gmane.org>
Date : 2011-05-02 22:39 (13 days old)
Handled-By : Florian Mickler <florian-sVu6HhrpSfRAfugRpC6u6w@public.gmane.org>
Patch : https://bugzilla.kernel.org/attachment.cgi?id=57582
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=32072
Subject : 2.6.38 Regression: Nvidia GeForce8400 + i915 = Crash on Boot
Submitter : simon-wM4F9T/ekXmXDw4h08c5KA@public.gmane.org
Date : 2011-03-24 15:20 (52 days old)
Message-ID : <fe471c05897776b7c26b9fd2603e3b76.squirrel-N82HvsEaY4kGLQ9C4TkFhg@public.gmane.orgcom>
References : http://marc.info/?l=linux-kernel&m=130100955926434&w=2
Patch : http://marc.info/?l=linux-xfs&m=130144519123809&w=2
Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=31522
Subject : i915/kms regression after 2.6.38-rc8 (was: Re: Linux 2.6.38)
Submitter : Melchior FRANZ <melchior.franz-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date : 2011-03-16 17:30 (60 days old)
Message-ID : <201103161830.52231-s3vZadu4I7qzZXS1Dc/lvw@public.gmane.org>
References : http://marc.info/?l=linux-kernel&m=130029706416659&w=2
http://marc.info/?l=linux-kernel&m=130409270332174&w=2
Patch : https://patchwork.kernel.org/patch/743162/
For details, please visit the bug entries and follow the links given in
references.
As you can see, there is a Bugzilla entry for each of the listed regressions.
There also is a Bugzilla entry used for tracking the regressions introduced
between 2.6.37 and 2.6.38, unresolved as well as resolved, at:
http://bugzilla.kernel.org/show_bug.cgi?id=27352
Please let the tracking team know if there are any Bugzilla entries that
should be added to the list in there.
Thanks!
^ permalink raw reply
* [net-next-2.6 00/13][pull request] Intel Wired LAN Driver Update
From: Jeff Kirsher @ 2011-05-15 1:23 UTC (permalink / raw)
To: davem; +Cc: Jeff Kirsher, netdev, gospo, bphilips
The following series contains updates to e1000e, ixgbevf and ixgbe.
-e1000e: minor comment fix
-ixgbevf: add support for macvlan
-ixgbe: mostly cleanup with the addition of support for a new adapter
The following are changes since commit 7be799a70ba3dd90a59e8d2c72bbe06020005b3f:
ipv4: Remove rt->rt_dst reference from ip_forward_options()
and are available in the git repository at:
master.kernel.org:/pub/scm/linux/kernel/git/jkirsher/net-next-2.6 master
Alexander Duyck (7):
ixgbe: move flags and state into the same cacheline
ixgbe: Combine SFP and multi-speed fiber task into single service
task
ixgbe: Merge watchdog functionality into service task
ixgbe: merge reset task into service task
ixgbe: Merge ATR reinit into the service task
ixgbe: Merge over-temp task into service task
ixgbe: cleanup some minor issues in ixgbe_down()
Bruce Allan (1):
e1000e: minor comment cleanups
Don Skidmore (1):
ixgbe: Add support for new 82599 adapter
Emil Tantilov (2):
ixgbe: force unlock on timeout
ixgbe: fix sparse warning
Greg Rose (2):
ixgbevf: Add macvlan support in the set rx mode op
ixgbe: Add macvlan support for VF
drivers/net/e1000e/lib.c | 4 +-
drivers/net/ixgbe/ixgbe.h | 110 +++--
drivers/net/ixgbe/ixgbe_82599.c | 3 +
drivers/net/ixgbe/ixgbe_common.c | 22 +
drivers/net/ixgbe/ixgbe_ethtool.c | 1 +
drivers/net/ixgbe/ixgbe_main.c | 972 ++++++++++++++++++++----------------
drivers/net/ixgbe/ixgbe_mbx.h | 1 +
drivers/net/ixgbe/ixgbe_sriov.c | 98 ++++-
drivers/net/ixgbe/ixgbe_type.h | 2 +
drivers/net/ixgbevf/ixgbevf_main.c | 30 ++
drivers/net/ixgbevf/mbx.h | 1 +
drivers/net/ixgbevf/vf.c | 34 ++
drivers/net/ixgbevf/vf.h | 1 +
13 files changed, 793 insertions(+), 486 deletions(-)
--
1.7.4.4
^ permalink raw reply
* [net-next-2.6 01/13] e1000e: minor comment cleanups
From: Jeff Kirsher @ 2011-05-15 1:23 UTC (permalink / raw)
To: davem; +Cc: Bruce Allan, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1305422627-9583-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/e1000e/lib.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 6432dda..dd8ab05 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -144,7 +144,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
* @hw: pointer to the HW structure
* @rar_count: receive address registers
*
- * Setups the receive address registers by setting the base receive address
+ * Setup the receive address registers by setting the base receive address
* register to the devices MAC address and clearing all the other receive
* address registers to 0.
**/
@@ -1181,7 +1181,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
* of pause frames. In this case, we had to advertise
* FULL flow control because we could not advertise Rx
* ONLY. Hence, we must now check to see if we need to
- * turn OFF the TRANSMISSION of PAUSE frames.
+ * turn OFF the TRANSMISSION of PAUSE frames.
*/
if (hw->fc.requested_mode == e1000_fc_full) {
hw->fc.current_mode = e1000_fc_full;
--
1.7.4.4
^ permalink raw reply related
* [net-next-2.6 02/13] ixgbevf: Add macvlan support in the set rx mode op
From: Jeff Kirsher @ 2011-05-15 1:23 UTC (permalink / raw)
To: davem; +Cc: Greg Rose, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1305422627-9583-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Greg Rose <gregory.v.rose@intel.com>
Implement setup of unicast address list in the VF driver's set_rx_mode
netdev op. Unicast addresses are sent to the PF via a mailbox message
and the PF will check if it has room in the RAR table and if so set the
filter for the VF.
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbevf/ixgbevf_main.c | 30 ++++++++++++++++++++++++++++++
drivers/net/ixgbevf/mbx.h | 1 +
drivers/net/ixgbevf/vf.c | 34 ++++++++++++++++++++++++++++++++++
drivers/net/ixgbevf/vf.h | 1 +
4 files changed, 66 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 05fa7c8..d7ab202 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -1460,6 +1460,34 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter)
}
}
+static int ixgbevf_write_uc_addr_list(struct net_device *netdev)
+{
+ struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ int count = 0;
+
+ if ((netdev_uc_count(netdev)) > 10) {
+ printk(KERN_ERR "Too many unicast filters - No Space\n");
+ return -ENOSPC;
+ }
+
+ if (!netdev_uc_empty(netdev)) {
+ struct netdev_hw_addr *ha;
+ netdev_for_each_uc_addr(ha, netdev) {
+ hw->mac.ops.set_uc_addr(hw, ++count, ha->addr);
+ udelay(200);
+ }
+ } else {
+ /*
+ * If the list is empty then send message to PF driver to
+ * clear all macvlans on this VF.
+ */
+ hw->mac.ops.set_uc_addr(hw, 0, NULL);
+ }
+
+ return count;
+}
+
/**
* ixgbevf_set_rx_mode - Multicast set
* @netdev: network interface device structure
@@ -1476,6 +1504,8 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev)
/* reprogram multicast list */
if (hw->mac.ops.update_mc_addr_list)
hw->mac.ops.update_mc_addr_list(hw, netdev);
+
+ ixgbevf_write_uc_addr_list(netdev);
}
static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
diff --git a/drivers/net/ixgbevf/mbx.h b/drivers/net/ixgbevf/mbx.h
index b2b5bf5..ea393eb 100644
--- a/drivers/net/ixgbevf/mbx.h
+++ b/drivers/net/ixgbevf/mbx.h
@@ -81,6 +81,7 @@
#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
+#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
diff --git a/drivers/net/ixgbevf/vf.c b/drivers/net/ixgbevf/vf.c
index eecd3bf..aa3682e 100644
--- a/drivers/net/ixgbevf/vf.c
+++ b/drivers/net/ixgbevf/vf.c
@@ -216,6 +216,39 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
return 0;
}
+static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
+{
+ struct ixgbe_mbx_info *mbx = &hw->mbx;
+ u32 msgbuf[3];
+ u8 *msg_addr = (u8 *)(&msgbuf[1]);
+ s32 ret_val;
+
+ memset(msgbuf, 0, sizeof(msgbuf));
+ /*
+ * If index is one then this is the start of a new list and needs
+ * indication to the PF so it can do it's own list management.
+ * If it is zero then that tells the PF to just clear all of
+ * this VF's macvlans and there is no new list.
+ */
+ msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
+ msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
+ if (addr)
+ memcpy(msg_addr, addr, 6);
+ ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
+
+ if (!ret_val)
+ ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
+
+ msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+
+ if (!ret_val)
+ if (msgbuf[0] ==
+ (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK))
+ ret_val = -ENOMEM;
+
+ return ret_val;
+}
+
/**
* ixgbevf_set_rar_vf - set device MAC address
* @hw: pointer to hardware structure
@@ -378,6 +411,7 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = {
.check_link = ixgbevf_check_mac_link_vf,
.set_rar = ixgbevf_set_rar_vf,
.update_mc_addr_list = ixgbevf_update_mc_addr_list_vf,
+ .set_uc_addr = ixgbevf_set_uc_addr_vf,
.set_vfta = ixgbevf_set_vfta_vf,
};
diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h
index 23eb114..10306b4 100644
--- a/drivers/net/ixgbevf/vf.h
+++ b/drivers/net/ixgbevf/vf.h
@@ -62,6 +62,7 @@ struct ixgbe_mac_operations {
/* RAR, Multicast, VLAN */
s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32);
+ s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *);
s32 (*init_rx_addrs)(struct ixgbe_hw *);
s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *);
s32 (*enable_mc)(struct ixgbe_hw *);
--
1.7.4.4
^ permalink raw reply related
* [net-next-2.6 03/13] ixgbe: Add macvlan support for VF
From: Jeff Kirsher @ 2011-05-15 1:23 UTC (permalink / raw)
To: davem; +Cc: Greg Rose, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1305422627-9583-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Greg Rose <gregory.v.rose@intel.com>
Add infrastructure in the PF driver to support macvlan in the VF driver.
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe.h | 13 +++++
drivers/net/ixgbe/ixgbe_main.c | 28 +++++++++++-
drivers/net/ixgbe/ixgbe_mbx.h | 1 +
drivers/net/ixgbe/ixgbe_sriov.c | 96 ++++++++++++++++++++++++++++++++++++++-
4 files changed, 134 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 37ff531..91c1540 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -106,6 +106,7 @@
#define IXGBE_MAX_VF_FUNCTIONS 64
#define IXGBE_MAX_VFTA_ENTRIES 128
#define MAX_EMULATION_MAC_ADDRS 16
+#define IXGBE_MAX_PF_MACVLANS 15
#define VMDQ_P(p) ((p) + adapter->num_vfs)
struct vf_data_storage {
@@ -121,6 +122,15 @@ struct vf_data_storage {
u16 tx_rate;
};
+struct vf_macvlans {
+ struct list_head l;
+ int vf;
+ int rar_entry;
+ bool free;
+ bool is_macvlan;
+ u8 vf_macvlan[ETH_ALEN];
+};
+
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */
struct ixgbe_tx_buffer {
@@ -471,6 +481,9 @@ struct ixgbe_adapter {
unsigned int num_vfs;
struct vf_data_storage *vfinfo;
int vf_rate_link_speed;
+ struct vf_macvlans vf_mvs;
+ struct vf_macvlans *mv_list;
+ bool antispoofing_enabled;
};
enum ixbge_state_t {
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index a3e384b..f8196e0 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -3188,7 +3188,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
/* enable Tx loopback for VF/PF communication */
IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
/* Enable MAC Anti-Spoofing */
- hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0),
+ hw->mac.ops.set_mac_anti_spoofing(hw,
+ (adapter->antispoofing_enabled =
+ (adapter->num_vfs != 0)),
adapter->num_vfs);
}
@@ -3497,7 +3499,7 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev)
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
unsigned int vfn = adapter->num_vfs;
- unsigned int rar_entries = hw->mac.num_rar_entries - (vfn + 1);
+ unsigned int rar_entries = IXGBE_MAX_PF_MACVLANS;
int count = 0;
/* return ENOMEM indicating insufficient memory for addresses */
@@ -7107,6 +7109,8 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
#ifdef CONFIG_PCI_IOV
struct ixgbe_hw *hw = &adapter->hw;
int err;
+ int num_vf_macvlans, i;
+ struct vf_macvlans *mv_list;
if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs)
return;
@@ -7123,6 +7127,26 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
e_err(probe, "Failed to enable PCI sriov: %d\n", err);
goto err_novfs;
}
+
+ num_vf_macvlans = hw->mac.num_rar_entries -
+ (IXGBE_MAX_PF_MACVLANS + 1 + adapter->num_vfs);
+
+ adapter->mv_list = mv_list = kcalloc(num_vf_macvlans,
+ sizeof(struct vf_macvlans),
+ GFP_KERNEL);
+ if (mv_list) {
+ /* Initialize list of VF macvlans */
+ INIT_LIST_HEAD(&adapter->vf_mvs.l);
+ for (i = 0; i < num_vf_macvlans; i++) {
+ mv_list->vf = -1;
+ mv_list->free = true;
+ mv_list->rar_entry = hw->mac.num_rar_entries -
+ (i + adapter->num_vfs + 1);
+ list_add(&mv_list->l, &adapter->vf_mvs.l);
+ mv_list++;
+ }
+ }
+
/* If call to enable VFs succeeded then allocate memory
* for per VF control structures.
*/
diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h
index f53dc5b..b239bda 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ixgbe/ixgbe_mbx.h
@@ -67,6 +67,7 @@
#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
+#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
/* length of permanent address message returned from PF */
#define IXGBE_VF_PERMADDR_MSG_LEN 4
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index 4765027..9f97246 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -82,6 +82,21 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
return 0;
}
+static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct list_head *pos;
+ struct vf_macvlans *entry;
+
+ list_for_each(pos, &adapter->vf_mvs.l) {
+ entry = list_entry(pos, struct vf_macvlans, l);
+ if (entry->free == false)
+ hw->mac.ops.set_rar(hw, entry->rar_entry,
+ entry->vf_macvlan,
+ entry->vf, IXGBE_RAH_AV);
+ }
+}
+
void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
@@ -102,6 +117,9 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
}
}
+
+ /* Restore any VF macvlans */
+ ixgbe_restore_vf_macvlans(adapter);
}
static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
@@ -200,6 +218,61 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
return 0;
}
+static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
+ int vf, int index, unsigned char *mac_addr)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct list_head *pos;
+ struct vf_macvlans *entry;
+
+ if (index <= 1) {
+ list_for_each(pos, &adapter->vf_mvs.l) {
+ entry = list_entry(pos, struct vf_macvlans, l);
+ if (entry->vf == vf) {
+ entry->vf = -1;
+ entry->free = true;
+ entry->is_macvlan = false;
+ hw->mac.ops.clear_rar(hw, entry->rar_entry);
+ }
+ }
+ }
+
+ /*
+ * If index was zero then we were asked to clear the uc list
+ * for the VF. We're done.
+ */
+ if (!index)
+ return 0;
+
+ entry = NULL;
+
+ list_for_each(pos, &adapter->vf_mvs.l) {
+ entry = list_entry(pos, struct vf_macvlans, l);
+ if (entry->free)
+ break;
+ }
+
+ /*
+ * If we traversed the entire list and didn't find a free entry
+ * then we're out of space on the RAR table. Also entry may
+ * be NULL because the original memory allocation for the list
+ * failed, which is not fatal but does mean we can't support
+ * VF requests for MACVLAN because we couldn't allocate
+ * memory for the list management required.
+ */
+ if (!entry || !entry->free)
+ return -ENOSPC;
+
+ entry->free = false;
+ entry->is_macvlan = true;
+ entry->vf = vf;
+ memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN);
+
+ hw->mac.ops.set_rar(hw, entry->rar_entry, mac_addr, vf, IXGBE_RAH_AV);
+
+ return 0;
+}
+
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
{
unsigned char vf_mac_addr[6];
@@ -256,7 +329,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
s32 retval;
int entries;
u16 *hash_list;
- int add, vid;
+ int add, vid, index;
u8 *new_mac;
retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
@@ -345,6 +418,24 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
retval = ixgbe_set_vf_vlan(adapter, add, vid, vf);
}
break;
+ case IXGBE_VF_SET_MACVLAN:
+ index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >>
+ IXGBE_VT_MSGINFO_SHIFT;
+ /*
+ * If the VF is allowed to set MAC filters then turn off
+ * anti-spoofing to avoid false positives. An index
+ * greater than 0 will indicate the VF is setting a
+ * macvlan MAC filter.
+ */
+ if (index > 0 && adapter->antispoofing_enabled) {
+ hw->mac.ops.set_mac_anti_spoofing(hw, false,
+ adapter->num_vfs);
+ hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
+ adapter->antispoofing_enabled = false;
+ }
+ retval = ixgbe_set_vf_macvlan(adapter, vf, index,
+ (unsigned char *)(&msgbuf[1]));
+ break;
default:
e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
retval = IXGBE_ERR_MBX;
@@ -452,7 +543,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
goto out;
ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
ixgbe_set_vmolr(hw, vf, false);
- hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
+ if (adapter->antispoofing_enabled)
+ hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
adapter->vfinfo[vf].pf_vlan = vlan;
adapter->vfinfo[vf].pf_qos = qos;
dev_info(&adapter->pdev->dev,
--
1.7.4.4
^ permalink raw reply related
* [net-next-2.6 05/13] ixgbe: move flags and state into the same cacheline
From: Jeff Kirsher @ 2011-05-15 1:23 UTC (permalink / raw)
To: davem; +Cc: Alexander Duyck, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1305422627-9583-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This change moves flags and state into the same cacheline. The reason for
this change is because both are frequently read around the same time and
infrequently written. By combining them into the same cacheline this
should help to reduce memory utilization.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Evan Swanson <evan.swanson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe.h | 88 +++++++++++++++++++++++----------------------
1 files changed, 45 insertions(+), 43 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 91c1540..ec948ff 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -341,10 +341,48 @@ struct ixgbe_q_vector {
/* board specific private data structure */
struct ixgbe_adapter {
- struct timer_list watchdog_timer;
+ unsigned long state;
+
+ /* Some features need tri-state capability,
+ * thus the additional *_CAPABLE flags.
+ */
+ u32 flags;
+#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1)
+#define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 1)
+#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 2)
+#define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 3)
+#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 4)
+#define IXGBE_FLAG_RX_1BUF_CAPABLE (u32)(1 << 6)
+#define IXGBE_FLAG_RX_PS_CAPABLE (u32)(1 << 7)
+#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 8)
+#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 9)
+#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 10)
+#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 11)
+#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 12)
+#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 13)
+#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 14)
+#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 16)
+#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
+#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
+#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
+#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
+#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
+#define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 23)
+#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 24)
+#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 25)
+#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 26)
+#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 27)
+#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 28)
+#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 29)
+#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 30)
+
+ u32 flags2;
+#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
+#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
+#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2)
+
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u16 bd_number;
- struct work_struct reset_task;
struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
/* DCB parameters */
@@ -387,43 +425,6 @@ struct ixgbe_adapter {
u32 alloc_rx_page_failed;
u32 alloc_rx_buff_failed;
- /* Some features need tri-state capability,
- * thus the additional *_CAPABLE flags.
- */
- u32 flags;
-#define IXGBE_FLAG_RX_CSUM_ENABLED (u32)(1)
-#define IXGBE_FLAG_MSI_CAPABLE (u32)(1 << 1)
-#define IXGBE_FLAG_MSI_ENABLED (u32)(1 << 2)
-#define IXGBE_FLAG_MSIX_CAPABLE (u32)(1 << 3)
-#define IXGBE_FLAG_MSIX_ENABLED (u32)(1 << 4)
-#define IXGBE_FLAG_RX_1BUF_CAPABLE (u32)(1 << 6)
-#define IXGBE_FLAG_RX_PS_CAPABLE (u32)(1 << 7)
-#define IXGBE_FLAG_RX_PS_ENABLED (u32)(1 << 8)
-#define IXGBE_FLAG_IN_NETPOLL (u32)(1 << 9)
-#define IXGBE_FLAG_DCA_ENABLED (u32)(1 << 10)
-#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 11)
-#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 12)
-#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 13)
-#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 14)
-#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 16)
-#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
-#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
-#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
-#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
-#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
-#define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 23)
-#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 24)
-#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 25)
-#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 26)
-#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 27)
-#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 28)
-#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 29)
-#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 30)
-
- u32 flags2;
-#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
-#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
-#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2)
/* default to trying for four seconds */
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
@@ -444,7 +445,6 @@ struct ixgbe_adapter {
u32 rx_eitr_param;
u32 tx_eitr_param;
- unsigned long state;
u64 tx_busy;
unsigned int tx_ring_count;
unsigned int rx_ring_count;
@@ -453,15 +453,18 @@ struct ixgbe_adapter {
bool link_up;
unsigned long link_check_timeout;
+ struct work_struct reset_task;
struct work_struct watchdog_task;
struct work_struct sfp_task;
- struct timer_list sfp_timer;
struct work_struct multispeed_fiber_task;
struct work_struct sfp_config_module_task;
+ struct work_struct fdir_reinit_task;
+ struct work_struct check_overtemp_task;
+ struct timer_list watchdog_timer;
+ struct timer_list sfp_timer;
u32 fdir_pballoc;
u32 atr_sample_rate;
spinlock_t fdir_perfect_lock;
- struct work_struct fdir_reinit_task;
#ifdef IXGBE_FCOE
struct ixgbe_fcoe fcoe;
#endif /* IXGBE_FCOE */
@@ -472,7 +475,6 @@ struct ixgbe_adapter {
int node;
u32 led_reg;
- struct work_struct check_overtemp_task;
u32 interrupt_event;
char lsc_int_name[IFNAMSIZ + 9];
--
1.7.4.4
^ permalink raw reply related
* [net-next-2.6 06/13] ixgbe: Combine SFP and multi-speed fiber task into single service task
From: Jeff Kirsher @ 2011-05-15 1:23 UTC (permalink / raw)
To: davem; +Cc: Alexander Duyck, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1305422627-9583-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This change is meant to address several race conditions with multi-speed
fiber SFP+ modules in 82599 adapters. Specifically issues have been seen
in which both the SFP configuration and the multi-speed fiber configuration
are running simultaneously which will result in the device getting into an
erroneous link down state.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Evan Swanson <evan.swanson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe.h | 26 ++--
drivers/net/ixgbe/ixgbe_main.c | 388 +++++++++++++++++++++-------------------
2 files changed, 213 insertions(+), 201 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index ec948ff..cbb04ba 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -367,19 +367,20 @@ struct ixgbe_adapter {
#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
-#define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 23)
-#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 24)
-#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 25)
-#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 26)
-#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 27)
-#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 28)
-#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 29)
-#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 30)
+#define IXGBE_FLAG_NEED_LINK_CONFIG (u32)(1 << 23)
+#define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 24)
+#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 25)
+#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 26)
+#define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 27)
+#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 28)
+#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 29)
u32 flags2;
#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2)
+#define IXGBE_FLAG2_SEARCH_FOR_SFP (u32)(1 << 4)
+#define IXGBE_FLAG2_SFP_NEEDS_RESET (u32)(1 << 5)
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u16 bd_number;
@@ -455,13 +456,11 @@ struct ixgbe_adapter {
struct work_struct reset_task;
struct work_struct watchdog_task;
- struct work_struct sfp_task;
- struct work_struct multispeed_fiber_task;
- struct work_struct sfp_config_module_task;
struct work_struct fdir_reinit_task;
struct work_struct check_overtemp_task;
+ struct work_struct service_task;
struct timer_list watchdog_timer;
- struct timer_list sfp_timer;
+ struct timer_list service_timer;
u32 fdir_pballoc;
u32 atr_sample_rate;
spinlock_t fdir_perfect_lock;
@@ -492,7 +491,8 @@ enum ixbge_state_t {
__IXGBE_TESTING,
__IXGBE_RESETTING,
__IXGBE_DOWN,
- __IXGBE_SFP_MODULE_NOT_FOUND
+ __IXGBE_SERVICE_SCHED,
+ __IXGBE_IN_SFP_INIT,
};
struct ixgbe_rsc_cb {
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index f8196e0..a5d4226 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -191,6 +191,22 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
}
+static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
+{
+ if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
+ !test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state))
+ schedule_work(&adapter->service_task);
+}
+
+static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter)
+{
+ BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state));
+
+ /* flush memory to make sure state is correct before next watchog */
+ smp_mb__before_clear_bit();
+ clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
+}
+
struct ixgbe_reg_info {
u32 ofs;
char *name;
@@ -1858,15 +1874,19 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
if (eicr & IXGBE_EICR_GPI_SDP2) {
/* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- schedule_work(&adapter->sfp_config_module_task);
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
+ ixgbe_service_event_schedule(adapter);
+ }
}
if (eicr & IXGBE_EICR_GPI_SDP1) {
/* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
- if (!test_bit(__IXGBE_DOWN, &adapter->state))
- schedule_work(&adapter->multispeed_fiber_task);
+ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+ ixgbe_service_event_schedule(adapter);
+ }
}
}
@@ -1937,8 +1957,10 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
ixgbe_check_fan_failure(adapter, eicr);
+ /* re-enable the original interrupt state, no lsc, no queues */
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, eicr &
+ ~(IXGBE_EIMS_LSC | IXGBE_EIMS_RTX_QUEUE));
return IRQ_HANDLED;
}
@@ -3772,31 +3794,16 @@ static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
**/
static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
{
- struct ixgbe_hw *hw = &adapter->hw;
+ /*
+ * We are assuming the worst case scenerio here, and that
+ * is that an SFP was inserted/removed after the reset
+ * but before SFP detection was enabled. As such the best
+ * solution is to just start searching as soon as we start
+ */
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
- if (hw->phy.multispeed_fiber) {
- /*
- * In multispeed fiber setups, the device may not have
- * had a physical connection when the driver loaded.
- * If that's the case, the initial link configuration
- * couldn't get the MAC into 10G or 1G mode, so we'll
- * never have a link status change interrupt fire.
- * We need to try and force an autonegotiation
- * session, then bring up link.
- */
- if (hw->mac.ops.setup_sfp)
- hw->mac.ops.setup_sfp(hw);
- if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
- schedule_work(&adapter->multispeed_fiber_task);
- } else {
- /*
- * Direct Attach Cu and non-multispeed fiber modules
- * still need to be configured properly prior to
- * attempting link.
- */
- if (!(adapter->flags & IXGBE_FLAG_IN_SFP_MOD_TASK))
- schedule_work(&adapter->sfp_config_module_task);
- }
+ adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
}
/**
@@ -3926,17 +3933,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
e_crit(drv, "Fan has stopped, replace the adapter\n");
}
- /*
- * For hot-pluggable SFP+ devices, a new SFP+ module may have
- * arrived before interrupts were enabled but after probe. Such
- * devices wouldn't have their type identified yet. We need to
- * kick off the SFP+ module setup first, then try to bring up link.
- * If we're not hot-pluggable SFP+, we just need to configure link
- * and bring it up.
- */
- if (hw->phy.type == ixgbe_phy_none)
- schedule_work(&adapter->sfp_config_module_task);
-
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
@@ -3945,6 +3941,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
adapter->link_check_timeout = jiffies;
mod_timer(&adapter->watchdog_timer, jiffies);
+ mod_timer(&adapter->service_timer, jiffies);
/* Set PF Reset Done bit so PF/VF Mail Ops can work */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
@@ -3957,6 +3954,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
{
WARN_ON(in_interrupt());
+ /* put off any impending NetWatchDogTimeout */
+ adapter->netdev->trans_start = jiffies;
+
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
usleep_range(1000, 2000);
ixgbe_down(adapter);
@@ -3985,10 +3985,20 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
int err;
+ /* lock SFP init bit to prevent race conditions with the watchdog */
+ while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+ usleep_range(1000, 2000);
+
+ /* clear all SFP and link config related flags while holding SFP_INIT */
+ adapter->flags2 &= ~(IXGBE_FLAG2_SEARCH_FOR_SFP |
+ IXGBE_FLAG2_SFP_NEEDS_RESET);
+ adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+
err = hw->mac.ops.init_hw(hw);
switch (err) {
case 0:
case IXGBE_ERR_SFP_NOT_PRESENT:
+ case IXGBE_ERR_SFP_NOT_SUPPORTED:
break;
case IXGBE_ERR_MASTER_REQUESTS_PENDING:
e_dev_err("master disable timed out\n");
@@ -4006,6 +4016,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
e_dev_err("Hardware Error: %d\n", err);
}
+ clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+
/* reprogram the RAR[0] in case user changed it. */
hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs,
IXGBE_RAH_AV);
@@ -4167,11 +4179,9 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
netif_tx_stop_all_queues(netdev);
- clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- del_timer_sync(&adapter->sfp_timer);
del_timer_sync(&adapter->watchdog_timer);
cancel_work_sync(&adapter->watchdog_task);
-
+ /* call carrier off first to avoid false dev_watchdog timeouts */
netif_carrier_off(netdev);
netif_tx_disable(netdev);
@@ -4179,6 +4189,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_napi_disable_all(adapter);
+ adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+
+ del_timer_sync(&adapter->service_timer);
+
/* Cleanup the affinity_hint CPU mask memory and callback */
for (i = 0; i < num_q_vectors; i++) {
struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
@@ -5148,57 +5162,6 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
}
/**
- * ixgbe_sfp_timer - worker thread to find a missing module
- * @data: pointer to our adapter struct
- **/
-static void ixgbe_sfp_timer(unsigned long data)
-{
- struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
-
- /*
- * Do the sfp_timer outside of interrupt context due to the
- * delays that sfp+ detection requires
- */
- schedule_work(&adapter->sfp_task);
-}
-
-/**
- * ixgbe_sfp_task - worker thread to find a missing module
- * @work: pointer to work_struct containing our data
- **/
-static void ixgbe_sfp_task(struct work_struct *work)
-{
- struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- sfp_task);
- struct ixgbe_hw *hw = &adapter->hw;
-
- if ((hw->phy.type == ixgbe_phy_nl) &&
- (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) {
- s32 ret = hw->phy.ops.identify_sfp(hw);
- if (ret == IXGBE_ERR_SFP_NOT_PRESENT)
- goto reschedule;
- ret = hw->phy.ops.reset(hw);
- if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- e_dev_err("failed to initialize because an unsupported "
- "SFP+ module type was detected.\n");
- e_dev_err("Reload the driver after installing a "
- "supported module.\n");
- unregister_netdev(adapter->netdev);
- } else {
- e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
- }
- /* don't need this routine any more */
- clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- }
- return;
-reschedule:
- if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state))
- mod_timer(&adapter->sfp_timer,
- round_jiffies(jiffies + (2 * HZ)));
-}
-
-/**
* ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter)
* @adapter: board private structure to initialize
*
@@ -6042,65 +6005,6 @@ watchdog_short_circuit:
}
/**
- * ixgbe_multispeed_fiber_task - worker thread to configure multispeed fiber
- * @work: pointer to work_struct containing our data
- **/
-static void ixgbe_multispeed_fiber_task(struct work_struct *work)
-{
- struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- multispeed_fiber_task);
- struct ixgbe_hw *hw = &adapter->hw;
- u32 autoneg;
- bool negotiation;
-
- adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK;
- autoneg = hw->phy.autoneg_advertised;
- if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
- hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
- hw->mac.autotry_restart = false;
- if (hw->mac.ops.setup_link)
- hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
- adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
- adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK;
-}
-
-/**
- * ixgbe_sfp_config_module_task - worker thread to configure a new SFP+ module
- * @work: pointer to work_struct containing our data
- **/
-static void ixgbe_sfp_config_module_task(struct work_struct *work)
-{
- struct ixgbe_adapter *adapter = container_of(work,
- struct ixgbe_adapter,
- sfp_config_module_task);
- struct ixgbe_hw *hw = &adapter->hw;
- u32 err;
-
- adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK;
-
- /* Time for electrical oscillations to settle down */
- msleep(100);
- err = hw->phy.ops.identify_sfp(hw);
-
- if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- e_dev_err("failed to initialize because an unsupported SFP+ "
- "module type was detected.\n");
- e_dev_err("Reload the driver after installing a supported "
- "module.\n");
- unregister_netdev(adapter->netdev);
- return;
- }
- if (hw->mac.ops.setup_sfp)
- hw->mac.ops.setup_sfp(hw);
-
- if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
- /* This will also work for DA Twinax connections */
- schedule_work(&adapter->multispeed_fiber_task);
- adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
-}
-
-/**
* ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table
* @work: pointer to work_struct containing our data
**/
@@ -6273,6 +6177,141 @@ static void ixgbe_watchdog_task(struct work_struct *work)
mutex_unlock(&ixgbe_watchdog_lock);
}
+/**
+ * ixgbe_sfp_detection_subtask - poll for SFP+ cable
+ * @adapter - the ixgbe adapter structure
+ **/
+static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ s32 err;
+
+ /* not searching for SFP so there is nothing to do here */
+ if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) &&
+ !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
+ return;
+
+ /* someone else is in init, wait until next service event */
+ if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+ return;
+
+ err = hw->phy.ops.identify_sfp(hw);
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto sfp_out;
+
+ if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
+ /* If no cable is present, then we need to reset
+ * the next time we find a good cable. */
+ adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
+ }
+
+ /* exit on error */
+ if (err)
+ goto sfp_out;
+
+ /* exit if reset not needed */
+ if (!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
+ goto sfp_out;
+
+ adapter->flags2 &= ~IXGBE_FLAG2_SFP_NEEDS_RESET;
+
+ /*
+ * A module may be identified correctly, but the EEPROM may not have
+ * support for that module. setup_sfp() will fail in that case, so
+ * we should not allow that module to load.
+ */
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ err = hw->phy.ops.reset(hw);
+ else
+ err = hw->mac.ops.setup_sfp(hw);
+
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto sfp_out;
+
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+ e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
+
+sfp_out:
+ clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+
+ if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) &&
+ (adapter->netdev->reg_state == NETREG_REGISTERED)) {
+ e_dev_err("failed to initialize because an unsupported "
+ "SFP+ module type was detected.\n");
+ e_dev_err("Reload the driver after installing a "
+ "supported module.\n");
+ unregister_netdev(adapter->netdev);
+ }
+}
+
+/**
+ * ixgbe_sfp_link_config_subtask - set up link SFP after module install
+ * @adapter - the ixgbe adapter structure
+ **/
+static void ixgbe_sfp_link_config_subtask(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 autoneg;
+ bool negotiation;
+
+ if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_CONFIG))
+ return;
+
+ /* someone else is in init, wait until next service event */
+ if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+ return;
+
+ adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+
+ autoneg = hw->phy.autoneg_advertised;
+ if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
+ hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
+ hw->mac.autotry_restart = false;
+ if (hw->mac.ops.setup_link)
+ hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
+
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+ adapter->link_check_timeout = jiffies;
+ clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+}
+
+/**
+ * ixgbe_service_timer - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+static void ixgbe_service_timer(unsigned long data)
+{
+ struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
+ unsigned long next_event_offset;
+
+ /* poll faster when waiting for link */
+ if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE)
+ next_event_offset = HZ / 10;
+ else
+ next_event_offset = HZ * 2;
+
+ /* Reset the timer */
+ mod_timer(&adapter->service_timer, next_event_offset + jiffies);
+
+ ixgbe_service_event_schedule(adapter);
+}
+
+/**
+ * ixgbe_service_task - manages and runs subtasks
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_service_task(struct work_struct *work)
+{
+ struct ixgbe_adapter *adapter = container_of(work,
+ struct ixgbe_adapter,
+ service_task);
+
+ ixgbe_sfp_detection_subtask(adapter);
+ ixgbe_sfp_link_config_subtask(adapter);
+
+ ixgbe_service_event_complete(adapter);
+}
+
static int ixgbe_tso(struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring, struct sk_buff *skb,
u32 tx_flags, u8 *hdr_len, __be16 protocol)
@@ -7317,22 +7356,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->phy.mdio.mdio_read = ixgbe_mdio_read;
hw->phy.mdio.mdio_write = ixgbe_mdio_write;
- /* set up this timer and work struct before calling get_invariants
- * which might start the timer
- */
- init_timer(&adapter->sfp_timer);
- adapter->sfp_timer.function = ixgbe_sfp_timer;
- adapter->sfp_timer.data = (unsigned long) adapter;
-
- INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
-
- /* multispeed fiber has its own tasklet, called from GPI SDP1 context */
- INIT_WORK(&adapter->multispeed_fiber_task, ixgbe_multispeed_fiber_task);
-
- /* a new SFP+ module arrival, called from GPI SDP2 context */
- INIT_WORK(&adapter->sfp_config_module_task,
- ixgbe_sfp_config_module_task);
-
ii->get_invariants(hw);
/* setup the private structure */
@@ -7366,17 +7389,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
hw->phy.reset_if_overtemp = false;
if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
hw->mac.type == ixgbe_mac_82598EB) {
- /*
- * Start a kernel thread to watch for a module to arrive.
- * Only do this for 82598, since 82599 will generate
- * interrupts on module arrival.
- */
- set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- mod_timer(&adapter->sfp_timer,
- round_jiffies(jiffies + (2 * HZ)));
err = 0;
} else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
- e_dev_err("failed to initialize because an unsupported SFP+ "
+ e_dev_err("failed to load because an unsupported SFP+ "
"module type was detected.\n");
e_dev_err("Reload the driver after installing a supported "
"module.\n");
@@ -7468,6 +7483,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
(hw->mac.type == ixgbe_mac_82599EB))))
hw->mac.ops.disable_tx_laser(hw);
+ setup_timer(&adapter->service_timer, &ixgbe_service_timer,
+ (unsigned long) adapter);
init_timer(&adapter->watchdog_timer);
adapter->watchdog_timer.function = ixgbe_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
@@ -7475,6 +7492,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task);
+ INIT_WORK(&adapter->service_task, ixgbe_service_task);
+ clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
+
err = ixgbe_init_interrupt_scheme(adapter);
if (err)
goto err_sw_init;
@@ -7593,11 +7613,7 @@ err_sw_init:
err_eeprom:
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
ixgbe_disable_sriov(adapter);
- clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
- del_timer_sync(&adapter->sfp_timer);
- cancel_work_sync(&adapter->sfp_task);
- cancel_work_sync(&adapter->multispeed_fiber_task);
- cancel_work_sync(&adapter->sfp_config_module_task);
+ adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
iounmap(hw->hw_addr);
err_ioremap:
free_netdev(netdev);
@@ -7625,19 +7641,15 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
struct net_device *netdev = adapter->netdev;
set_bit(__IXGBE_DOWN, &adapter->state);
+ cancel_work_sync(&adapter->service_task);
/*
* The timers may be rescheduled, so explicitly disable them
* from being rescheduled.
*/
- clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->sfp_timer);
cancel_work_sync(&adapter->watchdog_task);
- cancel_work_sync(&adapter->sfp_task);
- cancel_work_sync(&adapter->multispeed_fiber_task);
- cancel_work_sync(&adapter->sfp_config_module_task);
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
cancel_work_sync(&adapter->fdir_reinit_task);
--
1.7.4.4
^ permalink raw reply related
* [net-next-2.6 04/13] ixgbe: force unlock on timeout
From: Jeff Kirsher @ 2011-05-15 1:23 UTC (permalink / raw)
To: davem; +Cc: Emil Tantilov, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1305422627-9583-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Emil Tantilov <emil.s.tantilov@intel.com>
The semaphore can be in locked state upon driver load, particularly
on 82598 if a machine is rebooted due to panic and the semaphore was
acquired just prior to the panic.
This patch unlocks the semaphore if it times out.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ixgbe/ixgbe_common.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index c4730cd..b894b42 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1189,6 +1189,28 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
udelay(50);
}
+ if (i == timeout) {
+ hw_dbg(hw, "Driver can't access the Eeprom - SMBI Semaphore "
+ "not granted.\n");
+ /*
+ * this release is particularly important because our attempts
+ * above to get the semaphore may have succeeded, and if there
+ * was a timeout, we should unconditionally clear the semaphore
+ * bits to free the driver to make progress
+ */
+ ixgbe_release_eeprom_semaphore(hw);
+
+ udelay(50);
+ /*
+ * one last try
+ * If the SMBI bit is 0 when we read it, then the bit will be
+ * set and we have the semaphore
+ */
+ swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+ if (!(swsm & IXGBE_SWSM_SMBI))
+ status = 0;
+ }
+
/* Now get the semaphore between SW/FW through the SWESMBI bit */
if (status == 0) {
for (i = 0; i < timeout; i++) {
--
1.7.4.4
^ 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