* Re: [PATCH net-next] net: skb_segment() should preserve backpressure
From: David Miller @ 2014-10-29 18:47 UTC (permalink / raw)
To: eric.dumazet; +Cc: makita.toshiaki, netdev, herbert
In-Reply-To: <1414431051.16231.23.camel@edumazet-glaptop2.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 27 Oct 2014 10:30:51 -0700
> From: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
>
> This patch generalizes commit d6a4a1041176 ("tcp: GSO should be TSQ
> friendly") to protocols using skb_set_owner_w()
>
> TCP uses its own destructor (tcp_wfree) and needs a more complex scheme
> as explained in commit 6ff50cd55545 ("tcp: gso: do not generate out of
> order packets")
>
> This allows UDP sockets using UFO to get proper backpressure,
> thus avoiding qdisc drops and excessive cpu usage.
>
> Here are performance test results (macvlan on vlan):
...
> [edumazet] Rewrote patch and changelog.
>
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied, thanks everyone.
^ permalink raw reply
* Re: [PATCH v2 6/9] ARM: berlin: Add BG2 ethernet DT nodes
From: Sebastian Hesselbarth @ 2014-10-29 18:38 UTC (permalink / raw)
Cc: David S. Miller, Antoine Ténart, Florian Fainelli, Eric Miao,
Haojian Zhuang, linux-arm-kernel, netdev, devicetree,
linux-kernel
In-Reply-To: <1414002412-13615-7-git-send-email-sebastian.hesselbarth@gmail.com>
On 22.10.2014 20:26, Sebastian Hesselbarth wrote:
> Marvell BG2 has two fast ethernet controllers with internal PHY,
> add the corresponding nodes to SoC dtsi.
>
> Tested-by: Antoine Ténart <antoine.tenart@free-electrons.com>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Applied the four DT patches to berlin/dt.
Sebastian
> ---
> Changelog:
> v1->v2:
> - move phy-connection-type to controller node instead of PHY node
> (Reported by Sergei Shtylyov)
>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: "Antoine Ténart" <antoine.tenart@free-electrons.com>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: Eric Miao <eric.y.miao@gmail.com>
> Cc: Haojian Zhuang <haojian.zhuang@gmail.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: netdev@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
> arch/arm/boot/dts/berlin2.dtsi | 36 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
>
> diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
> index 9d7c810ebd0b..dc0227dfc691 100644
> --- a/arch/arm/boot/dts/berlin2.dtsi
> +++ b/arch/arm/boot/dts/berlin2.dtsi
> @@ -79,11 +79,47 @@
> clocks = <&chip CLKID_TWD>;
> };
>
> + eth1: ethernet@b90000 {
> + compatible = "marvell,pxa168-eth";
> + reg = <0xb90000 0x10000>;
> + clocks = <&chip CLKID_GETH1>;
> + interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
> + /* set by bootloader */
> + local-mac-address = [00 00 00 00 00 00];
> + #address-cells = <1>;
> + #size-cells = <0>;
> + phy-connection-type = "mii";
> + phy-handle = <ðphy1>;
> + status = "disabled";
> +
> + ethphy1: ethernet-phy@0 {
> + reg = <0>;
> + };
> + };
> +
> cpu-ctrl@dd0000 {
> compatible = "marvell,berlin-cpu-ctrl";
> reg = <0xdd0000 0x10000>;
> };
>
> + eth0: ethernet@e50000 {
> + compatible = "marvell,pxa168-eth";
> + reg = <0xe50000 0x10000>;
> + clocks = <&chip CLKID_GETH0>;
> + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> + /* set by bootloader */
> + local-mac-address = [00 00 00 00 00 00];
> + #address-cells = <1>;
> + #size-cells = <0>;
> + phy-connection-type = "mii";
> + phy-handle = <ðphy0>;
> + status = "disabled";
> +
> + ethphy0: ethernet-phy@0 {
> + reg = <0>;
> + };
> + };
> +
> apb@e80000 {
> compatible = "simple-bus";
> #address-cells = <1>;
>
^ permalink raw reply
* Re: [PATCH v3] ipv6: notify userspace when we added or changed an ipv6 token
From: David Miller @ 2014-10-29 18:35 UTC (permalink / raw)
To: lkundrak; +Cc: netdev, hannes, dborkman
In-Reply-To: <1414427956-20056-1-git-send-email-lkundrak@v3.sk>
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 27 Oct 2014 17:39:16 +0100
> NetworkManager might want to know that it changed when the router advertisement
> arrives.
>
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net-next v2 3/3] gianfar: Implement PAUSE frame generation support
From: David Miller @ 2014-10-29 18:34 UTC (permalink / raw)
To: matei.pavaluca; +Cc: netdev, claudiu.manoil
In-Reply-To: <1414399364-22308-3-git-send-email-matei.pavaluca@freescale.com>
From: Matei Pavaluca <matei.pavaluca@freescale.com>
Date: Mon, 27 Oct 2014 10:42:44 +0200
> The hardware can automatically generate pause frames when the number
> of free buffers drops under a certain threshold, but in order to do this,
> the address of the last free buffer needs to be written to a specific
> register for each RX queue.
>
> This has to be done in 'gfar_clean_rx_ring' which is called for each
> RX queue. In order not to impact performance, by adding a register write
> for each incoming packet, this operation is done only when the PAUSE frame
> transmission is enabled.
>
> Whenever the link is readjusted, this capability is turned on or off.
>
> Signed-off-by: Matei Pavaluca <matei.pavaluca@freescale.com>
Applied.
But I would turn pause frames on by default, and deal with the
"performance" issue by aggregating the register writes. Only
do it every N cleaned frames.
^ permalink raw reply
* Re: [PATCH net-next v2 2/3] Fix the way the local advertising flow options are determined
From: David Miller @ 2014-10-29 18:33 UTC (permalink / raw)
To: matei.pavaluca; +Cc: netdev, claudiu.manoil
In-Reply-To: <1414399364-22308-2-git-send-email-matei.pavaluca@freescale.com>
From: Matei Pavaluca <matei.pavaluca@freescale.com>
Date: Mon, 27 Oct 2014 10:42:43 +0200
> From: Pavaluca Matei-B46610 <matei.pavaluca@freescale.com>
>
> Local flow control options needed in order to resolve the negotiation
> are incorrectly calculated.
>
> Previously 'mii_advertise_flowctrl' was called to determine the local advertising
> options, but these were determined based on FLOW_CTRL_RX/TX flags which are
> never set through ethtool.
> The patch simply translates from ethtool flow options to mii flow options.
>
> Signed-off-by: Pavaluca Matei <matei.pavaluca@freescale.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next v2 1/3] Add flow control support flags to gianfar's capabilities
From: David Miller @ 2014-10-29 18:33 UTC (permalink / raw)
To: matei.pavaluca; +Cc: netdev, claudiu.manoil
In-Reply-To: <1414399364-22308-1-git-send-email-matei.pavaluca@freescale.com>
From: Matei Pavaluca <matei.pavaluca@freescale.com>
Date: Mon, 27 Oct 2014 10:42:42 +0200
> From: Pavaluca Matei-B46610 <matei.pavaluca@freescale.com>
>
> The phy device supports 802.3x flow control, but the specific flags are not set
> in the phy initialisation code. Flow control flags need to be added to the
> supported capabilities of the phydev by the driver.
>
> This is needed in order for ethtool to work ('ethtool -A' code checks for these
> flags)
>
> Signed-off-by: Pavaluca Matei <matei.pavaluca@freescale.com>
Applied.
^ permalink raw reply
* Re: e1000_netpoll(): disable_irq() triggers might_sleep() on linux-next
From: Thomas Gleixner @ 2014-10-29 18:33 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: Sabrina Dubroca, netdev, linux-kernel, jeffrey.t.kirsher
In-Reply-To: <20141029180734.GQ12706@worktop.programming.kicks-ass.net>
On Wed, 29 Oct 2014, Peter Zijlstra wrote:
> On Wed, Oct 29, 2014 at 04:56:20PM +0100, Sabrina Dubroca wrote:
> > commit e22b886a8a43b ("sched/wait: Add might_sleep() checks") included
> > in today's linux-next added a check that fires on e1000 with netpoll:
> >
> >
> > BUG: sleeping function called from invalid context at kernel/irq/manage.c:104
> > in_atomic(): 1, irqs_disabled(): 1, pid: 1, name: systemd
> > no locks held by systemd/1.
> > irq event stamp: 10102965
> > hardirqs last enabled at (10102965): [<ffffffff810cbafd>] vprintk_emit+0x2dd/0x6a0
> > hardirqs last disabled at (10102964): [<ffffffff810cb897>] vprintk_emit+0x77/0x6a0
> > softirqs last enabled at (10102342): [<ffffffff810666aa>] __do_softirq+0x27a/0x6f0
> > softirqs last disabled at (10102337): [<ffffffff81066e86>] irq_exit+0x56/0xe0
> > Preemption disabled at:[<ffffffff817de50d>] printk_emit+0x31/0x33
> >
> > CPU: 1 PID: 1 Comm: systemd Not tainted 3.18.0-rc2-next-20141029-dirty #222
> > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140617_173321-var-lib-archbuild-testing-x86_64-tobias 04/01/2014
> > ffffffff81a82291 ffff88001e743978 ffffffff817df31d 0000000000000000
> > 0000000000000000 ffff88001e7439a8 ffffffff8108dfa2 ffff88001e7439a8
> > ffffffff81a82291 0000000000000068 0000000000000000 ffff88001e7439d8
> > Call Trace:
> > [<ffffffff817df31d>] dump_stack+0x4f/0x7c
> > [<ffffffff8108dfa2>] ___might_sleep+0x182/0x2b0
> > [<ffffffff8108e10a>] __might_sleep+0x3a/0xc0
> > [<ffffffff810ce358>] synchronize_irq+0x38/0xa0
> > [<ffffffff810ce690>] disable_irq+0x20/0x30
> > [<ffffffff815d7253>] e1000_netpoll+0x23/0x60
> > [<ffffffff81678d02>] netpoll_poll_dev+0x72/0x3a0
> > [<ffffffff816791e7>] netpoll_send_skb_on_dev+0x1b7/0x2e0
> > [<ffffffff816795f3>] netpoll_send_udp+0x2e3/0x490
>
> Oh cute.. not entirely sure what to do there. This only works if you
> _know_ desc->threads_active will never be !0.
>
> The best I can come up with is something like this, which avoids the
> might_sleep() in the one special case.
>
> Thomas?
Yuck. No. You are just papering over the problem.
What happens if you add 'threadirqs' to the kernel command line? Or if
the interrupt line is shared with a real threaded interrupt user?
The proper solution is to have a poll_lock for e1000 which serializes
the hardware interrupt against netpoll instead of using
disable/enable_irq().
In fact that's less expensive than the disable/enable_irq() dance and
the chance of contention is pretty low. If done right it will be a
NOOP for the CONFIG_NET_POLL_CONTROLLER=n case.
Thanks,
tglx
^ permalink raw reply
* [PATCH net-next] neigh: optimize neigh_parms_release()
From: Nicolas Dichtel @ 2014-10-29 18:29 UTC (permalink / raw)
To: netdev; +Cc: davem, Nicolas Dichtel
In neigh_parms_release() we loop over all entries to find the entry given in
argument and being able to remove it from the list. By using a double linked
list, we can avoid this loop.
Here are some numbers with 30 000 dummy interfaces configured:
Before the patch:
$ time rmmod dummy
real 2m0.118s
user 0m0.000s
sys 1m50.048s
After the patch:
$ time rmmod dummy
real 1m9.970s
user 0m0.000s
sys 0m47.976s
Suggested-by: Thierry Herbelot <thierry.herbelot@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
include/net/neighbour.h | 3 ++-
net/core/neighbour.c | 32 +++++++++++++-------------------
2 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index f60558d0254c..dedfb188b1a7 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -69,7 +69,7 @@ struct neigh_parms {
struct net *net;
#endif
struct net_device *dev;
- struct neigh_parms *next;
+ struct list_head list;
int (*neigh_setup)(struct neighbour *);
void (*neigh_cleanup)(struct neighbour *);
struct neigh_table *tbl;
@@ -203,6 +203,7 @@ struct neigh_table {
void (*proxy_redo)(struct sk_buff *skb);
char *id;
struct neigh_parms parms;
+ struct list_head parms_list;
int gc_interval;
int gc_thresh1;
int gc_thresh2;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index ef31fef25e5a..edd04116ecb7 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -773,7 +773,7 @@ static void neigh_periodic_work(struct work_struct *work)
if (time_after(jiffies, tbl->last_rand + 300 * HZ)) {
struct neigh_parms *p;
tbl->last_rand = jiffies;
- for (p = &tbl->parms; p; p = p->next)
+ list_for_each_entry(p, &tbl->parms_list, list)
p->reachable_time =
neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME));
}
@@ -1446,7 +1446,7 @@ static inline struct neigh_parms *lookup_neigh_parms(struct neigh_table *tbl,
{
struct neigh_parms *p;
- for (p = &tbl->parms; p; p = p->next) {
+ list_for_each_entry(p, &tbl->parms_list, list) {
if ((p->dev && p->dev->ifindex == ifindex && net_eq(neigh_parms_net(p), net)) ||
(!p->dev && !ifindex && net_eq(net, &init_net)))
return p;
@@ -1481,8 +1481,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
}
write_lock_bh(&tbl->lock);
- p->next = tbl->parms.next;
- tbl->parms.next = p;
+ list_add(&p->list, &tbl->parms.list);
write_unlock_bh(&tbl->lock);
neigh_parms_data_state_cleanall(p);
@@ -1501,24 +1500,15 @@ static void neigh_rcu_free_parms(struct rcu_head *head)
void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
{
- struct neigh_parms **p;
-
if (!parms || parms == &tbl->parms)
return;
write_lock_bh(&tbl->lock);
- for (p = &tbl->parms.next; *p; p = &(*p)->next) {
- if (*p == parms) {
- *p = parms->next;
- parms->dead = 1;
- write_unlock_bh(&tbl->lock);
- if (parms->dev)
- dev_put(parms->dev);
- call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
- return;
- }
- }
+ list_del(&parms->list);
+ parms->dead = 1;
write_unlock_bh(&tbl->lock);
- neigh_dbg(1, "%s: not found\n", __func__);
+ if (parms->dev)
+ dev_put(parms->dev);
+ call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
}
EXPORT_SYMBOL(neigh_parms_release);
@@ -1535,6 +1525,8 @@ static void neigh_table_init_no_netlink(struct neigh_table *tbl)
unsigned long now = jiffies;
unsigned long phsize;
+ INIT_LIST_HEAD(&tbl->parms_list);
+ list_add(&tbl->parms.list, &tbl->parms_list);
write_pnet(&tbl->parms.net, &init_net);
atomic_set(&tbl->parms.refcnt, 1);
tbl->parms.reachable_time =
@@ -2154,7 +2146,9 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
NLM_F_MULTI) <= 0)
break;
- for (nidx = 0, p = tbl->parms.next; p; p = p->next) {
+ nidx = 0;
+ p = list_next_entry(&tbl->parms, list);
+ list_for_each_entry_from(p, &tbl->parms_list, list) {
if (!net_eq(neigh_parms_net(p), net))
continue;
--
2.1.0
^ permalink raw reply related
* Re: [Patch net 2/2] net_sched: always call ->destroy when ->init() fails
From: David Miller @ 2014-10-29 18:29 UTC (permalink / raw)
To: xiyou.wangcong
Cc: netdev, wang.bo116, john.r.fastabend, edumazet, kaber, vtlam
In-Reply-To: <1414194959-28006-2-git-send-email-xiyou.wangcong@gmail.com>
From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Fri, 24 Oct 2014 16:55:59 -0700
> In qdisc_create(), when ->init() exists and it fails, we should
> call ->destroy() to clean up the potentially partially initialized
> qdisc's. This will also make the ->init() implementation easier.
>
> qdisc_create_dflt() already does that. Most callers of qdisc_create_dflt()
> simply use noop_qdisc when it fails.
>
> And, most of the ->destroy() implementations are already able to clean up
> partially initialization, we don't need to worry.
>
> The following ->init()'s need to catch up:
> fq_codel_init(), hhf_init(), multiq_init(), sfq_init(), mq_init(),
> mqprio_init().
>
> Reported-by: Wang Bo <wang.bo116@zte.com.cn>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
As discussed, I really want to see ->init() clean up it's own crap.
There are certain kinds of initializations that cannot be tested for,
such as setting up a workqueue etc.
Therefore, the mere idea that we can call ->destroy() to handle this
is a pure non-starter as far as I am concerned.
Thanks.
^ permalink raw reply
* Re: [Patch net 1/2] sch_pie: schedule the timer after all init succeed
From: David Miller @ 2014-10-29 18:28 UTC (permalink / raw)
To: xiyou.wangcong; +Cc: netdev, vijaynsu
In-Reply-To: <1414194959-28006-1-git-send-email-xiyou.wangcong@gmail.com>
From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Fri, 24 Oct 2014 16:55:58 -0700
> Cc: Vijay Subramanian <vijaynsu@cisco.com>
> Cc: David S. Miller <davem@davemloft.net>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v3 00/15] net: dsa: Fixes and enhancements
From: Florian Fainelli @ 2014-10-29 18:22 UTC (permalink / raw)
To: Guenter Roeck, netdev; +Cc: David S. Miller, Andrew Lunn, linux-kernel
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
On 10/29/2014 10:44 AM, Guenter Roeck wrote:
> Patch 01/15 addresses a bug indicated by an an annoying and unhelpful
> log message.
>
> Patches 02/15 and 03/15 are minor enhancements, adding support for
> known switch revisions.
>
> Patches 04/15 and 05/15 add support for MV88E6352 and MV88E6176.
>
> Patch 06/15 adds support for hardware monitoring, specifically for
> reporting the chip temperature, to the dsa subsystem.
>
> Patches 07/15 and 08/15 implement hardware monitoring for MV88E6352,
> MV88E6176, MV88E6123, MV88E6161, and MV88E6165.
>
> Patch 09/15 and 10/15 add support for EEPROM access to the DSA subsystem.
>
> Patch 11/15 implements EEPROM access for MV88E6352 and MV88E6176.
>
> Patch 12/15 adds support for reading switch registers to the DSA
> subsystem.
>
> Patches 13/15 amd 14/15 implement support for reading switch registers
> to the drivers for MV88E6352, MV88E6176, MV88E6123, MV88E6161, and MV88E6165.
>
> Patch 15/15 adds support for reading additional RMON registers to the drivers
> for MV88E6352, MV88E6176, MV88E6123, MV88E6161, and MV88E6165.
>
> The series was tested on top of v3.18-rc2 in an x86 system with MV88E6352.
> Testing in systems with 88E6131, 88E6060 and MV88E6165 was done earlier
> (I don't have access to those systems right now). The series was also build
> tested using my build system at http://server.roeck-us.net:8010/builders.
> Look into the 'dsa' column for build results.
>
> The series merges cleanly into net-next as of today (10/29).
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Thanks Guenter!
>
> v3:
> - Fix bug in eeprom patches seen if devicetree is enabled:
> eeprom-length property is attached to switch devicetree node,
> not to dsa node, and there was a compile error.
> v2:
> - Made reporting chip temperatures through the hwmon subsystem optional
> with new Kconfig option
> - Changed the hwmon chip name to <network device name>_dsa<index>
> - Made EEPROM presence and size configurable through platform and devicetree
> data
> - Various minor changes and fixes (see individual patches for details)
>
> ----------------------------------------------------------------
> The following changes since commit cac7f2429872d3733dc3f9915857b1691da2eb2f:
>
> Linux 3.18-rc2 (2014-10-26 16:48:41 -0700)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git dsa
>
> for you to fetch changes up to 245472a4f3ca2a68c5632f2c37da41aa2d3fb2f0:
>
> net: dsa: Provide additional RMON statistics (2014-10-29 08:55:37 -0700)
>
> ----------------------------------------------------------------
> Guenter Roeck (15):
> net: dsa: Don't set skb->protocol on outgoing tagged packets
> net: dsa: Report known silicon revisions for Marvell 88E6060
> net: dsa: Report known silicon revisions for Marvell 88E6131
> net: dsa: Add support for Marvell 88E6352
> net: dsa/mv88e6352: Add support for MV88E6176
> net: dsa: Add support for reporting switch chip temperatures
> net: dsa/mv88e6352: Report chip temperature
> net: dsa/mv88e6123_61_65: Report chip temperature
> net: dsa: Add support for switch EEPROM access
> dsa: Add new optional devicetree property to describe EEPROM size
> net: dsa/mv88e6352: Implement EEPROM access functions
> net: dsa: Add support for reading switch registers with ethtool
> net: dsa/mv88e6123_61_65: Add support for reading switch registers
> net: dsa/mv88e6352: Add support for reading switch registers
> net: dsa: Provide additional RMON statistics
>
> Documentation/devicetree/bindings/net/dsa/dsa.txt | 9 +-
> MAINTAINERS | 5 +
> drivers/net/dsa/Kconfig | 9 +
> drivers/net/dsa/Makefile | 3 +
> drivers/net/dsa/mv88e6060.c | 5 +-
> drivers/net/dsa/mv88e6123_61_65.c | 73 +-
> drivers/net/dsa/mv88e6131.c | 12 +-
> drivers/net/dsa/mv88e6352.c | 788 ++++++++++++++++++++++
> drivers/net/dsa/mv88e6xxx.c | 53 +-
> drivers/net/dsa/mv88e6xxx.h | 15 +
> include/net/dsa.h | 33 +
> net/dsa/Kconfig | 11 +
> net/dsa/dsa.c | 135 ++++
> net/dsa/slave.c | 64 ++
> net/dsa/tag_dsa.c | 2 -
> net/dsa/tag_edsa.c | 2 -
> net/dsa/tag_trailer.c | 2 -
> 17 files changed, 1202 insertions(+), 19 deletions(-)
> create mode 100644 drivers/net/dsa/mv88e6352.c
>
^ permalink raw reply
* Re: e1000_netpoll(): disable_irq() triggers might_sleep() on linux-next
From: Peter Zijlstra @ 2014-10-29 18:07 UTC (permalink / raw)
To: Sabrina Dubroca; +Cc: netdev, linux-kernel, jeffrey.t.kirsher, Thomas Gleixner
In-Reply-To: <20141029155620.GA4886@kria>
On Wed, Oct 29, 2014 at 04:56:20PM +0100, Sabrina Dubroca wrote:
> commit e22b886a8a43b ("sched/wait: Add might_sleep() checks") included
> in today's linux-next added a check that fires on e1000 with netpoll:
>
>
> BUG: sleeping function called from invalid context at kernel/irq/manage.c:104
> in_atomic(): 1, irqs_disabled(): 1, pid: 1, name: systemd
> no locks held by systemd/1.
> irq event stamp: 10102965
> hardirqs last enabled at (10102965): [<ffffffff810cbafd>] vprintk_emit+0x2dd/0x6a0
> hardirqs last disabled at (10102964): [<ffffffff810cb897>] vprintk_emit+0x77/0x6a0
> softirqs last enabled at (10102342): [<ffffffff810666aa>] __do_softirq+0x27a/0x6f0
> softirqs last disabled at (10102337): [<ffffffff81066e86>] irq_exit+0x56/0xe0
> Preemption disabled at:[<ffffffff817de50d>] printk_emit+0x31/0x33
>
> CPU: 1 PID: 1 Comm: systemd Not tainted 3.18.0-rc2-next-20141029-dirty #222
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140617_173321-var-lib-archbuild-testing-x86_64-tobias 04/01/2014
> ffffffff81a82291 ffff88001e743978 ffffffff817df31d 0000000000000000
> 0000000000000000 ffff88001e7439a8 ffffffff8108dfa2 ffff88001e7439a8
> ffffffff81a82291 0000000000000068 0000000000000000 ffff88001e7439d8
> Call Trace:
> [<ffffffff817df31d>] dump_stack+0x4f/0x7c
> [<ffffffff8108dfa2>] ___might_sleep+0x182/0x2b0
> [<ffffffff8108e10a>] __might_sleep+0x3a/0xc0
> [<ffffffff810ce358>] synchronize_irq+0x38/0xa0
> [<ffffffff810ce690>] disable_irq+0x20/0x30
> [<ffffffff815d7253>] e1000_netpoll+0x23/0x60
> [<ffffffff81678d02>] netpoll_poll_dev+0x72/0x3a0
> [<ffffffff816791e7>] netpoll_send_skb_on_dev+0x1b7/0x2e0
> [<ffffffff816795f3>] netpoll_send_udp+0x2e3/0x490
Oh cute.. not entirely sure what to do there. This only works if you
_know_ desc->threads_active will never be !0.
The best I can come up with is something like this, which avoids the
might_sleep() in the one special case.
Thomas?
---
kernel/irq/manage.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 0a9104b4608b..b7cb736a8b32 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -100,8 +100,11 @@ void synchronize_irq(unsigned int irq)
* running. Now verify that no threaded handlers are
* active.
*/
- wait_event(desc->wait_for_threads,
- !atomic_read(&desc->threads_active));
+ if (atomic_read(&desc->threads_active)) {
+ might_sleep();
+ __wait_event(desc->wait_for_threads,
+ !atomic_read(&desc->threads_active));
+ }
}
}
EXPORT_SYMBOL(synchronize_irq);
^ permalink raw reply related
* [PATCH] Add missing descriptions for fwmark_reflect for ipv4 and ipv6.
From: Loganaden Velvindron @ 2014-10-29 17:29 UTC (permalink / raw)
To: netdev
Hi guys,
It was initially sent by Lorenzo Colitti, but was subsequently
lost in the final diff he submitted.
(It's my first time sending a diff to netdev, please let me know if
I made a mistake)
Signed-off-by: Loganaden Velvindron <logan@elandsys.com>
---
Documentation/networking/ip-sysctl.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 0307e28..a476b08 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -56,6 +56,13 @@ ip_forward_use_pmtu - BOOLEAN
0 - disabled
1 - enabled
+fwmark_reflect - BOOLEAN
+ Controls the fwmark of kernel-generated IPv4 reply packets that are not
+ associated with a socket for example, TCP RSTs or ICMP echo replies).
+ If unset, these packets have a fwmark of zero. If set, they have the
+ fwmark of the packet they are replying to.
+ Default: 0
+
route/max_size - INTEGER
Maximum number of routes allowed in the kernel. Increase
this when using large numbers of interfaces and/or routes.
@@ -1201,6 +1208,13 @@ conf/all/forwarding - BOOLEAN
proxy_ndp - BOOLEAN
Do proxy ndp.
+fwmark_reflect - BOOLEAN
+ Controls the fwmark of kernel-generated IPv6 reply packets that are not
+ associated with a socket for example, TCP RSTs or ICMPv6 echo replies).
+ If unset, these packets have a fwmark of zero. If set, they have the
+ fwmark of the packet they are replying to.
+ Default: 0
+
conf/interface/*:
Change special settings per interface.
--
1.9.1
^ permalink raw reply related
* [PATCH] Add missing descriptions for fwmark_reflect for ipv4 and ipv6.
From: Loganaden Velvindron @ 2014-10-29 17:56 UTC (permalink / raw)
To: netdev
Hi All,
It was initially sent by Lorenzo Colitti, but was subsequently
lost in the final diff he submitted.
(It's my first diff, please let me know if I screwed up in the submission
process)
Signed-off-by: Loganaden Velvindron <logan@elandsys.com>
---
Documentation/networking/ip-sysctl.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 0307e28..a476b08 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -56,6 +56,13 @@ ip_forward_use_pmtu - BOOLEAN
0 - disabled
1 - enabled
+fwmark_reflect - BOOLEAN
+ Controls the fwmark of kernel-generated IPv4 reply packets that are not
+ associated with a socket for example, TCP RSTs or ICMP echo replies).
+ If unset, these packets have a fwmark of zero. If set, they have the
+ fwmark of the packet they are replying to.
+ Default: 0
+
route/max_size - INTEGER
Maximum number of routes allowed in the kernel. Increase
this when using large numbers of interfaces and/or routes.
@@ -1201,6 +1208,13 @@ conf/all/forwarding - BOOLEAN
proxy_ndp - BOOLEAN
Do proxy ndp.
+fwmark_reflect - BOOLEAN
+ Controls the fwmark of kernel-generated IPv6 reply packets that are not
+ associated with a socket for example, TCP RSTs or ICMPv6 echo replies).
+ If unset, these packets have a fwmark of zero. If set, they have the
+ fwmark of the packet they are replying to.
+ Default: 0
+
conf/interface/*:
Change special settings per interface.
--
1.9.1
^ permalink raw reply related
* [PATCH v3 10/15] dsa: Add new optional devicetree property to describe EEPROM size
From: Guenter Roeck @ 2014-10-29 17:45 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck, devicetree, Ian Campbell, Kumar Gala, Mark Rutland,
Pawel Moll, Rob Herring
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
The dsa core now supports reading from and writing to a switch EEPROM
if connected. Describe optional devicetree property indicating that
an EEPROM is present and its size.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- eeprom-length property is attached to switch devicetree node,
not to dsa node.
v2:
- Added patch
Documentation/devicetree/bindings/net/dsa/dsa.txt | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt
index a62c889..e124847 100644
--- a/Documentation/devicetree/bindings/net/dsa/dsa.txt
+++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt
@@ -10,7 +10,7 @@ Required properties:
- dsa,ethernet : Should be a phandle to a valid Ethernet device node
- dsa,mii-bus : Should be a phandle to a valid MDIO bus device node
-Optionnal properties:
+Optional properties:
- interrupts : property with a value describing the switch
interrupt number (not supported by the driver)
@@ -23,6 +23,13 @@ Each of these switch child nodes should have the following required properties:
- #address-cells : Must be 1
- #size-cells : Must be 0
+A switch child node has the following optional property:
+
+- eeprom-length : Set to the length of an EEPROM connected to the
+ switch. Must be set if the switch can not detect
+ the presence and/or size of a connected EEPROM,
+ otherwise optional.
+
A switch may have multiple "port" children nodes
Each port children node must have the following mandatory properties:
--
1.9.1
^ permalink raw reply related
* [PATCH v3 08/15] net: dsa/mv88e6123_61_65: Report chip temperature
From: Guenter Roeck @ 2014-10-29 17:45 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
MV88E6123 and compatible chips support reading the chip temperature
from PHY register 6:26.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- No change
v2:
- Make new functionality optional, depending on CONFIG_NET_DSA_HWMON
drivers/net/dsa/mv88e6123_61_65.c | 68 +++++++++++++++++++++++++++++++++++++--
1 file changed, 66 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index a332c53..9f43c9b 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -291,6 +291,54 @@ static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p)
return 0;
}
+#ifdef CONFIG_NET_DSA_HWMON
+
+static int mv88e6123_61_65_get_temp(struct dsa_switch *ds, int *temp)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int ret;
+ int val;
+
+ *temp = 0;
+
+ mutex_lock(&ps->phy_mutex);
+
+ ret = mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6);
+ if (ret < 0)
+ goto error;
+
+ /* Enable temperature sensor */
+ ret = mv88e6xxx_phy_read(ds, 0x0, 0x1a);
+ if (ret < 0)
+ goto error;
+
+ ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5));
+ if (ret < 0)
+ goto error;
+
+ /* Wait for temperature to stabilize */
+ usleep_range(10000, 12000);
+
+ val = mv88e6xxx_phy_read(ds, 0x0, 0x1a);
+ if (val < 0) {
+ ret = val;
+ goto error;
+ }
+
+ /* Disable temperature sensor */
+ ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5));
+ if (ret < 0)
+ goto error;
+
+ *temp = ((val & 0x1f) - 5) * 5;
+
+error:
+ mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0);
+ mutex_unlock(&ps->phy_mutex);
+ return ret;
+}
+#endif /* CONFIG_NET_DSA_HWMON */
+
static int mv88e6123_61_65_setup(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -299,6 +347,7 @@ static int mv88e6123_61_65_setup(struct dsa_switch *ds)
mutex_init(&ps->smi_mutex);
mutex_init(&ps->stats_mutex);
+ mutex_init(&ps->phy_mutex);
ret = mv88e6123_61_65_switch_reset(ds);
if (ret < 0)
@@ -329,16 +378,28 @@ static int mv88e6123_61_65_port_to_phy_addr(int port)
static int
mv88e6123_61_65_phy_read(struct dsa_switch *ds, int port, int regnum)
{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int addr = mv88e6123_61_65_port_to_phy_addr(port);
- return mv88e6xxx_phy_read(ds, addr, regnum);
+ int ret;
+
+ mutex_lock(&ps->phy_mutex);
+ ret = mv88e6xxx_phy_read(ds, addr, regnum);
+ mutex_unlock(&ps->phy_mutex);
+ return ret;
}
static int
mv88e6123_61_65_phy_write(struct dsa_switch *ds,
int port, int regnum, u16 val)
{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int addr = mv88e6123_61_65_port_to_phy_addr(port);
- return mv88e6xxx_phy_write(ds, addr, regnum, val);
+ int ret;
+
+ mutex_lock(&ps->phy_mutex);
+ ret = mv88e6xxx_phy_write(ds, addr, regnum, val);
+ mutex_unlock(&ps->phy_mutex);
+ return ret;
}
static struct mv88e6xxx_hw_stat mv88e6123_61_65_hw_stats[] = {
@@ -406,6 +467,9 @@ struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
.get_strings = mv88e6123_61_65_get_strings,
.get_ethtool_stats = mv88e6123_61_65_get_ethtool_stats,
.get_sset_count = mv88e6123_61_65_get_sset_count,
+#ifdef CONFIG_NET_DSA_HWMON
+ .get_temp = mv88e6123_61_65_get_temp,
+#endif
};
MODULE_ALIAS("platform:mv88e6123");
--
1.9.1
^ permalink raw reply related
* [PATCH v3 05/15] net: dsa/mv88e6352: Add support for MV88E6176
From: Guenter Roeck @ 2014-10-29 17:44 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
MV88E6176 is mostly compatible to MV88E6352 and is documented
in the same functional specification. Add support for it.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- No change
v2:
- No change
drivers/net/dsa/Kconfig | 5 +++--
drivers/net/dsa/mv88e6352.c | 2 ++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 0987c33..2d1a55e 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -46,12 +46,13 @@ config NET_DSA_MV88E6171
chip.
config NET_DSA_MV88E6352
- tristate "Marvell 88E6352 ethernet switch chip support"
+ tristate "Marvell 88E6176/88E6352 ethernet switch chip support"
select NET_DSA
select NET_DSA_MV88E6XXX
select NET_DSA_TAG_EDSA
---help---
- This enables support for the Marvell 88E6352 ethernet switch chip.
+ This enables support for the Marvell 88E6176 and 88E6352 ethernet
+ switch chips.
config NET_DSA_BCM_SF2
tristate "Broadcom Starfighter 2 Ethernet switch support"
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 43a5826..f17364f 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -73,6 +73,8 @@ static char *mv88e6352_probe(struct device *host_dev, int sw_addr)
ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
if (ret >= 0) {
+ if ((ret & 0xfff0) == 0x1760)
+ return "Marvell 88E6176";
if (ret == 0x3521)
return "Marvell 88E6352 (A0)";
if (ret == 0x3522)
--
1.9.1
^ permalink raw reply related
* [PATCH v3 03/15] net: dsa: Report known silicon revisions for Marvell 88E6131
From: Guenter Roeck @ 2014-10-29 17:44 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
Report known silicon revisions when probing Marvell 88E6131 switches.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- No change
v2:
- No change
drivers/net/dsa/mv88e6131.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 244c735..1230f52 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -21,6 +21,7 @@
#define ID_6085 0x04a0
#define ID_6095 0x0950
#define ID_6131 0x1060
+#define ID_6131_B2 0x1066
static char *mv88e6131_probe(struct device *host_dev, int sw_addr)
{
@@ -32,12 +33,15 @@ static char *mv88e6131_probe(struct device *host_dev, int sw_addr)
ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
if (ret >= 0) {
- ret &= 0xfff0;
- if (ret == ID_6085)
+ int ret_masked = ret & 0xfff0;
+
+ if (ret_masked == ID_6085)
return "Marvell 88E6085";
- if (ret == ID_6095)
+ if (ret_masked == ID_6095)
return "Marvell 88E6095/88E6095F";
- if (ret == ID_6131)
+ if (ret == ID_6131_B2)
+ return "Marvell 88E6131 (B2)";
+ if (ret_masked == ID_6131)
return "Marvell 88E6131";
}
--
1.9.1
^ permalink raw reply related
* [PATCH v3 02/15] net: dsa: Report known silicon revisions for Marvell 88E6060
From: Guenter Roeck @ 2014-10-29 17:44 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
Report known silicon revisions when probing Marvell 88E6060 switches.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- No change
v2:
- No change
drivers/net/dsa/mv88e6060.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 05b0ca3..c29aebe 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -69,8 +69,11 @@ static char *mv88e6060_probe(struct device *host_dev, int sw_addr)
ret = mdiobus_read(bus, sw_addr + REG_PORT(0), 0x03);
if (ret >= 0) {
- ret &= 0xfff0;
if (ret == 0x0600)
+ return "Marvell 88E6060 (A0)";
+ if (ret == 0x0601 || ret == 0x0602)
+ return "Marvell 88E6060 (B0)";
+ if ((ret & 0xfff0) == 0x0600)
return "Marvell 88E6060";
}
--
1.9.1
^ permalink raw reply related
* [PATCH v3 00/15] net: dsa: Fixes and enhancements
From: Guenter Roeck @ 2014-10-29 17:44 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
Patch 01/15 addresses a bug indicated by an an annoying and unhelpful
log message.
Patches 02/15 and 03/15 are minor enhancements, adding support for
known switch revisions.
Patches 04/15 and 05/15 add support for MV88E6352 and MV88E6176.
Patch 06/15 adds support for hardware monitoring, specifically for
reporting the chip temperature, to the dsa subsystem.
Patches 07/15 and 08/15 implement hardware monitoring for MV88E6352,
MV88E6176, MV88E6123, MV88E6161, and MV88E6165.
Patch 09/15 and 10/15 add support for EEPROM access to the DSA subsystem.
Patch 11/15 implements EEPROM access for MV88E6352 and MV88E6176.
Patch 12/15 adds support for reading switch registers to the DSA
subsystem.
Patches 13/15 amd 14/15 implement support for reading switch registers
to the drivers for MV88E6352, MV88E6176, MV88E6123, MV88E6161, and MV88E6165.
Patch 15/15 adds support for reading additional RMON registers to the drivers
for MV88E6352, MV88E6176, MV88E6123, MV88E6161, and MV88E6165.
The series was tested on top of v3.18-rc2 in an x86 system with MV88E6352.
Testing in systems with 88E6131, 88E6060 and MV88E6165 was done earlier
(I don't have access to those systems right now). The series was also build
tested using my build system at http://server.roeck-us.net:8010/builders.
Look into the 'dsa' column for build results.
The series merges cleanly into net-next as of today (10/29).
v3:
- Fix bug in eeprom patches seen if devicetree is enabled:
eeprom-length property is attached to switch devicetree node,
not to dsa node, and there was a compile error.
v2:
- Made reporting chip temperatures through the hwmon subsystem optional
with new Kconfig option
- Changed the hwmon chip name to <network device name>_dsa<index>
- Made EEPROM presence and size configurable through platform and devicetree
data
- Various minor changes and fixes (see individual patches for details)
----------------------------------------------------------------
The following changes since commit cac7f2429872d3733dc3f9915857b1691da2eb2f:
Linux 3.18-rc2 (2014-10-26 16:48:41 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git dsa
for you to fetch changes up to 245472a4f3ca2a68c5632f2c37da41aa2d3fb2f0:
net: dsa: Provide additional RMON statistics (2014-10-29 08:55:37 -0700)
----------------------------------------------------------------
Guenter Roeck (15):
net: dsa: Don't set skb->protocol on outgoing tagged packets
net: dsa: Report known silicon revisions for Marvell 88E6060
net: dsa: Report known silicon revisions for Marvell 88E6131
net: dsa: Add support for Marvell 88E6352
net: dsa/mv88e6352: Add support for MV88E6176
net: dsa: Add support for reporting switch chip temperatures
net: dsa/mv88e6352: Report chip temperature
net: dsa/mv88e6123_61_65: Report chip temperature
net: dsa: Add support for switch EEPROM access
dsa: Add new optional devicetree property to describe EEPROM size
net: dsa/mv88e6352: Implement EEPROM access functions
net: dsa: Add support for reading switch registers with ethtool
net: dsa/mv88e6123_61_65: Add support for reading switch registers
net: dsa/mv88e6352: Add support for reading switch registers
net: dsa: Provide additional RMON statistics
Documentation/devicetree/bindings/net/dsa/dsa.txt | 9 +-
MAINTAINERS | 5 +
drivers/net/dsa/Kconfig | 9 +
drivers/net/dsa/Makefile | 3 +
drivers/net/dsa/mv88e6060.c | 5 +-
drivers/net/dsa/mv88e6123_61_65.c | 73 +-
drivers/net/dsa/mv88e6131.c | 12 +-
drivers/net/dsa/mv88e6352.c | 788 ++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx.c | 53 +-
drivers/net/dsa/mv88e6xxx.h | 15 +
include/net/dsa.h | 33 +
net/dsa/Kconfig | 11 +
net/dsa/dsa.c | 135 ++++
net/dsa/slave.c | 64 ++
net/dsa/tag_dsa.c | 2 -
net/dsa/tag_edsa.c | 2 -
net/dsa/tag_trailer.c | 2 -
17 files changed, 1202 insertions(+), 19 deletions(-)
create mode 100644 drivers/net/dsa/mv88e6352.c
^ permalink raw reply
* [PATCH v3 15/15] net: dsa: Provide additional RMON statistics
From: Guenter Roeck @ 2014-10-29 17:45 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
Display sw_in_discards, sw_in_filtered, and sw_out_filtered for chips
supported by mv88e6123_61_65 and mv88e6352 drivers.
The variables are provided in port registers, not the normal status registers.
Mark by adding 0x100 to the register offset and add special handling code
to mv88e6xxx_get_ethtool_stats.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- No change
v2:
- No change
drivers/net/dsa/mv88e6123_61_65.c | 3 +++
drivers/net/dsa/mv88e6352.c | 3 +++
drivers/net/dsa/mv88e6xxx.c | 26 +++++++++++++++++++++-----
3 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index e2d2e37..9a3f9e0 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -433,6 +433,9 @@ static struct mv88e6xxx_hw_stat mv88e6123_61_65_hw_stats[] = {
{ "hist_256_511bytes", 4, 0x0b, },
{ "hist_512_1023bytes", 4, 0x0c, },
{ "hist_1024_max_bytes", 4, 0x0d, },
+ { "sw_in_discards", 4, 0x110, },
+ { "sw_in_filtered", 2, 0x112, },
+ { "sw_out_filtered", 2, 0x113, },
};
static void
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index d5bbe49..258d9ef 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -539,6 +539,9 @@ static struct mv88e6xxx_hw_stat mv88e6352_hw_stats[] = {
{ "hist_256_511bytes", 4, 0x0b, },
{ "hist_512_1023bytes", 4, 0x0c, },
{ "hist_1024_max_bytes", 4, 0x0d, },
+ { "sw_in_discards", 4, 0x110, },
+ { "sw_in_filtered", 2, 0x112, },
+ { "sw_out_filtered", 2, 0x113, },
};
static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr)
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index c071fde..da558d8 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -485,17 +485,33 @@ void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
for (i = 0; i < nr_stats; i++) {
struct mv88e6xxx_hw_stat *s = stats + i;
u32 low;
- u32 high;
-
+ u32 high = 0;
+
+ if (s->reg >= 0x100) {
+ int ret;
+
+ ret = mv88e6xxx_reg_read(ds, REG_PORT(port),
+ s->reg - 0x100);
+ if (ret < 0)
+ goto error;
+ low = ret;
+ if (s->sizeof_stat == 4) {
+ ret = mv88e6xxx_reg_read(ds, REG_PORT(port),
+ s->reg - 0x100 + 1);
+ if (ret < 0)
+ goto error;
+ high = ret;
+ }
+ data[i] = (((u64)high) << 16) | low;
+ continue;
+ }
mv88e6xxx_stats_read(ds, s->reg, &low);
if (s->sizeof_stat == 8)
mv88e6xxx_stats_read(ds, s->reg + 1, &high);
- else
- high = 0;
data[i] = (((u64)high) << 32) | low;
}
-
+error:
mutex_unlock(&ps->stats_mutex);
}
--
1.9.1
^ permalink raw reply related
* [PATCH v3 14/15] net: dsa/mv88e6352: Add support for reading switch registers
From: Guenter Roeck @ 2014-10-29 17:45 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
Report switch register values to ethtool.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- No change
v2:
- No change
drivers/net/dsa/mv88e6352.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 8a956f9..d5bbe49 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -778,6 +778,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
#endif
.get_eeprom = mv88e6352_get_eeprom,
.set_eeprom = mv88e6352_set_eeprom,
+ .get_regs_len = mv88e6xxx_get_regs_len,
+ .get_regs = mv88e6xxx_get_regs,
};
MODULE_ALIAS("platform:mv88e6352");
--
1.9.1
^ permalink raw reply related
* [PATCH v3 13/15] net: dsa/mv88e6123_61_65: Add support for reading switch registers
From: Guenter Roeck @ 2014-10-29 17:45 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
The infrastructure can now report switch registers to ethtool.
Add support for it to the mv88e6123_61_65 driver.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- No change
v2:
- No change
drivers/net/dsa/mv88e6123_61_65.c | 2 ++
drivers/net/dsa/mv88e6xxx.c | 24 ++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx.h | 3 +++
3 files changed, 29 insertions(+)
diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index 9f43c9b..e2d2e37 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -470,6 +470,8 @@ struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
#ifdef CONFIG_NET_DSA_HWMON
.get_temp = mv88e6123_61_65_get_temp,
#endif
+ .get_regs_len = mv88e6xxx_get_regs_len,
+ .get_regs = mv88e6xxx_get_regs,
};
MODULE_ALIAS("platform:mv88e6123");
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 8e1090b..c071fde 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -499,6 +499,30 @@ void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
mutex_unlock(&ps->stats_mutex);
}
+int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
+{
+ return 32 * sizeof(u16);
+}
+
+void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
+ struct ethtool_regs *regs, void *_p)
+{
+ u16 *p = _p;
+ int i;
+
+ regs->version = 0;
+
+ memset(p, 0xff, 32 * sizeof(u16));
+
+ for (i = 0; i < 32; i++) {
+ int ret;
+
+ ret = mv88e6xxx_reg_read(ds, REG_PORT(port), i);
+ if (ret >= 0)
+ p[i] = ret;
+ }
+}
+
static int __init mv88e6xxx_init(void)
{
#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 29feed0..a0780b0 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -78,6 +78,9 @@ void mv88e6xxx_get_strings(struct dsa_switch *ds,
void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
int nr_stats, struct mv88e6xxx_hw_stat *stats,
int port, uint64_t *data);
+int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port);
+void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
+ struct ethtool_regs *regs, void *_p);
extern struct dsa_switch_driver mv88e6131_switch_driver;
extern struct dsa_switch_driver mv88e6123_61_65_switch_driver;
--
1.9.1
^ permalink raw reply related
* [PATCH v3 12/15] net: dsa: Add support for reading switch registers with ethtool
From: Guenter Roeck @ 2014-10-29 17:45 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
Add support for reading switch registers with 'ethtool -d'.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- No change
v2:
- Do not compare new function pointers against NULL
- Check if get_regs is set before calling it
include/net/dsa.h | 7 +++++++
net/dsa/slave.c | 23 +++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 37856a2..ed3c34b 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -268,6 +268,13 @@ struct dsa_switch_driver {
struct ethtool_eeprom *eeprom, u8 *data);
int (*set_eeprom)(struct dsa_switch *ds,
struct ethtool_eeprom *eeprom, u8 *data);
+
+ /*
+ * Register access.
+ */
+ int (*get_regs_len)(struct dsa_switch *ds, int port);
+ void (*get_regs)(struct dsa_switch *ds, int port,
+ struct ethtool_regs *regs, void *p);
};
void register_switch_driver(struct dsa_switch_driver *type);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ff2fbe7..474f296 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -249,6 +249,27 @@ static void dsa_slave_get_drvinfo(struct net_device *dev,
strlcpy(drvinfo->bus_info, "platform", sizeof(drvinfo->bus_info));
}
+static int dsa_slave_get_regs_len(struct net_device *dev)
+{
+ struct dsa_slave_priv *p = netdev_priv(dev);
+ struct dsa_switch *ds = p->parent;
+
+ if (ds->drv->get_regs_len)
+ return ds->drv->get_regs_len(ds, p->port);
+
+ return -EOPNOTSUPP;
+}
+
+static void
+dsa_slave_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
+{
+ struct dsa_slave_priv *p = netdev_priv(dev);
+ struct dsa_switch *ds = p->parent;
+
+ if (ds->drv->get_regs)
+ ds->drv->get_regs(ds, p->port, regs, _p);
+}
+
static int dsa_slave_nway_reset(struct net_device *dev)
{
struct dsa_slave_priv *p = netdev_priv(dev);
@@ -423,6 +444,8 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
.get_settings = dsa_slave_get_settings,
.set_settings = dsa_slave_set_settings,
.get_drvinfo = dsa_slave_get_drvinfo,
+ .get_regs_len = dsa_slave_get_regs_len,
+ .get_regs = dsa_slave_get_regs,
.nway_reset = dsa_slave_nway_reset,
.get_link = dsa_slave_get_link,
.get_eeprom_len = dsa_slave_get_eeprom_len,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 11/15] net: dsa/mv88e6352: Implement EEPROM access functions
From: Guenter Roeck @ 2014-10-29 17:45 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, Florian Fainelli, Andrew Lunn, linux-kernel,
Guenter Roeck
In-Reply-To: <1414604707-22407-1-git-send-email-linux@roeck-us.net>
MV88E6352 supports read and write access to its configuration eeprom.
There is no means to detect if an EEPROM is connected to the switch.
Also, the switch supports EEPROMs with different sizes, but can not detect
or report the type or size of connected EEPROMs. Therefore, do not implement
the get_eeprom_len callback but depend on platform or devicetree data to
provide information about EEPROM presence and size.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v3:
- No change
v2:
- EEPROM length must now be provided through platform or devicetree data
drivers/net/dsa/mv88e6352.c | 222 +++++++++++++++++++++++++++++++++++++++++++-
drivers/net/dsa/mv88e6xxx.h | 5 +
2 files changed, 224 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 744e6fa..8a956f9 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -22,18 +22,18 @@
#include <net/dsa.h>
#include "mv88e6xxx.h"
-static int mv88e6352_phy_wait(struct dsa_switch *ds)
+static int mv88e6352_wait(struct dsa_switch *ds, int reg, u16 mask)
{
unsigned long timeout = jiffies + HZ / 10;
while (time_before(jiffies, timeout)) {
int ret;
- ret = REG_READ(REG_GLOBAL2, 0x18);
+ ret = REG_READ(REG_GLOBAL2, reg);
if (ret < 0)
return ret;
- if (!(ret & 0x8000))
+ if (!(ret & mask))
return 0;
usleep_range(1000, 2000);
@@ -41,6 +41,21 @@ static int mv88e6352_phy_wait(struct dsa_switch *ds)
return -ETIMEDOUT;
}
+static inline int mv88e6352_phy_wait(struct dsa_switch *ds)
+{
+ return mv88e6352_wait(ds, 0x18, 0x8000);
+}
+
+static inline int mv88e6352_eeprom_load_wait(struct dsa_switch *ds)
+{
+ return mv88e6352_wait(ds, 0x14, 0x0800);
+}
+
+static inline int mv88e6352_eeprom_busy_wait(struct dsa_switch *ds)
+{
+ return mv88e6352_wait(ds, 0x14, 0x8000);
+}
+
static int __mv88e6352_phy_read(struct dsa_switch *ds, int addr, int regnum)
{
int ret;
@@ -429,6 +444,7 @@ static int mv88e6352_setup(struct dsa_switch *ds)
mutex_init(&ps->smi_mutex);
mutex_init(&ps->stats_mutex);
mutex_init(&ps->phy_mutex);
+ mutex_init(&ps->eeprom_mutex);
ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0;
@@ -525,6 +541,204 @@ static struct mv88e6xxx_hw_stat mv88e6352_hw_stats[] = {
{ "hist_1024_max_bytes", 4, 0x0d, },
};
+static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int ret;
+
+ mutex_lock(&ps->eeprom_mutex);
+
+ ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, 0x14,
+ 0xc000 | (addr & 0xff));
+ if (ret < 0)
+ goto error;
+
+ ret = mv88e6352_eeprom_busy_wait(ds);
+ if (ret < 0)
+ goto error;
+
+ ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, 0x15);
+error:
+ mutex_unlock(&ps->eeprom_mutex);
+ return ret;
+}
+
+static int mv88e6352_get_eeprom(struct dsa_switch *ds,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ int offset;
+ int len;
+ int ret;
+
+ offset = eeprom->offset;
+ len = eeprom->len;
+ eeprom->len = 0;
+
+ eeprom->magic = 0xc3ec4951;
+
+ ret = mv88e6352_eeprom_load_wait(ds);
+ if (ret < 0)
+ return ret;
+
+ if (offset & 1) {
+ int word;
+
+ word = mv88e6352_read_eeprom_word(ds, offset >> 1);
+ if (word < 0)
+ return word;
+
+ *data++ = (word >> 8) & 0xff;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ while (len >= 2) {
+ int word;
+
+ word = mv88e6352_read_eeprom_word(ds, offset >> 1);
+ if (word < 0)
+ return word;
+
+ *data++ = word & 0xff;
+ *data++ = (word >> 8) & 0xff;
+
+ offset += 2;
+ len -= 2;
+ eeprom->len += 2;
+ }
+
+ if (len) {
+ int word;
+
+ word = mv88e6352_read_eeprom_word(ds, offset >> 1);
+ if (word < 0)
+ return word;
+
+ *data++ = word & 0xff;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ return 0;
+}
+
+static int mv88e6352_eeprom_is_readonly(struct dsa_switch *ds)
+{
+ int ret;
+
+ ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, 0x14);
+ if (ret < 0)
+ return ret;
+
+ if (!(ret & 0x0400))
+ return -EROFS;
+
+ return 0;
+}
+
+static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr,
+ u16 data)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ int ret;
+
+ mutex_lock(&ps->eeprom_mutex);
+
+ ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, 0x15, data);
+ if (ret < 0)
+ goto error;
+
+ ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, 0x14,
+ 0xb000 | (addr & 0xff));
+ if (ret < 0)
+ goto error;
+
+ ret = mv88e6352_eeprom_busy_wait(ds);
+error:
+ mutex_unlock(&ps->eeprom_mutex);
+ return ret;
+}
+
+static int mv88e6352_set_eeprom(struct dsa_switch *ds,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ int offset;
+ int ret;
+ int len;
+
+ if (eeprom->magic != 0xc3ec4951)
+ return -EINVAL;
+
+ ret = mv88e6352_eeprom_is_readonly(ds);
+ if (ret)
+ return ret;
+
+ offset = eeprom->offset;
+ len = eeprom->len;
+ eeprom->len = 0;
+
+ ret = mv88e6352_eeprom_load_wait(ds);
+ if (ret < 0)
+ return ret;
+
+ if (offset & 1) {
+ int word;
+
+ word = mv88e6352_read_eeprom_word(ds, offset >> 1);
+ if (word < 0)
+ return word;
+
+ word = (*data++ << 8) | (word & 0xff);
+
+ ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
+ if (ret < 0)
+ return ret;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ while (len >= 2) {
+ int word;
+
+ word = *data++;
+ word |= *data++ << 8;
+
+ ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
+ if (ret < 0)
+ return ret;
+
+ offset += 2;
+ len -= 2;
+ eeprom->len += 2;
+ }
+
+ if (len) {
+ int word;
+
+ word = mv88e6352_read_eeprom_word(ds, offset >> 1);
+ if (word < 0)
+ return word;
+
+ word = (word & 0xff00) | *data++;
+
+ ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word);
+ if (ret < 0)
+ return ret;
+
+ offset++;
+ len--;
+ eeprom->len++;
+ }
+
+ return 0;
+}
+
static void
mv88e6352_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
{
@@ -562,6 +776,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
.set_temp_limit = mv88e6352_set_temp_limit,
.get_temp_alarm = mv88e6352_get_temp_alarm,
#endif
+ .get_eeprom = mv88e6352_get_eeprom,
+ .set_eeprom = mv88e6352_set_eeprom,
};
MODULE_ALIAS("platform:mv88e6352");
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index c0ce133..29feed0 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -43,6 +43,11 @@ struct mv88e6xxx_priv_state {
*/
struct mutex phy_mutex;
+ /* This mutex serializes eeprom access for chips with
+ * eeprom support.
+ */
+ struct mutex eeprom_mutex;
+
int id; /* switch product id */
};
--
1.9.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