* Re: [RFC] [PATCH] ethtool: Flags for fibre speed switching
From: David Miller @ 2010-06-22 17:17 UTC (permalink / raw)
To: bhutchings; +Cc: netdev, jgarzik, linux-net-drivers
In-Reply-To: <1276543562.2074.41.camel@achroite.uk.solarflarecom.com>
From: Ben Hutchings <bhutchings@solarflare.com>
Date: Mon, 14 Jun 2010 20:26:02 +0100
> ethtool.h currently defines only SUPPORTED_FIBRE to cover all fibre
> modes. However, SFP+ slots support both 1G and 10G fibre modules and
> some modules are dual-speed. Some drivers use the BASE-T flags for SFP+
> modules of all media types, but this is strictly incorrect and can be
> confusing as there are real BASE-T modules for SFP+. There should be
> distinct flags for fibre modes. However I'm not sure whether it's worth
> defining flags for each fibre mode (there are quite a few) or only for
> each speed.
>
> Similarly there is only ADVERTISED_FIBRE to cover all fibre modes.
> Although there is no AN protocol for fibre, an SFP+ NIC effectively
> autonegotiates its speed with the module. By default, an SFP+ NIC will
> accept both 1G and 10G modules and switch speed automatically. With a
> dual-speed module, the NIC driver can allow forcing the speed through
> ethtool, but unless it maintains some hidden state it must reset the
> speed whenever the module is hotplugged (perhaps accidentally). So it
> should be possible for the administrator to control speed selection in a
> sticky way through the advertising mask.
I'm fine with this, feel free to make a formal submission for
net-next-2.6
^ permalink raw reply
* Re: [PATCH net-next-2.6] ipv4: sysctl to block responding on down interface
From: David Miller @ 2010-06-22 17:15 UTC (permalink / raw)
To: shemminger; +Cc: joakim.tjernlund, netdev
In-Reply-To: <20100611084854.0680c014@nehalam>
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Fri, 11 Jun 2010 08:48:54 -0700
> The initial problem report was for a management application that used ICMP
> to check link availability.
That application is buggy, and even if we apply this patch it will
only properly function when speaking to systems in a non-default
configuration. And, it would be a non-default setting which, by your
own admission below, cannot function properly in valid interface
configurations.
It's easier to fix the app to work in all cases than to add another
sysctl knob hack for a segment of the world that can't seem to wrap
their head around the fact that our behavior is valid, specified, and
an explicit design decision meant to increase the chances of
successful communication between two systems.
> The default is disabled to maintain compatibility with previous behavior.
> This is not recommended for server systems because it makes fail over more
> difficult, and does not account for configurations where multiple interfaces
> have the same IP address.
The fact that the syctl knob, when enabled, can't even function properly
in this "multiple interfaces with same address" case is another reason I
have decided to not apply this.
^ permalink raw reply
* Re: bnx2 fails to compile on parisc because of missing get_dma_ops()
From: Grant Grundler @ 2010-06-22 17:14 UTC (permalink / raw)
To: FUJITA Tomonori
Cc: lethal, davem, mchan, vapier, JBottomley, netdev, linux-parisc,
linux-kernel
In-Reply-To: <20100622152823R.fujita.tomonori@lab.ntt.co.jp>
On Tue, Jun 22, 2010 at 03:30:08PM +0900, FUJITA Tomonori wrote:
...
> > I don't see any harm in letting drivers know whether we can support
> > consistent DMA allocs for a given struct device or not though, even if
> > the micro-optimization is marginal at best.
>
> I'm happier with exporting less DMA APIs to drivers because looks like
> new original ways to use the APIs wrongly can be always invented.
Agree.
...
> There are architectures that need to turn off the CPU cache for
> coherent memory, I can't find none of them that see if an address is
> coherent or not in dma_is_consistent().
parisc "knows" primarily based on chipset and then checks CPU model.
We hook in the correct dma_ops early in boot before any device drivers
are probed.
hth,
grant
^ permalink raw reply
* Re: [PATCH] hso: remove setting of low_latency flag
From: David Miller @ 2010-06-22 17:10 UTC (permalink / raw)
To: f.aben; +Cc: gregkh, linux-usb, netdev
In-Reply-To: <1276765415.1532.5.camel@filip-linux>
From: Filip Aben <f.aben@option.com>
Date: Thu, 17 Jun 2010 11:03:35 +0200
> Did the patch below get accepted or is there a problem with it ?
> Haven't seen it appearing in any git trees so far.
I've applied your patch.
^ permalink raw reply
* Re: 2.6.34 Crash in dmaengine_put()
From: Jeffrey Merkey @ 2010-06-22 16:36 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Andrew Morton, linux-kernel, Dan Williams, netdev
In-Reply-To: <1277217804.3057.428.camel@edumazet-laptop>
>
>> OK. This bug occurs if you OR in the IFF_UP flag while creating
>> virtual interfaces without going through the normal ifup/ifdown
>> scripts. Looks like a hole. I will post the trace shortly. It's
>> easy to reproduce, take the dummy net driver, OR in the IFF_UP flag in
>> dummy_setup, and watch the kernel crash.
>>
>
> Then dont do that ?
>
> No need to send us a trace, unless you use a pristine kernel.
>
> IFF_UP changes rules are very strict, dont try to avoid them and claim
> there is a hole or something wrong.
>
> Check __dev_open() , __dev_close() and __dev_change_flags() were OR/AND
> IFF_UP is done by core network.
>
> Net drivers are not allowed to change IFF_UP themselves.
>
> (DE-600 & DE-620 being the exceptions to confirm this rule, of course)
>
Gee. OK, its a bug. I see the crash when unregister_netdev is
called. Changing a flag in a driver should not cause the kernel to
crash. You should check the code. The dmaengine registration should
have nothing to do with registering a netdev -- period. I have coded
arounnd it but its damn convenient to create virtual drivers on the
fly and mark them as UP without needing to configure a bunch of text
scripts to bring one up or down.
The code itself is busted because it has a check if the dmaengine ref
count goes negative. If you are going to have a registration layer
the rest of the OS should not have to wonder about its disconnected
state. The busted code is right at the top of dmaengine_put where it
decrements the ref count then immediately jumps to a bug. Need a
better way here I think to prevent needless crashes. Someone could
just alter this flag remotely and crash a server -- HOLE - :)
Jeff
^ permalink raw reply
* Re: [PATCH] sky2: enable rx/tx in sky2_phy_reinit()
From: Mike McCormack @ 2010-06-22 14:57 UTC (permalink / raw)
To: Brandon Philips; +Cc: Stephen Hemminger, netdev, davem
In-Reply-To: <20100617022158.GA4135@jenkins.ifup.org>
Tested, and verified that it fixes the bug reported.
Tested-by: Mike McCormack <mikem@ring3k.org>
On 17 June 2010 11:21, Brandon Philips <brandon@ifup.org> wrote:
> sky2_phy_reinit is called by the ethtool helpers sky2_set_settings,
> sky2_nway_reset and sky2_set_pauseparam when netif_running.
>
> However, at the end of sky2_phy_init GM_GP_CTRL has GM_GPCR_RX_ENA and
> GM_GPCR_TX_ENA cleared. So, doing these commands causes the device to
> stop working:
>
> $ ethtool -r eth0
> $ ethtool -A eth0 autoneg off
>
> Fix this issue by enabling Rx/Tx after running sky2_phy_init in
> sky2_phy_reinit.
>
> Signed-off-by: Brandon Philips <bphilips@suse.de>
> Tested-by: Brandon Philips <bphilips@suse.de>
> Cc: stable@kernel.org
>
> ---
> drivers/net/sky2.c | 19 ++++++++++++++-----
> 1 files changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
> index 2111c7b..7985165 100644
> --- a/drivers/net/sky2.c
> +++ b/drivers/net/sky2.c
> @@ -717,11 +717,24 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
> sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
> }
>
> +/* Enable Rx/Tx */
> +static void sky2_enable_rx_tx(struct sky2_port *sky2)
> +{
> + struct sky2_hw *hw = sky2->hw;
> + unsigned port = sky2->port;
> + u16 reg;
> +
> + reg = gma_read16(hw, port, GM_GP_CTRL);
> + reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
> + gma_write16(hw, port, GM_GP_CTRL, reg);
> +}
> +
> /* Force a renegotiation */
> static void sky2_phy_reinit(struct sky2_port *sky2)
> {
> spin_lock_bh(&sky2->phy_lock);
> sky2_phy_init(sky2->hw, sky2->port);
> + sky2_enable_rx_tx(sky2);
> spin_unlock_bh(&sky2->phy_lock);
> }
>
> @@ -2040,7 +2053,6 @@ static void sky2_link_up(struct sky2_port *sky2)
> {
> struct sky2_hw *hw = sky2->hw;
> unsigned port = sky2->port;
> - u16 reg;
> static const char *fc_name[] = {
> [FC_NONE] = "none",
> [FC_TX] = "tx",
> @@ -2048,10 +2060,7 @@ static void sky2_link_up(struct sky2_port *sky2)
> [FC_BOTH] = "both",
> };
>
> - /* enable Rx/Tx */
> - reg = gma_read16(hw, port, GM_GP_CTRL);
> - reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
> - gma_write16(hw, port, GM_GP_CTRL, reg);
> + sky2_enable_rx_tx(sky2);
>
> gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
>
> --
> 1.7.1
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: 2.6.34 Crash in dmaengine_put()
From: Eric Dumazet @ 2010-06-22 14:43 UTC (permalink / raw)
To: Jeffrey Merkey; +Cc: Andrew Morton, linux-kernel, Dan Williams, netdev
In-Reply-To: <AANLkTimsDSrEL8vT877pLYSa4A338p4Y8w0Ya6Xm7BFJ@mail.gmail.com>
Le mardi 22 juin 2010 à 08:08 -0600, Jeffrey Merkey a écrit :
Please dont top post on lkml (or netdev) messages
> OK. This bug occurs if you OR in the IFF_UP flag while creating
> virtual interfaces without going through the normal ifup/ifdown
> scripts. Looks like a hole. I will post the trace shortly. It's
> easy to reproduce, take the dummy net driver, OR in the IFF_UP flag in
> dummy_setup, and watch the kernel crash.
>
Then dont do that ?
No need to send us a trace, unless you use a pristine kernel.
IFF_UP changes rules are very strict, dont try to avoid them and claim
there is a hole or something wrong.
Check __dev_open() , __dev_close() and __dev_change_flags() were OR/AND
IFF_UP is done by core network.
Net drivers are not allowed to change IFF_UP themselves.
(DE-600 & DE-620 being the exceptions to confirm this rule, of course)
> Jeff
>
> On Mon, Jun 21, 2010 at 9:28 PM, Andrew Morton
> <akpm@linux-foundation.org> wrote:
> > On Mon, 21 Jun 2010 20:57:40 -0600 Jeffrey Merkey <jeffmerkey@gmail.com> wrote:
> >
> >> If someone sets the IFF_UP flags in the netdev structure without going
> >> through ifup userspace stuff, during unregister of the the netdev
> >> the dmaengine-put code will decrement the reference counter negative,
> >> and crash at BUG! in the driver/dma/dmaengine.c code. This seems
> >> busted.
> >>
> >
> > Please send a copy of the kernel BUG trace.
> >
> -
^ permalink raw reply
* Link-local address handling for IPv4
From: Fischer, Anna @ 2010-06-22 13:17 UTC (permalink / raw)
To: netdev@vger.kernel.org
Hi,
Does the Linux kernel network stack do any specific handling of link-local address configuration and handling according to RFC 3927? I know that there is user-level code like Zeroconf / Avahi and these tools create ARP sockets directly on the specified network interfaces in order to support link-local address handling. But if I do not run any of these tools, does the kernel's ARP code take care of this, too?
Thanks,
Anna
^ permalink raw reply
* [PATCH NEXT 8/8] qlcnic: update version to 5.0.6
From: amit.salecha @ 2010-06-22 13:19 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1277212745-26857-1-git-send-email-amit.salecha@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 7fa761a..3675678 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -51,8 +51,8 @@
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 5
-#define QLCNIC_LINUX_VERSIONID "5.0.5"
+#define _QLCNIC_LINUX_SUBVERSION 6
+#define QLCNIC_LINUX_VERSIONID "5.0.6"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
--
1.6.0.2
^ permalink raw reply related
* [PATCH NEXT 7/8] qlcnic: mark context state freed after destroy
From: amit.salecha @ 2010-06-22 13:19 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1277212745-26857-1-git-send-email-amit.salecha@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
After destroying recv ctx, context state remain same.
Fix it by marking as FREED.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 2 +-
drivers/net/qlcnic/qlcnic_ctx.c | 2 ++
2 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 6ec34a7..7fa761a 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -573,7 +573,7 @@ struct qlcnic_recv_context {
/*
* Context state
*/
-
+#define QLCNIC_HOST_CTX_STATE_FREED 0
#define QLCNIC_HOST_CTX_STATE_ACTIVE 2
/*
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index be341c1..941cd08 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -280,6 +280,8 @@ qlcnic_fw_cmd_destroy_rx_ctx(struct qlcnic_adapter *adapter)
dev_err(&adapter->pdev->dev,
"Failed to destroy rx ctx in firmware\n");
}
+
+ recv_ctx->state = QLCNIC_HOST_CTX_STATE_FREED;
}
static int
--
1.6.0.2
^ permalink raw reply related
* [PATCH NEXT 1/8] qlcnic: cleanup skb allocation
From: amit.salecha @ 2010-06-22 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1277212745-26857-1-git-send-email-amit.salecha@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
No need to maintian separate state for alloced and freed skb.
This can be done by null check.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 2 --
drivers/net/qlcnic/qlcnic_ethtool.c | 2 --
drivers/net/qlcnic/qlcnic_init.c | 30 +++++++++++++-----------------
3 files changed, 13 insertions(+), 21 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 99ccdd8..86e4781 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -381,7 +381,6 @@ struct qlcnic_rx_buffer {
struct sk_buff *skb;
u64 dma;
u16 ref_handle;
- u16 state;
};
/* Board types */
@@ -423,7 +422,6 @@ struct qlcnic_adapter_stats {
u64 xmit_on;
u64 xmit_off;
u64 skb_alloc_failure;
- u64 null_skb;
u64 null_rxbuf;
u64 rx_dma_map_error;
u64 tx_dma_map_error;
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 3e4822a..a4f1120 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -69,8 +69,6 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = {
QLC_SIZEOF(stats.xmit_off), QLC_OFF(stats.xmit_off)},
{"skb_alloc_failure", QLC_SIZEOF(stats.skb_alloc_failure),
QLC_OFF(stats.skb_alloc_failure)},
- {"null skb",
- QLC_SIZEOF(stats.null_skb), QLC_OFF(stats.null_skb)},
{"null rxbuf",
QLC_SIZEOF(stats.null_rxbuf), QLC_OFF(stats.null_rxbuf)},
{"rx dma map error", QLC_SIZEOF(stats.rx_dma_map_error),
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 058ce61..1c3d5a9 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -112,14 +112,15 @@ void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter)
rds_ring = &recv_ctx->rds_rings[ring];
for (i = 0; i < rds_ring->num_desc; ++i) {
rx_buf = &(rds_ring->rx_buf_arr[i]);
- if (rx_buf->state == QLCNIC_BUFFER_FREE)
+ if (rx_buf->skb == NULL)
continue;
+
pci_unmap_single(adapter->pdev,
rx_buf->dma,
rds_ring->dma_size,
PCI_DMA_FROMDEVICE);
- if (rx_buf->skb != NULL)
- dev_kfree_skb_any(rx_buf->skb);
+
+ dev_kfree_skb_any(rx_buf->skb);
}
}
}
@@ -266,7 +267,6 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
list_add_tail(&rx_buf->list,
&rds_ring->free_list);
rx_buf->ref_handle = i;
- rx_buf->state = QLCNIC_BUFFER_FREE;
rx_buf++;
}
spin_lock_init(&rds_ring->lock);
@@ -1281,14 +1281,12 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
dma_addr_t dma;
struct pci_dev *pdev = adapter->pdev;
- buffer->skb = dev_alloc_skb(rds_ring->skb_size);
- if (!buffer->skb) {
+ skb = dev_alloc_skb(rds_ring->skb_size);
+ if (!skb) {
adapter->stats.skb_alloc_failure++;
return -ENOMEM;
}
- skb = buffer->skb;
-
skb_reserve(skb, 2);
dma = pci_map_single(pdev, skb->data,
@@ -1297,13 +1295,11 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
if (pci_dma_mapping_error(pdev, dma)) {
adapter->stats.rx_dma_map_error++;
dev_kfree_skb_any(skb);
- buffer->skb = NULL;
return -ENOMEM;
}
buffer->skb = skb;
buffer->dma = dma;
- buffer->state = QLCNIC_BUFFER_BUSY;
return 0;
}
@@ -1316,14 +1312,15 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
buffer = &rds_ring->rx_buf_arr[index];
+ if (unlikely(buffer->skb == NULL)) {
+ WARN_ON(1);
+ return NULL;
+ }
+
pci_unmap_single(adapter->pdev, buffer->dma, rds_ring->dma_size,
PCI_DMA_FROMDEVICE);
skb = buffer->skb;
- if (!skb) {
- adapter->stats.null_skb++;
- goto no_skb;
- }
if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) {
adapter->stats.csummed++;
@@ -1335,8 +1332,7 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter,
skb->dev = adapter->netdev;
buffer->skb = NULL;
-no_skb:
- buffer->state = QLCNIC_BUFFER_FREE;
+
return skb;
}
@@ -1511,7 +1507,7 @@ qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max)
WARN_ON(desc_cnt > 1);
- if (rxbuf)
+ if (likely(rxbuf))
list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
else
adapter->stats.null_rxbuf++;
--
1.6.0.2
^ permalink raw reply related
* [PATCH NEXT 5/8] qlcnic: dont free host resources during fw recovery
From: amit.salecha @ 2010-06-22 13:19 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1277212745-26857-1-git-send-email-amit.salecha@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
There is no need to free/alloc host resources during firmware
recovery.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/qlcnic/qlcnic_main.c | 32 +++-----------------------------
1 files changed, 3 insertions(+), 29 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 38d8fe0..c4602fa 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -1392,8 +1392,6 @@ static int __qlcnic_shutdown(struct pci_dev *pdev)
cancel_work_sync(&adapter->tx_timeout_task);
- qlcnic_detach(adapter);
-
qlcnic_clr_all_drv_state(adapter);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
@@ -1454,28 +1452,16 @@ qlcnic_resume(struct pci_dev *pdev)
}
if (netif_running(netdev)) {
- err = qlcnic_attach(adapter);
- if (err)
- goto err_out;
-
err = qlcnic_up(adapter, netdev);
if (err)
- goto err_out_detach;
-
+ goto done;
qlcnic_config_indev_addr(netdev, NETDEV_UP);
}
-
+done:
netif_device_attach(netdev);
qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
return 0;
-
-err_out_detach:
- qlcnic_detach(adapter);
-err_out:
- qlcnic_clr_all_drv_state(adapter);
- netif_device_attach(netdev);
- return err;
}
#endif
@@ -2426,10 +2412,6 @@ qlcnic_detach_work(struct work_struct *work)
qlcnic_down(adapter, netdev);
- rtnl_lock();
- qlcnic_detach(adapter);
- rtnl_unlock();
-
status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1);
if (status & QLCNIC_RCODE_FATAL_ERROR)
@@ -2518,18 +2500,10 @@ qlcnic_attach_work(struct work_struct *work)
struct qlcnic_adapter *adapter = container_of(work,
struct qlcnic_adapter, fw_work.work);
struct net_device *netdev = adapter->netdev;
- int err;
if (netif_running(netdev)) {
- err = qlcnic_attach(adapter);
- if (err)
- goto done;
-
- err = qlcnic_up(adapter, netdev);
- if (err) {
- qlcnic_detach(adapter);
+ if (qlcnic_up(adapter, netdev))
goto done;
- }
qlcnic_config_indev_addr(netdev, NETDEV_UP);
}
--
1.6.0.2
^ permalink raw reply related
* [PATCH NEXT 0/8]qlcnic: driver update
From: amit.salecha @ 2010-06-22 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman
Hi
Major changes:
1) Previously device context were created in probe and released in remove.
Now create during interface up and release in interface down.
2) Dont deallocate and allocate host memory during device reset.
3) Offload tx timeout recovery to fw recovery functions. Later will
check fw health before doing tx timeout recovery.
Series of 8 patches. Please apply them on net-next branch.
-Amit
^ permalink raw reply
* [PATCH NEXT 2/8] qlcnic: handshake with card after fw load
From: amit.salecha @ 2010-06-22 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1277212745-26857-1-git-send-email-amit.salecha@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
Instead of delaying rcv handshake till interface comes up,
do it just after fw load.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 1 -
drivers/net/qlcnic/qlcnic_init.c | 9 +++++++--
drivers/net/qlcnic/qlcnic_main.c | 6 ++----
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 86e4781..588b9a9 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -1105,7 +1105,6 @@ int qlcnic_wol_supported(struct qlcnic_adapter *adapter);
int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate);
/* Functions from qlcnic_init.c */
-int qlcnic_phantom_init(struct qlcnic_adapter *adapter);
int qlcnic_load_firmware(struct qlcnic_adapter *adapter);
int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter);
void qlcnic_request_firmware(struct qlcnic_adapter *adapter);
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index 1c3d5a9..d19d012 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -1138,7 +1138,7 @@ qlcnic_release_firmware(struct qlcnic_adapter *adapter)
adapter->fw = NULL;
}
-int qlcnic_phantom_init(struct qlcnic_adapter *adapter)
+static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter)
{
u32 val;
int retries = 60;
@@ -1163,7 +1163,8 @@ int qlcnic_phantom_init(struct qlcnic_adapter *adapter)
QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
out_err:
- dev_err(&adapter->pdev->dev, "firmware init failed\n");
+ dev_err(&adapter->pdev->dev, "Command Peg initialization not "
+ "complete, state: 0x%x.\n", val);
return -EIO;
}
@@ -1196,6 +1197,10 @@ int qlcnic_init_firmware(struct qlcnic_adapter *adapter)
{
int err;
+ err = qlcnic_cmd_peg_ready(adapter);
+ if (err)
+ return err;
+
err = qlcnic_receive_peg_ready(adapter);
if (err)
return err;
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 655bccd..9658b18 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -758,6 +758,7 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
if (first_boot != 0x55555555) {
QLCWR32(adapter, CRB_CMDPEG_STATE, 0);
+ QLCWR32(adapter, CRB_RCVPEG_STATE, 0);
qlcnic_pinit_from_rom(adapter);
msleep(1);
}
@@ -780,7 +781,7 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter)
wait_init:
/* Handshake with the card before we register the devices. */
- err = qlcnic_phantom_init(adapter);
+ err = qlcnic_init_firmware(adapter);
if (err)
goto err_out;
@@ -962,9 +963,6 @@ qlcnic_attach(struct qlcnic_adapter *adapter)
if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC)
return 0;
- err = qlcnic_init_firmware(adapter);
- if (err)
- return err;
err = qlcnic_napi_add(adapter, netdev);
if (err)
--
1.6.0.2
^ permalink raw reply related
* [PATCH NEXT 3/8] qlcnic: fix mac address mgmt
From: amit.salecha @ 2010-06-22 13:19 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1277212745-26857-1-git-send-email-amit.salecha@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
We first add mac address in driver local list and then send command to
fw to add same. There are checks in driver to ensure send command doesn't fail
before adding mac address in local list.
But instead fix should be:
Add mac address in fw and if it succeeds, add it in driver local list.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/qlcnic/qlcnic_hw.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index 10ba723..ad12425 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -413,10 +413,15 @@ static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr)
return -ENOMEM;
}
memcpy(cur->mac_addr, addr, ETH_ALEN);
- list_add_tail(&cur->list, &adapter->mac_list);
- return qlcnic_sre_macaddr_change(adapter,
- cur->mac_addr, QLCNIC_MAC_ADD);
+ if (qlcnic_sre_macaddr_change(adapter,
+ cur->mac_addr, QLCNIC_MAC_ADD)) {
+ kfree(cur);
+ return -EIO;
+ }
+
+ list_add_tail(&cur->list, &adapter->mac_list);
+ return 0;
}
void qlcnic_set_multi(struct net_device *netdev)
--
1.6.0.2
^ permalink raw reply related
* [PATCH NEXT 4/8] qlcnic: release device resources during interface down
From: amit.salecha @ 2010-06-22 13:19 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1277212745-26857-1-git-send-email-amit.salecha@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
Previously we were allocating device resources during probe and
release them during remove.
Now alloc during interface up and release in interface down.
This helps in device performance, as it doesn't need to keep
track of inactive resources.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 4 ++
drivers/net/qlcnic/qlcnic_ctx.c | 50 ++++++++++++++++++++---------
drivers/net/qlcnic/qlcnic_ethtool.c | 7 +++-
drivers/net/qlcnic/qlcnic_hw.c | 4 +-
drivers/net/qlcnic/qlcnic_init.c | 26 +++++++++++++++
drivers/net/qlcnic/qlcnic_main.c | 60 ++++++++++++++++++++++++----------
6 files changed, 114 insertions(+), 37 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 588b9a9..5c7d474 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -1124,6 +1124,10 @@ void __iomem *qlcnic_get_ioaddr(struct qlcnic_adapter *, u32);
int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter);
void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter);
+int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter);
+void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter);
+
+void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter);
void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter);
void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c
index 7c96c8e..be341c1 100644
--- a/drivers/net/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/qlcnic/qlcnic_ctx.c
@@ -180,6 +180,7 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
for (i = 0; i < nrds_rings; i++) {
rds_ring = &recv_ctx->rds_rings[i];
+ rds_ring->producer = 0;
prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
@@ -193,6 +194,8 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
for (i = 0; i < nsds_rings; i++) {
sds_ring = &recv_ctx->sds_rings[i];
+ sds_ring->consumer = 0;
+ memset(sds_ring->desc_head, 0, STATUS_DESC_RINGSIZE(sds_ring));
prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
@@ -293,6 +296,11 @@ qlcnic_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter)
dma_addr_t rq_phys_addr, rsp_phys_addr;
struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
+ /* reset host resources */
+ tx_ring->producer = 0;
+ tx_ring->sw_consumer = 0;
+ *(tx_ring->hw_consumer) = 0;
+
rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
rq_addr = pci_alloc_consistent(adapter->pdev,
rq_size, &rq_phys_addr);
@@ -476,15 +484,6 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
sds_ring->desc_head = (struct status_desc *)addr;
}
-
- err = qlcnic_fw_cmd_create_rx_ctx(adapter);
- if (err)
- goto err_out_free;
- err = qlcnic_fw_cmd_create_tx_ctx(adapter);
- if (err)
- goto err_out_free;
-
- set_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
return 0;
err_out_free:
@@ -492,15 +491,27 @@ err_out_free:
return err;
}
-void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
+
+int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter)
{
- struct qlcnic_recv_context *recv_ctx;
- struct qlcnic_host_rds_ring *rds_ring;
- struct qlcnic_host_sds_ring *sds_ring;
- struct qlcnic_host_tx_ring *tx_ring;
- int ring;
+ int err;
+
+ err = qlcnic_fw_cmd_create_rx_ctx(adapter);
+ if (err)
+ return err;
+ err = qlcnic_fw_cmd_create_tx_ctx(adapter);
+ if (err) {
+ qlcnic_fw_cmd_destroy_rx_ctx(adapter);
+ return err;
+ }
+
+ set_bit(__QLCNIC_FW_ATTACHED, &adapter->state);
+ return 0;
+}
+void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)
+{
if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
qlcnic_fw_cmd_destroy_rx_ctx(adapter);
qlcnic_fw_cmd_destroy_tx_ctx(adapter);
@@ -508,6 +519,15 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
/* Allow dma queues to drain after context reset */
msleep(20);
}
+}
+
+void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_recv_context *recv_ctx;
+ struct qlcnic_host_rds_ring *rds_ring;
+ struct qlcnic_host_sds_ring *sds_ring;
+ struct qlcnic_host_tx_ring *tx_ring;
+ int ring;
recv_ctx = &adapter->recv_ctx;
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index a4f1120..d4e803e 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -348,7 +348,7 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
for (i = 0; diag_registers[i] != -1; i++)
regs_buff[i] = QLCRD32(adapter, diag_registers[i]);
- if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+ if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
return;
regs_buff[i++] = 0xFFEFCDAB; /* Marker btw regs and ring count*/
@@ -833,6 +833,9 @@ static int qlcnic_blink_led(struct net_device *dev, u32 val)
struct qlcnic_adapter *adapter = netdev_priv(dev);
int ret;
+ if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
+ return -EIO;
+
ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
if (ret) {
dev_err(&adapter->pdev->dev,
@@ -904,7 +907,7 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
- if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+ if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
return -EINVAL;
/*
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c
index ad12425..e08c8b0 100644
--- a/drivers/net/qlcnic/qlcnic_hw.c
+++ b/drivers/net/qlcnic/qlcnic_hw.c
@@ -327,7 +327,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
i = 0;
- if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+ if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
return -EIO;
tx_ring = adapter->tx_ring;
@@ -431,7 +431,7 @@ void qlcnic_set_multi(struct net_device *netdev)
u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
u32 mode = VPORT_MISS_MODE_DROP;
- if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+ if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
return;
qlcnic_nic_add_mac(adapter, adapter->mac_addr);
diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c
index d19d012..6678127 100644
--- a/drivers/net/qlcnic/qlcnic_init.c
+++ b/drivers/net/qlcnic/qlcnic_init.c
@@ -125,6 +125,32 @@ void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter)
}
}
+void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter)
+{
+ struct qlcnic_recv_context *recv_ctx;
+ struct qlcnic_host_rds_ring *rds_ring;
+ struct qlcnic_rx_buffer *rx_buf;
+ int i, ring;
+
+ recv_ctx = &adapter->recv_ctx;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+
+ spin_lock(&rds_ring->lock);
+
+ INIT_LIST_HEAD(&rds_ring->free_list);
+
+ rx_buf = rds_ring->rx_buf_arr;
+ for (i = 0; i < rds_ring->num_desc; i++) {
+ list_add_tail(&rx_buf->list,
+ &rds_ring->free_list);
+ rx_buf++;
+ }
+
+ spin_unlock(&rds_ring->lock);
+ }
+}
+
void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter)
{
struct qlcnic_cmd_buffer *cmd_buf;
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index 9658b18..38d8fe0 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -346,7 +346,7 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
if (!is_valid_ether_addr(addr->sa_data))
return -EINVAL;
- if (netif_running(netdev)) {
+ if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
netif_device_detach(netdev);
qlcnic_napi_disable(adapter);
}
@@ -355,7 +355,7 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
qlcnic_set_multi(adapter->netdev);
- if (netif_running(netdev)) {
+ if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
netif_device_attach(netdev);
qlcnic_napi_enable(adapter);
}
@@ -877,9 +877,23 @@ qlcnic_init_coalesce_defaults(struct qlcnic_adapter *adapter)
static int
__qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
{
+ int ring;
+ struct qlcnic_host_rds_ring *rds_ring;
+
if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
return -EIO;
+ if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
+ return 0;
+
+ if (qlcnic_fw_create_ctx(adapter))
+ return -EIO;
+
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &adapter->recv_ctx.rds_rings[ring];
+ qlcnic_post_rx_buffers(adapter, ring, rds_ring);
+ }
+
qlcnic_set_multi(netdev);
qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu);
@@ -936,6 +950,9 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_napi_disable(adapter);
+ qlcnic_fw_destroy_ctx(adapter);
+
+ qlcnic_reset_rx_buffers_list(adapter);
qlcnic_release_tx_buffers(adapter);
spin_unlock(&adapter->tx_clean_lock);
}
@@ -957,13 +974,11 @@ qlcnic_attach(struct qlcnic_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
- int err, ring;
- struct qlcnic_host_rds_ring *rds_ring;
+ int err;
if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC)
return 0;
-
err = qlcnic_napi_add(adapter, netdev);
if (err)
return err;
@@ -971,7 +986,7 @@ qlcnic_attach(struct qlcnic_adapter *adapter)
err = qlcnic_alloc_sw_resources(adapter);
if (err) {
dev_err(&pdev->dev, "Error in setting sw resources\n");
- return err;
+ goto err_out_napi_del;
}
err = qlcnic_alloc_hw_resources(adapter);
@@ -980,16 +995,10 @@ qlcnic_attach(struct qlcnic_adapter *adapter)
goto err_out_free_sw;
}
-
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &adapter->recv_ctx.rds_rings[ring];
- qlcnic_post_rx_buffers(adapter, ring, rds_ring);
- }
-
err = qlcnic_request_irq(adapter);
if (err) {
dev_err(&pdev->dev, "failed to setup interrupt\n");
- goto err_out_free_rxbuf;
+ goto err_out_free_hw;
}
qlcnic_init_coalesce_defaults(adapter);
@@ -999,11 +1008,12 @@ qlcnic_attach(struct qlcnic_adapter *adapter)
adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC;
return 0;
-err_out_free_rxbuf:
- qlcnic_release_rx_buffers(adapter);
+err_out_free_hw:
qlcnic_free_hw_resources(adapter);
err_out_free_sw:
qlcnic_free_sw_resources(adapter);
+err_out_napi_del:
+ qlcnic_napi_del(adapter);
return err;
}
@@ -1038,6 +1048,8 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
}
}
+ qlcnic_fw_destroy_ctx(adapter);
+
qlcnic_detach(adapter);
adapter->diag_test = 0;
@@ -1056,6 +1068,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_host_sds_ring *sds_ring;
+ struct qlcnic_host_rds_ring *rds_ring;
int ring;
int ret;
@@ -1075,6 +1088,17 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
return ret;
}
+ ret = qlcnic_fw_create_ctx(adapter);
+ if (ret) {
+ qlcnic_detach(adapter);
+ return ret;
+ }
+
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &adapter->recv_ctx.rds_rings[ring];
+ qlcnic_post_rx_buffers(adapter, ring, rds_ring);
+ }
+
if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
for (ring = 0; ring < adapter->max_sds_rings; ring++) {
sds_ring = &adapter->recv_ctx.sds_rings[ring];
@@ -2636,7 +2660,7 @@ qlcnic_store_bridged_mode(struct device *dev,
if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_BDG))
goto err_out;
- if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+ if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
goto err_out;
if (strict_strtoul(buf, 2, &new))
@@ -2944,7 +2968,7 @@ recheck:
if (!adapter)
goto done;
- if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+ if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
goto done;
qlcnic_config_indev_addr(dev, event);
@@ -2980,7 +3004,7 @@ recheck:
if (!adapter)
goto done;
- if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+ if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
goto done;
switch (event) {
--
1.6.0.2
^ permalink raw reply related
* [PATCH NEXT 6/8] qlcnic: offload tx timeout recovery
From: amit.salecha @ 2010-06-22 13:19 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, Amit Kumar Salecha
In-Reply-To: <1277212745-26857-1-git-send-email-amit.salecha@qlogic.com>
From: Amit Kumar Salecha <amit.salecha@qlogic.com>
Offload tx timeout recovery to fw recovery func(check_health).
In check_health, first check health of device, if it its ok, then
do tx timeout recovery otherwise device recovery.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/qlcnic/qlcnic.h | 3 +-
drivers/net/qlcnic/qlcnic_main.c | 65 ++++++++++++++++++--------------------
2 files changed, 32 insertions(+), 36 deletions(-)
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h
index 5c7d474..6ec34a7 100644
--- a/drivers/net/qlcnic/qlcnic.h
+++ b/drivers/net/qlcnic/qlcnic.h
@@ -934,6 +934,7 @@ struct qlcnic_adapter {
u8 rx_csum;
u8 portnum;
u8 physical_port;
+ u8 reset_context;
u8 mc_enabled;
u8 max_mc_count;
@@ -1001,8 +1002,6 @@ struct qlcnic_adapter {
struct delayed_work fw_work;
- struct work_struct tx_timeout_task;
-
struct qlcnic_nic_intr_coalesce coal;
unsigned long state;
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c
index c4602fa..3b71dfc 100644
--- a/drivers/net/qlcnic/qlcnic_main.c
+++ b/drivers/net/qlcnic/qlcnic_main.c
@@ -75,7 +75,6 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev);
static int qlcnic_open(struct net_device *netdev);
static int qlcnic_close(struct net_device *netdev);
static void qlcnic_tx_timeout(struct net_device *netdev);
-static void qlcnic_tx_timeout_task(struct work_struct *work);
static void qlcnic_attach_work(struct work_struct *work);
static void qlcnic_fwinit_work(struct work_struct *work);
static void qlcnic_fw_poll_work(struct work_struct *work);
@@ -911,6 +910,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_linkevent_request(adapter, 1);
+ adapter->reset_context = 0;
set_bit(__QLCNIC_DEV_UP, &adapter->state);
return 0;
}
@@ -1110,6 +1110,27 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
return 0;
}
+/* Reset context in hardware only */
+static int
+qlcnic_reset_hw_context(struct qlcnic_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+ return -EBUSY;
+
+ netif_device_detach(netdev);
+
+ qlcnic_down(adapter, netdev);
+
+ qlcnic_up(adapter, netdev);
+
+ netif_device_attach(netdev);
+
+ clear_bit(__QLCNIC_RESETTING, &adapter->state);
+ return 0;
+}
+
int
qlcnic_reset_context(struct qlcnic_adapter *adapter)
{
@@ -1178,8 +1199,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter,
netdev->irq = adapter->msix_entries[0].vector;
- INIT_WORK(&adapter->tx_timeout_task, qlcnic_tx_timeout_task);
-
if (qlcnic_read_mac_addr(adapter))
dev_warn(&pdev->dev, "failed to read mac addr\n");
@@ -1350,8 +1369,6 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev)
unregister_netdev(netdev);
- cancel_work_sync(&adapter->tx_timeout_task);
-
qlcnic_detach(adapter);
if (adapter->npars != NULL)
@@ -1390,8 +1407,6 @@ static int __qlcnic_shutdown(struct pci_dev *pdev)
if (netif_running(netdev))
qlcnic_down(adapter, netdev);
- cancel_work_sync(&adapter->tx_timeout_task);
-
qlcnic_clr_all_drv_state(adapter);
clear_bit(__QLCNIC_RESETTING, &adapter->state);
@@ -1854,35 +1869,11 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
return;
dev_err(&netdev->dev, "transmit timeout, resetting.\n");
- schedule_work(&adapter->tx_timeout_task);
-}
-
-static void qlcnic_tx_timeout_task(struct work_struct *work)
-{
- struct qlcnic_adapter *adapter =
- container_of(work, struct qlcnic_adapter, tx_timeout_task);
-
- if (!netif_running(adapter->netdev))
- return;
-
- if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
- return;
if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS)
- goto request_reset;
-
- clear_bit(__QLCNIC_RESETTING, &adapter->state);
- if (!qlcnic_reset_context(adapter)) {
- adapter->netdev->trans_start = jiffies;
- return;
-
- /* context reset failed, fall through for fw reset */
- }
-
-request_reset:
- adapter->need_fw_reset = 1;
- clear_bit(__QLCNIC_RESETTING, &adapter->state);
- QLCDB(adapter, DRV, "Resetting adapter\n");
+ adapter->need_fw_reset = 1;
+ else
+ adapter->reset_context = 1;
}
static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
@@ -2540,6 +2531,12 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
adapter->fw_fail_cnt = 0;
if (adapter->need_fw_reset)
goto detach;
+
+ if (adapter->reset_context) {
+ qlcnic_reset_hw_context(adapter);
+ adapter->netdev->trans_start = jiffies;
+ }
+
return 0;
}
--
1.6.0.2
^ permalink raw reply related
* [PATCH 3/3] ucc_geth: Fix full TX queue processing
From: Petri Lehtinen @ 2010-06-22 13:02 UTC (permalink / raw)
To: linux-kernel
Cc: stable, netdev, Jiajun Wu, Anton Vorontsov, Stable,
"[2.6.32]", David S. Miller
In-Reply-To: <1277211752-14265-1-git-send-email-petri.lehtinen@inoi.fi>
From: Jiajun Wu <b06378@freescale.com>
commit 7583605b6d29f1f7f6fc505b883328089f3485ad ("ucc_geth: Fix empty
TX queue processing") fixed empty TX queue mishandling, but didn't
account another corner case: when TX queue becomes full.
Without this patch the driver will stop transmiting when TX queue
becomes full since 'bd == ugeth->txBd[txQ]' actually checks for
two things: queue empty or full.
Let's better check for NULL skb, which unambiguously signals an empty
queue.
Signed-off-by: Jiajun Wu <b06378@freescale.com>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Cc: Stable <stable@vger.kernel.org> [2.6.32]
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 34692421bc7d6145ef383b014860f4fde10b7505)
---
drivers/net/ucc_geth.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 5077fd9..b4b25ff 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3276,13 +3276,12 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
/* Handle the transmitted buffer and release */
/* the BD to be used with the current frame */
- if (bd == ugeth->txBd[txQ]) /* queue empty? */
+ skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]];
+ if (!skb)
break;
dev->stats.tx_packets++;
- skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]];
-
if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN &&
skb_recycle_check(skb,
ugeth->ug_info->uf_info.max_rx_buf_length +
--
1.7.1
^ permalink raw reply related
* [PATCH 2/3] ucc_geth: Fix netdev watchdog triggering on link changes
From: Petri Lehtinen @ 2010-06-22 13:02 UTC (permalink / raw)
To: linux-kernel
Cc: stable, netdev, Anton Vorontsov, Stable, "[2.6.32]",
David S. Miller
In-Reply-To: <1277211752-14265-1-git-send-email-petri.lehtinen@inoi.fi>
From: Anton Vorontsov <avorontsov@ru.mvista.com>
Since commit 864fdf884e82bacbe8ca5e93bd43393a61d2e2b4 ("ucc_geth:
Fix hangs after switching from full to half duplex") ucc_geth driver
disables the controller during MAC configuration changes. Though,
disabling the controller might take quite awhile, and so the netdev
watchdog might get upset:
NETDEV WATCHDOG: eth2 (ucc_geth): transmit queue 0 timed out
------------[ cut here ]------------
Badness at c02729a8 [verbose debug info unavailable]
NIP: c02729a8 LR: c02729a8 CTR: c01b6088
REGS: c0451c40 TRAP: 0700 Not tainted (2.6.32-trunk-8360e)
[...]
NIP [c02729a8] dev_watchdog+0x280/0x290
LR [c02729a8] dev_watchdog+0x280/0x290
Call Trace:
[c0451cf0] [c02729a8] dev_watchdog+0x280/0x290 (unreliable)
[c0451d50] [c00377c4] run_timer_softirq+0x164/0x224
[c0451da0] [c0032a38] __do_softirq+0xb8/0x13c
[c0451df0] [c00065cc] do_softirq+0xa0/0xac
[c0451e00] [c003280c] irq_exit+0x7c/0x9c
[c0451e10] [c00640c4] __ipipe_sync_stage+0x248/0x24c
[...]
This patch fixes the issue by detaching the netdev during the
time we change the configuration.
Reported-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Tested-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca>
Cc: Stable <stable@vger.kernel.org> [2.6.32]
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 08b5e1c91ce95793c59a59529a362a1bcc81faae)
---
drivers/net/ucc_geth.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 20aa5b5..5077fd9 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode)
static void ugeth_quiesce(struct ucc_geth_private *ugeth)
{
- /* Wait for and prevent any further xmits. */
+ /* Prevent any further xmits, plus detach the device. */
+ netif_device_detach(ugeth->ndev);
+
+ /* Wait for any current xmits to finish. */
netif_tx_disable(ugeth->ndev);
/* Disable the interrupt to avoid NAPI rescheduling. */
@@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth)
{
napi_enable(&ugeth->napi);
enable_irq(ugeth->ug_info->uf_info.irq);
- netif_tx_wake_all_queues(ugeth->ndev);
+ netif_device_attach(ugeth->ndev);
}
/* Called every time the controller might need to be made
--
1.7.1
^ permalink raw reply related
* [PATCH 1/3] ucc_geth: Fix empty TX queue processing
From: Petri Lehtinen @ 2010-06-22 13:02 UTC (permalink / raw)
To: linux-kernel
Cc: stable, netdev, Anton Vorontsov, Stable, "[2.6.32]",
David S. Miller
In-Reply-To: <1277211752-14265-1-git-send-email-petri.lehtinen@inoi.fi>
From: Anton Vorontsov <avorontsov@ru.mvista.com>
Following oops was seen with the ucc_geth driver:
Unable to handle kernel paging request for data at address 0x00000058
Faulting instruction address: 0xc024f2fc
Oops: Kernel access of bad area, sig: 11 [#1]
[...]
NIP [c024f2fc] skb_recycle_check+0x14/0x100
LR [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver]
Call Trace:
[df857d50] [c000b03c] __ipipe_grab_irq+0x3c/0xa4 (unreliable)
[df857d60] [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver]
[df857dd0] [c0258cf8] net_rx_action+0xf8/0x1b8
[df857e10] [c0032a38] __do_softirq+0xb8/0x13c
[df857e60] [c00065cc] do_softirq+0xa0/0xac
[...]
This is because ucc_geth_tx() tries to process an empty queue when
queues are logically stopped. Stopping the queues doesn't disable
polling, and since nowadays ucc_geth_tx() is actually called from
the polling routine, the oops above might pop up.
Fix this by removing 'netif_queue_stopped() == 0' check.
Reported-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Tested-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca>
Cc: Stable <stable@vger.kernel.org> [2.6.32]
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 7583605b6d29f1f7f6fc505b883328089f3485ad)
---
drivers/net/ucc_geth.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 4469f24..20aa5b5 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3273,7 +3273,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
/* Handle the transmitted buffer and release */
/* the BD to be used with the current frame */
- if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0))
+ if (bd == ugeth->txBd[txQ]) /* queue empty? */
break;
dev->stats.tx_packets++;
--
1.7.1
^ permalink raw reply related
* [stable] Please apply ucc_geth driver fixes to 2.6.32-stable
From: Petri Lehtinen @ 2010-06-22 13:02 UTC (permalink / raw)
To: linux-kernel; +Cc: stable, netdev
(I already sent these patches a few weeks ago and got no reply. I also
sent them to some of the recipients a few minutes ago and failed to
use git-send-email properly. So sorry for the noise.)
Please include the following three patches to 2.6.32-stable. They fix
serious flaws in the ucc_geth ethernet driver, making it unusable (at
least on my system).
They have been included in 2.6.33 and apply cleanly on top of
2.6.32-stable.
^ permalink raw reply
* [PATCH] phylib: Add autoload support for the LXT973 phy.
From: David Woodhouse @ 2010-06-22 12:38 UTC (permalink / raw)
To: Richard Cochran; +Cc: netdev
In-Reply-To: <20100531130932.GA15845@riccoc20.at.omicron.at>
Commit e13647c1 (phylib: Add support for the LXT973 phy.) added a new ID
but neglected to also add it to the MODULE_DEVICE_TABLE.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
When I did this stuff, I did wonder if we should make this happen
automatically somehow. I pondered some dirty macro hack in
phy_driver_register() which would do it somehow, but couldn't come up
with anything that'd work.
Removing the phy_id and phy_id_mask from struct phy_driver and having a
pointer to a match table would suck, since each driver only really
matches one device/mask. (Even where a single C file has multiple
drivers, they often differ in some methods or flags.)
The best option I can come up with right now, is probably to remove
phy_id and phy_id_mask from phy_driver and put a pointer to the driver
into the ID table, and take the ID table as the argument to
phy_driver_register(). I'm not sure I like that very much though -- I'd
prefer that we just remember to update the table and don't need to be
forced :)
(Another cheap option is to pass the ID table as an extra argument to
the existing phy_device_register(), I suppose, and it can just print a
warning if it doesn't find the same phy_id and phy_id_mask in the table)
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index dbd0034..29c39ff 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -226,6 +226,7 @@ module_exit(lxt_exit);
static struct mdio_device_id lxt_tbl[] = {
{ 0x78100000, 0xfffffff0 },
{ 0x001378e0, 0xfffffff0 },
+ { 0x00137a10, 0xfffffff0 },
{ }
};
^ permalink raw reply related
* Re: [v4 Patch 1/2] s2io: add dynamic LRO disable support
From: Stanislaw Gruszka @ 2010-06-22 12:31 UTC (permalink / raw)
To: Ben Hutchings
Cc: Amerigo Wang, netdev, nhorman, herbert.xu, Ramkrishna.Vepa, davem
In-Reply-To: <1277207080.2091.2.camel@achroite.uk.solarflarecom.com>
On Tue, 22 Jun 2010 12:44:40 +0100
Ben Hutchings <bhutchings@solarflare.com> wrote:
> On Tue, 2010-06-22 at 04:50 -0400, Amerigo Wang wrote:
> > This patch adds dynamic LRO diable support for s2io net driver.
> >
> > (I don't have s2io card, so only did compiling test. Anyone who wants
> > to test this is more than welcome.)
> >
> > This is based on Neil's initial work, and heavily modified
> > based on Ramkrishna's suggestions.
> [...]
> > +static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
> > +{
> > + struct s2io_nic *sp = netdev_priv(dev);
> > + int rc = 0;
> > + int changed = 0;
> > +
> > + if (data & ~ETH_FLAG_LRO)
> > + return -EOPNOTSUPP;
> > +
> > + if (data & ETH_FLAG_LRO) {
> > + if (lro_enable) {
> > + if (!(dev->features & NETIF_F_LRO)) {
> > + dev->features |= NETIF_F_LRO;
> > + changed = 1;
> > + }
> > + } else
> > + rc = -EOPNOTSUPP;
>
> Should lro_enable=0 really prevent enabling it later? This seems
> unusual.
We are doing this in bnx2x. Current Amerigo patch change to the
same behavior mlx4. For me that have sense - if you want to disallow
LRO - use module option.
In this case however lro_enable variable looks obsolete from times
where there was no ethtool possibility to dynamic set/unset LRO.
Perhaps it should be removed at all, but maybe not as part
of that patch.
Stanislaw
^ permalink raw reply
* Re: 2.6.34 + IPv6: Oops?
From: Andreas Klauer @ 2010-06-22 12:29 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Hagen Paul Pfeifer, netdev, Octavian Purdila
In-Reply-To: <20100621200413.GA2280@EIS>
On Mon, Jun 21, 2010 at 10:04:13PM +0200, Andreas Klauer wrote:
> Thanks a lot! This fix seems to work fine for me (tested locally only).
> I'll see what happens when I apply it to my server tomorrow.
The fix also works for my server.
Thank you
Andreas Klauer
^ permalink raw reply
* Re: [ethtool PATCH] ethtool: Support n-tuple filter programming
From: Ben Hutchings @ 2010-06-22 11:45 UTC (permalink / raw)
To: Peter P Waskiewicz Jr
Cc: Kirsher, Jeffrey T, jeff@garzik.org, davem@davemloft.net,
netdev@vger.kernel.org, gospo@redhat.com
In-Reply-To: <Pine.WNT.4.64.1006211326380.4956@PPWASKIE-MOBL2.amr.corp.intel.com>
On Mon, 2010-06-21 at 13:31 -0700, Peter P Waskiewicz Jr wrote:
> On Mon, 21 Jun 2010, Ben Hutchings wrote:
>
> > On Wed, 2010-02-03 at 23:51 -0800, Jeff Kirsher wrote:
> >> From: Peter Waskiewicz <peter.p.waskiewicz.jr@intel.com>
> >>
> >> Program underlying ethernet devices with n-tuple flow classification
> >> filters.
> >>
> >> This also adds a new flag to ethtool_flags, allowing n-tuple
> >> programming to be toggled using the set_flags call.
> >
> > I just noticed a problem with the implementation which makes me wonder
> > whether this was tested at all:
>
> Yes, it was tested. We didn't hit every corner case, which I think your
> catch below is a corner case issue. Our hardware can only do so much.
It's not a corner case. You have added options that cannot work
correctly.
[...]
> When this was proposed, we added the IPv4 address as a single int. People
> seemed ok with it at the time, so we went with it. If you have a
> different approach, please present it.
And you don't think it matters that the address has to be written
differently on big- and little-endian architectures?
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
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
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