* [PATCH RESEND] sched: add missing group change to qfq_change_class
From: Paolo Valente @ 2012-08-07 17:27 UTC (permalink / raw)
To: davem, shemminger, jhs
Cc: fchecconi, rizzo, netdev, linux-kernel, paolo.valente
[Resending again, as the text was corrupted by the email client]
To speed up operations, QFQ internally divides classes into
groups. Which group a class belongs to depends on the ratio between
the maximum packet length and the weight of the class. Unfortunately
the function qfq_change_class lacks the steps for changing the group
of a class when the ratio max_pkt_len/weight of the class changes.
For example, when the last of the following three commands is
executed, the group of class 1:1 is not correctly changed:
tc disc add dev XXX root handle 1: qfq
tc class add dev XXX parent 1: qfq classid 1:1 weight 1
tc class change dev XXX parent 1: classid 1:1 qfq weight 4
Not changing the group of a class does not affect the long-term
bandwidth guaranteed to the class, as the latter is independent of the
maximum packet length, and correctly changes (only) if the weight of
the class changes. In contrast, if the group of the class is not
updated, the class is still guaranteed the short-term bandwidth and
packet delay related to its old group, instead of the guarantees that
it should receive according to its new weight and/or maximum packet
length. This may also break service guarantees for other classes.
This patch adds the missing operations.
Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
---
net/sched/sch_qfq.c | 95 +++++++++++++++++++++++++++++++++++++--------------
1 file changed, 69 insertions(+), 26 deletions(-)
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 9af01f3..e4723d3 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -203,6 +203,34 @@ out:
return index;
}
+/* Length of the next packet (0 if the queue is empty). */
+static unsigned int qdisc_peek_len(struct Qdisc *sch)
+{
+ struct sk_buff *skb;
+
+ skb = sch->ops->peek(sch);
+ return skb ? qdisc_pkt_len(skb) : 0;
+}
+
+static void qfq_deactivate_class(struct qfq_sched *, struct qfq_class *);
+static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl,
+ unsigned int len);
+
+static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl,
+ u32 lmax, u32 inv_w, int delta_w)
+{
+ int i;
+
+ /* update qfq-specific data */
+ cl->lmax = lmax;
+ cl->inv_w = inv_w;
+ i = qfq_calc_index(cl->inv_w, cl->lmax);
+
+ cl->grp = &q->groups[i];
+
+ q->wsum += delta_w;
+}
+
static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
struct nlattr **tca, unsigned long *arg)
{
@@ -250,6 +278,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
lmax = 1UL << QFQ_MTU_SHIFT;
if (cl != NULL) {
+ bool need_reactivation = false;
+
if (tca[TCA_RATE]) {
err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
qdisc_root_sleeping_lock(sch),
@@ -258,12 +288,29 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
return err;
}
- if (inv_w != cl->inv_w) {
- sch_tree_lock(sch);
- q->wsum += delta_w;
- cl->inv_w = inv_w;
- sch_tree_unlock(sch);
+ if (lmax == cl->lmax && inv_w == cl->inv_w)
+ return 0; /* nothing to update */
+
+ i = qfq_calc_index(inv_w, lmax);
+ sch_tree_lock(sch);
+ if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) {
+ /*
+ * shift cl->F back, to not charge the
+ * class for the not-yet-served head
+ * packet
+ */
+ cl->F = cl->S;
+ /* remove class from its slot in the old group */
+ qfq_deactivate_class(q, cl);
+ need_reactivation = true;
}
+
+ qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
+
+ if (need_reactivation) /* activate in new group */
+ qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc));
+ sch_tree_unlock(sch);
+
return 0;
}
@@ -273,11 +320,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
cl->refcnt = 1;
cl->common.classid = classid;
- cl->lmax = lmax;
- cl->inv_w = inv_w;
- i = qfq_calc_index(cl->inv_w, cl->lmax);
- cl->grp = &q->groups[i];
+ qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
cl->qdisc = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops, classid);
@@ -294,7 +338,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
return err;
}
}
- q->wsum += weight;
sch_tree_lock(sch);
qdisc_class_hash_insert(&q->clhash, &cl->common);
@@ -711,15 +754,6 @@ static void qfq_update_eligible(struct qfq_sched *q, u64 old_V)
}
}
-/* What is length of next packet in queue (0 if queue is empty) */
-static unsigned int qdisc_peek_len(struct Qdisc *sch)
-{
- struct sk_buff *skb;
-
- skb = sch->ops->peek(sch);
- return skb ? qdisc_pkt_len(skb) : 0;
-}
-
/*
* Updates the class, returns true if also the group needs to be updated.
*/
@@ -843,11 +877,8 @@ static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
struct qfq_sched *q = qdisc_priv(sch);
- struct qfq_group *grp;
struct qfq_class *cl;
int err;
- u64 roundedS;
- int s;
cl = qfq_classify(skb, sch, &err);
if (cl == NULL) {
@@ -876,11 +907,25 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
return err;
/* If reach this point, queue q was idle */
- grp = cl->grp;
+ qfq_activate_class(q, cl, qdisc_pkt_len(skb));
+
+ return err;
+}
+
+/*
+ * Handle class switch from idle to backlogged.
+ */
+static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl,
+ unsigned int pkt_len)
+{
+ struct qfq_group *grp = cl->grp;
+ u64 roundedS;
+ int s;
+
qfq_update_start(q, cl);
/* compute new finish time and rounded start. */
- cl->F = cl->S + (u64)qdisc_pkt_len(skb) * cl->inv_w;
+ cl->F = cl->S + (u64)pkt_len * cl->inv_w;
roundedS = qfq_round_down(cl->S, grp->slot_shift);
/*
@@ -917,8 +962,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
skip_update:
qfq_slot_insert(grp, cl, roundedS);
-
- return err;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH net-next 4/7] sctp: Push struct net down into sctp_in_scope
From: Eric W. Biederman @ 2012-08-07 17:27 UTC (permalink / raw)
To: David Miller
Cc: Vlad Yasevich, linux-sctp, netdev, linux-kernel, Jan Ariyasu,
Jan Ariyasu, Neil Horman, Thomas Graf, Xi Wang
In-Reply-To: <87ipcud3ld.fsf_-_@xmission.com>
struct net will be needed shortly when the tunables are made per network
namespace.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
include/net/sctp/structs.h | 2 +-
net/sctp/bind_addr.c | 4 ++--
net/sctp/protocol.c | 2 +-
net/sctp/sm_make_chunk.c | 3 ++-
4 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 88d2179..b0882f3 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1248,7 +1248,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len,
__u16 port, gfp_t gfp);
sctp_scope_t sctp_scope(const union sctp_addr *);
-int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope);
+int sctp_in_scope(struct net *net, const union sctp_addr *addr, const sctp_scope_t scope);
int sctp_is_any(struct sock *sk, const union sctp_addr *addr);
int sctp_addr_is_valid(const union sctp_addr *addr);
int sctp_is_ep_boundall(struct sock *sk);
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index a85ce4b..23389ba 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -457,7 +457,7 @@ static int sctp_copy_one_addr(struct net *net, struct sctp_bind_addr *dest,
if (sctp_is_any(NULL, addr)) {
error = sctp_copy_local_addr_list(net, dest, scope, gfp, flags);
- } else if (sctp_in_scope(addr, scope)) {
+ } else if (sctp_in_scope(net, addr, scope)) {
/* Now that the address is in scope, check to see if
* the address type is supported by local sock as
* well as the remote peer.
@@ -494,7 +494,7 @@ int sctp_is_any(struct sock *sk, const union sctp_addr *addr)
}
/* Is 'addr' valid for 'scope'? */
-int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
+int sctp_in_scope(struct net *net, const union sctp_addr *addr, sctp_scope_t scope)
{
sctp_scope_t addr_scope = sctp_scope(addr);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index de25d9c..85f87c3 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -210,7 +210,7 @@ int sctp_copy_local_addr_list(struct net *net, struct sctp_bind_addr *bp,
list_for_each_entry_rcu(addr, &net->sctp.local_addr_list, list) {
if (!addr->valid)
continue;
- if (sctp_in_scope(&addr->a, scope)) {
+ if (sctp_in_scope(net, &addr->a, scope)) {
/* Now that the address is in scope, check to see if
* the address type is really supported by the local
* sock as well as the remote peer.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 479a70e..fb12835 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2466,6 +2466,7 @@ static int sctp_process_param(struct sctp_association *asoc,
const union sctp_addr *peer_addr,
gfp_t gfp)
{
+ struct net *net = sock_net(asoc->base.sk);
union sctp_addr addr;
int i;
__u16 sat;
@@ -2494,7 +2495,7 @@ do_addr_param:
af = sctp_get_af_specific(param_type2af(param.p->type));
af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0);
scope = sctp_scope(peer_addr);
- if (sctp_in_scope(&addr, scope))
+ if (sctp_in_scope(net, &addr, scope))
if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED))
return 0;
break;
--
1.7.5.4
^ permalink raw reply related
* [PATCH net-next 3/7] sctp: Push struct net down into sctp_transport_init
From: Eric W. Biederman @ 2012-08-07 17:26 UTC (permalink / raw)
To: David Miller
Cc: Vlad Yasevich, linux-sctp, netdev, linux-kernel, Jan Ariyasu,
Jan Ariyasu, Neil Horman, Thomas Graf, Xi Wang
In-Reply-To: <87ipcud3ld.fsf_-_@xmission.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
include/net/sctp/structs.h | 2 +-
net/sctp/associola.c | 3 ++-
net/sctp/sm_statefuns.c | 2 +-
net/sctp/transport.c | 8 +++++---
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 6bdfcab..88d2179 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1066,7 +1066,7 @@ struct sctp_transport {
__u64 hb_nonce;
};
-struct sctp_transport *sctp_transport_new(const union sctp_addr *,
+struct sctp_transport *sctp_transport_new(struct net *, const union sctp_addr *,
gfp_t);
void sctp_transport_set_owner(struct sctp_transport *,
struct sctp_association *);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 6bcbeca..93a4513 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -641,6 +641,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
const gfp_t gfp,
const int peer_state)
{
+ struct net *net = sock_net(asoc->base.sk);
struct sctp_transport *peer;
struct sctp_sock *sp;
unsigned short port;
@@ -674,7 +675,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
return peer;
}
- peer = sctp_transport_new(addr, gfp);
+ peer = sctp_transport_new(net, addr, gfp);
if (!peer)
return NULL;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index bee5e2c..ff2530c 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -5958,7 +5958,7 @@ static struct sctp_packet *sctp_ootb_pkt_new(struct net *net,
}
/* Make a transport for the bucket, Eliza... */
- transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC);
+ transport = sctp_transport_new(net, sctp_source(chunk), GFP_ATOMIC);
if (!transport)
goto nomem;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index c97472b..aada963 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -59,7 +59,8 @@
/* 1st Level Abstractions. */
/* Initialize a new transport from provided memory. */
-static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
+static struct sctp_transport *sctp_transport_init(struct net *net,
+ struct sctp_transport *peer,
const union sctp_addr *addr,
gfp_t gfp)
{
@@ -109,7 +110,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
}
/* Allocate and initialize a new transport. */
-struct sctp_transport *sctp_transport_new(const union sctp_addr *addr,
+struct sctp_transport *sctp_transport_new(struct net *net,
+ const union sctp_addr *addr,
gfp_t gfp)
{
struct sctp_transport *transport;
@@ -118,7 +120,7 @@ struct sctp_transport *sctp_transport_new(const union sctp_addr *addr,
if (!transport)
goto fail;
- if (!sctp_transport_init(transport, addr, gfp))
+ if (!sctp_transport_init(net, transport, addr, gfp))
goto fail_init;
transport->malloced = 1;
--
1.7.5.4
^ permalink raw reply related
* [PATCH net-next 2/7] sctp: Push struct net down to sctp_chunk_event_lookup
From: Eric W. Biederman @ 2012-08-07 17:25 UTC (permalink / raw)
To: David Miller
Cc: Vlad Yasevich, linux-sctp, netdev, linux-kernel, Jan Ariyasu,
Jan Ariyasu, Neil Horman, Thomas Graf, Xi Wang
In-Reply-To: <87ipcud3ld.fsf_-_@xmission.com>
This trickles up through sctp_sm_lookup_event up to sctp_do_sm
and up further into sctp_primitiv_NAME before the code reaches
places where struct net can be reliably found.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
include/net/sctp/sctp.h | 12 ++++++------
include/net/sctp/sm.h | 5 +++--
net/sctp/associola.c | 5 +++--
net/sctp/endpointola.c | 4 +++-
net/sctp/input.c | 4 +++-
net/sctp/primitive.c | 4 ++--
net/sctp/sm_sideeffect.c | 24 ++++++++++++++++--------
net/sctp/sm_statetable.c | 11 +++++++----
net/sctp/socket.c | 27 +++++++++++++++++----------
9 files changed, 60 insertions(+), 36 deletions(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 15037e7..ef4ca25 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -139,12 +139,12 @@ extern int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
/*
* sctp/primitive.c
*/
-int sctp_primitive_ASSOCIATE(struct sctp_association *, void *arg);
-int sctp_primitive_SHUTDOWN(struct sctp_association *, void *arg);
-int sctp_primitive_ABORT(struct sctp_association *, void *arg);
-int sctp_primitive_SEND(struct sctp_association *, void *arg);
-int sctp_primitive_REQUESTHEARTBEAT(struct sctp_association *, void *arg);
-int sctp_primitive_ASCONF(struct sctp_association *, void *arg);
+int sctp_primitive_ASSOCIATE(struct net *, struct sctp_association *, void *arg);
+int sctp_primitive_SHUTDOWN(struct net *, struct sctp_association *, void *arg);
+int sctp_primitive_ABORT(struct net *, struct sctp_association *, void *arg);
+int sctp_primitive_SEND(struct net *, struct sctp_association *, void *arg);
+int sctp_primitive_REQUESTHEARTBEAT(struct net *, struct sctp_association *, void *arg);
+int sctp_primitive_ASCONF(struct net *, struct sctp_association *, void *arg);
/*
* sctp/input.c
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 9148632..bcef130 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -178,7 +178,8 @@ sctp_state_fn_t sctp_sf_autoclose_timer_expire;
/* Prototypes for utility support functions. */
__u8 sctp_get_chunk_type(struct sctp_chunk *chunk);
-const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t,
+const sctp_sm_table_entry_t *sctp_sm_lookup_event(struct net *,
+ sctp_event_t,
sctp_state_t,
sctp_subtype_t);
int sctp_chunk_iif(const struct sctp_chunk *);
@@ -268,7 +269,7 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *);
/* Prototypes for statetable processing. */
-int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
+int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
sctp_state_t state,
struct sctp_endpoint *,
struct sctp_association *asoc,
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 8a1f27a..6bcbeca 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1118,6 +1118,7 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
struct sctp_association *asoc =
container_of(work, struct sctp_association,
base.inqueue.immediate);
+ struct net *net = sock_net(asoc->base.sk);
struct sctp_endpoint *ep;
struct sctp_chunk *chunk;
struct sctp_inq *inqueue;
@@ -1150,13 +1151,13 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
if (sctp_chunk_is_data(chunk))
asoc->peer.last_data_from = chunk->transport;
else
- SCTP_INC_STATS(sock_net(asoc->base.sk), SCTP_MIB_INCTRLCHUNKS);
+ SCTP_INC_STATS(net, SCTP_MIB_INCTRLCHUNKS);
if (chunk->transport)
chunk->transport->last_time_heard = jiffies;
/* Run through the state machine. */
- error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype,
+ error = sctp_do_sm(net, SCTP_EVENT_T_CHUNK, subtype,
state, ep, asoc, chunk, GFP_ATOMIC);
/* Check to see if the association is freed in response to
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 3edca80..8315792 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -413,6 +413,7 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
base.inqueue.immediate);
struct sctp_association *asoc;
struct sock *sk;
+ struct net *net;
struct sctp_transport *transport;
struct sctp_chunk *chunk;
struct sctp_inq *inqueue;
@@ -427,6 +428,7 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
asoc = NULL;
inqueue = &ep->base.inqueue;
sk = ep->base.sk;
+ net = sock_net(sk);
while (NULL != (chunk = sctp_inq_pop(inqueue))) {
subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
@@ -483,7 +485,7 @@ normal:
if (chunk->transport)
chunk->transport->last_time_heard = jiffies;
- error = sctp_do_sm(SCTP_EVENT_T_CHUNK, subtype, state,
+ error = sctp_do_sm(net, SCTP_EVENT_T_CHUNK, subtype, state,
ep, asoc, chunk, GFP_ATOMIC);
if (error && chunk)
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 5308301..a2ceb70 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -466,11 +466,13 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
}
} else {
+ struct net *net = sock_net(sk);
+
if (timer_pending(&t->proto_unreach_timer) &&
del_timer(&t->proto_unreach_timer))
sctp_association_put(asoc);
- sctp_do_sm(SCTP_EVENT_T_OTHER,
+ sctp_do_sm(net, SCTP_EVENT_T_OTHER,
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
asoc->state, asoc->ep, asoc, t,
GFP_ATOMIC);
diff --git a/net/sctp/primitive.c b/net/sctp/primitive.c
index 534c7ea..794bb14 100644
--- a/net/sctp/primitive.c
+++ b/net/sctp/primitive.c
@@ -57,7 +57,7 @@
#define DECLARE_PRIMITIVE(name) \
/* This is called in the code as sctp_primitive_ ## name. */ \
-int sctp_primitive_ ## name(struct sctp_association *asoc, \
+int sctp_primitive_ ## name(struct net *net, struct sctp_association *asoc, \
void *arg) { \
int error = 0; \
sctp_event_t event_type; sctp_subtype_t subtype; \
@@ -69,7 +69,7 @@ int sctp_primitive_ ## name(struct sctp_association *asoc, \
state = asoc ? asoc->state : SCTP_STATE_CLOSED; \
ep = asoc ? asoc->ep : NULL; \
\
- error = sctp_do_sm(event_type, subtype, state, ep, asoc, \
+ error = sctp_do_sm(net, event_type, subtype, state, ep, asoc, \
arg, GFP_KERNEL); \
return error; \
}
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index fe99628..02c4c1c 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -251,6 +251,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
int error;
struct sctp_transport *transport = (struct sctp_transport *) peer;
struct sctp_association *asoc = transport->asoc;
+ struct net *net = sock_net(asoc->base.sk);
/* Check whether a task is in the sock. */
@@ -271,7 +272,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
goto out_unlock;
/* Run through the state machine. */
- error = sctp_do_sm(SCTP_EVENT_T_TIMEOUT,
+ error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_T3_RTX),
asoc->state,
asoc->ep, asoc,
@@ -291,6 +292,7 @@ out_unlock:
static void sctp_generate_timeout_event(struct sctp_association *asoc,
sctp_event_timeout_t timeout_type)
{
+ struct net *net = sock_net(asoc->base.sk);
int error = 0;
sctp_bh_lock_sock(asoc->base.sk);
@@ -312,7 +314,7 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc,
goto out_unlock;
/* Run through the state machine. */
- error = sctp_do_sm(SCTP_EVENT_T_TIMEOUT,
+ error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
SCTP_ST_TIMEOUT(timeout_type),
asoc->state, asoc->ep, asoc,
(void *)timeout_type, GFP_ATOMIC);
@@ -371,6 +373,7 @@ void sctp_generate_heartbeat_event(unsigned long data)
int error = 0;
struct sctp_transport *transport = (struct sctp_transport *) data;
struct sctp_association *asoc = transport->asoc;
+ struct net *net = sock_net(asoc->base.sk);
sctp_bh_lock_sock(asoc->base.sk);
if (sock_owned_by_user(asoc->base.sk)) {
@@ -388,7 +391,7 @@ void sctp_generate_heartbeat_event(unsigned long data)
if (transport->dead)
goto out_unlock;
- error = sctp_do_sm(SCTP_EVENT_T_TIMEOUT,
+ error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_HEARTBEAT),
asoc->state, asoc->ep, asoc,
transport, GFP_ATOMIC);
@@ -408,6 +411,7 @@ void sctp_generate_proto_unreach_event(unsigned long data)
{
struct sctp_transport *transport = (struct sctp_transport *) data;
struct sctp_association *asoc = transport->asoc;
+ struct net *net = sock_net(asoc->base.sk);
sctp_bh_lock_sock(asoc->base.sk);
if (sock_owned_by_user(asoc->base.sk)) {
@@ -426,7 +430,7 @@ void sctp_generate_proto_unreach_event(unsigned long data)
if (asoc->base.dead)
goto out_unlock;
- sctp_do_sm(SCTP_EVENT_T_OTHER,
+ sctp_do_sm(net, SCTP_EVENT_T_OTHER,
SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);
@@ -753,8 +757,10 @@ static int sctp_cmd_process_sack(sctp_cmd_seq_t *cmds,
int err = 0;
if (sctp_outq_sack(&asoc->outqueue, sackh)) {
+ struct net *net = sock_net(asoc->base.sk);
+
/* There are no more TSNs awaiting SACK. */
- err = sctp_do_sm(SCTP_EVENT_T_OTHER,
+ err = sctp_do_sm(net, SCTP_EVENT_T_OTHER,
SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN),
asoc->state, asoc->ep, asoc, NULL,
GFP_ATOMIC);
@@ -1042,6 +1048,8 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc,
*/
static void sctp_cmd_send_asconf(struct sctp_association *asoc)
{
+ struct net *net = sock_net(asoc->base.sk);
+
/* Send the next asconf chunk from the addip chunk
* queue.
*/
@@ -1053,7 +1061,7 @@ static void sctp_cmd_send_asconf(struct sctp_association *asoc)
/* Hold the chunk until an ASCONF_ACK is received. */
sctp_chunk_hold(asconf);
- if (sctp_primitive_ASCONF(asoc, asconf))
+ if (sctp_primitive_ASCONF(net, asoc, asconf))
sctp_chunk_free(asconf);
else
asoc->addip_last_asconf = asconf;
@@ -1089,7 +1097,7 @@ static void sctp_cmd_send_asconf(struct sctp_association *asoc)
* If you want to understand all of lksctp, this is a
* good place to start.
*/
-int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
+int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
sctp_state_t state,
struct sctp_endpoint *ep,
struct sctp_association *asoc,
@@ -1110,7 +1118,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
/* Look up the state function, run it, and then process the
* side effects. These three steps are the heart of lksctp.
*/
- state_fn = sctp_sm_lookup_event(event_type, state, subtype);
+ state_fn = sctp_sm_lookup_event(net, event_type, state, subtype);
sctp_init_cmd_seq(&commands);
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 7c211a7..4a029d7 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -59,7 +59,8 @@ other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES];
static const sctp_sm_table_entry_t
timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES];
-static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net,
+ sctp_cid_t cid,
sctp_state_t state);
@@ -82,13 +83,14 @@ static const sctp_sm_table_entry_t bug = {
rtn; \
})
-const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
+const sctp_sm_table_entry_t *sctp_sm_lookup_event(struct net *net,
+ sctp_event_t event_type,
sctp_state_t state,
sctp_subtype_t event_subtype)
{
switch (event_type) {
case SCTP_EVENT_T_CHUNK:
- return sctp_chunk_event_lookup(event_subtype.chunk, state);
+ return sctp_chunk_event_lookup(net, event_subtype.chunk, state);
case SCTP_EVENT_T_TIMEOUT:
return DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout,
timeout_event_table);
@@ -906,7 +908,8 @@ static const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][S
TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
};
-static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
+static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(struct net *net,
+ sctp_cid_t cid,
sctp_state_t state)
{
if (state > SCTP_STATE_MAX)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5b6dd0e..a6a4226 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -427,6 +427,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
static int sctp_send_asconf(struct sctp_association *asoc,
struct sctp_chunk *chunk)
{
+ struct net *net = sock_net(asoc->base.sk);
int retval = 0;
/* If there is an outstanding ASCONF chunk, queue it for later
@@ -439,7 +440,7 @@ static int sctp_send_asconf(struct sctp_association *asoc,
/* Hold the chunk until an ASCONF_ACK is received. */
sctp_chunk_hold(chunk);
- retval = sctp_primitive_ASCONF(asoc, chunk);
+ retval = sctp_primitive_ASCONF(net, asoc, chunk);
if (retval)
sctp_chunk_free(chunk);
else
@@ -1050,6 +1051,7 @@ static int __sctp_connect(struct sock* sk,
int addrs_size,
sctp_assoc_t *assoc_id)
{
+ struct net *net = sock_net(sk);
struct sctp_sock *sp;
struct sctp_endpoint *ep;
struct sctp_association *asoc = NULL;
@@ -1200,7 +1202,7 @@ static int __sctp_connect(struct sock* sk,
goto out_free;
}
- err = sctp_primitive_ASSOCIATE(asoc, NULL);
+ err = sctp_primitive_ASSOCIATE(net, asoc, NULL);
if (err < 0) {
goto out_free;
}
@@ -1458,6 +1460,7 @@ SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
*/
SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
{
+ struct net *net = sock_net(sk);
struct sctp_endpoint *ep;
struct sctp_association *asoc;
struct list_head *pos, *temp;
@@ -1499,9 +1502,9 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
chunk = sctp_make_abort_user(asoc, NULL, 0);
if (chunk)
- sctp_primitive_ABORT(asoc, chunk);
+ sctp_primitive_ABORT(net, asoc, chunk);
} else
- sctp_primitive_SHUTDOWN(asoc, NULL);
+ sctp_primitive_SHUTDOWN(net, asoc, NULL);
}
/* On a TCP-style socket, block for at most linger_time if set. */
@@ -1569,6 +1572,7 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *, sctp_cmsgs_t *);
SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t msg_len)
{
+ struct net *net = sock_net(sk);
struct sctp_sock *sp;
struct sctp_endpoint *ep;
struct sctp_association *new_asoc=NULL, *asoc=NULL;
@@ -1714,7 +1718,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
if (sinfo_flags & SCTP_EOF) {
SCTP_DEBUG_PRINTK("Shutting down association: %p\n",
asoc);
- sctp_primitive_SHUTDOWN(asoc, NULL);
+ sctp_primitive_SHUTDOWN(net, asoc, NULL);
err = 0;
goto out_unlock;
}
@@ -1727,7 +1731,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
}
SCTP_DEBUG_PRINTK("Aborting association: %p\n", asoc);
- sctp_primitive_ABORT(asoc, chunk);
+ sctp_primitive_ABORT(net, asoc, chunk);
err = 0;
goto out_unlock;
}
@@ -1900,7 +1904,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
/* Auto-connect, if we aren't connected already. */
if (sctp_state(asoc, CLOSED)) {
- err = sctp_primitive_ASSOCIATE(asoc, NULL);
+ err = sctp_primitive_ASSOCIATE(net, asoc, NULL);
if (err < 0)
goto out_free;
SCTP_DEBUG_PRINTK("We associated primitively.\n");
@@ -1928,7 +1932,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
* works that way today. Keep it that way or this
* breaks.
*/
- err = sctp_primitive_SEND(asoc, datamsg);
+ err = sctp_primitive_SEND(net, asoc, datamsg);
/* Did the lower layer accept the chunk? */
if (err)
sctp_datamsg_free(datamsg);
@@ -2320,7 +2324,9 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
int error;
if (params->spp_flags & SPP_HB_DEMAND && trans) {
- error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans);
+ struct net *net = sock_net(trans->asoc->base.sk);
+
+ error = sctp_primitive_REQUESTHEARTBEAT(net, trans->asoc, trans);
if (error)
return error;
}
@@ -4011,6 +4017,7 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
*/
SCTP_STATIC void sctp_shutdown(struct sock *sk, int how)
{
+ struct net *net = sock_net(sk);
struct sctp_endpoint *ep;
struct sctp_association *asoc;
@@ -4022,7 +4029,7 @@ SCTP_STATIC void sctp_shutdown(struct sock *sk, int how)
if (!list_empty(&ep->asocs)) {
asoc = list_entry(ep->asocs.next,
struct sctp_association, asocs);
- sctp_primitive_SHUTDOWN(asoc, NULL);
+ sctp_primitive_SHUTDOWN(net, asoc, NULL);
}
}
}
--
1.7.5.4
^ permalink raw reply related
* [PATCH net-next 1/7] sctp: Add infrastructure for per net sysctls
From: Eric W. Biederman @ 2012-08-07 17:23 UTC (permalink / raw)
To: David Miller
Cc: Vlad Yasevich, linux-sctp, netdev, linux-kernel, Jan Ariyasu,
Jan Ariyasu, Neil Horman, Thomas Graf, Xi Wang
In-Reply-To: <87ipcud3ld.fsf_-_@xmission.com>
Start with an empty sctp_net_table that will be populated as the various
tunable sysctls are made per net.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
include/net/netns/sctp.h | 6 +++++-
include/net/sctp/sctp.h | 4 ++++
net/sctp/protocol.c | 7 +++++++
net/sctp/sysctl.c | 21 +++++++++++++++++++++
4 files changed, 37 insertions(+), 1 deletions(-)
diff --git a/include/net/netns/sctp.h b/include/net/netns/sctp.h
index 06ccddf..9576b60 100644
--- a/include/net/netns/sctp.h
+++ b/include/net/netns/sctp.h
@@ -4,6 +4,7 @@
struct sock;
struct proc_dir_entry;
struct sctp_mib;
+struct ctl_table_header;
struct netns_sctp {
DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics);
@@ -11,7 +12,9 @@ struct netns_sctp {
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_net_sctp;
#endif
-
+#ifdef CONFIG_SYSCTL
+ struct ctl_table_header *sysctl_header;
+#endif
/* This is the global socket data structure used for responding to
* the Out-of-the-blue (OOTB) packets. A control sock will be created
* for this socket at the initialization time.
@@ -32,6 +35,7 @@ struct netns_sctp {
/* Lock that protects the local_addr_list writers */
spinlock_t local_addr_lock;
+
};
#endif /* __NETNS_SCTP_H__ */
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index b0e6fe5..15037e7 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -375,9 +375,13 @@ static inline void sctp_dbg_objcnt_exit(void) { return; }
#if defined CONFIG_SYSCTL
void sctp_sysctl_register(void);
void sctp_sysctl_unregister(void);
+int sctp_sysctl_net_register(struct net *net);
+void sctp_sysctl_net_unregister(struct net *net);
#else
static inline void sctp_sysctl_register(void) { return; }
static inline void sctp_sysctl_unregister(void) { return; }
+static inline int sctp_sysctl_net_register(struct net *net) { return 0; }
+static inline void sctp_sysctl_net_unregister(struct net *net) { return; }
#endif
/* Size of Supported Address Parameter for 'x' address types. */
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 69bdc72..de25d9c 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1169,6 +1169,10 @@ static int sctp_net_init(struct net *net)
{
int status;
+ status = sctp_sysctl_net_register(net);
+ if (status)
+ goto err_sysctl_register;
+
/* Allocate and initialise sctp mibs. */
status = init_sctp_mibs(net);
if (status)
@@ -1205,6 +1209,8 @@ err_ctl_sock_init:
err_init_proc:
cleanup_sctp_mibs(net);
err_init_mibs:
+ sctp_sysctl_net_unregister(net);
+err_sysctl_register:
return status;
}
@@ -1219,6 +1225,7 @@ static void sctp_net_exit(struct net *net)
sctp_proc_exit(net);
cleanup_sctp_mibs(net);
+ sctp_sysctl_net_unregister(net);
}
static struct pernet_operations sctp_net_ops = {
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 2b2bfe9..7528d59 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -284,6 +284,27 @@ static ctl_table sctp_table[] = {
{ /* sentinel */ }
};
+static ctl_table sctp_net_table[] = {
+ { /* sentinel */ }
+};
+
+int sctp_sysctl_net_register(struct net *net)
+{
+ struct ctl_table *table;
+
+ table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
+ if (!table)
+ return -ENOMEM;
+
+ net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
+ return 0;
+}
+
+void sctp_sysctl_net_unregister(struct net *net)
+{
+ unregister_net_sysctl_table(net->sctp.sysctl_header);
+}
+
static struct ctl_table_header * sctp_sysctl_header;
/* Sysctl registration. */
--
1.7.5.4
^ permalink raw reply related
* Re: [PATCH net-next 0/7] sctp: network namespace support Part 2: per net tunables
From: Eric W. Biederman @ 2012-08-07 17:17 UTC (permalink / raw)
To: David Miller
Cc: Vlad Yasevich, linux-sctp, netdev, linux-kernel, Jan Ariyasu,
Jan Ariyasu, Neil Horman, Thomas Graf, Xi Wang
In-Reply-To: <87zk67q31q.fsf_-_@xmission.com>
Since I am motivated to get things done, and since there has been much
grumbling about my patches not implementing tunables, I have added
tunable support on top of my last patchset.
I have performed basic testing on the these patches and nothing
appears amis.
The sm statemachine is a major tease as it has all of these association
and endpoint pointers in the common set of function parameters that turn
out to be NULL at the most inconvinient times. So I added to the common
parameter list a struct net pointer, that is never NULL.
include/net/netns/sctp.h | 96 +++++++-
include/net/sctp/sctp.h | 16 +-
include/net/sctp/sm.h | 8 +-
include/net/sctp/structs.h | 126 +---------
net/sctp/associola.c | 18 +-
net/sctp/auth.c | 20 ++-
net/sctp/bind_addr.c | 6 +-
net/sctp/endpointola.c | 13 +-
net/sctp/input.c | 6 +-
net/sctp/primitive.c | 4 +-
net/sctp/protocol.c | 137 +++++-----
net/sctp/sm_make_chunk.c | 61 +++--
net/sctp/sm_sideeffect.c | 26 ++-
net/sctp/sm_statefuns.c | 631 ++++++++++++++++++++++++--------------------
net/sctp/sm_statetable.c | 17 +-
net/sctp/socket.c | 92 ++++---
net/sctp/sysctl.c | 200 ++++++++------
net/sctp/transport.c | 23 +-
18 files changed, 817 insertions(+), 683 deletions(-)
Eric W. Biederman (7):
sctp: Add infrastructure for per net sysctls
sctp: Push struct net down to sctp_chunk_event_lookup
sctp: Push struct net down into sctp_transport_init
sctp: Push struct net down into sctp_in_scope
sctp: Push struct net down into all of the state machine functions
sctp: Push struct net down into sctp_verify_ext_param
sctp: Making sysctl tunables per net
Eric
^ permalink raw reply
* Re: [PATCH] netdev/phy: skip disabled mdio-mux nodes
From: Timur Tabi @ 2012-08-07 17:04 UTC (permalink / raw)
To: David Daney
Cc: david.daney-YGCgFSpz5w/QT0dZR+AlfA, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
Rob Herring, David Miller
In-Reply-To: <5021496D.8070200-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
David Daney wrote:
> Although this will get the job done, I don't think it is the cleanest
> approach.
>
> Would it be better to create a new iterator
> (for_each_available_child_of_node perhaps) that skips the unavailable
> nodes? This seems like a general problem that is not restricted to mdio
> multiplexers.
You're probably right, but this is how it's normally done. If you're
going to scan child nodes manually, you have to skip disabled nodes.
If someone else wants to implement for_each_available_child_of_node(), I'm
all for it, but such a patch would not be merged until 3.7. I was hoping
to have my patch applied to 3.6, since it fixes a real bug.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* Re: [PATCH] netdev/phy: skip disabled mdio-mux nodes
From: David Daney @ 2012-08-07 16:59 UTC (permalink / raw)
To: Timur Tabi, Grant Likely, Rob Herring
Cc: david.daney, David Miller, netdev,
devicetree-discuss@lists.ozlabs.org
In-Reply-To: <1344358266-5450-1-git-send-email-timur@freescale.com>
On 08/07/2012 09:51 AM, Timur Tabi wrote:
> The mdio-mux driver scans all child mdio nodes, without regard to whether
> the node is actually used. Some device trees include all possible
> mdio-mux nodes and rely on the boot loader to disable those that are not
> present, based on some run-time configuration. Those nodes need to be
> skipped.
>
> Signed-off-by: Timur Tabi<timur@freescale.com>
> ---
> drivers/net/phy/mdio-mux.c | 9 +++++++++
> 1 files changed, 9 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c
> index 5c12018..d0c231e 100644
> --- a/drivers/net/phy/mdio-mux.c
> +++ b/drivers/net/phy/mdio-mux.c
> @@ -135,6 +135,15 @@ int mdio_mux_init(struct device *dev,
> for_each_child_of_node(dev->of_node, child_bus_node) {
> u32 v;
>
> + /*
> + * Some device trees include all possible mdio-mux nodes and
> + * rely on the boot loader to disable those that are not
> + * present, based on some run-time configuration. Those nodes
> + * need to be skipped.
> + */
> + if (!of_device_is_available(child_bus_node))
> + continue;
Although this will get the job done, I don't think it is the cleanest
approach.
Would it be better to create a new iterator
(for_each_available_child_of_node perhaps) that skips the unavailable
nodes? This seems like a general problem that is not restricted to mdio
multiplexers.
David Daney
^ permalink raw reply
* Re: [PATCH] net: fib: fix incorrect call_rcu_bh()
From: Paul E. McKenney @ 2012-08-07 16:34 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1344336431.28967.14.camel@edumazet-glaptop>
On Tue, Aug 07, 2012 at 12:47:11PM +0200, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> After IP route cache removal, I believe rcu_bh() has very little use and
> we should remove this RCU variant, since it adds some cycles in fast
> path.
Do you mean remove all uses of RCU-bh globally and also removing the
implementation itself? That would actually be a good thing, from my
perspective.
Or were you meaning something more localized?
Thanx, Paul
> Anyway, the call_rcu_bh() use in fib_true is obviously wrong, since
> some users only assert rcu_read_lock().
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> ---
> net/ipv4/fib_trie.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
> index f0cdb30..57bd978 100644
> --- a/net/ipv4/fib_trie.c
> +++ b/net/ipv4/fib_trie.c
> @@ -367,7 +367,7 @@ static void __leaf_free_rcu(struct rcu_head *head)
>
> static inline void free_leaf(struct leaf *l)
> {
> - call_rcu_bh(&l->rcu, __leaf_free_rcu);
> + call_rcu(&l->rcu, __leaf_free_rcu);
> }
>
> static inline void free_leaf_info(struct leaf_info *leaf)
>
>
^ permalink raw reply
* [PATCH] netdev/phy: skip disabled mdio-mux nodes
From: Timur Tabi @ 2012-08-07 16:51 UTC (permalink / raw)
To: david.daney, David Miller, netdev
The mdio-mux driver scans all child mdio nodes, without regard to whether
the node is actually used. Some device trees include all possible
mdio-mux nodes and rely on the boot loader to disable those that are not
present, based on some run-time configuration. Those nodes need to be
skipped.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
drivers/net/phy/mdio-mux.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c
index 5c12018..d0c231e 100644
--- a/drivers/net/phy/mdio-mux.c
+++ b/drivers/net/phy/mdio-mux.c
@@ -135,6 +135,15 @@ int mdio_mux_init(struct device *dev,
for_each_child_of_node(dev->of_node, child_bus_node) {
u32 v;
+ /*
+ * Some device trees include all possible mdio-mux nodes and
+ * rely on the boot loader to disable those that are not
+ * present, based on some run-time configuration. Those nodes
+ * need to be skipped.
+ */
+ if (!of_device_is_available(child_bus_node))
+ continue;
+
r = of_property_read_u32(child_bus_node, "reg", &v);
if (r)
continue;
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH] net: fib: fix incorrect call_rcu_bh()
From: Eric Dumazet @ 2012-08-07 16:48 UTC (permalink / raw)
To: paulmck; +Cc: David Miller, netdev
In-Reply-To: <20120807163454.GF2378@linux.vnet.ibm.com>
On Tue, 2012-08-07 at 09:34 -0700, Paul E. McKenney wrote:
> On Tue, Aug 07, 2012 at 12:47:11PM +0200, Eric Dumazet wrote:
> > From: Eric Dumazet <edumazet@google.com>
> >
> > After IP route cache removal, I believe rcu_bh() has very little use and
> > we should remove this RCU variant, since it adds some cycles in fast
> > path.
>
> Do you mean remove all uses of RCU-bh globally and also removing the
> implementation itself? That would actually be a good thing, from my
> perspective.
>
Yes I meant that there are now too few rcu_bh users, and that they
probably could switch to regular rcu.
We could then remove the implementation.
rcu_bh was needed because we could sit forever in softirq mode in one
cpu, and we needed to allocate/free dsts with RCU protection.
^ permalink raw reply
* [PATCH] net: force dst_default_metrics to const section
From: Eric Dumazet @ 2012-08-07 16:11 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
While investigating on network performance problems, I found this little
gem :
$ nm -v vmlinux | grep -1 dst_default_metrics
ffffffff82736540 b busy.46605
ffffffff82736560 B dst_default_metrics
ffffffff82736598 b dst_busy_list
Apparently, declaring a const array without initializer put it in
(writeable) bss section, in middle of possibly often dirtied cache
lines.
Since we really want dst_default_metrics be const to avoid any possible
false sharing and catch any buggy writes, I force a null initializer.
ffffffff818a4c20 R dst_default_metrics
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
For reference, dst_default_metrics was added in 2.6.39
net/core/dst.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/net/core/dst.c b/net/core/dst.c
index 069d51d..4c538be 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -149,7 +149,15 @@ int dst_discard(struct sk_buff *skb)
}
EXPORT_SYMBOL(dst_discard);
-const u32 dst_default_metrics[RTAX_MAX];
+const u32 dst_default_metrics[RTAX_MAX] = {
+ /* This initializer is needed to force linker to place this variable
+ * into const section. Otherwise it might end into bss section.
+ * We really want to avoid false sharing on this variable, and catch
+ * any writes on it.
+ */
+ 0
+};
+
void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
int initial_ref, int initial_obsolete, unsigned short flags)
^ permalink raw reply related
* Re: Adding routes to another table: no such process
From: Ignacy Gawędzki @ 2012-08-07 15:57 UTC (permalink / raw)
To: netdev
In-Reply-To: <20120807141306.GB32655@zenon.in.qult.net>
On Tue, Aug 07, 2012 at 04:13:06PM +0200, thus spake Ignacy Gawedzki:
> Hi,
>
> I'm having a hard time setting some routes on a router and can't find any
> relevant information anywhere, so I resort to asking on this list.
>
> The router has one interface, say eth0, with configured address 10.0.0.1/32.
>
> Now I would like to do:
>
> ip rule add from 10.0.0.1 table 100
> ip route add 10.0.0.2/32 dev eth0 table 100
> ip route add 10.0.0.3/32 via 10.0.0.2 table 100
>
> but I get
>
> RTNETLINK answers: No such process
Okay, I think I got it right, at last. Apparently it all depends on how the
rules are set up.
The rule to lookup table 100 when the source address is 10.0.0.1 doesn't
concern the general situation of route to 10.0.0.2/32 (for which packets may
have any source address).
The solution in my case is to put
ip rule add to 10.0.0.0/8 table 100
Cheers,
Ignacy
--
:wq!
^ permalink raw reply
* Re: [PATCH v3 3/7] mv643xx.c: Add basic device tree support.
From: Ian Molton @ 2012-08-07 15:56 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-arm-kernel, andrew, thomas.petazzoni, ben.dooks, netdev
In-Reply-To: <201208071456.41412.arnd@arndb.de>
On 07/08/12 15:56, Arnd Bergmann wrote:
> Hi Ian,
>
> Have you had a look at Documentation/devicetree/bindings/marvell.txt
> ?
Nope. I had no idea it was hiding there.
> I think it documents some of the same thing,
Not really. It documents some godawful hack that recycled the platform
device -based driver and provided a DT binding for it, just for PPC.
I cant even *find* anything that implements code for whatever
"marvell,mv64360-mdio" might be. I'm sure it might exist somewhere.
> We might also want to move some of the
> code from arch/powerpc/sysdev/mv64x60_dev.c to live in the same place
> as the device driver.
I hope not. I don't really want to touch that stuff at all. If it works
the way it
is, then it can stay that way. If the PPC folk want to send patches to
add the
properties they use to the driver, then they can do. I'll send an email
their
way and see if they want to join in.
>From my perspective, the next thing that needs to happen to the driver is
for it to be broken up into ethernet and mdio drivers, so that we can
get rid
of all this shared_smi craziness... But that's for another patch series.
-Ian
^ permalink raw reply
* Re: [Resend PATCH 7/8] bridge: add some comments for NETDEV_RELEASE
From: Cong Wang @ 2012-08-07 15:13 UTC (permalink / raw)
To: David Miller; +Cc: netdev, shemminger
In-Reply-To: <20120807.001036.438256708920992598.davem@davemloft.net>
On Tue, 2012-08-07 at 00:10 -0700, David Miller wrote:
> You must repost the entire series when you respinning patches in
> response to feedback, thank you.
Okay. Will do!
^ permalink raw reply
* Adding routes to another table: no such process
From: Ignacy Gawędzki @ 2012-08-07 14:13 UTC (permalink / raw)
To: netdev
Hi,
I'm having a hard time setting some routes on a router and can't find any
relevant information anywhere, so I resort to asking on this list.
The router has one interface, say eth0, with configured address 10.0.0.1/32.
Now I would like to do:
ip rule add from 10.0.0.1 table 100
ip route add 10.0.0.2/32 dev eth0 table 100
ip route add 10.0.0.3/32 via 10.0.0.2 table 100
but I get
RTNETLINK answers: No such process
on the third command. It's just as though the kernel refused to use a
gateway for which there's no route in the main table. Is this an actual
requirement for gateways? I could find some examples around the web setting
routes with gateways in other tables than main, but they obviously don't work,
yielding the same error message.
Thanks for your help.
Ignacy
--
The groove will take you through times without money
much better than money will take you through times without groove.
^ permalink raw reply
* Re: [PATCH v3 3/7] mv643xx.c: Add basic device tree support.
From: Arnd Bergmann @ 2012-08-07 14:56 UTC (permalink / raw)
To: Ian Molton; +Cc: linux-arm-kernel, andrew, thomas.petazzoni, ben.dooks, netdev
In-Reply-To: <1344350092-24050-4-git-send-email-ian.molton@codethink.co.uk>
On Tuesday 07 August 2012, Ian Molton wrote:
> This patch adds basic device tree support to the mv643xx ethernet driver.
>
> It should be enough for most current users of the device, and should allow
> a painless migration.
>
> Signed-off-by: Ian Molton <ian.molton@codethink.co.uk>
> ---
> Documentation/devicetree/bindings/net/mv643xx.txt | 75 +++++++++++++++++
> drivers/net/ethernet/marvell/mv643xx_eth.c | 93 +++++++++++++++++++--
> 2 files changed, 161 insertions(+), 7 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/net/mv643xx.txt
Hi Ian,
Have you had a look at Documentation/devicetree/bindings/marvell.txt ?
I think it documents some of the same thing, so it would be good
to keep all of that in one place. We might also want to move
some of the code from arch/powerpc/sysdev/mv64x60_dev.c
to live in the same place as the device driver.
Arnd
^ permalink raw reply
* [PATCH v3 6/7] DT: Convert all kirkwood boards with mv643xx that use DT
From: Ian Molton @ 2012-08-07 14:34 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: andrew, thomas.petazzoni, ben.dooks, arnd, netdev
In-Reply-To: <1344350092-24050-1-git-send-email-ian.molton@codethink.co.uk>
This patch converts all present DT capable kirkwood board configurations
to use DT to configure the mv643xx ethernet controller.
Signed-off-by: Ian Molton <ian.molton@codethink.co.uk>
---
arch/arm/boot/dts/kirkwood-dnskw.dtsi | 9 +++++++++
arch/arm/boot/dts/kirkwood-dreamplug.dts | 18 ++++++++++++++++++
arch/arm/boot/dts/kirkwood-goflexnet.dts | 8 ++++++++
arch/arm/boot/dts/kirkwood-ib62x0.dts | 10 ++++++++++
arch/arm/boot/dts/kirkwood-iconnect.dts | 10 ++++++++++
arch/arm/boot/dts/kirkwood-lsxl.dtsi | 17 +++++++++++++++++
arch/arm/boot/dts/kirkwood-ts219-6281.dts | 8 +++++++-
arch/arm/boot/dts/kirkwood-ts219-6282.dts | 8 +++++++-
arch/arm/boot/dts/kirkwood-ts219.dtsi | 3 +++
arch/arm/mach-kirkwood/board-dnskw.c | 7 +------
arch/arm/mach-kirkwood/board-dreamplug.c | 13 ++-----------
arch/arm/mach-kirkwood/board-goflexnet.c | 7 +------
arch/arm/mach-kirkwood/board-ib62x0.c | 7 +------
arch/arm/mach-kirkwood/board-iconnect.c | 7 +------
arch/arm/mach-kirkwood/board-lsxl.c | 13 ++-----------
arch/arm/mach-kirkwood/board-ts219.c | 10 +---------
16 files changed, 98 insertions(+), 57 deletions(-)
diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
index 7408655..214fe0b 100644
--- a/arch/arm/boot/dts/kirkwood-dnskw.dtsi
+++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi
@@ -65,5 +65,14 @@
reg = <0x7b00000 0x500000>;
};
};
+
+ smi0: mdio@72000 {
+ status = "ok";
+ };
+
+ egiga0 {
+ phy_addr = <8>;
+ status = "ok";
+ };
};
};
diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts
index 26e281f..c27ed1c 100644
--- a/arch/arm/boot/dts/kirkwood-dreamplug.dts
+++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts
@@ -53,6 +53,24 @@
status = "okay";
nr-ports = <1>;
};
+
+ smi0: mdio@72000 {
+ status = "ok";
+ };
+
+ smi1: mdio@76000 {
+ status = "ok";
+ };
+
+ egiga0 {
+ phy_addr = <0>;
+ status = "ok";
+ };
+
+ egiga1 {
+ phy_addr = <1>;
+ status = "ok";
+ };
};
gpio-leds {
diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts
index 7c8238f..f03dbd0 100644
--- a/arch/arm/boot/dts/kirkwood-goflexnet.dts
+++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts
@@ -50,6 +50,14 @@
nr-ports = <2>;
};
+ smi0: mdio@72000 {
+ status = "ok";
+ };
+
+ egiga0 {
+ phy_addr = <0>;
+ status = "ok";
+ };
};
gpio-leds {
compatible = "gpio-leds";
diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts
index 66794ed..8c462a1 100644
--- a/arch/arm/boot/dts/kirkwood-ib62x0.dts
+++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts
@@ -45,6 +45,16 @@
};
};
+
+ smi0: mdio@72000 {
+ status = "ok";
+ };
+
+ egiga0 {
+ phy_addr = <8>;
+ status = "ok";
+ };
+
};
gpio_keys {
diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts
index 52d9470..9fc82be 100644
--- a/arch/arm/boot/dts/kirkwood-iconnect.dts
+++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
@@ -30,6 +30,16 @@
clock-frequency = <200000000>;
status = "ok";
};
+
+ smi0: mdio@72000 {
+ status = "ok";
+ };
+
+ egiga0 {
+ phy_addr = <b>;
+ status = "ok";
+ };
+
};
gpio-leds {
compatible = "gpio-leds";
diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
index 8ac51c0..2f47661 100644
--- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi
+++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
@@ -40,6 +40,23 @@
};
};
};
+ smi0: mdio@72000 {
+ status = "ok";
+ };
+
+ smi1: mdio@76000 {
+ status = "ok";
+ };
+
+ egiga0 {
+ phy_addr = <0>;
+ status = "ok";
+ };
+
+ egiga1 {
+ phy_addr = <8>;
+ status = "ok";
+ };
};
gpio_keys {
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6281.dts b/arch/arm/boot/dts/kirkwood-ts219-6281.dts
index ccbf327..4ca49b5 100644
--- a/arch/arm/boot/dts/kirkwood-ts219-6281.dts
+++ b/arch/arm/boot/dts/kirkwood-ts219-6281.dts
@@ -3,6 +3,12 @@
/include/ "kirkwood-ts219.dtsi"
/ {
+ ocp@f1000000 {
+ egiga0 {
+ phy_addr = <8>;
+ status = "ok";
+ };
+ };
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
@@ -18,4 +24,4 @@
gpios = <&gpio0 16 1>;
};
};
-};
\ No newline at end of file
+};
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/kirkwood-ts219-6282.dts
index fbe9932..40f3c61 100644
--- a/arch/arm/boot/dts/kirkwood-ts219-6282.dts
+++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts
@@ -3,6 +3,12 @@
/include/ "kirkwood-ts219.dtsi"
/ {
+ ocp@f1000000 {
+ egiga0 {
+ phy_addr = <0>;
+ status = "ok";
+ };
+ };
gpio_keys {
compatible = "gpio-keys";
#address-cells = <1>;
@@ -18,4 +24,4 @@
gpios = <&gpio1 5 1>;
};
};
-};
\ No newline at end of file
+};
diff --git a/arch/arm/boot/dts/kirkwood-ts219.dtsi b/arch/arm/boot/dts/kirkwood-ts219.dtsi
index 64ea27c..06caf41 100644
--- a/arch/arm/boot/dts/kirkwood-ts219.dtsi
+++ b/arch/arm/boot/dts/kirkwood-ts219.dtsi
@@ -74,5 +74,8 @@
status = "okay";
nr-ports = <2>;
};
+ smi0: mdio@72000 {
+ status = "ok";
+ };
};
};
diff --git a/arch/arm/mach-kirkwood/board-dnskw.c b/arch/arm/mach-kirkwood/board-dnskw.c
index 4ab3506..4d8216b 100644
--- a/arch/arm/mach-kirkwood/board-dnskw.c
+++ b/arch/arm/mach-kirkwood/board-dnskw.c
@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
-#include <linux/mv643xx_eth.h>
#include <linux/of.h>
#include <linux/gpio.h>
#include <linux/input.h>
@@ -29,10 +28,6 @@
#include "common.h"
#include "mpp.h"
-static struct mv643xx_eth_platform_data dnskw_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
static unsigned int dnskw_mpp_config[] __initdata = {
MPP13_UART1_TXD, /* Custom ... */
MPP14_UART1_RXD, /* ... Controller (DNS-320 only) */
@@ -112,7 +107,7 @@ void __init dnskw_init(void)
kirkwood_mpp_conf(dnskw_mpp_config);
kirkwood_ehci_init();
- kirkwood_ge00_init(&dnskw_ge00_data);
+ kirkwood_ge00_init(NULL);
platform_device_register(&dnskw_fan_device);
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c
index aeb234d..b97a112 100644
--- a/arch/arm/mach-kirkwood/board-dreamplug.c
+++ b/arch/arm/mach-kirkwood/board-dreamplug.c
@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
-#include <linux/mv643xx_eth.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
@@ -34,14 +33,6 @@
#include "common.h"
#include "mpp.h"
-static struct mv643xx_eth_platform_data dreamplug_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
-};
-
-static struct mv643xx_eth_platform_data dreamplug_ge01_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(1),
-};
-
static struct mvsdio_platform_data dreamplug_mvsdio_data = {
/* unfortunately the CD signal has not been connected */
};
@@ -65,7 +56,7 @@ void __init dreamplug_init(void)
kirkwood_mpp_conf(dreamplug_mpp_config);
kirkwood_ehci_init();
- kirkwood_ge00_init(&dreamplug_ge00_data);
- kirkwood_ge01_init(&dreamplug_ge01_data);
+ kirkwood_ge00_init(NULL);
+ kirkwood_ge01_init(NULL);
kirkwood_sdio_init(&dreamplug_mvsdio_data);
}
diff --git a/arch/arm/mach-kirkwood/board-goflexnet.c b/arch/arm/mach-kirkwood/board-goflexnet.c
index 413e2c8..be7437d 100644
--- a/arch/arm/mach-kirkwood/board-goflexnet.c
+++ b/arch/arm/mach-kirkwood/board-goflexnet.c
@@ -20,7 +20,6 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
-#include <linux/mv643xx_eth.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
@@ -36,10 +35,6 @@
#include "common.h"
#include "mpp.h"
-static struct mv643xx_eth_platform_data goflexnet_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
-};
-
static unsigned int goflexnet_mpp_config[] __initdata = {
MPP29_GPIO, /* USB Power Enable */
MPP47_GPIO, /* LED Orange */
@@ -67,5 +62,5 @@ void __init goflexnet_init(void)
pr_err("can't setup GPIO 29 (USB Power Enable)\n");
kirkwood_ehci_init();
- kirkwood_ge00_init(&goflexnet_ge00_data);
+ kirkwood_ge00_init(NULL);
}
diff --git a/arch/arm/mach-kirkwood/board-ib62x0.c b/arch/arm/mach-kirkwood/board-ib62x0.c
index cfc47f8..0a29183 100644
--- a/arch/arm/mach-kirkwood/board-ib62x0.c
+++ b/arch/arm/mach-kirkwood/board-ib62x0.c
@@ -16,7 +16,6 @@
#include <linux/platform_device.h>
#include <linux/mtd/partitions.h>
#include <linux/ata_platform.h>
-#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <asm/mach-types.h>
@@ -27,10 +26,6 @@
#define IB62X0_GPIO_POWER_OFF 24
-static struct mv643xx_eth_platform_data ib62x0_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
static unsigned int ib62x0_mpp_config[] __initdata = {
MPP0_NF_IO2,
MPP1_NF_IO3,
@@ -62,7 +57,7 @@ void __init ib62x0_init(void)
kirkwood_mpp_conf(ib62x0_mpp_config);
kirkwood_ehci_init();
- kirkwood_ge00_init(&ib62x0_ge00_data);
+ kirkwood_ge00_init(NULL);
if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 &&
gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0)
pm_power_off = ib62x0_power_off;
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c
index d7a9198..220f0d4 100644
--- a/arch/arm/mach-kirkwood/board-iconnect.c
+++ b/arch/arm/mach-kirkwood/board-iconnect.c
@@ -17,7 +17,6 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/mtd/partitions.h>
-#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
@@ -26,10 +25,6 @@
#include "common.h"
#include "mpp.h"
-static struct mv643xx_eth_platform_data iconnect_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(11),
-};
-
static unsigned int iconnect_mpp_config[] __initdata = {
MPP12_GPIO,
MPP35_GPIO,
@@ -92,7 +87,7 @@ void __init iconnect_init(void)
kirkwood_nand_init(ARRAY_AND_SIZE(iconnect_nand_parts), 25);
kirkwood_ehci_init();
- kirkwood_ge00_init(&iconnect_ge00_data);
+ kirkwood_ge00_init(NULL);
platform_device_register(&iconnect_button_device);
}
diff --git a/arch/arm/mach-kirkwood/board-lsxl.c b/arch/arm/mach-kirkwood/board-lsxl.c
index 83d8975..60331d1 100644
--- a/arch/arm/mach-kirkwood/board-lsxl.c
+++ b/arch/arm/mach-kirkwood/board-lsxl.c
@@ -18,7 +18,6 @@
#include <linux/ata_platform.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
-#include <linux/mv643xx_eth.h>
#include <linux/gpio.h>
#include <linux/gpio-fan.h>
#include <linux/input.h>
@@ -28,14 +27,6 @@
#include "common.h"
#include "mpp.h"
-static struct mv643xx_eth_platform_data lsxl_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
-};
-
-static struct mv643xx_eth_platform_data lsxl_ge01_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
static unsigned int lsxl_mpp_config[] __initdata = {
MPP10_GPO, /* HDD Power Enable */
MPP11_GPIO, /* USB Vbus Enable */
@@ -126,8 +117,8 @@ void __init lsxl_init(void)
gpio_set_value(LSXL_GPIO_HDD_POWER, 1);
kirkwood_ehci_init();
- kirkwood_ge00_init(&lsxl_ge00_data);
- kirkwood_ge01_init(&lsxl_ge01_data);
+ kirkwood_ge00_init(NULL);
+ kirkwood_ge01_init(NULL);
platform_device_register(&lsxl_fan_device);
/* register power-off method */
diff --git a/arch/arm/mach-kirkwood/board-ts219.c b/arch/arm/mach-kirkwood/board-ts219.c
index 1750e68..7e7fe6c 100644
--- a/arch/arm/mach-kirkwood/board-ts219.c
+++ b/arch/arm/mach-kirkwood/board-ts219.c
@@ -18,7 +18,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
@@ -29,10 +28,6 @@
#include "mpp.h"
#include "tsx1x-common.h"
-static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(8),
-};
-
static unsigned int qnap_ts219_mpp_config[] __initdata = {
MPP0_SPI_SCn,
MPP1_SPI_MOSI,
@@ -62,10 +57,7 @@ void __init qnap_dt_ts219_init(void)
kirkwood_mpp_conf(qnap_ts219_mpp_config);
kirkwood_pcie_id(&dev, &rev);
- if (dev == MV88F6282_DEV_ID)
- qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
-
- kirkwood_ge00_init(&qnap_ts219_ge00_data);
+ kirkwood_ge00_init(NULL);
kirkwood_ehci_init();
pm_power_off = qnap_tsx1x_power_off;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 7/7] NET: mv643xx: remove device name macro.
From: Ian Molton @ 2012-08-07 14:34 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: andrew, thomas.petazzoni, ben.dooks, arnd, netdev
In-Reply-To: <1344350092-24050-1-git-send-email-ian.molton@codethink.co.uk>
Coding style: remove the macros:
MV643XX_ETH_NAME and
MV643XX_ETH_SHARED_NAME
Signed-off-by: Ian Molton <ian.molton@codethink.co.uk>
---
arch/arm/mach-kirkwood/board-dt.c | 4 ++--
arch/arm/mach-kirkwood/common.c | 4 ++--
arch/arm/plat-orion/common.c | 24 ++++++++++++------------
arch/powerpc/platforms/chrp/pegasos_eth.c | 4 ++--
arch/powerpc/sysdev/mv64x60_dev.c | 5 ++---
drivers/net/ethernet/marvell/mv643xx_eth.c | 8 ++++----
include/linux/mv643xx_eth.h | 2 --
7 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index aa213b6..91784d9 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -34,9 +34,9 @@ struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL),
- OF_DEV_AUXDATA("marvell,mv643xx", 0xf1072000, "mv643xx_eth_port.0",
+ OF_DEV_AUXDATA("marvell,mv643xx", 0xf1072000, "mv643xx_eth.0",
NULL),
- OF_DEV_AUXDATA("marvell,mv643xx", 0xf1076000, "mv643xx_eth_port.1",
+ OF_DEV_AUXDATA("marvell,mv643xx", 0xf1076000, "mv643xx_eth.1",
NULL),
{},
};
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 57b91cf..eb0a253 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -264,8 +264,8 @@ void __init kirkwood_clk_init(void)
/* clkdev entries, mapping clks to devices */
orion_clkdev_add(NULL, "orion_spi.0", runit);
orion_clkdev_add(NULL, "orion_spi.1", runit);
- orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0);
- orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1);
+ orion_clkdev_add(NULL, "mv643xx_eth.0", ge0);
+ orion_clkdev_add(NULL, "mv643xx_eth.1", ge1);
orion_clkdev_add(NULL, "orion_wdt", tclk);
orion_clkdev_add("0", "sata_mv.0", sata0);
orion_clkdev_add("1", "sata_mv.0", sata1);
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index d245a87..d4a6467 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -42,10 +42,10 @@ void __init orion_clkdev_init(struct clk *tclk)
{
orion_clkdev_add(NULL, "orion_spi.0", tclk);
orion_clkdev_add(NULL, "orion_spi.1", tclk);
- orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", tclk);
- orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", tclk);
- orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk);
- orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk);
+ orion_clkdev_add(NULL, "mv643xx_eth.0", tclk);
+ orion_clkdev_add(NULL, "mv643xx_eth.1", tclk);
+ orion_clkdev_add(NULL, "mv643xx_eth.2", tclk);
+ orion_clkdev_add(NULL, "mv643xx_eth.3", tclk);
orion_clkdev_add(NULL, "orion_wdt", tclk);
orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", tclk);
}
@@ -264,7 +264,7 @@ static struct resource orion_ge00_shared_resources[] = {
};
static struct platform_device orion_ge00_shared = {
- .name = MV643XX_ETH_SHARED_NAME,
+ .name = "mdio-mv643xx",
.id = 0,
.dev = {
.platform_data = &orion_ge00_shared_data,
@@ -279,7 +279,7 @@ static struct resource orion_ge00_resources[] = {
};
static struct platform_device orion_ge00 = {
- .name = MV643XX_ETH_NAME,
+ .name = "mv643xx_eth",
.id = 0,
.num_resources = 1,
.resource = orion_ge00_resources,
@@ -316,7 +316,7 @@ static struct resource orion_ge01_shared_resources[] = {
};
static struct platform_device orion_ge01_shared = {
- .name = MV643XX_ETH_SHARED_NAME,
+ .name = "mdio-mv643xx",
.id = 1,
.dev = {
.platform_data = &orion_ge01_shared_data,
@@ -331,7 +331,7 @@ static struct resource orion_ge01_resources[] = {
};
static struct platform_device orion_ge01 = {
- .name = MV643XX_ETH_NAME,
+ .name = "mv643xx_eth",
.id = 1,
.num_resources = 1,
.resource = orion_ge01_resources,
@@ -368,7 +368,7 @@ static struct resource orion_ge10_shared_resources[] = {
};
static struct platform_device orion_ge10_shared = {
- .name = MV643XX_ETH_SHARED_NAME,
+ .name = "mdio-mv643xx",
.id = 1,
.dev = {
.platform_data = &orion_ge10_shared_data,
@@ -383,7 +383,7 @@ static struct resource orion_ge10_resources[] = {
};
static struct platform_device orion_ge10 = {
- .name = MV643XX_ETH_NAME,
+ .name = "mv643xx_eth",
.id = 1,
.num_resources = 2,
.resource = orion_ge10_resources,
@@ -420,7 +420,7 @@ static struct resource orion_ge11_shared_resources[] = {
};
static struct platform_device orion_ge11_shared = {
- .name = MV643XX_ETH_SHARED_NAME,
+ .name = "mdio-mv643xx",
.id = 1,
.dev = {
.platform_data = &orion_ge11_shared_data,
@@ -435,7 +435,7 @@ static struct resource orion_ge11_resources[] = {
};
static struct platform_device orion_ge11 = {
- .name = MV643XX_ETH_NAME,
+ .name = "mv643xx_eth",
.id = 1,
.num_resources = 2,
.resource = orion_ge11_resources,
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 039fc8e..1832127 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -41,7 +41,7 @@ static struct resource mv643xx_eth_shared_resources[] = {
};
static struct platform_device mv643xx_eth_shared_device = {
- .name = MV643XX_ETH_SHARED_NAME,
+ .name = "mdio-mv643xx",
.id = 0,
.num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
.resource = mv643xx_eth_shared_resources,
@@ -71,7 +71,7 @@ static struct mv643xx_eth_platform_data eth_port1_pd = {
};
static struct platform_device eth_port1_device = {
- .name = MV643XX_ETH_NAME,
+ .name = "mv643xx_eth",
.id = 1,
.num_resources = ARRAY_SIZE(mv643xx_eth_port1_resources),
.resource = mv643xx_eth_port1_resources,
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 0f6af41..ca404ec 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -221,8 +221,7 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev(
if (err)
return ERR_PTR(err);
- pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, id,
- r, 1);
+ pdev = platform_device_register_simple("mdio-mv643xx", id, i r, 1);
return pdev;
}
@@ -296,7 +295,7 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id,
of_node_put(phy);
- pdev = platform_device_alloc(MV643XX_ETH_NAME, id);
+ pdev = platform_device_alloc("mv643xx_eth", id);
if (!pdev)
return -ENOMEM;
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index bb80050..9371601 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2746,7 +2746,7 @@ static struct platform_driver mv643xx_eth_shared_driver = {
.probe = mv643xx_eth_shared_probe,
.remove = mv643xx_eth_shared_remove,
.driver = {
- .name = MV643XX_ETH_SHARED_NAME,
+ .name = "mdio-mv643xx",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(mv_mdio_dt_ids),
},
@@ -3113,7 +3113,7 @@ static struct platform_driver mv643xx_eth_driver = {
.remove = mv643xx_eth_remove,
.shutdown = mv643xx_eth_shutdown,
.driver = {
- .name = MV643XX_ETH_NAME,
+ .name = "mv643xx_eth",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(mv_eth_dt_ids),
},
@@ -3145,5 +3145,5 @@ MODULE_AUTHOR("Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, "
"Manish Lachwani, Dale Farnsworth and Lennert Buytenhek");
MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" MV643XX_ETH_SHARED_NAME);
-MODULE_ALIAS("platform:" MV643XX_ETH_NAME);
+MODULE_ALIAS("platform:" "mdio-mv643xx");
+MODULE_ALIAS("platform:" "mv643xx_eth");
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h
index 51bf8ad..33dc6f4 100644
--- a/include/linux/mv643xx_eth.h
+++ b/include/linux/mv643xx_eth.h
@@ -7,8 +7,6 @@
#include <linux/mbus.h>
-#define MV643XX_ETH_SHARED_NAME "mv643xx_eth"
-#define MV643XX_ETH_NAME "mv643xx_eth_port"
#define MV643XX_ETH_SHARED_REGS 0x2000
#define MV643XX_ETH_SHARED_REGS_SIZE 0x2000
#define MV643XX_ETH_BAR_4 0x2220
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 5/7] csb1724: Enable device tree based mv643xx ethernet support.
From: Ian Molton @ 2012-08-07 14:34 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: andrew, thomas.petazzoni, ben.dooks, arnd, netdev
In-Reply-To: <1344350092-24050-1-git-send-email-ian.molton@codethink.co.uk>
This patch enables mv643xx based ethernet built into the SoM on the
csb1724, via flattened device tree.
Signed-off-by: Ian Molton <ian.molton@codethink.co.uk>
---
arch/arm/boot/dts/kirkwood-csb1724.dts | 19 ++++++++++++++++++
arch/arm/boot/dts/kirkwood.dtsi | 33 ++++++++++++++++++++++++++++++++
arch/arm/mach-kirkwood/board-csb1724.c | 1 +
3 files changed, 53 insertions(+)
diff --git a/arch/arm/boot/dts/kirkwood-csb1724.dts b/arch/arm/boot/dts/kirkwood-csb1724.dts
index 44dfe9a..f43f8dd 100644
--- a/arch/arm/boot/dts/kirkwood-csb1724.dts
+++ b/arch/arm/boot/dts/kirkwood-csb1724.dts
@@ -25,6 +25,25 @@
nr-ports = <2>;
status = "ok";
};
+
+ smi0: mdio@72000 {
+ status = "ok";
+ };
+
+ smi1: mdio@76000 {
+ status = "ok";
+ };
+
+ egiga0 {
+ phy_addr = <0>;
+ status = "ok";
+ };
+
+ egiga1 {
+ phy_addr = <1>;
+ status = "ok";
+ };
+
};
};
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index cef9616..f5f1f92 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -76,6 +76,39 @@
status = "okay";
};
+ smi0: mdio@72000 {
+ compatible = "marvell,mdio-mv643xx";
+ reg = <0x72000 0x4000>;
+ interrupts = <46>;
+ tx_csum_limit = <1600>;
+ status = "disabled";
+ };
+
+ egiga0 {
+ compatible = "marvell,mv643xx-eth";
+ reg = <0x72000 0x4000>;
+ mdio = <&smi0>;
+ interrupts = <11>;
+ status = "disabled";
+ };
+
+ smi1: mdio@76000 {
+ compatible = "marvell,mdio-mv643xx";
+ reg = <0x76000 0x4000>;
+ interrupts = <47>;
+ shared_smi = <&smi0>;
+ tx_csum_limit = <1600>;
+ status = "disabled";
+ };
+
+ egiga1 {
+ compatible = "marvell,mv643xx-eth";
+ reg = <0x76000 0x4000>;
+ mdio = <&smi1>;
+ interrupts = <15>;
+ status = "disabled";
+ };
+
sata@80000 {
compatible = "marvell,orion-sata";
reg = <0x80000 0x5000>;
diff --git a/arch/arm/mach-kirkwood/board-csb1724.c b/arch/arm/mach-kirkwood/board-csb1724.c
index 979112d..9c58b92 100644
--- a/arch/arm/mach-kirkwood/board-csb1724.c
+++ b/arch/arm/mach-kirkwood/board-csb1724.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include "common.h"
#include "mpp.h"
static unsigned int csb1724_mpp_config[] __initdata = {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 3/7] mv643xx.c: Add basic device tree support.
From: Ian Molton @ 2012-08-07 14:34 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: andrew, thomas.petazzoni, ben.dooks, arnd, netdev
In-Reply-To: <1344350092-24050-1-git-send-email-ian.molton@codethink.co.uk>
This patch adds basic device tree support to the mv643xx ethernet driver.
It should be enough for most current users of the device, and should allow
a painless migration.
Signed-off-by: Ian Molton <ian.molton@codethink.co.uk>
---
Documentation/devicetree/bindings/net/mv643xx.txt | 75 +++++++++++++++++
drivers/net/ethernet/marvell/mv643xx_eth.c | 93 +++++++++++++++++++--
2 files changed, 161 insertions(+), 7 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/mv643xx.txt
diff --git a/Documentation/devicetree/bindings/net/mv643xx.txt b/Documentation/devicetree/bindings/net/mv643xx.txt
new file mode 100644
index 0000000..2727f79
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/mv643xx.txt
@@ -0,0 +1,75 @@
+mv643xx related nodes.
+
+marvell,mdio-mv643xx:
+
+Required properties:
+
+ - interrupts : <a> where a is the SMI interrupt number.
+ - reg : the base address and size of the controllers register space.
+
+Optional properties:
+ - shared_smi : on some chips, the second PHY is "shared", meaning it is
+ really accessed via the first SMI controller. It is passed in this
+ way due to the present structure of the driver, which requires the
+ base address for the MAC to be passed in via the SMI controllers
+ platform data.
+ - tx_csum_limit : on some devices, this option is required for proper
+ operation wrt. jumbo frames.
+
+
+Example:
+
+smi0: mdio@72000 {
+ compatible = "marvell,mdio-mv643xx";
+ reg = <0x72000 0x4000>;
+ interrupts = <46>;
+ tx_csum_limit = <1600>;
+ status = "disabled";
+};
+
+smi1: mdio@76000 {
+ compatible = "marvell,mdio-mv643xx";
+ reg = <0x76000 0x4000>;
+ interrupts = <47>;
+ shared_smi = <&smi0>;
+ tx_csum_limit = <1600>;
+ status = "disabled";
+};
+
+
+
+marvell,mv643xx-eth:
+
+Required properties:
+ - interrupts : the port interrupt number.
+ - mdio : phandle of the smi device as drescribed above
+
+Optional properties:
+ - port_number : the port number on this bus.
+ - phy_addr : the PHY address.
+ - reg : should match the mdio reg this device is attached to.
+ this is a required hack for now due to the way the
+ driver is constructed. This allows the device clock to be
+ kept running so that the MAC is not lost after boot.
+
+
+Example:
+
+egiga0 {
+ compatible = "marvell,mv643xx-eth";
+ reg = <0x72000 0x4000>;
+ mdio = <&smi0>;
+ port_number = <0>;
+ phy_addr = <0x80>;
+ interrupts = <11>;
+};
+
+egiga1 {
+ compatible = "marvell,mv643xx-eth";
+ reg = <0x76000 0x4000>;
+ mdio = <&smi1>;
+ port_number = <0>;
+ phy_addr = <0x81>;
+ interrupts = <15>;
+};
+
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 92497eb..bb80050 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -48,6 +48,9 @@
#include <linux/ethtool.h>
#include <linux/platform_device.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
@@ -2601,7 +2604,7 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp)
static int mv643xx_eth_shared_probe(struct platform_device *pdev)
{
static int mv643xx_eth_version_printed;
- struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
+ struct mv643xx_eth_shared_platform_data *pd;
struct mv643xx_eth_shared_private *msp;
const struct mbus_dram_target_info *dram;
struct resource *res;
@@ -2625,6 +2628,26 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
if (msp->base == NULL)
goto out_free;
+ if (pdev->dev.of_node) {
+ struct device_node *np = NULL;
+
+ /* when all users of this driver use FDT, we can remove this */
+ pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_dbg(&pdev->dev, "Could not allocate platform data\n");
+ goto out_free;
+ }
+
+ of_property_read_u32(pdev->dev.of_node,
+ "tx_csum_limit", &pd->tx_csum_limit);
+
+ np = of_parse_phandle(pdev->dev.of_node, "shared_smi", 0);
+ if (np)
+ pd->shared_smi = of_find_device_by_node(np);
+
+ } else {
+ pd = pdev->dev.platform_data;
+ }
/*
* Set up and register SMI bus.
*/
@@ -2657,7 +2680,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (res != NULL) {
int err;
-
err = request_irq(res->start, mv643xx_eth_err_irq,
IRQF_SHARED, "mv643xx_eth", msp);
if (!err) {
@@ -2675,6 +2697,10 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ?
pd->tx_csum_limit : 9 * 1024;
+
+ if (pdev->dev.of_node)
+ kfree(pd); /* If we created a fake pd, free it now */
+
infer_hw_params(msp);
platform_set_drvdata(pdev, msp);
@@ -2708,12 +2734,21 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_OF
+static struct of_device_id mv_mdio_dt_ids[] __devinitdata = {
+ { .compatible = "marvell,mdio-mv643xx", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mv_mdio_dt_ids);
+#endif
+
static struct platform_driver mv643xx_eth_shared_driver = {
.probe = mv643xx_eth_shared_probe,
.remove = mv643xx_eth_shared_remove,
.driver = {
.name = MV643XX_ETH_SHARED_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(mv_mdio_dt_ids),
},
};
@@ -2873,7 +2908,36 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
struct resource *res;
int err;
- pd = pdev->dev.platform_data;
+ if (pdev->dev.of_node) {
+ struct device_node *np = NULL;
+
+ /* when all users of this driver use FDT, we can remove this */
+ pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_dbg(&pdev->dev, "Could not allocate platform data\n");
+ return -ENOMEM;
+ }
+
+ of_property_read_u32(pdev->dev.of_node,
+ "port_number", &pd->port_number);
+
+ if (!of_property_read_u32(pdev->dev.of_node,
+ "phy_addr", &pd->phy_addr))
+ pd->phy_addr = MV643XX_ETH_PHY_ADDR(pd->phy_addr);
+ else
+ pd->phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT;
+
+ np = of_parse_phandle(pdev->dev.of_node, "mdio", 0);
+ if (np) {
+ pd->shared = of_find_device_by_node(np);
+ } else {
+ kfree(pd);
+ return -ENODEV;
+ }
+ } else {
+ pd = pdev->dev.platform_data;
+ }
+
if (pd == NULL) {
dev_err(&pdev->dev, "no mv643xx_eth_platform_data\n");
return -ENODEV;
@@ -2881,12 +2945,15 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
if (pd->shared == NULL) {
dev_err(&pdev->dev, "no mv643xx_eth_platform_data->shared\n");
- return -ENODEV;
+ err = -ENODEV;
+ goto out_free_pd;
}
dev = alloc_etherdev_mq(sizeof(struct mv643xx_eth_private), 8);
- if (!dev)
- return -ENOMEM;
+ if (!dev) {
+ err = -ENOMEM;
+ goto out_free_pd;
+ }
mp = netdev_priv(dev);
platform_set_drvdata(pdev, mp);
@@ -2923,6 +2990,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
init_pscr(mp, pd->speed, pd->duplex);
+ if (pdev->dev.of_node)
+ kfree(pd); /* If we created a fake pd, free it now */
mib_counters_clear(mp);
@@ -2942,7 +3011,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
mp->rx_oom.data = (unsigned long)mp;
mp->rx_oom.function = oom_timer_wrapper;
-
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
BUG_ON(!res);
dev->irq = res->start;
@@ -2991,6 +3059,8 @@ out:
}
#endif
free_netdev(dev);
+out_free_pd:
+ kfree(pd);
return err;
}
@@ -3030,6 +3100,14 @@ static void mv643xx_eth_shutdown(struct platform_device *pdev)
port_reset(mp);
}
+#ifdef CONFIG_OF
+static struct of_device_id mv_eth_dt_ids[] __devinitdata = {
+ { .compatible = "marvell,mv643xx-eth", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mv_eth_dt_ids);
+#endif
+
static struct platform_driver mv643xx_eth_driver = {
.probe = mv643xx_eth_probe,
.remove = mv643xx_eth_remove,
@@ -3037,6 +3115,7 @@ static struct platform_driver mv643xx_eth_driver = {
.driver = {
.name = MV643XX_ETH_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(mv_eth_dt_ids),
},
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 4/7] kirkwood: Add fixups for DT based mv643xx ethernet.
From: Ian Molton @ 2012-08-07 14:34 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: andrew, thomas.petazzoni, ben.dooks, arnd, netdev
In-Reply-To: <1344350092-24050-1-git-send-email-ian.molton@codethink.co.uk>
This patch adds auxdata for kirkwood ethernet and an ethernet clock setup
helper function allowing the mv643xx clock to be kept enabled after boot so
that the MAC address(es) are not lost.
Signed-off-by: Ian Molton <ian.molton@codethink.co.uk>
---
arch/arm/mach-kirkwood/board-dt.c | 7 +++++++
arch/arm/mach-kirkwood/common.c | 22 ++++++++++++++++++++++
arch/arm/mach-kirkwood/common.h | 3 +++
3 files changed, 32 insertions(+)
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 7679f7f..aa213b6 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/mv643xx_eth.h>
#include <linux/kexec.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -33,6 +34,10 @@ struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL),
OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL),
OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL),
+ OF_DEV_AUXDATA("marvell,mv643xx", 0xf1072000, "mv643xx_eth_port.0",
+ NULL),
+ OF_DEV_AUXDATA("marvell,mv643xx", 0xf1076000, "mv643xx_eth_port.1",
+ NULL),
{},
};
@@ -92,6 +97,8 @@ static void __init kirkwood_dt_init(void)
of_platform_populate(NULL, kirkwood_dt_match_table,
kirkwood_auxdata_lookup, NULL);
+
+ kirkwood_eth_clock_fixup();
}
static const char *kirkwood_dt_board_compat[] = {
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index c4b64ad..57b91cf 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -18,6 +18,7 @@
#include <linux/clk-provider.h>
#include <linux/spinlock.h>
#include <linux/mv643xx_i2c.h>
+#include <linux/of.h>
#include <net/dsa.h>
#include <asm/page.h>
#include <asm/timex.h>
@@ -293,6 +294,27 @@ void __init kirkwood_ehci_init(void)
orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA);
}
+/* Fixup ethernet clocks for DT based kirkwood platforms.
+ * This is required because if the clock is not kept running, the
+ * Interface will forget its MAC address.
+ */
+#ifdef CONFIG_OF
+void __init kirkwood_eth_clock_fixup(void)
+{
+ struct device_node *np;
+
+ np = of_find_node_by_name(NULL, "egiga0");
+ if (np && of_device_is_available(np))
+ clk_prepare_enable(ge0);
+ of_node_put(np);
+
+ np = of_find_node_by_name(NULL, "egiga1");
+ if (np && of_device_is_available(np))
+ clk_prepare_enable(ge1);
+ of_node_put(np);
+
+}
+#endif
/*****************************************************************************
* GE00
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 8aab1ae..7183718 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -36,6 +36,9 @@ void kirkwood_enable_pcie(void);
void kirkwood_pcie_id(u32 *dev, u32 *rev);
void kirkwood_ehci_init(void);
+#ifdef CONFIG_OF
+void kirkwood_eth_clock_fixup(void);
+#endif
void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data);
void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 1/7] Initial csb1724 board support (FDT)
From: Ian Molton @ 2012-08-07 14:34 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: andrew, thomas.petazzoni, ben.dooks, arnd, netdev
In-Reply-To: <1344350092-24050-1-git-send-email-ian.molton@codethink.co.uk>
This patch adds support for the csb1724 SoM.
It includes serial and SATA support.
Signed-off-by: Ian Molton <ian.molton@codethink.co.uk>
---
arch/arm/boot/dts/kirkwood-csb1724.dts | 30 ++++++++++++++++
arch/arm/mach-kirkwood/Kconfig | 7 ++++
arch/arm/mach-kirkwood/Makefile | 1 +
arch/arm/mach-kirkwood/Makefile.boot | 1 +
arch/arm/mach-kirkwood/board-csb1724.c | 59 ++++++++++++++++++++++++++++++++
arch/arm/mach-kirkwood/board-dt.c | 4 +++
arch/arm/mach-kirkwood/common.h | 6 ++++
7 files changed, 108 insertions(+)
create mode 100644 arch/arm/boot/dts/kirkwood-csb1724.dts
create mode 100644 arch/arm/mach-kirkwood/board-csb1724.c
diff --git a/arch/arm/boot/dts/kirkwood-csb1724.dts b/arch/arm/boot/dts/kirkwood-csb1724.dts
new file mode 100644
index 0000000..44dfe9a
--- /dev/null
+++ b/arch/arm/boot/dts/kirkwood-csb1724.dts
@@ -0,0 +1,30 @@
+/dts-v1/;
+
+/include/ "kirkwood.dtsi"
+
+/ {
+ model = "Cogent CSB1724-88F-628X SoM";
+ compatible = "cogent,csb1724", "marvell,kirkwood-88f6281", "marvell,kirkwood";
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8 earlyprintk";
+ };
+
+ ocp@f1000000 {
+ serial@12000 {
+ clock-frequency = <200000000>;
+ status = "ok";
+ };
+
+ sata@80000 {
+ nr-ports = <2>;
+ status = "ok";
+ };
+ };
+
+};
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index ca5c15a..6d51c50 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -109,6 +109,13 @@ config MACH_LSXL_DT
Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using
Flattened Device Tree.
+config MACH_CSB1724_DT
+ bool "Cogent CSB1724 SoM (Flattened Device Tree)"
+ select ARCH_KIRKWOOD_DT
+ help
+ Say 'Y' here if you want your kernel to support the
+ Cogent CSB1724 SoM, using Flattened Device Tree.
+
config MACH_TS219
bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS"
help
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index 055c85a..665ed63 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o
obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o
obj-$(CONFIG_MACH_GOFLEXNET_DT) += board-goflexnet.o
obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o
+obj-$(CONFIG_MACH_CSB1724_DT) += board-csb1724.o
diff --git a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot
index 2a576ab..899bc80 100644
--- a/arch/arm/mach-kirkwood/Makefile.boot
+++ b/arch/arm/mach-kirkwood/Makefile.boot
@@ -2,6 +2,7 @@
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
+dtb-$(CONFIG_MACH_CSB1724_DT) += kirkwood-csb1724.dtb
dtb-$(CONFIG_MACH_DREAMPLUG_DT) += kirkwood-dreamplug.dtb
dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns320.dtb
dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb
diff --git a/arch/arm/mach-kirkwood/board-csb1724.c b/arch/arm/mach-kirkwood/board-csb1724.c
new file mode 100644
index 0000000..979112d
--- /dev/null
+++ b/arch/arm/mach-kirkwood/board-csb1724.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2012 (C), Ian Molton <ian.molton@codethink.co.uk>
+ *
+ * arch/arm/mach-kirkwood/board-csb1724.c
+ *
+ * Cogent csb1724 Board Init for drivers not converted to
+ * flattened device tree yet.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include "mpp.h"
+
+static unsigned int csb1724_mpp_config[] __initdata = {
+ MPP0_NF_IO2,
+ MPP1_NF_IO3,
+ MPP2_NF_IO4,
+ MPP3_NF_IO5,
+ MPP4_NF_IO6,
+ MPP5_NF_IO7,
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP12_SD_CLK,
+ MPP13_SD_CMD,
+ MPP14_SD_D0,
+ MPP15_SD_D1,
+ MPP16_SD_D2,
+ MPP17_SD_D3,
+ MPP18_NF_IO0,
+ MPP19_NF_IO1,
+ MPP20_GE1_TXD0,
+ MPP21_GE1_TXD1,
+ MPP22_GE1_TXD2,
+ MPP23_GE1_TXD3,
+ MPP24_GE1_RXD0,
+ MPP25_GE1_RXD1,
+ MPP26_GE1_RXD2,
+ MPP27_GE1_RXD3,
+ MPP30_GE1_RXCTL,
+ MPP31_GE1_RXCLK,
+ MPP32_GE1_TCLKOUT,
+ MPP33_GE1_TXCTL,
+ MPP34_SATA1_ACTn,
+ MPP35_SATA0_ACTn,
+ MPP36_TW1_SDA,
+ MPP37_TW1_SCK,
+};
+
+void __init csb1724_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_mpp_conf(csb1724_mpp_config);
+}
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index e4eb450..7679f7f 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -87,6 +87,9 @@ static void __init kirkwood_dt_init(void)
if (of_machine_is_compatible("buffalo,lsxl"))
lsxl_init();
+ if (of_machine_is_compatible("cogent,csb1724"))
+ csb1724_init();
+
of_platform_populate(NULL, kirkwood_dt_match_table,
kirkwood_auxdata_lookup, NULL);
}
@@ -100,6 +103,7 @@ static const char *kirkwood_dt_board_compat[] = {
"qnap,ts219",
"seagate,goflexnet",
"buffalo,lsxl",
+ "cogent,csb1724",
NULL
};
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 304dd1a..8aab1ae 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -94,6 +94,12 @@ void lsxl_init(void);
static inline void lsxl_init(void) {};
#endif
+#ifdef CONFIG_MACH_CSB1724_DT
+void csb1724_init(void);
+#else
+static inline void csb1724_init(void) {};
+#endif
+
/* early init functions not converted to fdt yet */
char *kirkwood_id(void);
void kirkwood_l2_init(void);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 0/7] mv643xx.c: Add basic device tree support.
From: Ian Molton @ 2012-08-07 14:34 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: andrew, thomas.petazzoni, ben.dooks, arnd, netdev
Fixed all comments.
* Dropped csb1724 defconfig.
* Added patch to remove MV643XX_ETH_SHARED_NAME and MV643XX_ETH_NAME
* Dropped un-necessary D-T irq fixup code
Ian Molton (7):
Initial csb1724 board support (FDT)
mv643xx.c: Remove magic numbers.
mv643xx.c: Add basic device tree support.
kirkwood: Add fixups for DT based mv643xx ethernet.
csb1724: Enable device tree based mv643xx ethernet support.
DT: Convert all kirkwood boards with mv643xx that use DT
NET: mv643xx: remove device name macro.
Documentation/devicetree/bindings/net/mv643xx.txt | 75 +++++++++++++++
arch/arm/boot/dts/kirkwood-csb1724.dts | 49 ++++++++++
arch/arm/boot/dts/kirkwood-dnskw.dtsi | 9 ++
arch/arm/boot/dts/kirkwood-dreamplug.dts | 18 ++++
arch/arm/boot/dts/kirkwood-goflexnet.dts | 8 ++
arch/arm/boot/dts/kirkwood-ib62x0.dts | 10 ++
arch/arm/boot/dts/kirkwood-iconnect.dts | 10 ++
arch/arm/boot/dts/kirkwood-lsxl.dtsi | 17 ++++
arch/arm/boot/dts/kirkwood-ts219-6281.dts | 8 +-
arch/arm/boot/dts/kirkwood-ts219-6282.dts | 8 +-
arch/arm/boot/dts/kirkwood-ts219.dtsi | 3 +
arch/arm/boot/dts/kirkwood.dtsi | 33 +++++++
arch/arm/mach-kirkwood/Kconfig | 7 ++
arch/arm/mach-kirkwood/Makefile | 1 +
arch/arm/mach-kirkwood/Makefile.boot | 1 +
arch/arm/mach-kirkwood/board-csb1724.c | 60 ++++++++++++
arch/arm/mach-kirkwood/board-dnskw.c | 7 +-
arch/arm/mach-kirkwood/board-dreamplug.c | 13 +--
arch/arm/mach-kirkwood/board-dt.c | 11 +++
arch/arm/mach-kirkwood/board-goflexnet.c | 7 +-
arch/arm/mach-kirkwood/board-ib62x0.c | 7 +-
arch/arm/mach-kirkwood/board-iconnect.c | 7 +-
arch/arm/mach-kirkwood/board-lsxl.c | 13 +--
arch/arm/mach-kirkwood/board-ts219.c | 10 +-
arch/arm/mach-kirkwood/common.c | 26 +++++-
arch/arm/mach-kirkwood/common.h | 9 ++
arch/arm/plat-orion/common.c | 24 ++---
arch/powerpc/platforms/chrp/pegasos_eth.c | 4 +-
arch/powerpc/sysdev/mv64x60_dev.c | 5 +-
drivers/net/ethernet/marvell/mv643xx_eth.c | 104 ++++++++++++++++++---
include/linux/mv643xx_eth.h | 2 -
31 files changed, 476 insertions(+), 90 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/mv643xx.txt
create mode 100644 arch/arm/boot/dts/kirkwood-csb1724.dts
create mode 100644 arch/arm/mach-kirkwood/board-csb1724.c
--
1.7.9.5
^ permalink raw reply
* [PATCH v3 2/7] mv643xx.c: Remove magic numbers.
From: Ian Molton @ 2012-08-07 14:34 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: andrew, thomas.petazzoni, ben.dooks, arnd, netdev
In-Reply-To: <1344350092-24050-1-git-send-email-ian.molton@codethink.co.uk>
replace magic number with RX_CSUM_WITH_HEADER.
Signed-off-by: Ian Molton <ian.molton@codethink.co.uk>
---
drivers/net/ethernet/marvell/mv643xx_eth.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 4fbba57..92497eb 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -86,6 +86,7 @@ static char mv643xx_eth_driver_version[] = "1.4";
* port #0, 0x0800 for port #1, and 0x0c00 for port #2.
*/
#define PORT_CONFIG 0x0000
+#define RX_CSUM_WITH_HEADER 0x02000000
#define UNICAST_PROMISCUOUS_MODE 0x00000001
#define PORT_CONFIG_EXT 0x0004
#define MAC_ADDR_LOW 0x0014
@@ -1607,7 +1608,7 @@ mv643xx_eth_set_features(struct net_device *dev, netdev_features_t features)
struct mv643xx_eth_private *mp = netdev_priv(dev);
bool rx_csum = features & NETIF_F_RXCSUM;
- wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000);
+ wrlp(mp, PORT_CONFIG, rx_csum ? RX_CSUM_WITH_HEADER : 0x00000000);
return 0;
}
--
1.7.9.5
^ 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