* Re: [PATCH net-next] net: use bigger pages in __netdev_alloc_frag
From: Alexander Duyck @ 2012-09-26 16:00 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1348650402.5093.176.camel@edumazet-glaptop>
On 09/26/2012 02:06 AM, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> We currently use percpu order-0 pages in __netdev_alloc_frag
> to deliver fragments used by __netdev_alloc_skb()
>
> Depending on NIC driver and arch being 32 or 64 bit, it allows a page to
> be split in several fragments (between 1 and 8), assuming PAGE_SIZE=4096
>
> Switching to bigger pages (32768 bytes for PAGE_SIZE=4096 case) allows :
>
> - Better filling of space (the ending hole overhead is less an issue)
>
> - Less calls to page allocator or accesses to page->_count
>
> - Could allow struct skb_shared_info futures changes without major
> performance impact.
>
> This patch implements a transparent fallback to smaller
> pages in case of memory pressure.
>
> It also uses a standard "struct page_frag" instead of a custom one.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Alexander Duyck <alexander.h.duyck@intel.com>
> ---
> net/core/skbuff.c | 46 ++++++++++++++++++++++++++++----------------
> 1 file changed, 30 insertions(+), 16 deletions(-)
>
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 2ede3cf..4ab83ce 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -340,43 +340,57 @@ struct sk_buff *build_skb(void *data, unsigned int frag_size)
> EXPORT_SYMBOL(build_skb);
>
> struct netdev_alloc_cache {
> - struct page *page;
> - unsigned int offset;
> - unsigned int pagecnt_bias;
> + struct page_frag frag;
> + /* we maintain a pagecount bias, so that we dont dirty cache line
> + * containing page->_count every time we allocate a fragment.
> + */
> + unsigned int pagecnt_bias;
> };
> static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache);
>
> -#define NETDEV_PAGECNT_BIAS (PAGE_SIZE / SMP_CACHE_BYTES)
> +#define NETDEV_FRAG_PAGE_MAX_ORDER get_order(32768)
> +#define NETDEV_FRAG_PAGE_MAX_SIZE (PAGE_SIZE << NETDEV_FRAG_PAGE_MAX_ORDER)
> +#define NETDEV_PAGECNT_MAX_BIAS NETDEV_FRAG_PAGE_MAX_SIZE
>
> static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
> {
> struct netdev_alloc_cache *nc;
> void *data = NULL;
> + int order;
> unsigned long flags;
>
> local_irq_save(flags);
> nc = &__get_cpu_var(netdev_alloc_cache);
> - if (unlikely(!nc->page)) {
> + if (unlikely(!nc->frag.page)) {
> refill:
> - nc->page = alloc_page(gfp_mask);
> - if (unlikely(!nc->page))
> - goto end;
> + for (order = NETDEV_FRAG_PAGE_MAX_ORDER; ;) {
> + gfp_t gfp = gfp_mask;
> +
> + if (order)
> + gfp |= __GFP_COMP | __GFP_NOWARN;
> + nc->frag.page = alloc_pages(gfp, order);
> + if (likely(nc->frag.page))
> + break;
> + if (--order <= 0)
> + goto end;
> + }
> + nc->frag.size = PAGE_SIZE << order;
> recycle:
> - atomic_set(&nc->page->_count, NETDEV_PAGECNT_BIAS);
> - nc->pagecnt_bias = NETDEV_PAGECNT_BIAS;
> - nc->offset = 0;
> + atomic_set(&nc->frag.page->_count, NETDEV_PAGECNT_MAX_BIAS);
> + nc->pagecnt_bias = NETDEV_PAGECNT_MAX_BIAS;
> + nc->frag.offset = 0;
> }
>
> - if (nc->offset + fragsz > PAGE_SIZE) {
> + if (nc->frag.offset + fragsz > nc->frag.size) {
> /* avoid unnecessary locked operations if possible */
> - if ((atomic_read(&nc->page->_count) == nc->pagecnt_bias) ||
> - atomic_sub_and_test(nc->pagecnt_bias, &nc->page->_count))
> + if ((atomic_read(&nc->frag.page->_count) == nc->pagecnt_bias) ||
> + atomic_sub_and_test(nc->pagecnt_bias, &nc->frag.page->_count))
> goto recycle;
> goto refill;
> }
>
> - data = page_address(nc->page) + nc->offset;
> - nc->offset += fragsz;
> + data = page_address(nc->frag.page) + nc->frag.offset;
> + nc->frag.offset += fragsz;
> nc->pagecnt_bias--;
> end:
> local_irq_restore(flags);
>
>
One minor thought. Instead of tracking offset and size why not just
work from the top down instead of the bottom up?
So instead of starting with the frag offset at 0, why not start it at
PAGE_SIZE << order, and then work your way down to 0. That way you
don't need to track both size and offset.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH 02/11] inet_diag: pass inet_diag module to netlink_dump_start
From: Stephen Hemminger @ 2012-09-26 16:07 UTC (permalink / raw)
To: Gao feng
Cc: davem, netfilter-devel, linux-rdma, netdev, eric.dumazet, pablo,
steffen.klassert, linux-crypto, jengelh, stephen.hemminger
In-Reply-To: <1348635140-20225-2-git-send-email-gaofeng@cn.fujitsu.com>
On Wed, 26 Sep 2012 12:52:11 +0800
Gao feng <gaofeng@cn.fujitsu.com> wrote:
> struct netlink_dump_control c = {
> .dump = inet_diag_dump_compat,
> + .done = netlink_dump_done,
> + .module = THIS_MODULE,
> };
Since these are immutable, why the netlink_dump_control structures
on the stack (which requires code to generate at runtime), and instead
make them global
static const struct netlink_dump_control unix_diag_ctrl = {
...
^ permalink raw reply
* Re: [PATCH net-next] net: use bigger pages in __netdev_alloc_frag
From: Eric Dumazet @ 2012-09-26 16:14 UTC (permalink / raw)
To: Alexander Duyck; +Cc: David Miller, netdev
In-Reply-To: <50632681.40208@intel.com>
On Wed, 2012-09-26 at 09:00 -0700, Alexander Duyck wrote:
> One minor thought. Instead of tracking offset and size why not just
> work from the top down instead of the bottom up?
>
> So instead of starting with the frag offset at 0, why not start it at
> PAGE_SIZE << order, and then work your way down to 0. That way you
> don't need to track both size and offset.
>
How do you refill then ?
(ie setting xxx->offset back to PAGE_SIZE << order)
I am not sure we have direct access to a page order given a struct page
pointer.
I also like struct page_frag abstraction, because it might allow us
better code factorization with other frag allocators.
( skb_append_datato_frags(), sk_page_frag_refill(), ...)
^ permalink raw reply
* Re: [PATCH 5/5] smsc95xx: enable power saving mode during system suspend
From: Bjørn Mork @ 2012-09-26 16:17 UTC (permalink / raw)
To: Steve Glendinning; +Cc: netdev
In-Reply-To: <CAKh2mn4XLCPfTFySEvtZc56J+WM863JtnsjF2D-RyDJatoyAww@mail.gmail.com>
Steve Glendinning <steve@shawell.net> writes:
>>> I hadn't thought that was a situation that could arise, is it? Would
>>> this happen if the USB device was removed during suspend?
>>
>> No, it should not happen. But then, why test at all?
>
> I thought it was common practice to add these tests to document an
> assumption the developer made that later code relies on? I had
> assumed that the !dev condition should not be possible, hence the
> simple BUG test. If it is possible then I agree - I definitely need
> to handle this more gracefully.
>
> In this case, asserting that dev is not NULL will make the code fail
> loudly there instead of a few lines down when the netdev_info call
> dereferences dev->net. Either way something bad will happen!
Yes, but you are a lot less likely to know about it if you BUG out. The
user will be left with no other choice than hitting reset or poweroff.
What's the point of that?
If your driver crashes but the machine is left running, then the user
may forward the Oops to you. That's much more useful.
Bjørn
^ permalink raw reply
* Re: [PATCH net-next] net: use bigger pages in __netdev_alloc_frag
From: Alexander Duyck @ 2012-09-26 16:36 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1348676085.5093.361.camel@edumazet-glaptop>
On 09/26/2012 09:14 AM, Eric Dumazet wrote:
> On Wed, 2012-09-26 at 09:00 -0700, Alexander Duyck wrote:
>
>> One minor thought. Instead of tracking offset and size why not just
>> work from the top down instead of the bottom up?
>>
>> So instead of starting with the frag offset at 0, why not start it at
>> PAGE_SIZE << order, and then work your way down to 0. That way you
>> don't need to track both size and offset.
>>
> How do you refill then ?
>
> (ie setting xxx->offset back to PAGE_SIZE << order)
>
> I am not sure we have direct access to a page order given a struct page
> pointer.
>
> I also like struct page_frag abstraction, because it might allow us
> better code factorization with other frag allocators.
>
> ( skb_append_datato_frags(), sk_page_frag_refill(), ...)
I forgot about the page recycling portion of it. I was still thinking
of the original implementation that had a fixed page order. You are
correct, with the page order being dynamic you will have to store size
somewhere.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH] rtlwifi: use %*ph[C] to dump small buffers
From: Joe Perches @ 2012-09-26 16:45 UTC (permalink / raw)
To: Andy Shevchenko, Larry Finger, Chaoming Li
Cc: David S. Miller, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1348667852-5957-1-git-send-email-andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
On Wed, 2012-09-26 at 16:57 +0300, Andy Shevchenko wrote:
> Signed-off-by: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Hi Andy.
(adding Larry and Chaoming to cc's)
Please use scripts/get_maintainer.pl on your patches to
see who maintains these files so you can cc them.
One comment below, it looks like a possible endian bug.
(not in your patch)
> ---
> drivers/net/wireless/rtlwifi/cam.c | 7 ++-----
> drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 6 ++----
> drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 6 ++----
> 3 files changed, 6 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
> index 5b4b4d4..6ba9f80 100644
> --- a/drivers/net/wireless/rtlwifi/cam.c
> +++ b/drivers/net/wireless/rtlwifi/cam.c
> @@ -52,11 +52,8 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
> u32 target_content = 0;
> u8 entry_i;
>
> - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
> - "key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
> - key_cont_128[0], key_cont_128[1],
> - key_cont_128[2], key_cont_128[3],
> - key_cont_128[4], key_cont_128[5]);
> + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "key_cont_128: %*ph\n",
> + 6, key_cont_128);
>
> for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
> target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
> diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
> index 86d73b3..932780d 100644
> --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
> +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
> @@ -1918,10 +1918,8 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
> (ratr_index << 28);
> rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
> RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
> - "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
> - ratr_index, ratr_bitmap,
> - rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
> - rate_mask[4]);
> + "Rate_index:%x, ratr_val:%x, %*phC\n",
> + ratr_index, ratr_bitmap, 5, rate_mask);
> rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
>
> if (macid != 0)
> diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
> index 4bbb711..7554501 100644
> --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
> +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
> @@ -2169,10 +2169,8 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
> ratr_index << 28);
> rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
> RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
> - "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
> - ratr_index, ratr_bitmap,
> - rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
> - rate_mask[4]);
> + "Rate_index:%x, ratr_val:%x, %*phC\n",
> + ratr_index, ratr_bitmap, 5, rate_mask);
> rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
> }
>
rate_mask uses:
u32 ratr_bitmap = (u32) mac->basic_rates;
...
u8 rate_mask[5];
...
[sets ratr_bitmap as u32]
...
*(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) |
ratr_index << 28);
...
rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
Looks like a possible endian misuse to me.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" 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 net-next v2] net: use bigger pages in __netdev_alloc_frag
From: Eric Dumazet @ 2012-09-26 16:46 UTC (permalink / raw)
To: Alexander Duyck; +Cc: David Miller, netdev, Benjamin LaHaise
In-Reply-To: <50632F06.1040306@intel.com>
From: Eric Dumazet <edumazet@google.com>
We currently use percpu order-0 pages in __netdev_alloc_frag
to deliver fragments used by __netdev_alloc_skb()
Depending on NIC driver and arch being 32 or 64 bit, it allows a page to
be split in several fragments (between 1 and 8), assuming PAGE_SIZE=4096
Switching to bigger pages (32768 bytes for PAGE_SIZE=4096 case) allows :
- Better filling of space (the ending hole overhead is less an issue)
- Less calls to page allocator or accesses to page->_count
- Could allow struct skb_shared_info futures changes without major
performance impact.
This patch implements a transparent fallback to smaller
pages in case of memory pressure.
It also uses a standard "struct page_frag" instead of a custom one.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Alexander Duyck <alexander.h.duyck@intel.com>
Cc: Benjamin LaHaise <bcrl@kvack.org>
---
v2 : fix the (--order <= 0) test, as Benjamin pointed out
net/core/skbuff.c | 46 ++++++++++++++++++++++++++++----------------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2ede3cf..607a70f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -340,43 +340,57 @@ struct sk_buff *build_skb(void *data, unsigned int frag_size)
EXPORT_SYMBOL(build_skb);
struct netdev_alloc_cache {
- struct page *page;
- unsigned int offset;
- unsigned int pagecnt_bias;
+ struct page_frag frag;
+ /* we maintain a pagecount bias, so that we dont dirty cache line
+ * containing page->_count every time we allocate a fragment.
+ */
+ unsigned int pagecnt_bias;
};
static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache);
-#define NETDEV_PAGECNT_BIAS (PAGE_SIZE / SMP_CACHE_BYTES)
+#define NETDEV_FRAG_PAGE_MAX_ORDER get_order(32768)
+#define NETDEV_FRAG_PAGE_MAX_SIZE (PAGE_SIZE << NETDEV_FRAG_PAGE_MAX_ORDER)
+#define NETDEV_PAGECNT_MAX_BIAS NETDEV_FRAG_PAGE_MAX_SIZE
static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
{
struct netdev_alloc_cache *nc;
void *data = NULL;
+ int order;
unsigned long flags;
local_irq_save(flags);
nc = &__get_cpu_var(netdev_alloc_cache);
- if (unlikely(!nc->page)) {
+ if (unlikely(!nc->frag.page)) {
refill:
- nc->page = alloc_page(gfp_mask);
- if (unlikely(!nc->page))
- goto end;
+ for (order = NETDEV_FRAG_PAGE_MAX_ORDER; ;) {
+ gfp_t gfp = gfp_mask;
+
+ if (order)
+ gfp |= __GFP_COMP | __GFP_NOWARN;
+ nc->frag.page = alloc_pages(gfp, order);
+ if (likely(nc->frag.page))
+ break;
+ if (--order < 0)
+ goto end;
+ }
+ nc->frag.size = PAGE_SIZE << order;
recycle:
- atomic_set(&nc->page->_count, NETDEV_PAGECNT_BIAS);
- nc->pagecnt_bias = NETDEV_PAGECNT_BIAS;
- nc->offset = 0;
+ atomic_set(&nc->frag.page->_count, NETDEV_PAGECNT_MAX_BIAS);
+ nc->pagecnt_bias = NETDEV_PAGECNT_MAX_BIAS;
+ nc->frag.offset = 0;
}
- if (nc->offset + fragsz > PAGE_SIZE) {
+ if (nc->frag.offset + fragsz > nc->frag.size) {
/* avoid unnecessary locked operations if possible */
- if ((atomic_read(&nc->page->_count) == nc->pagecnt_bias) ||
- atomic_sub_and_test(nc->pagecnt_bias, &nc->page->_count))
+ if ((atomic_read(&nc->frag.page->_count) == nc->pagecnt_bias) ||
+ atomic_sub_and_test(nc->pagecnt_bias, &nc->frag.page->_count))
goto recycle;
goto refill;
}
- data = page_address(nc->page) + nc->offset;
- nc->offset += fragsz;
+ data = page_address(nc->frag.page) + nc->frag.offset;
+ nc->frag.offset += fragsz;
nc->pagecnt_bias--;
end:
local_irq_restore(flags);
^ permalink raw reply related
* [PATCH net-next] net: struct napi_struct fields reordering
From: Eric Dumazet @ 2012-09-26 17:07 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
Remove two holes on 64bit arches, and put dev_list at the end of
napi_struct since its not used in fast path.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/netdevice.h | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 6c131f0..dd320bb 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -338,18 +338,16 @@ struct napi_struct {
unsigned long state;
int weight;
+ unsigned int gro_count;
int (*poll)(struct napi_struct *, int);
#ifdef CONFIG_NETPOLL
spinlock_t poll_lock;
int poll_owner;
#endif
-
- unsigned int gro_count;
-
struct net_device *dev;
- struct list_head dev_list;
struct sk_buff *gro_list;
struct sk_buff *skb;
+ struct list_head dev_list;
};
enum {
^ permalink raw reply related
* [PATCH] bnx2: Clean up remaining iounmap
From: Neil Horman @ 2012-09-26 17:22 UTC (permalink / raw)
To: netdev; +Cc: Neil Horman, Michael Chan, David S. Miller
commit c0357e975afdbbedab5c662d19bef865f02adc17 modified bnx2 to switch from
using ioremap/iounmap to pci_iomap/pci_iounmap. They missed a spot in the error
path of bnx2_init_one though. This patch just cleans that up.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Michael Chan <mcan@broadcom.com>
CC: "David S. Miller" <davem@davemloft.net>
---
drivers/net/ethernet/broadcom/bnx2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 79cebd8..e48312f 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -8564,7 +8564,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
error:
- iounmap(bp->regview);
+ pci_iounmap(pdev, bp->regview);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
--
1.7.11.4
^ permalink raw reply related
* [PATCH 2/2] net: ti cpsw ethernet: set IFCTL_{A,B} bits for RMII mode
From: Daniel Mack @ 2012-09-26 17:24 UTC (permalink / raw)
To: netdev
Cc: devicetree-discuss, Daniel Mack, Mugunthan V N, Vaibhav Hiremath,
David S. Miller
In-Reply-To: <1348680268-8194-1-git-send-email-zonque@gmail.com>
For RMII mode operation in 100Mbps, the CPSW needs to set the
IFCTL_A / IFCTL_B bits in the MACCONTROL register.
Signed-off-by: Daniel Mack <zonque@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
Cc: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/ti/cpsw.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 3d7594e..d88dbfa 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -386,6 +386,12 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
mac_control |= BIT(7); /* GIGABITEN */
if (phy->duplex)
mac_control |= BIT(0); /* FULLDUPLEXEN */
+
+ /* set speed_in input in case RMII mode is used in >10Mbps */
+ if (phy->speed > 10 && slave->slave_num < 2 &&
+ phy->interface == PHY_INTERFACE_MODE_RMII)
+ mac_control |= BIT(15 + slave->slave_num);
+
*link = true;
} else {
mac_control = 0;
--
1.7.11.4
^ permalink raw reply related
* [PATCH 1/2] net: ti cpsw ethernet: allow reading phy interface mode from DT
From: Daniel Mack @ 2012-09-26 17:24 UTC (permalink / raw)
To: netdev
Cc: devicetree-discuss, Daniel Mack, Mugunthan V N, Vaibhav Hiremath,
David S. Miller
Allow users to specify the phy interface of the CPSW slaves. The new
node parameter is called "phy_if_mode" and is optional. The original
behaviour of the driver is preserved when not given.
Signed-off-by: Daniel Mack <zonque@gmail.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
Cc: David S. Miller <davem@davemloft.net>
---
Documentation/devicetree/bindings/net/cpsw.txt | 3 +++
drivers/net/ethernet/ti/cpsw.c | 3 +++
2 files changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt
index dcaabe9..d87f7d2 100644
--- a/Documentation/devicetree/bindings/net/cpsw.txt
+++ b/Documentation/devicetree/bindings/net/cpsw.txt
@@ -25,6 +25,8 @@ Required properties:
- slave_reg_ofs : Specifies slave register offset
- sliver_reg_ofs : Specifies slave sliver register offset
- phy_id : Specifies slave phy id
+- phy_if_mode : Specified slave phy interface mode (optional)
+ (one of the PHY_INTERFACE_MODE_* as numerical value)
- mac-address : Specifies slave MAC address
Optional properties:
@@ -62,6 +64,7 @@ Examples:
slave_reg_ofs = <0x208>;
sliver_reg_ofs = <0xd80>;
phy_id = "davinci_mdio.16:00";
+ phy_if_mode = <6>; /* PHY_INTERFACE_MODE_RGMII */
/* Filled in by U-Boot */
mac-address = [ 00 00 00 00 00 00 ];
};
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index aa78168..3d7594e 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -850,6 +850,9 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
}
slave_data->sliver_reg_ofs = prop;
+ if (!of_property_read_u32(slave_node, "phy_if_mode", &prop))
+ slave_data->phy_if = prop;
+
mac_addr = of_get_mac_address(slave_node);
if (mac_addr)
memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN);
--
1.7.11.4
^ permalink raw reply related
* Re: [PATCH 02/11] inet_diag: pass inet_diag module to netlink_dump_start
From: Pablo Neira Ayuso @ 2012-09-26 17:26 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Gao feng, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
netfilter-devel-u79uwXL29TY76Z2rM5mHXA,
linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w,
steffen.klassert-opNxpl+3fjRBDgjK7y7TUQ,
linux-crypto-u79uwXL29TY76Z2rM5mHXA, jengelh-9+2X+4sQBs8,
stephen.hemminger-ZtmgI6mnKB3QT0dZR+AlfA
In-Reply-To: <20120926090714.618a4b39-We1ePj4FEcvRI77zikRAJc56i+j3xesD0e7PPNI6Mm0@public.gmane.org>
On Wed, Sep 26, 2012 at 09:07:14AM -0700, Stephen Hemminger wrote:
> On Wed, 26 Sep 2012 12:52:11 +0800
> Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org> wrote:
>
> > struct netlink_dump_control c = {
> > .dump = inet_diag_dump_compat,
> > + .done = netlink_dump_done,
> > + .module = THIS_MODULE,
> > };
>
> Since these are immutable, why the netlink_dump_control structures
> on the stack (which requires code to generate at runtime), and instead
> make them global
>
> static const struct netlink_dump_control unix_diag_ctrl = {
> ...
I made that code. I can send a patch to statify those
netlink_dump_control structures.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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
* Re: [PATCH v5 01/10] ipc: remove forced assignment of selected message
From: Serge Hallyn @ 2012-09-26 17:37 UTC (permalink / raw)
To: Stanislav Kinsbursky
Cc: akpm, manfred, a.p.zijlstra, netdev, will.deacon, linux-kernel,
cmetcalf, jmorris, linux-driver, linux-security-module, hughd,
ron.mercer, viro, james.l.morris, catalin.marinas, casey, eparis,
sds, jitendra.kalsaria, devel
In-Reply-To: <20120919160531.11254.48182.stgit@localhost6.localdomain6>
Quoting Stanislav Kinsbursky (skinsbursky@parallels.com):
> This is a cleanup patch. The assignment is redundant.
>
> Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
> ---
> ipc/msg.c | 1 -
> 1 files changed, 0 insertions(+), 1 deletions(-)
>
> diff --git a/ipc/msg.c b/ipc/msg.c
> index 7385de2..f3bfbb8 100644
> --- a/ipc/msg.c
> +++ b/ipc/msg.c
> @@ -787,7 +787,6 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
> !security_msg_queue_msgrcv(msq, walk_msg, current,
> msgtyp, mode)) {
>
> - msg = walk_msg;
> if (mode == SEARCH_LESSEQUAL &&
> walk_msg->m_type != 1) {
> msg = walk_msg;
Perhaps your tree is different from mine, but it looks to me like it would
be simpler to remove the 'msg = walk_msg' from both the 'if' and 'else',
and keep them above the if/else?
^ permalink raw reply
* Re: [PATCH] bnx2: Clean up remaining iounmap
From: Michael Chan @ 2012-09-26 18:33 UTC (permalink / raw)
To: Neil Horman; +Cc: netdev, Michael Chan, David S. Miller
In-Reply-To: <1348680122-9711-1-git-send-email-nhorman@tuxdriver.com>
On Wed, 2012-09-26 at 13:22 -0400, Neil Horman wrote:
> commit c0357e975afdbbedab5c662d19bef865f02adc17 modified bnx2 to switch from
> using ioremap/iounmap to pci_iomap/pci_iounmap. They missed a spot in the error
> path of bnx2_init_one though. This patch just cleans that up.
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Michael Chan <mcan@broadcom.com>
> CC: "David S. Miller" <davem@davemloft.net>
Acked-by: Michael Chan <mchan@broadcom.com>
> ---
> drivers/net/ethernet/broadcom/bnx2.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
> index 79cebd8..e48312f 100644
> --- a/drivers/net/ethernet/broadcom/bnx2.c
> +++ b/drivers/net/ethernet/broadcom/bnx2.c
> @@ -8564,7 +8564,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
> return 0;
>
> error:
> - iounmap(bp->regview);
> + pci_iounmap(pdev, bp->regview);
> pci_release_regions(pdev);
> pci_disable_device(pdev);
> pci_set_drvdata(pdev, NULL);
^ permalink raw reply
* Re: ixgbe unstable performance at 1Gb/s
From: Charles Vejnar @ 2012-09-26 18:33 UTC (permalink / raw)
To: Tantilov, Emil S, netdev@vger.kernel.org
In-Reply-To: <87618083B2453E4A8714035B62D6799216E25153@FMSMSX102.amr.corp.intel.com>
Le 25/09/2012 19:58, Tantilov, Emil S a écrit :
>> -----Original Message-----
>> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On
>> Behalf Of Charles
>> Sent: Monday, September 24, 2012 10:47 AM
>> To: netdev@vger.kernel.org
>> Subject: ixgbe unstable performance at 1Gb/s
>>
>> Hi,
>>
>> I hope I am posting on the right mailing-list. If not, sorry; please
>> redirect me
>> to the right place. Thanks.
>>
>> I have a new motherboard with integrated Intel X540 10GBase-T. For now, I
>> want
>> to use it at 1Gb/s.
>>
>> The bandwidth is only of ~300 Mbit/s (with Iperf). It's actually very
>> unstable
>> (always varies between 100 to 800 Mbit/s during the transfer).
> Do you by any chance have CONFIG_IXGBE_PTP set in your kernel config?
>
> If so, try disabling it and see if it fixes your performance.
>
> Thanks,
> Emil
>
Hi,
Thanks for your reply.
I compiled manually the ixgbe module with the default options of my
distribution (Archlinux). I had the same problem.
I then changed the CONFIG_IXGBE_PTP to no (default is yes) as you
suggested, and recompiled. The problem disappeared; normal transfer.
Could you please explain why this PTP is causing a problem? How can this
be fixed without having to recompile the module (ethtool, /sys, bios...
)? Thanks
Regards,
Charles
^ permalink raw reply
* RE: [PATCH 2/2] net: ti cpsw ethernet: set IFCTL_{A,B} bits for RMII mode
From: N, Mugunthan V @ 2012-09-26 18:50 UTC (permalink / raw)
To: Daniel Mack, netdev@vger.kernel.org
Cc: devicetree-discuss@lists.ozlabs.org, Hiremath, Vaibhav,
David S. Miller
In-Reply-To: <1348680268-8194-2-git-send-email-zonque@gmail.com>
> -----Original Message-----
> From: Daniel Mack [mailto:zonque@gmail.com]
> Sent: Wednesday, September 26, 2012 10:54 PM
> To: netdev@vger.kernel.org
> Cc: devicetree-discuss@lists.ozlabs.org; Daniel Mack; N, Mugunthan V;
> Hiremath, Vaibhav; David S. Miller
> Subject: [PATCH 2/2] net: ti cpsw ethernet: set IFCTL_{A,B} bits for
> RMII mode
>
> For RMII mode operation in 100Mbps, the CPSW needs to set the
> IFCTL_A / IFCTL_B bits in the MACCONTROL register.
>
> Signed-off-by: Daniel Mack <zonque@gmail.com>
> Cc: Mugunthan V N <mugunthanvnm@ti.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> Cc: David S. Miller <davem@davemloft.net>
> ---
> drivers/net/ethernet/ti/cpsw.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/net/ethernet/ti/cpsw.c
> b/drivers/net/ethernet/ti/cpsw.c
> index 3d7594e..d88dbfa 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -386,6 +386,12 @@ static void _cpsw_adjust_link(struct cpsw_slave
> *slave,
> mac_control |= BIT(7); /* GIGABITEN */
> if (phy->duplex)
> mac_control |= BIT(0); /* FULLDUPLEXEN */
> +
> + /* set speed_in input in case RMII mode is used in >10Mbps
> */
> + if (phy->speed > 10 && slave->slave_num < 2 &&
> + phy->interface == PHY_INTERFACE_MODE_RMII)
> + mac_control |= BIT(15 + slave->slave_num);
Mac control register is separate for both the slaves and has same bit definitions,
Bit 15 has to be set for 100Mbps link for RMII and RGMII Phy interface to control
the RMII/RGMII gasket and in GMII this bit is Un-used by CPSW.
For slave 1, Bit 16 is set with the above code which is not used control the
RMII/RGMII gasket control. So it is not required to pass the Phy mode from DT.
This patch has to be reworked to set Bit 15 with any Phy mode connected.
The original driver present was tested with GMII (Beagle Bone A5) and
RGMII (AM3358 EVM) phy , but CPSW works fine without setting this bit in
RGMII phymode so this issue was not caught in testing.
Regards
Mugunthan V N
> +
> *link = true;
> } else {
> mac_control = 0;
> --
> 1.7.11.4
^ permalink raw reply
* [PATCH] rapidio/rionet: fix multicast packet transmit logic
From: Alexandre Bounine @ 2012-09-26 19:14 UTC (permalink / raw)
To: Andrew Morton, linux-kernel, linuxppc-dev
Cc: Alexandre Bounine, Matt Porter, David S. Miller, netdev
Fix multicast packet transmit logic to account for repetitive transmission
of single skb:
- correct check for available buffers (this bug may produce NULL pointer
crash dump in case of heavy traffic);
- update skb user count (incorrect user counter causes a warning dump from
net_tx_action routine during multicast transfers in systems with three or
more rionet participants).
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: netdev@vger.kernel.org
---
drivers/net/rionet.c | 20 +++++++++++++++++---
1 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 91d2588..1470d3e 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -79,6 +79,7 @@ static int rionet_capable = 1;
* on system trade-offs.
*/
static struct rio_dev **rionet_active;
+static int nact; /* total number of active rionet peers */
#define is_rionet_capable(src_ops, dst_ops) \
((src_ops & RIO_SRC_OPS_DATA_MSG) && \
@@ -175,6 +176,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
struct ethhdr *eth = (struct ethhdr *)skb->data;
u16 destid;
unsigned long flags;
+ int add_num = 1;
local_irq_save(flags);
if (!spin_trylock(&rnet->tx_lock)) {
@@ -182,7 +184,10 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_LOCKED;
}
- if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
+ if (is_multicast_ether_addr(eth->h_dest))
+ add_num = nact;
+
+ if ((rnet->tx_cnt + add_num) > RIONET_TX_RING_SIZE) {
netif_stop_queue(ndev);
spin_unlock_irqrestore(&rnet->tx_lock, flags);
printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
@@ -191,11 +196,16 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
if (is_multicast_ether_addr(eth->h_dest)) {
+ int count = 0;
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
i++)
- if (rionet_active[i])
+ if (rionet_active[i]) {
rionet_queue_tx_msg(skb, ndev,
rionet_active[i]);
+ if (count)
+ atomic_inc(&skb->users);
+ count++;
+ }
} else if (RIONET_MAC_MATCH(eth->h_dest)) {
destid = RIONET_GET_DESTID(eth->h_dest);
if (rionet_active[destid])
@@ -220,14 +230,17 @@ static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u
if (info == RIONET_DOORBELL_JOIN) {
if (!rionet_active[sid]) {
list_for_each_entry(peer, &rionet_peers, node) {
- if (peer->rdev->destid == sid)
+ if (peer->rdev->destid == sid) {
rionet_active[sid] = peer->rdev;
+ nact++;
+ }
}
rio_mport_send_doorbell(mport, sid,
RIONET_DOORBELL_JOIN);
}
} else if (info == RIONET_DOORBELL_LEAVE) {
rionet_active[sid] = NULL;
+ nact--;
} else {
if (netif_msg_intr(rnet))
printk(KERN_WARNING "%s: unhandled doorbell\n",
@@ -523,6 +536,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
rc = rionet_setup_netdev(rdev->net->hport, ndev);
rionet_check = 1;
+ nact = 0;
}
/*
--
1.7.8.4
^ permalink raw reply related
* RE: ixgbe unstable performance at 1Gb/s
From: Tantilov, Emil S @ 2012-09-26 20:22 UTC (permalink / raw)
To: Charles Vejnar, netdev@vger.kernel.org; +Cc: Kirsher, Jeffrey T
In-Reply-To: <50634A60.40609@unige.ch>
>-----Original Message-----
>From: Charles Vejnar [mailto:Charles.Vejnar@unige.ch]
>Sent: Wednesday, September 26, 2012 11:33 AM
>To: Tantilov, Emil S; netdev@vger.kernel.org
>Subject: Re: ixgbe unstable performance at 1Gb/s
>
>Le 25/09/2012 19:58, Tantilov, Emil S a écrit :
>>> -----Original Message-----
>>> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
>On
>>> Behalf Of Charles
>>> Sent: Monday, September 24, 2012 10:47 AM
>>> To: netdev@vger.kernel.org
>>> Subject: ixgbe unstable performance at 1Gb/s
>>>
>>> Hi,
>>>
>>> I hope I am posting on the right mailing-list. If not, sorry; please
>>> redirect me
>>> to the right place. Thanks.
>>>
>>> I have a new motherboard with integrated Intel X540 10GBase-T. For now,
>I
>>> want
>>> to use it at 1Gb/s.
>>>
>>> The bandwidth is only of ~300 Mbit/s (with Iperf). It's actually very
>>> unstable
>>> (always varies between 100 to 800 Mbit/s during the transfer).
>> Do you by any chance have CONFIG_IXGBE_PTP set in your kernel config?
>>
>> If so, try disabling it and see if it fixes your performance.
>>
>> Thanks,
>> Emil
>>
>Hi,
>
>Thanks for your reply.
>
>I compiled manually the ixgbe module with the default options of my
>distribution (Archlinux). I had the same problem.
>
>I then changed the CONFIG_IXGBE_PTP to no (default is yes) as you
>suggested, and recompiled. The problem disappeared; normal transfer.
>
>Could you please explain why this PTP is causing a problem? How can this
>be fixed without having to recompile the module (ethtool, /sys, bios...
>)? Thanks
This is actually a bug in the driver. We should have a patch out very soon to address it.
>
>Regards,
>
>Charles
Thanks,
Emil
^ permalink raw reply
* Re: [PATCH V4 0/7] ipvs: IPv6 fragment handling for IPVS
From: Julian Anastasov @ 2012-09-26 20:50 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: Hans Schillstrom, Hans Schillstrom, netdev, Pablo Neira Ayuso,
lvs-devel, Patrick McHardy, Thomas Graf, Wensong Zhang,
netfilter-devel, Simon Horman
In-Reply-To: <20120926120534.24804.78415.stgit@dragon>
Hello,
On Wed, 26 Sep 2012, Jesper Dangaard Brouer wrote:
> The following patchset implement IPv6 fragment handling for IPVS.
>
> This work is based upon patches from Hans Schillstrom. I have taken
> over the patchset, in close agreement with Hans, because he don't have
> (gotten allocated) time to complete his work.
>
> I have cleaned up the patchset significantly, and split the patchset
> up into seven patches.
>
> The first 3 patches, are ready to be merged
>
> Patch01: Trivial changes, use compressed IPv6 address in output
> Patch02: IPv6 extend ICMPv6 handling for future types
> Patch03: Use config macro IS_ENABLED()
>
> The next 4 patches, is V4 of the patches I have submitted earlier.
> Where I have incorporated Julian's recent feedback.
>
> - Notice that patch04 of patchset V3, have been dropped.
>
> I have also tried to make the patches easier to review, by
> reorganizing the changes, to be more strictly split (exthdr
> vs. fragment handling).
>
> I have also removed the API changes, and moved those to patch06. This
> is done, (1) to make it easier to review the patches, and (2) to allow
> easier integration of Patricks idea and my RFC patch of caching exthdr
> info in skb->cb[]. Thus, we can get these patches applied (and later
> go back and apply the caching scheme easier).
>
> Patch04: Fix faulty IPv6 extension header handling in IPVS
> Patch05: Complete IPv6 fragment handling for IPVS
> Patch06: IPVS API change to avoid rescan of IPv6 exthdr
> Patch07: IPVS SIP fragment handling
>
> The SIP frag handling have been split into its own patch, as I have
> not been able to test this part my self.
>
> This patchset is based upon:
> Pablo's nf-next tree: git://1984.lsi.us.es/nf-next
> On top of:
> commit 2cbc78a29e76a2e92c172651204f3117491877d2
> (netfilter: combine ipt_REDIRECT and ip6t_REDIRECT)
>
> ---
>
> Jesper Dangaard Brouer (7):
> ipvs: SIP fragment handling
> ipvs: API change to avoid rescan of IPv6 exthdr
> ipvs: Complete IPv6 fragment handling for IPVS
> ipvs: Fix faulty IPv6 extension header handling in IPVS
> ipvs: Use config macro IS_ENABLED()
> ipvs: IPv6 extend ICMPv6 handling for future types
> ipvs: Trivial changes, use compressed IPv6 address in output
All 7 patches look good to me. Thanks!
Acked-by: Julian Anastasov <ja@ssi.bg>
> include/net/ip_vs.h | 194 +++++++++++----
> net/netfilter/ipvs/Kconfig | 7 -
> net/netfilter/ipvs/ip_vs_conn.c | 15 -
> net/netfilter/ipvs/ip_vs_core.c | 404 +++++++++++++++++--------------
> net/netfilter/ipvs/ip_vs_dh.c | 2
> net/netfilter/ipvs/ip_vs_lblc.c | 2
> net/netfilter/ipvs/ip_vs_lblcr.c | 2
> net/netfilter/ipvs/ip_vs_pe_sip.c | 21 +-
> net/netfilter/ipvs/ip_vs_proto.c | 6
> net/netfilter/ipvs/ip_vs_proto_ah_esp.c | 9 -
> net/netfilter/ipvs/ip_vs_proto_sctp.c | 42 +--
> net/netfilter/ipvs/ip_vs_proto_tcp.c | 40 +--
> net/netfilter/ipvs/ip_vs_proto_udp.c | 41 +--
> net/netfilter/ipvs/ip_vs_sched.c | 2
> net/netfilter/ipvs/ip_vs_sh.c | 2
> net/netfilter/ipvs/ip_vs_xmit.c | 73 +++---
> net/netfilter/xt_ipvs.c | 4
> 17 files changed, 504 insertions(+), 362 deletions(-)
>
>
> --
> Best regards,
> Jesper Dangaard Brouer
> MSc.CS, Sr. Network Kernel Developer at Red Hat
> Author of http://www.iptv-analyzer.org
> LinkedIn: http://www.linkedin.com/in/brouer
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* Re: Problems with tg3 on BCM5720
From: Nithin Nayak Sujir @ 2012-09-26 21:13 UTC (permalink / raw)
To: Dirkjan Ochtman; +Cc: netdev
In-Reply-To: <CAKmKYaCBG5hURNomffgp9gRhS7g2BYsNG-LTmBrKsX-iyVzVxg@mail.gmail.com>
Hi Dirkjan,
A few questions -
1. Can you tell me the last patch that is included in the tg3 driver in 3.4.9 on your distro?
2. Can you give more info about the working setup?
3. Was there any system reset or driver reload between the working and not working setups? Or was it
just a cable switch?
4. Please give the output of
ethtool eth0
ethtool -i eth0
ethtool -k eth0
5. Can you run ethtool --test in the working setup?
6. I noticed in the syslog, the link is coming up at 100 Mbps. Is this expected?
7. Does it fail immediately on connect to the data center switch? Or is it after some traffic goes
through?
Thanks,
Nithin.
On 09/26/2012 06:48 AM, Dirkjan Ochtman wrote:
> Hi,
>
> I hope this is the right list for this; please let me know if there is
> some more appropriate venue for this kind of problem.
>
> We have bought a Dell PowerEdge server recently with Broadcom ethernet
> controllers:
>
> 01:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5720
> Gigabit Ethernet PCIe
> 01:00.1 Ethernet controller: Broadcom Corporation NetXtreme BCM5720
> Gigabit Ethernet PCIe
> 02:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5720
> Gigabit Ethernet PCIe
> 02:00.1 Ethernet controller: Broadcom Corporation NetXtreme BCM5720
> Gigabit Ethernet PCIe
>
> Using the tg3 driver as provided by the 3.4.9 kernel (it's a distro
> kernel, but I verified that there are no relevant patches on top of
> the vanilla 3.4.9), networking works fine on a small VLAN. However,
> we've run into trouble connecting one of the interfaces to switch run
> by our data center vendor (the switch side works fine when connecting
> with a laptop). The driver keeps erroring out with "transmit timed
> out, resetting" (full syslog output is at [1]). This also keeps
> happening when I use the latest tg3.{c,h} from torvalds/linux-2.6
> (though I've had to revert a few things to make it compile inside the
> 3.4.9 kernel).
>
> I've also run some tests with ethtool:
>
> djc@jansky ~ $ sudo ethtool --test eth0
> The test result is FAIL
> The test extra info:
> nvram test (online) 0
> link test (online) 1
> register test (offline) 0
> memory test (offline) 0
> mac loopback test (offline) 7
> phy loopback test (offline) 7
> ext loopback test (offline) 0
> interrupt test (offline) 1
>
> While I'd be happy to do more digging, at this point I'm out of ideas
> on how to go about that.
>
> Again, sorry if this is off-topic for this list, any help would be appreciated.
>
> Cheers,
>
> Dirkjan
>
> [1] http://dirkjan.ochtman.nl/files/tg3-fail.txt
> --
> 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: Problems with tg3 on BCM5720
From: Michael Chan @ 2012-09-26 21:40 UTC (permalink / raw)
To: Dirkjan Ochtman; +Cc: netdev
In-Reply-To: <CAKmKYaCBG5hURNomffgp9gRhS7g2BYsNG-LTmBrKsX-iyVzVxg@mail.gmail.com>
On Wed, 2012-09-26 at 15:48 +0200, Dirkjan Ochtman wrote:
> I've also run some tests with ethtool:
>
> djc@jansky ~ $ sudo ethtool --test eth0
> The test result is FAIL
> The test extra info:
> nvram test (online) 0
> link test (online) 1
> register test (offline) 0
> memory test (offline) 0
> mac loopback test (offline) 7
> phy loopback test (offline) 7
> ext loopback test (offline) 0
> interrupt test (offline) 1
It is most likely that the device eth0 is down. The device needs to be
up in order to perform all the tests that failed. Please bring up the
device and run the test again. Thanks.
>
>
^ permalink raw reply
* [PATCH] tcp: Remove unused parameter from tcp_v4_save_options
From: Christoph Paasch @ 2012-09-26 21:59 UTC (permalink / raw)
To: David Miller; +Cc: netdev
struct sock *sk is not used inside tcp_v4_save_options. Thus it can be
removed.
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
---
net/ipv4/tcp_ipv4.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 93406c5..385eb79 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -925,8 +925,7 @@ EXPORT_SYMBOL(tcp_syn_flood_action);
/*
* Save and compile IPv4 options into the request_sock if needed.
*/
-static struct ip_options_rcu *tcp_v4_save_options(struct sock *sk,
- struct sk_buff *skb)
+static struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb)
{
const struct ip_options *opt = &(IPCB(skb)->opt);
struct ip_options_rcu *dopt = NULL;
@@ -1568,7 +1567,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
ireq->loc_addr = daddr;
ireq->rmt_addr = saddr;
ireq->no_srccheck = inet_sk(sk)->transparent;
- ireq->opt = tcp_v4_save_options(sk, skb);
+ ireq->opt = tcp_v4_save_options(skb);
if (security_inet_conn_request(sk, skb, req))
goto drop_and_free;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/7 net-next] tg3: Introduce separate functions to allocate/free RX/TX rings.
From: Michael Chan @ 2012-09-26 22:32 UTC (permalink / raw)
To: davem; +Cc: netdev
This is preparation work to allow the number of RX and TX rings to be
configured separately.
Reviewed-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 220 +++++++++++++++++++++++------------
drivers/net/ethernet/broadcom/tg3.h | 2 +
2 files changed, 146 insertions(+), 76 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index bf906c5..93b8120 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -7607,15 +7607,11 @@ static int tg3_init_rings(struct tg3 *tp)
return 0;
}
-/*
- * Must not be invoked with interrupt sources disabled and
- * the hardware shutdown down.
- */
-static void tg3_free_consistent(struct tg3 *tp)
+static void tg3_mem_tx_release(struct tg3 *tp)
{
int i;
- for (i = 0; i < tp->irq_cnt; i++) {
+ for (i = 0; i < tp->irq_max; i++) {
struct tg3_napi *tnapi = &tp->napi[i];
if (tnapi->tx_ring) {
@@ -7626,17 +7622,114 @@ static void tg3_free_consistent(struct tg3 *tp)
kfree(tnapi->tx_buffers);
tnapi->tx_buffers = NULL;
+ }
+}
- if (tnapi->rx_rcb) {
- dma_free_coherent(&tp->pdev->dev,
- TG3_RX_RCB_RING_BYTES(tp),
- tnapi->rx_rcb,
- tnapi->rx_rcb_mapping);
- tnapi->rx_rcb = NULL;
- }
+static int tg3_mem_tx_acquire(struct tg3 *tp)
+{
+ int i;
+ struct tg3_napi *tnapi = &tp->napi[0];
+
+ /* If multivector TSS is enabled, vector 0 does not handle
+ * tx interrupts. Don't allocate any resources for it.
+ */
+ if (tg3_flag(tp, ENABLE_TSS))
+ tnapi++;
+
+ for (i = 0; i < tp->txq_cnt; i++, tnapi++) {
+ tnapi->tx_buffers = kzalloc(sizeof(struct tg3_tx_ring_info) *
+ TG3_TX_RING_SIZE, GFP_KERNEL);
+ if (!tnapi->tx_buffers)
+ goto err_out;
+
+ tnapi->tx_ring = dma_alloc_coherent(&tp->pdev->dev,
+ TG3_TX_RING_BYTES,
+ &tnapi->tx_desc_mapping,
+ GFP_KERNEL);
+ if (!tnapi->tx_ring)
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ tg3_mem_tx_release(tp);
+ return -ENOMEM;
+}
+
+static void tg3_mem_rx_release(struct tg3 *tp)
+{
+ int i;
+
+ for (i = 0; i < tp->irq_max; i++) {
+ struct tg3_napi *tnapi = &tp->napi[i];
tg3_rx_prodring_fini(tp, &tnapi->prodring);
+ if (!tnapi->rx_rcb)
+ continue;
+
+ dma_free_coherent(&tp->pdev->dev,
+ TG3_RX_RCB_RING_BYTES(tp),
+ tnapi->rx_rcb,
+ tnapi->rx_rcb_mapping);
+ tnapi->rx_rcb = NULL;
+ }
+}
+
+static int tg3_mem_rx_acquire(struct tg3 *tp)
+{
+ unsigned int i, limit;
+
+ limit = tp->rxq_cnt;
+
+ /* If RSS is enabled, we need a (dummy) producer ring
+ * set on vector zero. This is the true hw prodring.
+ */
+ if (tg3_flag(tp, ENABLE_RSS))
+ limit++;
+
+ for (i = 0; i < limit; i++) {
+ struct tg3_napi *tnapi = &tp->napi[i];
+
+ if (tg3_rx_prodring_init(tp, &tnapi->prodring))
+ goto err_out;
+
+ /* If multivector RSS is enabled, vector 0
+ * does not handle rx or tx interrupts.
+ * Don't allocate any resources for it.
+ */
+ if (!i && tg3_flag(tp, ENABLE_RSS))
+ continue;
+
+ tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev,
+ TG3_RX_RCB_RING_BYTES(tp),
+ &tnapi->rx_rcb_mapping,
+ GFP_KERNEL);
+ if (!tnapi->rx_rcb)
+ goto err_out;
+
+ memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+ }
+
+ return 0;
+
+err_out:
+ tg3_mem_rx_release(tp);
+ return -ENOMEM;
+}
+
+/*
+ * Must not be invoked with interrupt sources disabled and
+ * the hardware shutdown down.
+ */
+static void tg3_free_consistent(struct tg3 *tp)
+{
+ int i;
+
+ for (i = 0; i < tp->irq_cnt; i++) {
+ struct tg3_napi *tnapi = &tp->napi[i];
+
if (tnapi->hw_status) {
dma_free_coherent(&tp->pdev->dev, TG3_HW_STATUS_SIZE,
tnapi->hw_status,
@@ -7645,6 +7738,9 @@ static void tg3_free_consistent(struct tg3 *tp)
}
}
+ tg3_mem_rx_release(tp);
+ tg3_mem_tx_release(tp);
+
if (tp->hw_stats) {
dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats),
tp->hw_stats, tp->stats_mapping);
@@ -7683,72 +7779,38 @@ static int tg3_alloc_consistent(struct tg3 *tp)
memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
sblk = tnapi->hw_status;
- if (tg3_rx_prodring_init(tp, &tnapi->prodring))
- goto err_out;
+ if (tg3_flag(tp, ENABLE_RSS)) {
+ u16 *prodptr = 0;
- /* If multivector TSS is enabled, vector 0 does not handle
- * tx interrupts. Don't allocate any resources for it.
- */
- if ((!i && !tg3_flag(tp, ENABLE_TSS)) ||
- (i && tg3_flag(tp, ENABLE_TSS))) {
- tnapi->tx_buffers = kzalloc(
- sizeof(struct tg3_tx_ring_info) *
- TG3_TX_RING_SIZE, GFP_KERNEL);
- if (!tnapi->tx_buffers)
- goto err_out;
-
- tnapi->tx_ring = dma_alloc_coherent(&tp->pdev->dev,
- TG3_TX_RING_BYTES,
- &tnapi->tx_desc_mapping,
- GFP_KERNEL);
- if (!tnapi->tx_ring)
- goto err_out;
- }
-
- /*
- * When RSS is enabled, the status block format changes
- * slightly. The "rx_jumbo_consumer", "reserved",
- * and "rx_mini_consumer" members get mapped to the
- * other three rx return ring producer indexes.
- */
- switch (i) {
- default:
- if (tg3_flag(tp, ENABLE_RSS)) {
- tnapi->rx_rcb_prod_idx = NULL;
+ /*
+ * When RSS is enabled, the status block format changes
+ * slightly. The "rx_jumbo_consumer", "reserved",
+ * and "rx_mini_consumer" members get mapped to the
+ * other three rx return ring producer indexes.
+ */
+ switch (i) {
+ case 1:
+ prodptr = &sblk->idx[0].rx_producer;
+ break;
+ case 2:
+ prodptr = &sblk->rx_jumbo_consumer;
+ break;
+ case 3:
+ prodptr = &sblk->reserved;
+ break;
+ case 4:
+ prodptr = &sblk->rx_mini_consumer;
break;
}
- /* Fall through */
- case 1:
+ tnapi->rx_rcb_prod_idx = prodptr;
+ } else {
tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;
- break;
- case 2:
- tnapi->rx_rcb_prod_idx = &sblk->rx_jumbo_consumer;
- break;
- case 3:
- tnapi->rx_rcb_prod_idx = &sblk->reserved;
- break;
- case 4:
- tnapi->rx_rcb_prod_idx = &sblk->rx_mini_consumer;
- break;
}
-
- /*
- * If multivector RSS is enabled, vector 0 does not handle
- * rx or tx interrupts. Don't allocate any resources for it.
- */
- if (!i && tg3_flag(tp, ENABLE_RSS))
- continue;
-
- tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev,
- TG3_RX_RCB_RING_BYTES(tp),
- &tnapi->rx_rcb_mapping,
- GFP_KERNEL);
- if (!tnapi->rx_rcb)
- goto err_out;
-
- memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
}
+ if (tg3_mem_tx_acquire(tp) || tg3_mem_rx_acquire(tp))
+ goto err_out;
+
return 0;
err_out:
@@ -10154,6 +10216,7 @@ static bool tg3_enable_msix(struct tg3 *tp)
* one to the number of vectors we are requesting.
*/
tp->irq_cnt = min_t(unsigned, tp->irq_cnt + 1, tp->irq_max);
+ tp->rxq_cnt = tp->irq_cnt - 1;
}
for (i = 0; i < tp->irq_max; i++) {
@@ -10170,14 +10233,13 @@ static bool tg3_enable_msix(struct tg3 *tp)
netdev_notice(tp->dev, "Requested %d MSI-X vectors, received %d\n",
tp->irq_cnt, rc);
tp->irq_cnt = rc;
+ tp->rxq_cnt = max(rc - 1, 1);
}
for (i = 0; i < tp->irq_max; i++)
tp->napi[i].irq_vec = msix_ent[i].vector;
- netif_set_real_num_tx_queues(tp->dev, 1);
- rc = tp->irq_cnt > 1 ? tp->irq_cnt - 1 : 1;
- if (netif_set_real_num_rx_queues(tp->dev, rc)) {
+ if (netif_set_real_num_rx_queues(tp->dev, tp->rxq_cnt)) {
pci_disable_msix(tp->pdev);
return false;
}
@@ -10188,7 +10250,8 @@ static bool tg3_enable_msix(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
tg3_flag_set(tp, ENABLE_TSS);
- netif_set_real_num_tx_queues(tp->dev, tp->irq_cnt - 1);
+ tp->txq_cnt = tp->rxq_cnt;
+ netif_set_real_num_tx_queues(tp->dev, tp->txq_cnt);
}
}
@@ -10224,6 +10287,11 @@ defcfg:
if (!tg3_flag(tp, USING_MSIX)) {
tp->irq_cnt = 1;
tp->napi[0].irq_vec = tp->pdev->irq;
+ }
+
+ if (tp->irq_cnt == 1) {
+ tp->txq_cnt = 1;
+ tp->rxq_cnt = 1;
netif_set_real_num_tx_queues(tp->dev, 1);
netif_set_real_num_rx_queues(tp->dev, 1);
}
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 6d52cb2..5838dea 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -3037,6 +3037,7 @@ struct tg3 {
void (*write32_tx_mbox) (struct tg3 *, u32,
u32);
u32 dma_limit;
+ u32 txq_cnt;
/* begin "rx thread" cacheline section */
struct tg3_napi napi[TG3_IRQ_MAX_VECS];
@@ -3051,6 +3052,7 @@ struct tg3 {
u32 rx_std_max_post;
u32 rx_offset;
u32 rx_pkt_map_sz;
+ u32 rxq_cnt;
bool rx_refill;
--
1.7.1
^ permalink raw reply related
* [PATCH 5/7 net-next] tg3: Refactor tg3_close()
From: Michael Chan @ 2012-09-26 22:32 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1348698769-760-4-git-send-email-mchan@broadcom.com>
by introducing tg3_stop() that does the opposite of tg3_start(). This
function will be useful when adding the support for changing the numbe
of rx and tx rings.
Reviewed-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 70 +++++++++++++++++++----------------
1 files changed, 38 insertions(+), 32 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 9bd99ce..3f2197e 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -10448,6 +10448,43 @@ err_out1:
return err;
}
+static void tg3_stop(struct tg3 *tp)
+{
+ int i;
+
+ tg3_napi_disable(tp);
+ tg3_reset_task_cancel(tp);
+
+ netif_tx_disable(tp->dev);
+
+ tg3_timer_stop(tp);
+
+ tg3_hwmon_close(tp);
+
+ tg3_phy_stop(tp);
+
+ tg3_full_lock(tp, 1);
+
+ tg3_disable_ints(tp);
+
+ tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+ tg3_free_rings(tp);
+ tg3_flag_clear(tp, INIT_COMPLETE);
+
+ tg3_full_unlock(tp);
+
+ for (i = tp->irq_cnt - 1; i >= 0; i--) {
+ struct tg3_napi *tnapi = &tp->napi[i];
+ free_irq(tnapi->irq_vec, tnapi);
+ }
+
+ tg3_ints_fini(tp);
+
+ tg3_napi_fini(tp);
+
+ tg3_free_consistent(tp);
+}
+
static int tg3_open(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
@@ -10490,45 +10527,14 @@ static int tg3_open(struct net_device *dev)
static int tg3_close(struct net_device *dev)
{
- int i;
struct tg3 *tp = netdev_priv(dev);
- tg3_napi_disable(tp);
- tg3_reset_task_cancel(tp);
-
- netif_tx_stop_all_queues(dev);
-
- tg3_timer_stop(tp);
-
- tg3_hwmon_close(tp);
-
- tg3_phy_stop(tp);
-
- tg3_full_lock(tp, 1);
-
- tg3_disable_ints(tp);
-
- tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- tg3_free_rings(tp);
- tg3_flag_clear(tp, INIT_COMPLETE);
-
- tg3_full_unlock(tp);
-
- for (i = tp->irq_cnt - 1; i >= 0; i--) {
- struct tg3_napi *tnapi = &tp->napi[i];
- free_irq(tnapi->irq_vec, tnapi);
- }
-
- tg3_ints_fini(tp);
+ tg3_stop(tp);
/* Clear stats across close / open calls */
memset(&tp->net_stats_prev, 0, sizeof(tp->net_stats_prev));
memset(&tp->estats_prev, 0, sizeof(tp->estats_prev));
- tg3_napi_fini(tp);
-
- tg3_free_consistent(tp);
-
tg3_power_down(tp);
netif_carrier_off(tp->dev);
--
1.7.1
^ permalink raw reply related
* [PATCH 3/7 net-next] tg3: Separate coalescing setup for rx and tx
From: Michael Chan @ 2012-09-26 22:32 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1348698769-760-2-git-send-email-mchan@broadcom.com>
since the number of rings can be different.
Reviewed-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 74 +++++++++++++++++++++--------------
1 files changed, 45 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 330356b..ddf260c 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -8331,9 +8331,10 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr,
nic_addr);
}
-static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
+
+static void tg3_coal_tx_init(struct tg3 *tp, struct ethtool_coalesce *ec)
{
- int i;
+ int i = 0;
if (!tg3_flag(tp, ENABLE_TSS)) {
tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
@@ -8343,31 +8344,43 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
tw32(HOSTCC_TXCOL_TICKS, 0);
tw32(HOSTCC_TXMAX_FRAMES, 0);
tw32(HOSTCC_TXCOAL_MAXF_INT, 0);
+
+ for (; i < tp->txq_cnt; i++) {
+ u32 reg;
+
+ reg = HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18;
+ tw32(reg, ec->tx_coalesce_usecs);
+ reg = HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18;
+ tw32(reg, ec->tx_max_coalesced_frames);
+ reg = HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18;
+ tw32(reg, ec->tx_max_coalesced_frames_irq);
+ }
+ }
+
+ for (; i < tp->irq_max - 1; i++) {
+ tw32(HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18, 0);
+ tw32(HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18, 0);
+ tw32(HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
}
+}
+
+static void tg3_coal_rx_init(struct tg3 *tp, struct ethtool_coalesce *ec)
+{
+ int i = 0;
+ u32 limit = tp->rxq_cnt;
if (!tg3_flag(tp, ENABLE_RSS)) {
tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
+ limit--;
} else {
tw32(HOSTCC_RXCOL_TICKS, 0);
tw32(HOSTCC_RXMAX_FRAMES, 0);
tw32(HOSTCC_RXCOAL_MAXF_INT, 0);
}
- if (!tg3_flag(tp, 5705_PLUS)) {
- u32 val = ec->stats_block_coalesce_usecs;
-
- tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
- tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq);
-
- if (!netif_carrier_ok(tp->dev))
- val = 0;
-
- tw32(HOSTCC_STAT_COAL_TICKS, val);
- }
-
- for (i = 0; i < tp->irq_cnt - 1; i++) {
+ for (; i < limit; i++) {
u32 reg;
reg = HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18;
@@ -8376,27 +8389,30 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
tw32(reg, ec->rx_max_coalesced_frames);
reg = HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18;
tw32(reg, ec->rx_max_coalesced_frames_irq);
-
- if (tg3_flag(tp, ENABLE_TSS)) {
- reg = HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18;
- tw32(reg, ec->tx_coalesce_usecs);
- reg = HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18;
- tw32(reg, ec->tx_max_coalesced_frames);
- reg = HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18;
- tw32(reg, ec->tx_max_coalesced_frames_irq);
- }
}
for (; i < tp->irq_max - 1; i++) {
tw32(HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18, 0);
tw32(HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18, 0);
tw32(HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
+ }
+}
- if (tg3_flag(tp, ENABLE_TSS)) {
- tw32(HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18, 0);
- tw32(HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18, 0);
- tw32(HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
- }
+static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
+{
+ tg3_coal_tx_init(tp, ec);
+ tg3_coal_rx_init(tp, ec);
+
+ if (!tg3_flag(tp, 5705_PLUS)) {
+ u32 val = ec->stats_block_coalesce_usecs;
+
+ tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
+ tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq);
+
+ if (!netif_carrier_ok(tp->dev))
+ val = 0;
+
+ tw32(HOSTCC_STAT_COAL_TICKS, val);
}
}
--
1.7.1
^ 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