Netdev List
 help / color / mirror / Atom feed
* Re: [patch net-next 0/2] mlxsw: spectrum_buffers: couple of cosmetic patches
From: David Miller @ 2016-04-15 17:03 UTC (permalink / raw)
  To: jiri; +Cc: netdev, idosch, eladr, yotamg, ogerlitz, David.Laight
In-Reply-To: <1460725778-14655-1-git-send-email-jiri@resnulli.us>

From: Jiri Pirko <jiri@resnulli.us>
Date: Fri, 15 Apr 2016 15:09:36 +0200

> As suggested by David Laight

Series applied.

^ permalink raw reply

* Re: [PATCH for-next V1 0/2] mlx5_core: mlx5_ifc updates
From: Saeed Mahameed @ 2016-04-15 17:10 UTC (permalink / raw)
  To: Saeed Mahameed
  Cc: David S. Miller, Doug Ledford, Linux Netdev List, linux-rdma,
	Or Gerlitz, Matan Barak, Leon Romanovsky, Tal Alon
In-Reply-To: <1460563864-22931-1-git-send-email-saeedm@mellanox.com>

On Wed, Apr 13, 2016 at 7:11 PM, Saeed Mahameed <saeedm@mellanox.com> wrote:
> Hi Dave and Doug
>
> Changes form V0:
>         - 2nd patch commit message fixes.
>
> This series include mlx5_core updates for both net-next and rdma
> trees for 4.7 kernel cycle. This is the only shared code planned
> for 4.7 between rdma and net trees. Hopefully, this will prevent
> future conflicts when merging between ib-next and net-next once
> 4.7 cycle is over and merge window is opened.
>
> Both Mellanox rdma and net submissions will proceed once this series
> is applied into both trees.
>
> Future shared code will be sent to both maintainers as pull requests
> from Mellanox's kernel.org tree.
>
> We have included all the maintainers of respective drivers.
> Kindly review the change and let us know in case of any review comments.
>
> Saeed Mahameed (1):
>   net/mlx5: Update mlx5_ifc hardware features
>
> Tariq Toukan (1):
>   net/mlx5: Fix mlx5 ifc cmd_hca_cap bad offsets
>
>  include/linux/mlx5/mlx5_ifc.h |  253 +++++++++++++++++++++++++++++------------
>  1 files changed, 179 insertions(+), 74 deletions(-)
>
> --

Hi Dave,

This series is still in "Changes Requested" state in patchwork, but
there is nothing to change here.
I will be glad if you give it a shot, it is blocking all of our mlx5
activities for both net and rdma trees.

Thanks,
Saeed.

^ permalink raw reply

* Re: Deleting child qdisc doesn't reset parent to default qdisc?
From: David Miller @ 2016-04-15 17:13 UTC (permalink / raw)
  To: eric.dumazet; +Cc: jhs, jikos, phil, netdev, linux-kernel
In-Reply-To: <1460732328.10638.74.camel@edumazet-glaptop3.roam.corp.google.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 15 Apr 2016 07:58:48 -0700

> Having some hidden qdiscs is the real problem here.

+1

^ permalink raw reply

* [PATCH net-next 0/2] Minor IFF_NO_QUEUE conversion follow-up
From: Phil Sutter @ 2016-04-15 17:14 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

The following series converts two further drivers away from setting
'tx_queue_len = 0' to adding IFF_NO_QUEUE to priv_flags instead.

The first one, rtl8188eu in staging didn't exist back when all drivers
were converted. The second one, openvswitch seems to have slipped through
my grep'ing back then, no idea why.

Phil Sutter (2):
  staging: rtl8188eu: Convert to using IFF_NO_QUEUE
  openvswitch: Convert to using IFF_NO_QUEUE

 drivers/staging/rtl8188eu/os_dep/mon.c | 2 +-
 net/openvswitch/vport-internal_dev.c   | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

-- 
2.8.0

^ permalink raw reply

* [PATCH net-next 2/2] openvswitch: Convert to using IFF_NO_QUEUE
From: Phil Sutter @ 2016-04-15 17:14 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Pravin Shelar
In-Reply-To: <1460740460-12859-1-git-send-email-phil@nwl.cc>

Cc: Pravin Shelar <pshelar@nicira.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 net/openvswitch/vport-internal_dev.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 7c8b90bf0e540..2ee48e447b724 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -165,11 +165,10 @@ static void do_setup(struct net_device *netdev)
 
 	netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
 	netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_OPENVSWITCH |
-			      IFF_PHONY_HEADROOM;
+			      IFF_PHONY_HEADROOM | IFF_NO_QUEUE;
 	netdev->destructor = internal_dev_destructor;
 	netdev->ethtool_ops = &internal_dev_ethtool_ops;
 	netdev->rtnl_link_ops = &internal_dev_link_ops;
-	netdev->tx_queue_len = 0;
 
 	netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST |
 			   NETIF_F_HIGHDMA | NETIF_F_HW_CSUM |
-- 
2.8.0

^ permalink raw reply related

* [PATCH net-next 1/2] staging: rtl8188eu: Convert to using IFF_NO_QUEUE
From: Phil Sutter @ 2016-04-15 17:14 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Jakub Sitnicki
In-Reply-To: <1460740460-12859-1-git-send-email-phil@nwl.cc>

Cc: Jakub Sitnicki <jsitnicki@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 drivers/staging/rtl8188eu/os_dep/mon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/rtl8188eu/os_dep/mon.c b/drivers/staging/rtl8188eu/os_dep/mon.c
index 63bb87593af0c..d976e5e18d50e 100644
--- a/drivers/staging/rtl8188eu/os_dep/mon.c
+++ b/drivers/staging/rtl8188eu/os_dep/mon.c
@@ -155,7 +155,7 @@ static void mon_setup(struct net_device *dev)
 	dev->netdev_ops = &mon_netdev_ops;
 	dev->destructor = free_netdev;
 	ether_setup(dev);
-	dev->tx_queue_len = 0;
+	dev->priv_flags |= IFF_NO_QUEUE;
 	dev->type = ARPHRD_IEEE80211;
 	/*
 	 * Use a locally administered address (IEEE 802)
-- 
2.8.0

^ permalink raw reply related

* Re: [PATCH 1/2] [v4] net: emac: emac gigabit ethernet controller driver
From: Timur Tabi @ 2016-04-15 17:23 UTC (permalink / raw)
  To: Rob Herring
  Cc: Vikram Sethi, Florian Fainelli, netdev,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	linux-arm-msm, Sagar Dharia, Shanker Donthineni,
	Greg Kroah-Hartman, Christopher Covington, Gilad Avidov,
	Andrew Lunn, Bjorn Andersson, Mark Langsdorf, Jon Masters,
	Andy Gross, David S. Miller
In-Reply-To: <CAL_Jsq+1ssgBHERNyBNhz=SDC5j20xjE8PWM5JCgWSvHCnGQyw@mail.gmail.com>

Rob Herring wrote:
> You may only care about the size, but the binding has to handle the
> more complex case. Here's an example
>
> <0x0 0x2 0x0 0x1 0x0>
>
> dma address 0 (cell 0) maps to cpu (parent) address 0x2_00000000 (cell
> 1-2) and the range/size is 4G (cell 3-4).
>
> If you have the same base address, then use the same address. The core
> will calculate the mask based on the size. IIRC, we also handle ~0 as
> a special case to support 4G for #size-cell=1.

So the first thing I noticed is that Gilad had this:

	reg =   <0xfeb20000 0x10000>,
		<0xfeb36000 0x1000>,
		<0xfeb3c000 0x4000>,
		<0xfeb38000 0x400>;
	#address-cells = <0>;

Shouldn't address-cells have been 1 instead?

Ok, let me see if I get this right:

32-bit:

soc {
	#address-cells = <1>;
	#size-cells = <1>;

	emac0: qcom,emac@feb20000 {
		compatible = "qcom,fsm9900-emac";
		#address-cells = <1>;
		#size-cells = <1>;
		reg-names = "base", "csr", "ptp", "sgmii";
		reg =   <0xfeb20000 0x10000>,
			<0xfeb36000 0x1000>,
			<0xfeb3c000 0x4000>,
			<0xfeb38000 0x400>;
		dma-ranges = <0 0 0xffffffff>;
		interrupt-parent = <&emac0>;

64-bit

soc {
	#address-cells = <2>;
	#size-cells = <2>;

	emac0: qcom,emac@feb20000 {
		compatible = "qcom,fsm9900-emac";
		#address-cells = <2>;
		#size-cells = <2>;
		reg-names = "base", "csr", "ptp", "sgmii";
		reg =   <0 0xfeb20000 0 0x10000>,
			<0 0xfeb36000 0 0x1000>,
			<0 0xfeb3c000 0 0x4000>,
			<0 0xfeb38000 0 0x400>;
		dma-ranges = <0 0 0 0 0xffffffff 0xffffffff>;

This seems inelegant, though.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
Forum, a Linux Foundation collaborative project.

^ permalink raw reply

* [PATCH net-next 0/5] tipc: improvements to the link setup algorithm
From: Jon Maloy @ 2016-04-15 17:33 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion

This series addresses some smaller issues regarding the link setup 
algorithm. The first commit fixes a rare bug we have discovered during
testing; the second one may have some future impact on cluster 
scalabilty, while remaining ones can be regarded as cosmetic in
a wider sense of the word.

Jon Maloy (5):
  tipc: guarantee peer bearer id exchange after reboot
  tipc: reduce transmission rate of reset messages when link is down
  tipc: refactor function tipc_link_timeout()
  tipc: ensure that first packets on link are sent in order
  tipc: let first message on link be a state message

 net/tipc/link.c | 55 ++++++++++++++++++++++++++++++-------------------------
 net/tipc/link.h |  2 +-
 net/tipc/msg.h  | 10 ++++++++++
 net/tipc/node.c |  9 ++++++++-
 4 files changed, 49 insertions(+), 27 deletions(-)

-- 
1.9.1


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply

* [PATCH net-next 1/5] tipc: guarantee peer bearer id exchange after reboot
From: Jon Maloy @ 2016-04-15 17:33 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1460741587-13935-1-git-send-email-jon.maloy@ericsson.com>

When a link endpoint is going down locally, e.g., because its interface
is being stopped, it will spontaneously send out a RESET message to
its peer, informing it about this fact. This saves the peer from
detecting the failure via probing, and hence gives both speedier and
less resource consuming failure detection on the peer side.

According to the link FSM, a receiver of a RESET message, ignoring the
reason for it, must now consider the sender ready to come back up, and
starts periodically sending out ACTIVATE messages to the peer in order
to re-establish the link. Also, according to the FSM, the receiver of
an ACTIVATE message can now go directly to state ESTABLISHED and start
sending regular traffic packets. This is a well-proven and robust FSM.

However, in the case of a reboot, there is a small possibilty that link
endpoint on the rebooted node may have been re-created with a new bearer
identity between the moment it sent its (pre-boot) RESET and the moment
it receives the ACTIVATE from the peer. The new bearer identity cannot
be known by the peer according to this scenario, since traffic headers
don't convey such information. This is a problem, because both endpoints
need to know the correct value of the peer's bearer id at any moment in
time in order to be able to produce correct link events for their users.

The only way to guarantee this is to enforce a full setup message
exchange (RESET + ACTIVATE) even after the reboot, since those messages
carry the bearer idientity in their header.

In this commit we do this by introducing and setting a "stopping" bit in
the header of the spontaneously generated RESET messages, informing the
peer that the sender will not be immediately ready to re-establish the
link. A receiver seeing this bit must act as if this were a locally
detected connectivity failure, and hence has to go through a full two-
way setup message exchange before any link can be re-established.

Although never reported, this problem seems to have always been around.

This protocol addition is fully backwards compatible.

Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/link.c | 10 +++++++++-
 net/tipc/msg.h  | 10 ++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 7d2bb3e..8b98faf 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1140,11 +1140,17 @@ int tipc_link_build_ack_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
 void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
 {
 	int mtyp = RESET_MSG;
+	struct sk_buff *skb;
 
 	if (l->state == LINK_ESTABLISHING)
 		mtyp = ACTIVATE_MSG;
 
 	tipc_link_build_proto_msg(l, mtyp, 0, 0, 0, 0, xmitq);
+
+	/* Inform peer that this endpoint is going down if applicable */
+	skb = skb_peek_tail(xmitq);
+	if (skb && (l->state == LINK_RESET))
+		msg_set_peer_stopping(buf_msg(skb), 1);
 }
 
 /* tipc_link_build_nack_msg: prepare link nack message for transmission
@@ -1411,7 +1417,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
 			l->priority = peers_prio;
 
 		/* ACTIVATE_MSG serves as PEER_RESET if link is already down */
-		if ((mtyp == RESET_MSG) || !link_is_up(l))
+		if (msg_peer_stopping(hdr))
+			rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
+		else if ((mtyp == RESET_MSG) || !link_is_up(l))
 			rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT);
 
 		/* ACTIVATE_MSG takes up link if it was already locally reset */
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index f34f639..58bf515 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -715,6 +715,16 @@ static inline void msg_set_redundant_link(struct tipc_msg *m, u32 r)
 	msg_set_bits(m, 5, 12, 0x1, r);
 }
 
+static inline u32 msg_peer_stopping(struct tipc_msg *m)
+{
+	return msg_bits(m, 5, 13, 0x1);
+}
+
+static inline void msg_set_peer_stopping(struct tipc_msg *m, u32 s)
+{
+	msg_set_bits(m, 5, 13, 0x1, s);
+}
+
 static inline char *msg_media_addr(struct tipc_msg *m)
 {
 	return (char *)&m->hdr[TIPC_MEDIA_INFO_OFFSET];
-- 
1.9.1


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related

* [PATCH net-next 2/5] tipc: reduce transmission rate of reset messages when link is down
From: Jon Maloy @ 2016-04-15 17:33 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1460741587-13935-1-git-send-email-jon.maloy@ericsson.com>

When a link is down, it will continuously try to re-establish contact
with the peer by sending out a RESET or an ACTIVATE message at each
timeout interval. The default value for this interval is currently
375 ms. This is wasteful, and may become a problem in very large
clusters with dozens or hundreds of nodes being down simultaneously.

We now introduce a simple backoff algorithm for these cases. The
first five messages are sent at default rate; thereafter a message
is sent only each 16th timer interval.

This will cover the vast majority of link recycling cases, since the
endpoint starting last will transmit at the higher speed, and the link
should normally be established well be before the rate needs to be
reduced.

The only case where we will see a degradation of link re-establishment
times is when the endpoints remain intact, and a glitch in the
transmission media is causing the link reset. We will then experience
a worst-case re-establishing time of 6 seconds, something we deem
acceptable.

Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/link.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 8b98faf..238b125 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -140,6 +140,7 @@ struct tipc_link {
 	char if_name[TIPC_MAX_IF_NAME];
 	u32 priority;
 	char net_plane;
+	u16 rst_cnt;
 
 	/* Failover/synch */
 	u16 drop_point;
@@ -701,8 +702,6 @@ static void link_profile_stats(struct tipc_link *l)
 
 /* tipc_link_timeout - perform periodic task as instructed from node timeout
  */
-/* tipc_link_timeout - perform periodic task as instructed from node timeout
- */
 int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq)
 {
 	int rc = 0;
@@ -730,7 +729,8 @@ int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq)
 		l->silent_intv_cnt++;
 		break;
 	case LINK_RESET:
-		xmit = true;
+		xmit = l->rst_cnt++ <= 4;
+		xmit |= !(l->rst_cnt % 16);
 		mtyp = RESET_MSG;
 		break;
 	case LINK_ESTABLISHING:
@@ -833,6 +833,7 @@ void tipc_link_reset(struct tipc_link *l)
 	l->rcv_nxt = 1;
 	l->acked = 0;
 	l->silent_intv_cnt = 0;
+	l->rst_cnt = 0;
 	l->stats.recv_info = 0;
 	l->stale_count = 0;
 	l->bc_peer_is_up = false;
-- 
1.9.1


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related

* [PATCH net-next 3/5] tipc: refactor function tipc_link_timeout()
From: Jon Maloy @ 2016-04-15 17:33 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1460741587-13935-1-git-send-email-jon.maloy@ericsson.com>

The function tipc_link_timeout() is unnecessary complex, and can
easily be made more readable.

We do that with this commit. The only functional change is that we
remove a redundant test for whether the broadcast link is up or not.

Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/link.c | 36 ++++++++++++++++--------------------
 1 file changed, 16 insertions(+), 20 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 238b125..774ad3c 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -704,37 +704,33 @@ static void link_profile_stats(struct tipc_link *l)
  */
 int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq)
 {
-	int rc = 0;
-	int mtyp = STATE_MSG;
-	bool xmit = false;
-	bool prb = false;
+	int mtyp, rc = 0;
+	bool state = false;
+	bool probe = false;
+	bool setup = false;
 	u16 bc_snt = l->bc_sndlink->snd_nxt - 1;
 	u16 bc_acked = l->bc_rcvlink->acked;
-	bool bc_up = link_is_up(l->bc_rcvlink);
 
 	link_profile_stats(l);
 
 	switch (l->state) {
 	case LINK_ESTABLISHED:
 	case LINK_SYNCHING:
-		if (!l->silent_intv_cnt) {
-			if (bc_up && (bc_acked != bc_snt))
-				xmit = true;
-		} else if (l->silent_intv_cnt <= l->abort_limit) {
-			xmit = true;
-			prb = true;
-		} else {
-			rc |= tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
-		}
-		l->silent_intv_cnt++;
+		if (l->silent_intv_cnt > l->abort_limit)
+			return tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
+		mtyp = STATE_MSG;
+		state = bc_acked != bc_snt;
+		probe = l->silent_intv_cnt;
+		if (probe)
+			l->silent_intv_cnt++;
 		break;
 	case LINK_RESET:
-		xmit = l->rst_cnt++ <= 4;
-		xmit |= !(l->rst_cnt % 16);
+		setup = l->rst_cnt++ <= 4;
+		setup |= !(l->rst_cnt % 16);
 		mtyp = RESET_MSG;
 		break;
 	case LINK_ESTABLISHING:
-		xmit = true;
+		setup = true;
 		mtyp = ACTIVATE_MSG;
 		break;
 	case LINK_PEER_RESET:
@@ -745,8 +741,8 @@ int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq)
 		break;
 	}
 
-	if (xmit)
-		tipc_link_build_proto_msg(l, mtyp, prb, 0, 0, 0, xmitq);
+	if (state || probe || setup)
+		tipc_link_build_proto_msg(l, mtyp, probe, 0, 0, 0, xmitq);
 
 	return rc;
 }
-- 
1.9.1


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related

* [PATCH net-next 4/5] tipc: ensure that first packets on link are sent in order
From: Jon Maloy @ 2016-04-15 17:33 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1460741587-13935-1-git-send-email-jon.maloy@ericsson.com>

In some link establishment scenarios we see that packet #2 may be sent
out before packet #1, forcing the receiver to demand retransmission of
the missing packet. This is harmless, but may cause confusion among
people tracing the packet flow.

Since this is extremely easy to fix, we do so by adding en extra send
call to the bearer immediately after the link has come up.

Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/node.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/tipc/node.c b/net/tipc/node.c
index ace178f..b00e12c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -581,8 +581,12 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
 static void tipc_node_link_up(struct tipc_node *n, int bearer_id,
 			      struct sk_buff_head *xmitq)
 {
+	struct tipc_media_addr *maddr;
+
 	tipc_node_write_lock(n);
 	__tipc_node_link_up(n, bearer_id, xmitq);
+	maddr = &n->links[bearer_id].maddr;
+	tipc_bearer_xmit(n->net, bearer_id, xmitq, maddr);
 	tipc_node_write_unlock(n);
 }
 
-- 
1.9.1


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related

* [PATCH net-next 5/5] tipc: let first message on link be a state message
From: Jon Maloy @ 2016-04-15 17:33 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, Paul Gortmaker, tipc-discussion
In-Reply-To: <1460741587-13935-1-git-send-email-jon.maloy@ericsson.com>

According to the link FSM, a received traffic packet can take a link
from state ESTABLISHING to ESTABLISHED, but the link can still not be
fully set up in one atomic operation. This means that even if the the
very first packet on the link is a traffic packet with sequence number
1 (one), it has to be dropped and retransmitted.

This can be avoided if we let the mentioned packet be preceded by a
LINK_PROTOCOL/STATE message, which takes up the endpoint before the
arrival of the traffic.

We add this small feature in this commit.

This is a fully compatible change.

Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/link.c | 6 +++---
 net/tipc/link.h | 2 +-
 net/tipc/node.c | 5 ++++-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 774ad3c..2e28a7d 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1107,12 +1107,12 @@ static bool tipc_link_release_pkts(struct tipc_link *l, u16 acked)
 	return released;
 }
 
-/* tipc_link_build_ack_msg: prepare link acknowledge message for transmission
+/* tipc_link_build_state_msg: prepare link state message for transmission
  *
  * Note that sending of broadcast ack is coordinated among nodes, to reduce
  * risk of ack storms towards the sender
  */
-int tipc_link_build_ack_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
+int tipc_link_build_state_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
 {
 	if (!l)
 		return 0;
@@ -1222,7 +1222,7 @@ int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
 		if (!tipc_data_input(l, skb, l->inputq))
 			rc |= tipc_link_input(l, skb, l->inputq);
 		if (unlikely(++l->rcv_unacked >= TIPC_MIN_LINK_WIN))
-			rc |= tipc_link_build_ack_msg(l, xmitq);
+			rc |= tipc_link_build_state_msg(l, xmitq);
 		if (unlikely(rc & ~TIPC_LINK_SND_BC_ACK))
 			break;
 	} while ((skb = __skb_dequeue(defq)));
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 6a94175..d7e9d42 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -123,7 +123,7 @@ int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
 int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq);
 int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
 		  struct sk_buff_head *xmitq);
-int tipc_link_build_ack_msg(struct tipc_link *l, struct sk_buff_head *xmitq);
+int tipc_link_build_state_msg(struct tipc_link *l, struct sk_buff_head *xmitq);
 void tipc_link_add_bc_peer(struct tipc_link *snd_l,
 			   struct tipc_link *uc_l,
 			   struct sk_buff_head *xmitq);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index b00e12c..68d9f7b 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -545,6 +545,9 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
 	pr_debug("Established link <%s> on network plane %c\n",
 		 tipc_link_name(nl), tipc_link_plane(nl));
 
+	/* Ensure that a STATE message goes first */
+	tipc_link_build_state_msg(nl, xmitq);
+
 	/* First link? => give it both slots */
 	if (!ol) {
 		*slot0 = bearer_id;
@@ -1283,7 +1286,7 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id
 	/* Broadcast ACKs are sent on a unicast link */
 	if (rc & TIPC_LINK_SND_BC_ACK) {
 		tipc_node_read_lock(n);
-		tipc_link_build_ack_msg(le->link, &xmitq);
+		tipc_link_build_state_msg(le->link, &xmitq);
 		tipc_node_read_unlock(n);
 	}
 
-- 
1.9.1


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z

^ permalink raw reply related

* Re: [PATCH 1/2] [v4] net: emac: emac gigabit ethernet controller driver
From: Bjorn Andersson @ 2016-04-15 17:35 UTC (permalink / raw)
  To: Timur Tabi
  Cc: Vikram Sethi, Florian Fainelli, netdev, linux-kernel, devicetree,
	linux-arm-msm, sdharia, Shanker Donthineni, Greg Kroah-Hartman,
	cov, gavidov, Rob Herring, andrew, Mark Langsdorf, Jon Masters,
	Andy Gross, David S. Miller
In-Reply-To: <57111E33.606@codeaurora.org>

On Fri 15 Apr 10:00 PDT 2016, Timur Tabi wrote:

> Bjorn Andersson wrote:
> >For platform devices being populated via from DT you will pass:
> >of_platform_bus_create()
> >   of_platform_device_create_pdata()
> >     of_dma_configure()
> >
> >Which calls of_dma_get_range() to acquire this information from the
> >dma-ranges property and set up the dma ops and properties.
> 
> This seems excessive.  I have to create a platform bus just to configure the
> DMA mask?  Most drivers just call dma_set_mask and give it a number, and
> that's not device-tree specific.  I also need to come up with a way to get
> this to work on ACPI.
> 
> I just seems like a lot of work only because I need to determine at runtime
> what my DMA mask is.  I also don't see any drivers that call
> of_dma_configure().
> 

Your driver is a platform driver and it's being probed from DT. As such
all this is already taken care of for you, by the core.

The listing is for your reference to know why the dma-ranges property
would affect your device.

Regards,
Bjorn

^ permalink raw reply

* [PATCH net] net: bcmgenet: device stats are unsigned long
From: Eric Dumazet @ 2016-04-15 17:47 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Florian Fainelli

From: Eric Dumazet <edumazet@google.com>

On 64bit kernels, device stats are 64bit wide, not 32bit.

Fixes: 1c1008c793fa4 ("net: bcmgenet: add main driver file")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index cf6445d148ca..44ad1490b472 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -878,7 +878,11 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
 		else
 			p = (char *)priv;
 		p += s->stat_offset;
-		data[i] = *(u32 *)p;
+		if (sizeof(unsigned long) != sizeof(u32) &&
+		    s->stat_sizeof == sizeof(unsigned long))
+			data[i] = *(unsigned long *)p;
+		else
+			data[i] = *(u32 *)p;
 	}
 }
 

^ permalink raw reply related

* [RFC net-next] soreuseport: fix ordering for mixed v4/v6 sockets
From: Craig Gallek @ 2016-04-15 17:58 UTC (permalink / raw)
  To: davem; +Cc: netdev

From: Craig Gallek <kraig@google.com>

With the SO_REUSEPORT socket option, it is possible to create sockets
in the AF_INET and AF_INET6 domains which are bound to the same IPv4 address.
This is only possible with SO_REUSEPORT and when not using IPV6_V6ONLY on
the AF_INET6 sockets.

Prior to the commits referenced below, an incoming IPv4 packet would
always be routed to a socket of type AF_INET when this mixed-mode was used.
After those changes, the same packet would be routed to the most recently
bound socket (if this happened to be an AF_INET6 socket, it would
have an IPv4 mapped IPv6 address).

The change in behavior occurred because the recent SO_REUSEPORT optimizations
short-circuit the socket scoring logic as soon as they find a match.  They
did not take into account the scoring logic that favors AF_INET sockets
over AF_INET6 sockets in the event of a tie.

To fix this problem, this patch changes the insertion order of AF_INET
and AF_INET6 addresses in the TCP and UDP socket lists when the sockets
have SO_REUSEPORT set.  AF_INET sockets will be inserted at the head of the
list and AF_INET6 sockets with SO_REUSEPORT set will always be inserted at
the tail of the list.  This will force AF_INET sockets to always be
considered first.

Fixes: e32ea7e74727 ("soreuseport: fast reuseport UDP socket selection")
Fixes: 125e80b88687 ("soreuseport: fast reuseport TCP socket selection")
Signed-off-by: Craig Gallek <kraig@google.com>
---
A similar patch was recently accepted to the net tree:
d894ba18d4e4 ("soreuseport: fix ordering for mixed v4/v6 sockets")

However, two patches have already been submitted to net-next which
will conflict when net is merged back into net-next:
ca065d0cf80f ("udp: no longer use SLAB_DESTROY_BY_RCU")
3b24d854cb35 ("tcp/dccp: do not touch listener sk_refcnt under synflood")

These net-next patches change the TCP and UDP socket list datastructures
from hlist_nulls to hlists.  The fix for net needed to extend the
hlist_nulls API, the fix for net-next will need to extend the hlist API.
Further, the TCP stack now directly uses the hlist API rather than
the sk_* helper functions that wrapped them.

This RFC patch is a re-implementation of the net patch for the net-next
tree.  It could be used if the net patch is first reverted before merging to
net-next or simply used as a reference to correct the merge conflict.
The test submitted with the initial patch should work in both cases.
---
 include/linux/rculist.h    | 35 +++++++++++++++++++++++++++++++++++
 include/net/sock.h         |  6 +++++-
 net/ipv4/inet_hashtables.c |  6 +++++-
 net/ipv4/udp.c             |  9 +++++++--
 4 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index 17d4f849c65e..7c5a8f7b0cb1 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -542,6 +542,41 @@ static inline void hlist_add_behind_rcu(struct hlist_node *n,
 		n->next->pprev = &n->next;
 }
 
+/**
+ * hlist_add_tail_rcu
+ * @n: the element to add to the hash list.
+ * @h: the list to add to.
+ *
+ * Description:
+ * Adds the specified element to the end of the specified hlist_nulls,
+ * while permitting racing traversals.  NOTE: tail insertion requires
+ * list traversal.
+ *
+ * The caller must take whatever precautions are necessary
+ * (such as holding appropriate locks) to avoid racing
+ * with another list-mutation primitive, such as hlist_add_head_rcu()
+ * or hlist_del_rcu(), running on this same list.
+ * However, it is perfectly legal to run concurrently with
+ * the _rcu list-traversal primitives, such as
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
+ * problems on Alpha CPUs.  Regardless of the type of CPU, the
+ * list-traversal primitive must be guarded by rcu_read_lock().
+ */
+
+static inline void hlist_add_tail_rcu(struct hlist_node *n,
+					struct hlist_head *h)
+{
+	struct hlist_node *i, *last = NULL;
+
+	for (i = hlist_first_rcu(h); i; i = hlist_next_rcu(i))
+		last = i;
+
+	if (last)
+		hlist_add_behind_rcu(n, last);
+	else
+		hlist_add_head_rcu(n, h);
+}
+
 #define __hlist_for_each_rcu(pos, head)				\
 	for (pos = rcu_dereference(hlist_first_rcu(head));	\
 	     pos;						\
diff --git a/include/net/sock.h b/include/net/sock.h
index d997ec13a643..2b620c79f531 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -630,7 +630,11 @@ static inline void sk_add_node(struct sock *sk, struct hlist_head *list)
 static inline void sk_add_node_rcu(struct sock *sk, struct hlist_head *list)
 {
 	sock_hold(sk);
-	hlist_add_head_rcu(&sk->sk_node, list);
+	if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport &&
+	    sk->sk_family == AF_INET6)
+		hlist_add_tail_rcu(&sk->sk_node, list);
+	else
+		hlist_add_head_rcu(&sk->sk_node, list);
 }
 
 static inline void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list)
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index fcadb670f50b..b76b0d7e59c1 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -479,7 +479,11 @@ int __inet_hash(struct sock *sk, struct sock *osk,
 		if (err)
 			goto unlock;
 	}
-	hlist_add_head_rcu(&sk->sk_node, &ilb->head);
+	if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport &&
+		sk->sk_family == AF_INET6)
+		hlist_add_tail_rcu(&sk->sk_node, &ilb->head);
+	else
+		hlist_add_head_rcu(&sk->sk_node, &ilb->head);
 	sock_set_flag(sk, SOCK_RCU_FREE);
 	sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
 unlock:
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index f1863136d3e4..fe294b320c83 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -336,8 +336,13 @@ found:
 
 		hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
 		spin_lock(&hslot2->lock);
-		hlist_add_head_rcu(&udp_sk(sk)->udp_portaddr_node,
-					 &hslot2->head);
+		if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport &&
+			sk->sk_family == AF_INET6)
+			hlist_add_tail_rcu(&udp_sk(sk)->udp_portaddr_node,
+					   &hslot2->head);
+		else
+			hlist_add_head_rcu(&udp_sk(sk)->udp_portaddr_node,
+					   &hslot2->head);
 		hslot2->count++;
 		spin_unlock(&hslot2->lock);
 	}
-- 
2.8.0.rc3.226.g39d4020

^ permalink raw reply related

* Re: [PATCH pci] pci: Add helper function to set VPD size
From: Bjorn Helgaas @ 2016-04-15 18:13 UTC (permalink / raw)
  To: Hariprasad Shenai
  Cc: bhelgaas, davem, linux-pci, netdev, Casey Leedom, Steve Wise,
	nirranjan, santosh, Hannes Reinecke, Ariel Elior, linux-kernel
In-Reply-To: <1460657525-17551-1-git-send-email-hariprasad@chelsio.com>

[+cc Hannes, Ariel, LKML]

On Thu, Apr 14, 2016 at 11:42:05PM +0530, Hariprasad Shenai wrote:
> commit 104daa71b396 ("PCI: Determine actual VPD size on first access")
> introduced a regression in cxgb4 driver and used to fail in pci probe.
> 
> The problem is stemming from the fact that the Chelsio adapters actually
> have two VPD structures stored in the VPD. An abbreviated on at Offset 0x0
> and the complete VPD at Offset 0x400. The abbreviated one only contains
> the PN, SN and EC Keywords, while the complete VPD contains those plus
> various adapter constants contained in V0, V1, etc. And it also contains
> the Base Ethernet MAC Address in the "NA" Keyword which the cxgb4 driver
> needs when it can't contact the adapter firmware. (We don't have the "NA"
> Keywork in the VPD Structure at Offset 0x0 because that's not an allowed
> VPD Keyword in the PCI-E 3.0 specification.)
> 
> With the new code, the computed size of the VPD is 0x200 and so our efforts
> to read the VPD at Offset 0x400 silently fails. We check the result of the
> read looking for a signature 0x82 byte but we're checking against random
> stack garbage.
> 
> The fix is to add a PCI helper function to set the VPD size, so the
> driver can expicitly set the exact size of the VPD.
> 
> Fixes commit 104daa71b396 ("PCI: Determine actual VPD size on first access")
> 
> Signed-off-by: Casey Leedom <leedom@chelsio.com>
> Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>

This looks good to me.  I applied it with the following changes to my
for-linus branch for v4.6:

  - Split into two patches (PCI core and Chelsio).  I did this because
    of the concern that bnx2x might also be broken.  But I looked
    again, and I think bnx2x is fine because the driver computes the
    size the same way the PCI core does, and I think it only reads up
    to that size.  It'd be good if the bnx2x folks could verify this.

  - Renamed pci_set_size_vpd() to pci_set_vpd_size() so it reads
    better.

  - Changed pci_set_vpd_size() from ssize_t to int, since it only
    returns zero or a negative errno.  Also, t4_get_raw_vpd_params()
    puts the return value into an int.

I'll append the patches as applied at the end.

> ---
>  drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 10 +++++++
>  drivers/pci/access.c                       | 42 ++++++++++++++++++++++++++++++
>  drivers/pci/pci.h                          |  1 +
>  include/linux/pci.h                        |  1 +
>  4 files changed, 54 insertions(+)
> 
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
> index cc1736bece0f..2033159e26a5 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
> @@ -2557,6 +2557,7 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
>  }
>  
>  #define EEPROM_STAT_ADDR   0x7bfc
> +#define VPD_SIZE           0x800
>  #define VPD_BASE           0x400
>  #define VPD_BASE_OLD       0
>  #define VPD_LEN            1024
> @@ -2594,6 +2595,15 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p)
>  	if (!vpd)
>  		return -ENOMEM;
>  
> +	/* We have two VPD data structures stored in the adapter VPD area.
> +	 * By default, Linux calculates the size of the VPD area by traversing
> +	 * the first VPD area at offset 0x0, so we need to tell the OS what
> +	 * our real VPD size is.
> +	 */
> +	ret = pci_set_size_vpd(adapter->pdev, VPD_SIZE);
> +	if (ret < 0)
> +		goto out;
> +
>  	/* Card information normally starts at VPD_BASE but early cards had
>  	 * it at 0.
>  	 */
> diff --git a/drivers/pci/access.c b/drivers/pci/access.c
> index 01b9d0a00abc..e69b3877bd37 100644
> --- a/drivers/pci/access.c
> +++ b/drivers/pci/access.c
> @@ -275,6 +275,19 @@ ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void
>  }
>  EXPORT_SYMBOL(pci_write_vpd);
>  
> +/**
> + * pci_set_size_vpd - Set size of Vital Product Data space
> + * @dev:	pci device struct
> + * @len:	size of vpd space
> + */
> +ssize_t pci_set_size_vpd(struct pci_dev *dev, size_t len)
> +{
> +	if (!dev->vpd || !dev->vpd->ops)
> +		return -ENODEV;
> +	return dev->vpd->ops->set_size(dev, len);
> +}
> +EXPORT_SYMBOL(pci_set_size_vpd);
> +
>  #define PCI_VPD_MAX_SIZE (PCI_VPD_ADDR_MASK + 1)
>  
>  /**
> @@ -498,9 +511,23 @@ out:
>  	return ret ? ret : count;
>  }
>  
> +static ssize_t pci_vpd_set_size(struct pci_dev *dev, size_t len)
> +{
> +	struct pci_vpd *vpd = dev->vpd;
> +
> +	if (len == 0 || len > PCI_VPD_MAX_SIZE)
> +		return -EIO;
> +
> +	vpd->valid = 1;
> +	vpd->len = len;
> +
> +	return 0;
> +}
> +
>  static const struct pci_vpd_ops pci_vpd_ops = {
>  	.read = pci_vpd_read,
>  	.write = pci_vpd_write,
> +	.set_size = pci_vpd_set_size,
>  };
>  
>  static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
> @@ -533,9 +560,24 @@ static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
>  	return ret;
>  }
>  
> +static ssize_t pci_vpd_f0_set_size(struct pci_dev *dev, size_t len)
> +{
> +	struct pci_dev *tdev = pci_get_slot(dev->bus,
> +					    PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
> +	ssize_t ret;
> +
> +	if (!tdev)
> +		return -ENODEV;
> +
> +	ret = pci_set_size_vpd(tdev, len);
> +	pci_dev_put(tdev);
> +	return ret;
> +}
> +
>  static const struct pci_vpd_ops pci_vpd_f0_ops = {
>  	.read = pci_vpd_f0_read,
>  	.write = pci_vpd_f0_write,
> +	.set_size = pci_vpd_f0_set_size,
>  };
>  
>  int pci_vpd_init(struct pci_dev *dev)
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index d0fb93481573..8239d186f1ed 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -97,6 +97,7 @@ static inline bool pci_has_subordinate(struct pci_dev *pci_dev)
>  struct pci_vpd_ops {
>  	ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
>  	ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
> +	ssize_t (*set_size)(struct pci_dev *dev, size_t len);
>  };
>  
>  struct pci_vpd {
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 004b8133417d..1ab1b7458a8b 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1111,6 +1111,7 @@ void pci_unlock_rescan_remove(void);
>  /* Vital product data routines */
>  ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
>  ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
> +ssize_t pci_set_size_vpd(struct pci_dev *dev, size_t len);
>  
>  /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
>  resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx);
> -- 
> 2.3.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

commit cb92148b58a49455f3a7204eba3aee09a8b7683c
Author: Hariprasad Shenai <hariprasad@chelsio.com>
Date:   Fri Apr 15 13:00:11 2016 -0500

    PCI: Add pci_set_vpd_size() to set VPD size
    
    After 104daa71b396 ("PCI: Determine actual VPD size on first access"), the
    PCI core computes the valid VPD size by parsing the VPD starting at offset
    0x0.  We don't attempt to read past that valid size because that causes
    some devices to crash.
    
    However, some devices do have data past that valid size.  For example,
    Chelsio adapters contain two VPD structures, and the driver needs both of
    them.
    
    Add pci_set_vpd_size().  If a driver knows it is safe to read past the end
    of the VPD data structure at offset 0, it can use pci_set_vpd_size() to
    allow access to as much data as it needs.
    
    [bhelgaas: changelog, split patches, rename to pci_set_vpd_size() and
    return int (not ssize_t)]
    Fixes: 104daa71b396 ("PCI: Determine actual VPD size on first access")
    Tested-by: Steve Wise <swise@opengridcomputing.com>
    Signed-off-by: Casey Leedom <leedom@chelsio.com>
    Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 01b9d0a..d11cdbb 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -275,6 +275,19 @@ ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void
 }
 EXPORT_SYMBOL(pci_write_vpd);
 
+/**
+ * pci_set_vpd_size - Set size of Vital Product Data space
+ * @dev:	pci device struct
+ * @len:	size of vpd space
+ */
+int pci_set_vpd_size(struct pci_dev *dev, size_t len)
+{
+	if (!dev->vpd || !dev->vpd->ops)
+		return -ENODEV;
+	return dev->vpd->ops->set_size(dev, len);
+}
+EXPORT_SYMBOL(pci_set_vpd_size);
+
 #define PCI_VPD_MAX_SIZE (PCI_VPD_ADDR_MASK + 1)
 
 /**
@@ -498,9 +511,23 @@ out:
 	return ret ? ret : count;
 }
 
+static int pci_vpd_set_size(struct pci_dev *dev, size_t len)
+{
+	struct pci_vpd *vpd = dev->vpd;
+
+	if (len == 0 || len > PCI_VPD_MAX_SIZE)
+		return -EIO;
+
+	vpd->valid = 1;
+	vpd->len = len;
+
+	return 0;
+}
+
 static const struct pci_vpd_ops pci_vpd_ops = {
 	.read = pci_vpd_read,
 	.write = pci_vpd_write,
+	.set_size = pci_vpd_set_size,
 };
 
 static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
@@ -533,9 +560,24 @@ static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
 	return ret;
 }
 
+static int pci_vpd_f0_set_size(struct pci_dev *dev, size_t len)
+{
+	struct pci_dev *tdev = pci_get_slot(dev->bus,
+					    PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+	int ret;
+
+	if (!tdev)
+		return -ENODEV;
+
+	ret = pci_set_vpd_size(tdev, len);
+	pci_dev_put(tdev);
+	return ret;
+}
+
 static const struct pci_vpd_ops pci_vpd_f0_ops = {
 	.read = pci_vpd_f0_read,
 	.write = pci_vpd_f0_write,
+	.set_size = pci_vpd_f0_set_size,
 };
 
 int pci_vpd_init(struct pci_dev *dev)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index d0fb934..a814bbb 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -97,6 +97,7 @@ static inline bool pci_has_subordinate(struct pci_dev *pci_dev)
 struct pci_vpd_ops {
 	ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
 	ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
+	int (*set_size)(struct pci_dev *dev, size_t len);
 };
 
 struct pci_vpd {
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 004b813..932ec74 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1111,6 +1111,7 @@ void pci_unlock_rescan_remove(void);
 /* Vital product data routines */
 ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
 ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
+int pci_set_vpd_size(struct pci_dev *dev, size_t len);
 
 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
 resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx);

commit 67e658794ca191b3221b143f2a1c10d002c40bc8
Author: Hariprasad Shenai <hariprasad@chelsio.com>
Date:   Fri Apr 15 13:00:18 2016 -0500

    cxgb4: Set VPD size so we can read both VPD structures
    
    Chelsio adapters have two VPD structures stored in the VPD:
    
      - offset 0x000: an abbreviated VPD, and
      - offset 0x400: the complete VPD.
    
    After 104daa71b396 ("PCI: Determine actual VPD size on first access"), the
    PCI core computes the valid VPD size by parsing the VPD starting at offset
    0x0.  That size only includes the abbreviated VPD structure, so reads of
    the complete VPD at 0x400 fail.
    
    Explicitly set the VPD size with pci_set_vpd_size() so the driver can read
    both VPD structures.
    
    [bhelgaas: changelog, split patches, rename to pci_set_vpd_size() and
    return int (not ssize_t)]
    Fixes: 104daa71b396 ("PCI: Determine actual VPD size on first access")
    Tested-by: Steve Wise <swise@opengridcomputing.com>
    Signed-off-by: Casey Leedom <leedom@chelsio.com>
    Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index cc1736b..c7efb11 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -2557,6 +2557,7 @@ void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
 }
 
 #define EEPROM_STAT_ADDR   0x7bfc
+#define VPD_SIZE           0x800
 #define VPD_BASE           0x400
 #define VPD_BASE_OLD       0
 #define VPD_LEN            1024
@@ -2594,6 +2595,15 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p)
 	if (!vpd)
 		return -ENOMEM;
 
+	/* We have two VPD data structures stored in the adapter VPD area.
+	 * By default, Linux calculates the size of the VPD area by traversing
+	 * the first VPD area at offset 0x0, so we need to tell the OS what
+	 * our real VPD size is.
+	 */
+	ret = pci_set_vpd_size(adapter->pdev, VPD_SIZE);
+	if (ret < 0)
+		goto out;
+
 	/* Card information normally starts at VPD_BASE but early cards had
 	 * it at 0.
 	 */

^ permalink raw reply related

* Re: [PATCH 1/2] [v4] net: emac: emac gigabit ethernet controller driver
From: Timur Tabi @ 2016-04-15 18:22 UTC (permalink / raw)
  To: Bjorn Andersson
  Cc: Vikram Sethi, Florian Fainelli, netdev, linux-kernel, devicetree,
	linux-arm-msm, sdharia, Shanker Donthineni, Greg Kroah-Hartman,
	cov, gavidov, Rob Herring, andrew, Mark Langsdorf, Jon Masters,
	Andy Gross, David S. Miller
In-Reply-To: <20160415173529.GY391@tuxbot>

Bjorn Andersson wrote:
> Your driver is a platform driver and it's being probed from DT. As such
> all this is already taken care of for you, by the core.
>
> The listing is for your reference to know why the dma-ranges property
> would affect your device.

Ah, sorry. I misunderstood what you meant by "you will pass".

Coincidentally, it looks like Lorenzo Pieralisi has posted patches the 
ACPI equivalent just yesterday: https://lkml.org/lkml/2016/4/14/694

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
Forum, a Linux Foundation collaborative project.

^ permalink raw reply

* Re: [PATCH 2/2] rtlwifi: Fix reusable codes in core.c
From: Kalle Valo @ 2016-04-15 18:25 UTC (permalink / raw)
  To: Byeoungwook Kim
  Cc: Larry.Finger, chaoming_li, linux-wireless, netdev, linux-kernel
In-Reply-To: <20160203020139.GA13619@gmail.com>

Byeoungwook Kim <quddnr145@gmail.com> writes:

> rtl_*_delay() functions were reused same codes about addr variable.
> So i have converted to rtl_addr_delay() from code about addr variable.
>
> Signed-off-by: Byeoungwook Kim <quddnr145@gmail.com>
> Reviewed-by: Julian Calaby <julian.calaby@gmail.com>

Doesn't apply:

Applying: rtlwifi: Fix reusable codes in core.c
fatal: sha1 information is lacking or useless (drivers/net/wireless/realtek/rtlwifi/core.c).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0001 rtlwifi: Fix reusable codes in core.c

Please rebase and resend.

-- 
Kalle Valo

^ permalink raw reply

* [PATCH net-next 0/7] net: dsa: mv88e6xxx: factorize switch info
From: Vivien Didelot @ 2016-04-15 18:25 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

This patchset factorizes drastically the mv88e6xxx code by sharing a new
extendable info structure to store static data such as switch family,
product number, number of ports, number of databases and the name.

The next step is to add a "features" bitmap member to the info structure
in order to simplify the shared code with a feature-based logic instead
of checking their family/ID.

This is a step forward having a single mv88e6xxx driver supporting many
similar devices, like any usual Linux driver.

Vivien Didelot (7):
  net: dsa: mv88e6xxx: drop double ds assignment
  net: dsa: mv88e6xxx: drop revision probing
  net: dsa: mv88e6xxx: add switch info
  net: dsa: mv88e6xxx: add family to info
  net: dsa: mv88e6xxx: add number of ports to info
  net: dsa: mv88e6xxx: add number of database to info
  net: dsa: mv88e6xxx: drop switch id

 drivers/net/dsa/mv88e6123.c |  29 +------
 drivers/net/dsa/mv88e6131.c |  32 ++-----
 drivers/net/dsa/mv88e6171.c |  15 ++--
 drivers/net/dsa/mv88e6352.c |  24 ++----
 drivers/net/dsa/mv88e6xxx.c | 201 ++++++++++++--------------------------------
 drivers/net/dsa/mv88e6xxx.h |  83 +++++++-----------
 6 files changed, 106 insertions(+), 278 deletions(-)

-- 
2.8.0

^ permalink raw reply

* [PATCH net-next 1/7] net: dsa: mv88e6xxx: drop double ds assignment
From: Vivien Didelot @ 2016-04-15 18:25 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot
In-Reply-To: <1460744750-13896-1-git-send-email-vivien.didelot@savoirfairelinux.com>

Every driver assigns ps->ds even though it gets assigned in the shared
mv88e6xxx_setup_common function. Kill redundancy.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c | 2 --
 drivers/net/dsa/mv88e6131.c | 2 --
 drivers/net/dsa/mv88e6171.c | 2 --
 drivers/net/dsa/mv88e6352.c | 2 --
 4 files changed, 8 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index c34283d..88a812d 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -76,8 +76,6 @@ static int mv88e6123_setup(struct dsa_switch *ds)
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
-	ps->ds = ds;
-
 	ret = mv88e6xxx_setup_common(ds);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index f5d75fc..6b2bcb0 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -94,8 +94,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
-	ps->ds = ds;
-
 	ret = mv88e6xxx_setup_common(ds);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index f562250..40222b0 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -72,8 +72,6 @@ static int mv88e6171_setup(struct dsa_switch *ds)
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
-	ps->ds = ds;
-
 	ret = mv88e6xxx_setup_common(ds);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index e54ee27..dbd920e 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -84,8 +84,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
-	ps->ds = ds;
-
 	ret = mv88e6xxx_setup_common(ds);
 	if (ret < 0)
 		return ret;
-- 
2.8.0

^ permalink raw reply related

* [PATCH net-next 2/7] net: dsa: mv88e6xxx: drop revision probing
From: Vivien Didelot @ 2016-04-15 18:25 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot
In-Reply-To: <1460744750-13896-1-git-send-email-vivien.didelot@savoirfairelinux.com>

There is no point in having special case for the revision when probing a
switch model. The code gets cluttered with unnecessary defines, and
leads to errors when code such as mv88e6131_setup compares
PORT_SWITCH_ID_6131_B2 to ps->id which mask the revision.

Drop every revision definitions, add a ps->rev variable for eventual
runtime checking and lookup only the product number.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  6 ------
 drivers/net/dsa/mv88e6131.c |  2 --
 drivers/net/dsa/mv88e6352.c |  6 ------
 drivers/net/dsa/mv88e6xxx.c | 19 ++++++-------------
 drivers/net/dsa/mv88e6xxx.h | 15 ++-------------
 5 files changed, 8 insertions(+), 40 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 88a812d..00c1121 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -19,14 +19,8 @@
 
 static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
 	{ PORT_SWITCH_ID_6123, "Marvell 88E6123" },
-	{ PORT_SWITCH_ID_6123_A1, "Marvell 88E6123 (A1)" },
-	{ PORT_SWITCH_ID_6123_A2, "Marvell 88E6123 (A2)" },
 	{ PORT_SWITCH_ID_6161, "Marvell 88E6161" },
-	{ PORT_SWITCH_ID_6161_A1, "Marvell 88E6161 (A1)" },
-	{ PORT_SWITCH_ID_6161_A2, "Marvell 88E6161 (A2)" },
 	{ PORT_SWITCH_ID_6165, "Marvell 88E6165" },
-	{ PORT_SWITCH_ID_6165_A1, "Marvell 88E6165 (A1)" },
-	{ PORT_SWITCH_ID_6165_A2, "Marvell 88e6165 (A2)" },
 };
 
 static char *mv88e6123_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 6b2bcb0..df534da 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -21,7 +21,6 @@ static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
 	{ PORT_SWITCH_ID_6085, "Marvell 88E6085" },
 	{ PORT_SWITCH_ID_6095, "Marvell 88E6095/88E6095F" },
 	{ PORT_SWITCH_ID_6131, "Marvell 88E6131" },
-	{ PORT_SWITCH_ID_6131_B2, "Marvell 88E6131 (B2)" },
 	{ PORT_SWITCH_ID_6185, "Marvell 88E6185" },
 };
 
@@ -109,7 +108,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
 		ps->num_ports = 11;
 		break;
 	case PORT_SWITCH_ID_6131:
-	case PORT_SWITCH_ID_6131_B2:
 		ps->num_ports = 8;
 		break;
 	default:
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index dbd920e..30fc5f6 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -27,14 +27,8 @@ static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
 	{ PORT_SWITCH_ID_6176, "Marvell 88E6176" },
 	{ PORT_SWITCH_ID_6240, "Marvell 88E6240" },
 	{ PORT_SWITCH_ID_6320, "Marvell 88E6320" },
-	{ PORT_SWITCH_ID_6320_A1, "Marvell 88E6320 (A1)" },
-	{ PORT_SWITCH_ID_6320_A2, "Marvell 88e6320 (A2)" },
 	{ PORT_SWITCH_ID_6321, "Marvell 88E6321" },
-	{ PORT_SWITCH_ID_6321_A1, "Marvell 88E6321 (A1)" },
-	{ PORT_SWITCH_ID_6321_A2, "Marvell 88e6321 (A2)" },
 	{ PORT_SWITCH_ID_6352, "Marvell 88E6352" },
-	{ PORT_SWITCH_ID_6352_A0, "Marvell 88E6352 (A0)" },
-	{ PORT_SWITCH_ID_6352_A1, "Marvell 88E6352 (A1)" },
 };
 
 static char *mv88e6352_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 9985a0c..ad29040 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2663,11 +2663,15 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 int mv88e6xxx_setup_common(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	int id;
 
 	ps->ds = ds;
 	mutex_init(&ps->smi_mutex);
 
-	ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0;
+	id = REG_READ(REG_PORT(0), PORT_SWITCH_ID);
+
+	ps->id = id & 0xfff0;
+	ps->rev = id & 0xf;
 
 	INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
 
@@ -3083,19 +3087,8 @@ static char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
 
 	/* Look up the exact switch ID */
 	for (i = 0; i < num; ++i)
-		if (table[i].id == ret)
-			return table[i].name;
-
-	/* Look up only the product number */
-	for (i = 0; i < num; ++i) {
-		if (table[i].id == (ret & PORT_SWITCH_ID_PROD_NUM_MASK)) {
-			dev_warn(&bus->dev,
-				 "unknown revision %d, using base switch 0x%x\n",
-				 ret & PORT_SWITCH_ID_REV_MASK,
-				 ret & PORT_SWITCH_ID_PROD_NUM_MASK);
+		if (table[i].id == (ret & 0xfff0))
 			return table[i].name;
-		}
-	}
 
 	return NULL;
 }
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 5d27dec..7304f88 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -84,18 +84,11 @@
 #define PORT_SWITCH_ID_6121	0x1040
 #define PORT_SWITCH_ID_6122	0x1050
 #define PORT_SWITCH_ID_6123	0x1210
-#define PORT_SWITCH_ID_6123_A1	0x1212
-#define PORT_SWITCH_ID_6123_A2	0x1213
 #define PORT_SWITCH_ID_6131	0x1060
-#define PORT_SWITCH_ID_6131_B2	0x1066
 #define PORT_SWITCH_ID_6152	0x1a40
 #define PORT_SWITCH_ID_6155	0x1a50
 #define PORT_SWITCH_ID_6161	0x1610
-#define PORT_SWITCH_ID_6161_A1	0x1612
-#define PORT_SWITCH_ID_6161_A2	0x1613
 #define PORT_SWITCH_ID_6165	0x1650
-#define PORT_SWITCH_ID_6165_A1	0x1652
-#define PORT_SWITCH_ID_6165_A2	0x1653
 #define PORT_SWITCH_ID_6171	0x1710
 #define PORT_SWITCH_ID_6172	0x1720
 #define PORT_SWITCH_ID_6175	0x1750
@@ -104,16 +97,10 @@
 #define PORT_SWITCH_ID_6185	0x1a70
 #define PORT_SWITCH_ID_6240	0x2400
 #define PORT_SWITCH_ID_6320	0x1150
-#define PORT_SWITCH_ID_6320_A1	0x1151
-#define PORT_SWITCH_ID_6320_A2	0x1152
 #define PORT_SWITCH_ID_6321	0x3100
-#define PORT_SWITCH_ID_6321_A1	0x3101
-#define PORT_SWITCH_ID_6321_A2	0x3102
 #define PORT_SWITCH_ID_6350	0x3710
 #define PORT_SWITCH_ID_6351	0x3750
 #define PORT_SWITCH_ID_6352	0x3520
-#define PORT_SWITCH_ID_6352_A0	0x3521
-#define PORT_SWITCH_ID_6352_A1	0x3522
 #define PORT_CONTROL		0x04
 #define PORT_CONTROL_USE_CORE_TAG	BIT(15)
 #define PORT_CONTROL_DROP_ON_LOCK	BIT(14)
@@ -397,6 +384,8 @@ struct mv88e6xxx_priv_port {
 };
 
 struct mv88e6xxx_priv_state {
+	int rev;
+
 	/* The dsa_switch this private structure is related to */
 	struct dsa_switch *ds;
 
-- 
2.8.0

^ permalink raw reply related

* [PATCH net-next 3/7] net: dsa: mv88e6xxx: add switch info
From: Vivien Didelot @ 2016-04-15 18:25 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot
In-Reply-To: <1460744750-13896-1-git-send-email-vivien.didelot@savoirfairelinux.com>

Add a new switch info structure which will be later extended to store
switch models static information, such as product number, name, number
of ports, number of databases, etc.

Merge the lookup function in the probing code, so that we avoid multiple
checking of the MII bus, as well a multiple ID reading.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  8 +++---
 drivers/net/dsa/mv88e6131.c | 10 +++----
 drivers/net/dsa/mv88e6171.c | 10 +++----
 drivers/net/dsa/mv88e6352.c | 14 +++++-----
 drivers/net/dsa/mv88e6xxx.c | 67 +++++++++++++++++++--------------------------
 drivers/net/dsa/mv88e6xxx.h | 14 ++++++----
 6 files changed, 58 insertions(+), 65 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 00c1121..02bf16c 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -17,10 +17,10 @@
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
-static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
-	{ PORT_SWITCH_ID_6123, "Marvell 88E6123" },
-	{ PORT_SWITCH_ID_6161, "Marvell 88E6161" },
-	{ PORT_SWITCH_ID_6165, "Marvell 88E6165" },
+static const struct mv88e6xxx_info mv88e6123_table[] = {
+	{ MV88E6XXX_INFO(0x121, "Marvell 88E6123") },
+	{ MV88E6XXX_INFO(0x161, "Marvell 88E6161") },
+	{ MV88E6XXX_INFO(0x165, "Marvell 88E6165") },
 };
 
 static char *mv88e6123_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index df534da..27dd102 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -17,11 +17,11 @@
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
-static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
-	{ PORT_SWITCH_ID_6085, "Marvell 88E6085" },
-	{ PORT_SWITCH_ID_6095, "Marvell 88E6095/88E6095F" },
-	{ PORT_SWITCH_ID_6131, "Marvell 88E6131" },
-	{ PORT_SWITCH_ID_6185, "Marvell 88E6185" },
+static const struct mv88e6xxx_info mv88e6131_table[] = {
+	{ MV88E6XXX_INFO(0x095, "Marvell 88E6095/88E6095F") },
+	{ MV88E6XXX_INFO(0x04a, "Marvell 88E6085") },
+	{ MV88E6XXX_INFO(0x106, "Marvell 88E6131") },
+	{ MV88E6XXX_INFO(0x1a7, "Marvell 88E6185") },
 };
 
 static char *mv88e6131_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 40222b0..334e097 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -17,11 +17,11 @@
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
-static const struct mv88e6xxx_switch_id mv88e6171_table[] = {
-	{ PORT_SWITCH_ID_6171, "Marvell 88E6171" },
-	{ PORT_SWITCH_ID_6175, "Marvell 88E6175" },
-	{ PORT_SWITCH_ID_6350, "Marvell 88E6350" },
-	{ PORT_SWITCH_ID_6351, "Marvell 88E6351" },
+static const struct mv88e6xxx_info mv88e6171_table[] = {
+	{ MV88E6XXX_INFO(0x171, "Marvell 88E6171") },
+	{ MV88E6XXX_INFO(0x175, "Marvell 88E6175") },
+	{ MV88E6XXX_INFO(0x371, "Marvell 88E6350") },
+	{ MV88E6XXX_INFO(0x375, "Marvell 88E6351") },
 };
 
 static char *mv88e6171_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 30fc5f6..371edd7 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -22,13 +22,13 @@
 #include <net/dsa.h>
 #include "mv88e6xxx.h"
 
-static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
-	{ PORT_SWITCH_ID_6172, "Marvell 88E6172" },
-	{ PORT_SWITCH_ID_6176, "Marvell 88E6176" },
-	{ PORT_SWITCH_ID_6240, "Marvell 88E6240" },
-	{ PORT_SWITCH_ID_6320, "Marvell 88E6320" },
-	{ PORT_SWITCH_ID_6321, "Marvell 88E6321" },
-	{ PORT_SWITCH_ID_6352, "Marvell 88E6352" },
+static const struct mv88e6xxx_info mv88e6352_table[] = {
+	{ MV88E6XXX_INFO(0x115, "Marvell 88E6320") },
+	{ MV88E6XXX_INFO(0x310, "Marvell 88E6321") },
+	{ MV88E6XXX_INFO(0x172, "Marvell 88E6172") },
+	{ MV88E6XXX_INFO(0x176, "Marvell 88E6176") },
+	{ MV88E6XXX_INFO(0x240, "Marvell 88E6240") },
+	{ MV88E6XXX_INFO(0x352, "Marvell 88E6352") },
 };
 
 static char *mv88e6352_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index ad29040..48fd1f4 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2663,16 +2663,10 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 int mv88e6xxx_setup_common(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	int id;
 
 	ps->ds = ds;
 	mutex_init(&ps->smi_mutex);
 
-	id = REG_READ(REG_PORT(0), PORT_SWITCH_ID);
-
-	ps->id = id & 0xfff0;
-	ps->rev = id & 0xf;
-
 	INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
 
 	return 0;
@@ -3072,51 +3066,46 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
 }
 #endif /* CONFIG_NET_DSA_HWMON */
 
-static char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
-				   const struct mv88e6xxx_switch_id *table,
-				   unsigned int num)
+char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
+			  int sw_addr, void **priv,
+			  const struct mv88e6xxx_info *table, unsigned int num)
 {
-	int i, ret;
+	const struct mv88e6xxx_info *info;
+	struct mv88e6xxx_priv_state *ps;
+	struct mii_bus *bus;
+	int id, i;
 
+	bus = dsa_host_dev_to_mii_bus(host_dev);
 	if (!bus)
 		return NULL;
 
-	ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
-	if (ret < 0)
+	id = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
+	if (id < 0)
 		return NULL;
 
-	/* Look up the exact switch ID */
-	for (i = 0; i < num; ++i)
-		if (table[i].id == (ret & 0xfff0))
-			return table[i].name;
+	for (i = 0, info = &table[i]; i < num; info = &table[++i])
+		if (info->prod_num == (id & 0xfff0) >> 4)
+			goto found;
 
 	return NULL;
-}
 
-char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
-			  int sw_addr, void **priv,
-			  const struct mv88e6xxx_switch_id *table,
-			  unsigned int num)
-{
-	struct mv88e6xxx_priv_state *ps;
-	struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
-	char *name;
-
-	if (!bus)
+found:
+	ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
+	if (!ps)
 		return NULL;
 
-	name = mv88e6xxx_lookup_name(bus, sw_addr, table, num);
-	if (name) {
-		ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
-		if (!ps)
-			return NULL;
-		*priv = ps;
-		ps->bus = dsa_host_dev_to_mii_bus(host_dev);
-		if (!ps->bus)
-			return NULL;
-		ps->sw_addr = sw_addr;
-	}
-	return name;
+	*priv = ps;
+
+	ps->bus = bus;
+	ps->sw_addr = sw_addr;
+	ps->info = info;
+	ps->id = id & 0xfff0;
+	ps->rev = id & 0xf;
+
+	dev_info(&ps->bus->dev, "found switch %s, revision %u\n",
+		 ps->info->name, ps->rev);
+
+	return (char *) ps->info->name;
 }
 
 static int __init mv88e6xxx_init(void)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 7304f88..5556098 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -354,11 +354,15 @@
 
 #define MV88E6XXX_N_FID		4096
 
-struct mv88e6xxx_switch_id {
-	u16 id;
-	char *name;
+struct mv88e6xxx_info {
+	u16 prod_num;
+	const char *name;
 };
 
+#define MV88E6XXX_INFO(_prod_num, _name) \
+	.prod_num = _prod_num, \
+	.name = _name, \
+
 struct mv88e6xxx_atu_entry {
 	u16	fid;
 	u8	state;
@@ -384,6 +388,7 @@ struct mv88e6xxx_priv_port {
 };
 
 struct mv88e6xxx_priv_state {
+	const struct mv88e6xxx_info *info;
 	int rev;
 
 	/* The dsa_switch this private structure is related to */
@@ -453,8 +458,7 @@ struct mv88e6xxx_hw_stat {
 int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
 char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
 			  int sw_addr, void **priv,
-			  const struct mv88e6xxx_switch_id *table,
-			  unsigned int num);
+			  const struct mv88e6xxx_info *table, unsigned int num);
 
 int mv88e6xxx_setup_ports(struct dsa_switch *ds);
 int mv88e6xxx_setup_common(struct dsa_switch *ds);
-- 
2.8.0

^ permalink raw reply related

* [PATCH net-next 4/7] net: dsa: mv88e6xxx: add family to info
From: Vivien Didelot @ 2016-04-15 18:25 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot
In-Reply-To: <1460744750-13896-1-git-send-email-vivien.didelot@savoirfairelinux.com>

Add an mv88e6xxx_family enum to the info structure for better family
indentification.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c |  6 ++--
 drivers/net/dsa/mv88e6131.c |  8 ++---
 drivers/net/dsa/mv88e6171.c |  8 ++---
 drivers/net/dsa/mv88e6352.c | 12 ++++----
 drivers/net/dsa/mv88e6xxx.c | 71 +++++----------------------------------------
 drivers/net/dsa/mv88e6xxx.h | 16 +++++++++-
 6 files changed, 40 insertions(+), 81 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 02bf16c..36a0340 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -18,9 +18,9 @@
 #include "mv88e6xxx.h"
 
 static const struct mv88e6xxx_info mv88e6123_table[] = {
-	{ MV88E6XXX_INFO(0x121, "Marvell 88E6123") },
-	{ MV88E6XXX_INFO(0x161, "Marvell 88E6161") },
-	{ MV88E6XXX_INFO(0x165, "Marvell 88E6165") },
+	{ MV88E6XXX_INFO(6165, 0x121, "Marvell 88E6123") },
+	{ MV88E6XXX_INFO(6165, 0x161, "Marvell 88E6161") },
+	{ MV88E6XXX_INFO(6165, 0x165, "Marvell 88E6165") },
 };
 
 static char *mv88e6123_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 27dd102..f75d2dd 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -18,10 +18,10 @@
 #include "mv88e6xxx.h"
 
 static const struct mv88e6xxx_info mv88e6131_table[] = {
-	{ MV88E6XXX_INFO(0x095, "Marvell 88E6095/88E6095F") },
-	{ MV88E6XXX_INFO(0x04a, "Marvell 88E6085") },
-	{ MV88E6XXX_INFO(0x106, "Marvell 88E6131") },
-	{ MV88E6XXX_INFO(0x1a7, "Marvell 88E6185") },
+	{ MV88E6XXX_INFO(6095, 0x095, "Marvell 88E6095/88E6095F") },
+	{ MV88E6XXX_INFO(6097, 0x04a, "Marvell 88E6085") },
+	{ MV88E6XXX_INFO(6185, 0x106, "Marvell 88E6131") },
+	{ MV88E6XXX_INFO(6185, 0x1a7, "Marvell 88E6185") },
 };
 
 static char *mv88e6131_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 334e097..cb5bb19 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -18,10 +18,10 @@
 #include "mv88e6xxx.h"
 
 static const struct mv88e6xxx_info mv88e6171_table[] = {
-	{ MV88E6XXX_INFO(0x171, "Marvell 88E6171") },
-	{ MV88E6XXX_INFO(0x175, "Marvell 88E6175") },
-	{ MV88E6XXX_INFO(0x371, "Marvell 88E6350") },
-	{ MV88E6XXX_INFO(0x375, "Marvell 88E6351") },
+	{ MV88E6XXX_INFO(6351, 0x171, "Marvell 88E6171") },
+	{ MV88E6XXX_INFO(6351, 0x175, "Marvell 88E6175") },
+	{ MV88E6XXX_INFO(6351, 0x371, "Marvell 88E6350") },
+	{ MV88E6XXX_INFO(6351, 0x375, "Marvell 88E6351") },
 };
 
 static char *mv88e6171_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 371edd7..94db0c3 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -23,12 +23,12 @@
 #include "mv88e6xxx.h"
 
 static const struct mv88e6xxx_info mv88e6352_table[] = {
-	{ MV88E6XXX_INFO(0x115, "Marvell 88E6320") },
-	{ MV88E6XXX_INFO(0x310, "Marvell 88E6321") },
-	{ MV88E6XXX_INFO(0x172, "Marvell 88E6172") },
-	{ MV88E6XXX_INFO(0x176, "Marvell 88E6176") },
-	{ MV88E6XXX_INFO(0x240, "Marvell 88E6240") },
-	{ MV88E6XXX_INFO(0x352, "Marvell 88E6352") },
+	{ MV88E6XXX_INFO(6320, 0x115, "Marvell 88E6320") },
+	{ MV88E6XXX_INFO(6320, 0x310, "Marvell 88E6321") },
+	{ MV88E6XXX_INFO(6352, 0x172, "Marvell 88E6172") },
+	{ MV88E6XXX_INFO(6352, 0x176, "Marvell 88E6176") },
+	{ MV88E6XXX_INFO(6352, 0x240, "Marvell 88E6240") },
+	{ MV88E6XXX_INFO(6352, 0x352, "Marvell 88E6352") },
 };
 
 static char *mv88e6352_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 48fd1f4..05d59f9 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -369,111 +369,56 @@ static bool mv88e6xxx_6065_family(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6031:
-	case PORT_SWITCH_ID_6061:
-	case PORT_SWITCH_ID_6035:
-	case PORT_SWITCH_ID_6065:
-		return true;
-	}
-	return false;
+	return ps->info->family == MV88E6XXX_FAMILY_6065;
 }
 
 static bool mv88e6xxx_6095_family(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6092:
-	case PORT_SWITCH_ID_6095:
-		return true;
-	}
-	return false;
+	return ps->info->family == MV88E6XXX_FAMILY_6095;
 }
 
 static bool mv88e6xxx_6097_family(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6046:
-	case PORT_SWITCH_ID_6085:
-	case PORT_SWITCH_ID_6096:
-	case PORT_SWITCH_ID_6097:
-		return true;
-	}
-	return false;
+	return ps->info->family == MV88E6XXX_FAMILY_6097;
 }
 
 static bool mv88e6xxx_6165_family(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6123:
-	case PORT_SWITCH_ID_6161:
-	case PORT_SWITCH_ID_6165:
-		return true;
-	}
-	return false;
+	return ps->info->family == MV88E6XXX_FAMILY_6165;
 }
 
 static bool mv88e6xxx_6185_family(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6121:
-	case PORT_SWITCH_ID_6122:
-	case PORT_SWITCH_ID_6152:
-	case PORT_SWITCH_ID_6155:
-	case PORT_SWITCH_ID_6182:
-	case PORT_SWITCH_ID_6185:
-	case PORT_SWITCH_ID_6108:
-	case PORT_SWITCH_ID_6131:
-		return true;
-	}
-	return false;
+	return ps->info->family == MV88E6XXX_FAMILY_6185;
 }
 
 static bool mv88e6xxx_6320_family(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6320:
-	case PORT_SWITCH_ID_6321:
-		return true;
-	}
-	return false;
+	return ps->info->family == MV88E6XXX_FAMILY_6320;
 }
 
 static bool mv88e6xxx_6351_family(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6171:
-	case PORT_SWITCH_ID_6175:
-	case PORT_SWITCH_ID_6350:
-	case PORT_SWITCH_ID_6351:
-		return true;
-	}
-	return false;
+	return ps->info->family == MV88E6XXX_FAMILY_6351;
 }
 
 static bool mv88e6xxx_6352_family(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6172:
-	case PORT_SWITCH_ID_6176:
-	case PORT_SWITCH_ID_6240:
-	case PORT_SWITCH_ID_6352:
-		return true;
-	}
-	return false;
+	return ps->info->family == MV88E6XXX_FAMILY_6352;
 }
 
 static unsigned int mv88e6xxx_num_databases(struct dsa_switch *ds)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 5556098..3d2a186 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -352,14 +352,28 @@
 #define GLOBAL2_QOS_WEIGHT	0x1c
 #define GLOBAL2_MISC		0x1d
 
+enum mv88e6xxx_family {
+	MV88E6XXX_FAMILY_NONE,
+	MV88E6XXX_FAMILY_6065,	/* 6031 6035 6061 6065 */
+	MV88E6XXX_FAMILY_6095,	/* 6092 6095 */
+	MV88E6XXX_FAMILY_6097,	/* 6046 6085 6096 6097 */
+	MV88E6XXX_FAMILY_6165,	/* 6123 6161 6165 */
+	MV88E6XXX_FAMILY_6185,	/* 6108 6121 6122 6131 6152 6155 6182 6185 */
+	MV88E6XXX_FAMILY_6320,	/* 6320 6321 */
+	MV88E6XXX_FAMILY_6351,	/* 6171 6175 6350 6351 */
+	MV88E6XXX_FAMILY_6352,	/* 6172 6176 6240 6352 */
+};
+
 #define MV88E6XXX_N_FID		4096
 
 struct mv88e6xxx_info {
+	enum mv88e6xxx_family family;
 	u16 prod_num;
 	const char *name;
 };
 
-#define MV88E6XXX_INFO(_prod_num, _name) \
+#define MV88E6XXX_INFO(_family, _prod_num, _name) \
+	.family = MV88E6XXX_FAMILY_##_family, \
 	.prod_num = _prod_num, \
 	.name = _name, \
 
-- 
2.8.0

^ permalink raw reply related

* [PATCH net-next 5/7] net: dsa: mv88e6xxx: add number of ports to info
From: Vivien Didelot @ 2016-04-15 18:25 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot
In-Reply-To: <1460744750-13896-1-git-send-email-vivien.didelot@savoirfairelinux.com>

Drop the ps->num_ports variable for a new member of the info structure.
This removes the need to assign it at setup time.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6123.c | 19 +++----------------
 drivers/net/dsa/mv88e6131.c | 26 +++++---------------------
 drivers/net/dsa/mv88e6171.c | 11 ++++-------
 drivers/net/dsa/mv88e6352.c | 14 ++++++--------
 drivers/net/dsa/mv88e6xxx.c | 38 +++++++++++++++++++-------------------
 drivers/net/dsa/mv88e6xxx.h |  6 +++---
 6 files changed, 40 insertions(+), 74 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 36a0340..2048719 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -18,9 +18,9 @@
 #include "mv88e6xxx.h"
 
 static const struct mv88e6xxx_info mv88e6123_table[] = {
-	{ MV88E6XXX_INFO(6165, 0x121, "Marvell 88E6123") },
-	{ MV88E6XXX_INFO(6165, 0x161, "Marvell 88E6161") },
-	{ MV88E6XXX_INFO(6165, 0x165, "Marvell 88E6165") },
+	{ MV88E6XXX_INFO(6165, 0x121, 3, "Marvell 88E6123") },
+	{ MV88E6XXX_INFO(6165, 0x161, 6, "Marvell 88E6161") },
+	{ MV88E6XXX_INFO(6165, 0x165, 6, "Marvell 88E6165") },
 };
 
 static char *mv88e6123_drv_probe(struct device *dsa_dev,
@@ -67,25 +67,12 @@ static int mv88e6123_setup_global(struct dsa_switch *ds)
 
 static int mv88e6123_setup(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
 	ret = mv88e6xxx_setup_common(ds);
 	if (ret < 0)
 		return ret;
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6123:
-		ps->num_ports = 3;
-		break;
-	case PORT_SWITCH_ID_6161:
-	case PORT_SWITCH_ID_6165:
-		ps->num_ports = 6;
-		break;
-	default:
-		return -ENODEV;
-	}
-
 	ret = mv88e6xxx_switch_reset(ds, false);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index f75d2dd..2eb9fa3 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -18,10 +18,10 @@
 #include "mv88e6xxx.h"
 
 static const struct mv88e6xxx_info mv88e6131_table[] = {
-	{ MV88E6XXX_INFO(6095, 0x095, "Marvell 88E6095/88E6095F") },
-	{ MV88E6XXX_INFO(6097, 0x04a, "Marvell 88E6085") },
-	{ MV88E6XXX_INFO(6185, 0x106, "Marvell 88E6131") },
-	{ MV88E6XXX_INFO(6185, 0x1a7, "Marvell 88E6185") },
+	{ MV88E6XXX_INFO(6095, 0x095, 11, "Marvell 88E6095/88E6095F") },
+	{ MV88E6XXX_INFO(6097, 0x04a, 10, "Marvell 88E6085") },
+	{ MV88E6XXX_INFO(6185, 0x106, 8,  "Marvell 88E6131") },
+	{ MV88E6XXX_INFO(6185, 0x1a7, 10, "Marvell 88E6185") },
 };
 
 static char *mv88e6131_drv_probe(struct device *dsa_dev,
@@ -90,7 +90,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
 
 static int mv88e6131_setup(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
 	ret = mv88e6xxx_setup_common(ds);
@@ -99,21 +98,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
 
 	mv88e6xxx_ppu_state_init(ds);
 
-	switch (ps->id) {
-	case PORT_SWITCH_ID_6085:
-	case PORT_SWITCH_ID_6185:
-		ps->num_ports = 10;
-		break;
-	case PORT_SWITCH_ID_6095:
-		ps->num_ports = 11;
-		break;
-	case PORT_SWITCH_ID_6131:
-		ps->num_ports = 8;
-		break;
-	default:
-		return -ENODEV;
-	}
-
 	ret = mv88e6xxx_switch_reset(ds, false);
 	if (ret < 0)
 		return ret;
@@ -129,7 +113,7 @@ static int mv88e6131_port_to_phy_addr(struct dsa_switch *ds, int port)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	if (port >= 0 && port < ps->num_ports)
+	if (port >= 0 && port < ps->info->num_ports)
 		return port;
 
 	return -EINVAL;
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index cb5bb19..d5f33d7 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -18,10 +18,10 @@
 #include "mv88e6xxx.h"
 
 static const struct mv88e6xxx_info mv88e6171_table[] = {
-	{ MV88E6XXX_INFO(6351, 0x171, "Marvell 88E6171") },
-	{ MV88E6XXX_INFO(6351, 0x175, "Marvell 88E6175") },
-	{ MV88E6XXX_INFO(6351, 0x371, "Marvell 88E6350") },
-	{ MV88E6XXX_INFO(6351, 0x375, "Marvell 88E6351") },
+	{ MV88E6XXX_INFO(6351, 0x171, 7, "Marvell 88E6171") },
+	{ MV88E6XXX_INFO(6351, 0x175, 7, "Marvell 88E6175") },
+	{ MV88E6XXX_INFO(6351, 0x371, 7, "Marvell 88E6350") },
+	{ MV88E6XXX_INFO(6351, 0x375, 7, "Marvell 88E6351") },
 };
 
 static char *mv88e6171_drv_probe(struct device *dsa_dev,
@@ -69,15 +69,12 @@ static int mv88e6171_setup_global(struct dsa_switch *ds)
 
 static int mv88e6171_setup(struct dsa_switch *ds)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	int ret;
 
 	ret = mv88e6xxx_setup_common(ds);
 	if (ret < 0)
 		return ret;
 
-	ps->num_ports = 7;
-
 	ret = mv88e6xxx_switch_reset(ds, true);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 94db0c3..e529c18 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -23,12 +23,12 @@
 #include "mv88e6xxx.h"
 
 static const struct mv88e6xxx_info mv88e6352_table[] = {
-	{ MV88E6XXX_INFO(6320, 0x115, "Marvell 88E6320") },
-	{ MV88E6XXX_INFO(6320, 0x310, "Marvell 88E6321") },
-	{ MV88E6XXX_INFO(6352, 0x172, "Marvell 88E6172") },
-	{ MV88E6XXX_INFO(6352, 0x176, "Marvell 88E6176") },
-	{ MV88E6XXX_INFO(6352, 0x240, "Marvell 88E6240") },
-	{ MV88E6XXX_INFO(6352, 0x352, "Marvell 88E6352") },
+	{ MV88E6XXX_INFO(6320, 0x115, 7, "Marvell 88E6320") },
+	{ MV88E6XXX_INFO(6320, 0x310, 7, "Marvell 88E6321") },
+	{ MV88E6XXX_INFO(6352, 0x172, 7, "Marvell 88E6172") },
+	{ MV88E6XXX_INFO(6352, 0x176, 7, "Marvell 88E6176") },
+	{ MV88E6XXX_INFO(6352, 0x240, 7, "Marvell 88E6240") },
+	{ MV88E6XXX_INFO(6352, 0x352, 7, "Marvell 88E6352") },
 };
 
 static char *mv88e6352_drv_probe(struct device *dsa_dev,
@@ -82,8 +82,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
 	if (ret < 0)
 		return ret;
 
-	ps->num_ports = 7;
-
 	mutex_init(&ps->eeprom_mutex);
 
 	ret = mv88e6xxx_switch_reset(ds, true);
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 05d59f9..f3e8c68 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -518,7 +518,7 @@ void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
 		reg |= PORT_PCS_CTRL_DUPLEX_FULL;
 
 	if ((mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds)) &&
-	    (port >= ps->num_ports - 2)) {
+	    (port >= ps->info->num_ports - 2)) {
 		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
 			reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK;
 		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
@@ -1099,7 +1099,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct dsa_switch *ds, int port)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 	struct net_device *bridge = ps->ports[port].bridge_dev;
-	const u16 mask = (1 << ps->num_ports) - 1;
+	const u16 mask = (1 << ps->info->num_ports) - 1;
 	u16 output_ports = 0;
 	int reg;
 	int i;
@@ -1108,7 +1108,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct dsa_switch *ds, int port)
 	if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
 		output_ports = mask;
 	} else {
-		for (i = 0; i < ps->num_ports; ++i) {
+		for (i = 0; i < ps->info->num_ports; ++i) {
 			/* allow sending frames to every group member */
 			if (bridge && ps->ports[i].bridge_dev == bridge)
 				output_ports |= BIT(i);
@@ -1249,7 +1249,7 @@ static int _mv88e6xxx_vtu_stu_data_read(struct dsa_switch *ds,
 		regs[i] = ret;
 	}
 
-	for (i = 0; i < ps->num_ports; ++i) {
+	for (i = 0; i < ps->info->num_ports; ++i) {
 		unsigned int shift = (i % 4) * 4 + nibble_offset;
 		u16 reg = regs[i / 4];
 
@@ -1268,7 +1268,7 @@ static int _mv88e6xxx_vtu_stu_data_write(struct dsa_switch *ds,
 	int i;
 	int ret;
 
-	for (i = 0; i < ps->num_ports; ++i) {
+	for (i = 0; i < ps->info->num_ports; ++i) {
 		unsigned int shift = (i % 4) * 4 + nibble_offset;
 		u8 data = entry->data[i];
 
@@ -1600,7 +1600,7 @@ static int _mv88e6xxx_fid_new(struct dsa_switch *ds, u16 *fid)
 	bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
 
 	/* Set every FID bit used by the (un)bridged ports */
-	for (i = 0; i < ps->num_ports; ++i) {
+	for (i = 0; i < ps->info->num_ports; ++i) {
 		err = _mv88e6xxx_port_fid_get(ds, i, fid);
 		if (err)
 			return err;
@@ -1650,7 +1650,7 @@ static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid,
 		return err;
 
 	/* exclude all ports except the CPU and DSA ports */
-	for (i = 0; i < ps->num_ports; ++i)
+	for (i = 0; i < ps->info->num_ports; ++i)
 		vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)
 			? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED
 			: GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
@@ -1739,7 +1739,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
 		if (vlan.vid > vid_end)
 			break;
 
-		for (i = 0; i < ps->num_ports; ++i) {
+		for (i = 0; i < ps->info->num_ports; ++i) {
 			if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
 				continue;
 
@@ -1888,7 +1888,7 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
 
 	/* keep the VLAN unless all ports are excluded */
 	vlan.valid = false;
-	for (i = 0; i < ps->num_ports; ++i) {
+	for (i = 0; i < ps->info->num_ports; ++i) {
 		if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
 			continue;
 
@@ -2197,11 +2197,11 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
 	mutex_lock(&ps->smi_mutex);
 
 	/* Get or create the bridge FID and assign it to the port */
-	for (i = 0; i < ps->num_ports; ++i)
+	for (i = 0; i < ps->info->num_ports; ++i)
 		if (ps->ports[i].bridge_dev == bridge)
 			break;
 
-	if (i < ps->num_ports)
+	if (i < ps->info->num_ports)
 		err = _mv88e6xxx_port_fid_get(ds, i, &fid);
 	else
 		err = _mv88e6xxx_fid_new(ds, &fid);
@@ -2215,7 +2215,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
 	/* Assign the bridge and remap each port's VLANTable */
 	ps->ports[port].bridge_dev = bridge;
 
-	for (i = 0; i < ps->num_ports; ++i) {
+	for (i = 0; i < ps->info->num_ports; ++i) {
 		if (ps->ports[i].bridge_dev == bridge) {
 			err = _mv88e6xxx_port_based_vlan_map(ds, i);
 			if (err)
@@ -2246,7 +2246,7 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
 	/* Unassign the bridge and remap each port's VLANTable */
 	ps->ports[port].bridge_dev = NULL;
 
-	for (i = 0; i < ps->num_ports; ++i)
+	for (i = 0; i < ps->info->num_ports; ++i)
 		if (i == port || ps->ports[i].bridge_dev == bridge)
 			if (_mv88e6xxx_port_based_vlan_map(ds, i))
 				netdev_warn(ds->ports[i], "failed to remap\n");
@@ -2265,7 +2265,7 @@ static void mv88e6xxx_bridge_work(struct work_struct *work)
 
 	mutex_lock(&ps->smi_mutex);
 
-	for (port = 0; port < ps->num_ports; ++port)
+	for (port = 0; port < ps->info->num_ports; ++port)
 		if (test_and_clear_bit(port, ps->port_state_update_mask) &&
 		    _mv88e6xxx_port_state(ds, port, ps->ports[port].state))
 			netdev_warn(ds->ports[port], "failed to update state to %s\n",
@@ -2597,7 +2597,7 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
 	int ret;
 	int i;
 
-	for (i = 0; i < ps->num_ports; i++) {
+	for (i = 0; i < ps->info->num_ports; i++) {
 		ret = mv88e6xxx_setup_port(ds, i);
 		if (ret < 0)
 			return ret;
@@ -2675,7 +2675,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 	for (i = 0; i < 8; i++)
 		REG_WRITE(REG_GLOBAL2, GLOBAL2_TRUNK_MASK,
 			  0x8000 | (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) |
-			  ((1 << ps->num_ports) - 1));
+			  ((1 << ps->info->num_ports) - 1));
 
 	/* Clear all trunk mappings. */
 	for (i = 0; i < 16; i++)
@@ -2710,7 +2710,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
 		 * ingress rate limit registers to their initial
 		 * state.
 		 */
-		for (i = 0; i < ps->num_ports; i++)
+		for (i = 0; i < ps->info->num_ports; i++)
 			REG_WRITE(REG_GLOBAL2, GLOBAL2_INGRESS_OP,
 				  0x9000 | (i << 8));
 	}
@@ -2747,7 +2747,7 @@ int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active)
 	int i;
 
 	/* Set all ports to the disabled state. */
-	for (i = 0; i < ps->num_ports; i++) {
+	for (i = 0; i < ps->info->num_ports; i++) {
 		ret = REG_READ(REG_PORT(i), PORT_CONTROL);
 		REG_WRITE(REG_PORT(i), PORT_CONTROL, ret & 0xfffc);
 	}
@@ -2815,7 +2815,7 @@ static int mv88e6xxx_port_to_phy_addr(struct dsa_switch *ds, int port)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
 
-	if (port >= 0 && port < ps->num_ports)
+	if (port >= 0 && port < ps->info->num_ports)
 		return port;
 	return -EINVAL;
 }
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 3d2a186..6b2d62e 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -369,12 +369,14 @@ enum mv88e6xxx_family {
 struct mv88e6xxx_info {
 	enum mv88e6xxx_family family;
 	u16 prod_num;
+	unsigned int num_ports;
 	const char *name;
 };
 
-#define MV88E6XXX_INFO(_family, _prod_num, _name) \
+#define MV88E6XXX_INFO(_family, _prod_num, _num_ports, _name) \
 	.family = MV88E6XXX_FAMILY_##_family, \
 	.prod_num = _prod_num, \
+	.num_ports = _num_ports, \
 	.name = _name, \
 
 struct mv88e6xxx_atu_entry {
@@ -447,8 +449,6 @@ struct mv88e6xxx_priv_state {
 	struct mutex eeprom_mutex;
 
 	int		id; /* switch product id */
-	int		num_ports;	/* number of switch ports */
-
 	struct mv88e6xxx_priv_port	ports[DSA_MAX_PORTS];
 
 	DECLARE_BITMAP(port_state_update_mask, DSA_MAX_PORTS);
-- 
2.8.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox