* (unknown),
From: Zheng, C. @ 2014-02-20 19:19 UTC (permalink / raw)
Cc: inf@fi.fa
تهنئة الخاص بك البريد الإلكتروني قد فقط فاز لك مبلغ (1,000,000.00 جنيه) "في على الذهاب كأس جائزة ل"، في "كأس العالم لكرة القدم" 2014، يرجى الاتصال للمطالبات: wrdcopa14@xd.ae
^ permalink raw reply
* Re: [PATCH net] net: sctp: fix multihoming retransmission path selection to rfc4960
From: Vlad Yasevich @ 2014-02-20 19:26 UTC (permalink / raw)
To: Daniel Borkmann, davem; +Cc: netdev, linux-sctp, Gui Jianfeng
In-Reply-To: <1392897186-26841-1-git-send-email-dborkman@redhat.com>
On 02/20/2014 06:53 AM, Daniel Borkmann wrote:
> Problem statement: 1) both paths (primary path1 and alternate
> path2) are up after the association has been established i.e.,
> HB packets are normally exchanged, 2) path2 gets inactive after
> path_max_retrans * max_rto timed out (i.e. path2 is down completely),
> 3) now, if a transmission times out on the only surviving/active
> path1 (any ~1sec network service impact could cause this like
> a channel bonding failover), then the retransmitted packets are
> sent over the inactive path2; this happens with partial failover
> and without it.
>
Interesting. The problem above is actually triggered by
sctp_retransmit(). When the T3-timeout occurs, we have
active_patch == retrans_path, and even though the timeout
occurred on the initial transmission of data, not a retransmit,
we end up updating retransmit path.
It might be worth adding adding this as a condition. See below.
> Besides not being optimal in the above scenario, a small failure
> or timeout in the only existing path has the potential to cause
> long delays in the retransmission (depending on RTO_MAX) until
> the still active path is reselected.
>
> RFC4960, section 6.4. "Multi-Homed SCTP Endpoints" states under
> 6.4.1. "Failover from an Inactive Destination Address" the
> following:
>
> Some of the transport addresses of a multi-homed SCTP endpoint
> may become inactive due to either the occurrence of certain
> error conditions (see Section 8.2) or adjustments from the
> SCTP user.
>
> When there is outbound data to send and the primary path
> becomes inactive (e.g., due to failures), or where the SCTP
> user explicitly requests to send data to an inactive
> destination transport address, before reporting an error to
> its ULP, the SCTP endpoint should try to send the data to an
> alternate *active* destination transport address if one exists.
>
> When retransmitting data that timed out, if the endpoint is
> multihomed, it should consider each source-destination address
> pair in its retransmission selection policy. When retransmitting
> timed-out data, the endpoint should attempt to pick the most
> divergent source-destination pair from the original
> source-destination pair to which the packet was transmitted.
>
> Note: Rules for picking the most divergent source-destination
> pair are an implementation decision and are not specified
> within this document.
>
> So, we should first reconsider to take the current active
> retransmission transport if we cannot find an alternative
> active one, as otherwise, by sending a user message to an
> inactive destination transport address while excluding an
> active destination transport address, we would not comply
> to RFC4960. If all of that fails, we can still round robin
> through unkown, partial failover, and inactive ones in the
> hope to find something still suitable/useful.
>
> Commit 4141ddc02a92 ("sctp: retran_path update bug fix") broke
> that behaviour by selecting the next non-active transport when
> no other active transport was found besides the current assoc's
> peer.retran_path. Before commit 4141ddc02a92, we would have
> traversed through the list until we reach our peer.retran_path
> again, and in case that is still in state SCTP_ACTIVE, we would
> take it and return. Only if that is not the case either, we
> take the next inactive transport. Besides all that, another
> issue is that transports in state SCTP_UNKNOWN could be preferred
> over transports in state SCTP_ACTIVE in case a SCTP_ACTIVE
> transport appears after SCTP_UNKNOWN in the transport list
> yielding a "weaker" transport state to be used in retransmission.
>
> This patch mostly reverts 4141ddc02a92, but also rewrites
> this function to introduce more clarity and strictness into
> the code. A strict priority of transport states is enforced
> in this patch, hence selection is active > unkown > partial
> failover > inactive.
>
> Fixes: 4141ddc02a92 ("sctp: retran_path update bug fix")
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> Cc: Gui Jianfeng <guijianfeng@cn.fujitsu.com>
> ---
> net/sctp/associola.c | 123 ++++++++++++++++++++++++++++++---------------------
> 1 file changed, 73 insertions(+), 50 deletions(-)
>
> diff --git a/net/sctp/associola.c b/net/sctp/associola.c
> index f558433..bac47a4 100644
> --- a/net/sctp/associola.c
> +++ b/net/sctp/associola.c
> @@ -1239,78 +1239,101 @@ void sctp_assoc_update(struct sctp_association *asoc,
> }
>
> /* Update the retran path for sending a retransmitted packet.
> - * Round-robin through the active transports, else round-robin
> - * through the inactive transports as this is the next best thing
> - * we can try.
> + * See also RFC4960, 6.4. Multi-Homed SCTP Endpoints:
> + *
> + * When there is outbound data to send and the primary path
> + * becomes inactive (e.g., due to failures), or where the
> + * SCTP user explicitly requests to send data to an
> + * inactive destination transport address, before reporting
> + * an error to its ULP, the SCTP endpoint should try to send
> + * the data to an alternate active destination transport
> + * address if one exists.
> + *
> + * When retransmitting data that timed out, if the endpoint
> + * is multihomed, it should consider each source-destination
> + * address pair in its retransmission selection policy.
> + * When retransmitting timed-out data, the endpoint should
> + * attempt to pick the most divergent source-destination
> + * pair from the original source-destination pair to which
> + * the packet was transmitted.
> + *
> + * Note: Rules for picking the most divergent source-destination
> + * pair are an implementation decision and are not specified
> + * within this document.
> + *
> + * Our basic strategy is to round-robin transports in priorities
> + * according to sctp_state_prio_map[] e.g., if no such
> + * transport with state SCTP_ACTIVE exists, round-robin through
> + * SCTP_UNKNOWN, etc. You get the picture.
> */
> -void sctp_assoc_update_retran_path(struct sctp_association *asoc)
> +static const u8 sctp_trans_state_to_prio_map[] = {
> + [SCTP_ACTIVE] = 3, /* best case */
> + [SCTP_UNKNOWN] = 2,
> + [SCTP_PF] = 1,
> + [SCTP_INACTIVE] = 0, /* worst case */
> +};
> +
> +static u8 sctp_trans_score(const struct sctp_transport *trans)
> {
> - struct sctp_transport *t, *next;
> - struct list_head *head = &asoc->peer.transport_addr_list;
> - struct list_head *pos;
> + return sctp_trans_state_to_prio_map[trans->state];
> +}
>
> - if (asoc->peer.transport_count == 1)
> - return;
> +static struct sctp_transport *sctp_trans_elect_best(struct sctp_transport *curr,
> + struct sctp_transport *best)
> +{
> + if (best == NULL)
> + return curr;
>
> - /* Find the next transport in a round-robin fashion. */
> - t = asoc->peer.retran_path;
> - pos = &t->transports;
> - next = NULL;
> + return sctp_trans_score(curr) > sctp_trans_score(best) ? curr : best;
> +}
>
> - while (1) {
> - /* Skip the head. */
> - if (pos->next == head)
> - pos = head->next;
> - else
> - pos = pos->next;
> +void sctp_assoc_update_retran_path(struct sctp_association *asoc)
> +{
> + struct sctp_transport *trans = asoc->peer.retran_path;
> + struct sctp_transport *trans_next = NULL;
>
> - t = list_entry(pos, struct sctp_transport, transports);
> + /* We're done as we only have the one and only path. */
> + if (asoc->peer.transport_count == 1)
> + return;
>
I think we should to do one more short circuit here:
/* If active_path and retrans_path are the same and active,
* then this is the only active path. Use it.
*/
if (asoc->peer.active_path == asoc->peer.retrans_path &&
asoc->peer.active_path->state == SCTP_ACTIVE)
return;
> - /* We have exhausted the list, but didn't find any
> - * other active transports. If so, use the next
> - * transport.
> - */
> - if (t == asoc->peer.retran_path) {
> - t = next;
> + /* Iterate from retran_path's successor back to retran_path. */
> + for (trans = list_next_entry(trans, transports); 1;
> + trans = list_next_entry(trans, transports)) {
> + /* Manually skip the head element. */
> + if (&trans->transports == &asoc->peer.transport_addr_list)
> + continue;
Alternative way would be:
head = &asoc->peer.transport_addr_list;
list_for_each_enty_from(trans, head, transport) {
... do the work...
/* Manually skip head element if it's next */
if (list_next_entry(trans, transports) == head)
trans = list_first_entry(head);
}
It's up to you if you like this better or not.
-vlad
> + if (trans->state == SCTP_UNCONFIRMED)
> + continue;
> + trans_next = sctp_trans_elect_best(trans, trans_next);
> + /* Active is good enough for immediate return. */
> + if (trans_next->state == SCTP_ACTIVE)
> break;
> - }
> -
> - /* Try to find an active transport. */
> -
> - if ((t->state == SCTP_ACTIVE) ||
> - (t->state == SCTP_UNKNOWN)) {
> + /* We've reached the end, time to update path. */
> + if (trans == asoc->peer.retran_path)
> break;
> - } else {
> - /* Keep track of the next transport in case
> - * we don't find any active transport.
> - */
> - if (t->state != SCTP_UNCONFIRMED && !next)
> - next = t;
> - }
> }
>
> - if (t)
> - asoc->peer.retran_path = t;
> - else
> - t = asoc->peer.retran_path;
> + if (trans_next != NULL)
> + asoc->peer.retran_path = trans_next;
>
> - pr_debug("%s: association:%p addr:%pISpc\n", __func__, asoc,
> - &t->ipaddr.sa);
> + pr_debug("%s: association:%p updated new path to addr:%pISpc\n",
> + __func__, asoc, &asoc->peer.retran_path->ipaddr.sa);
> }
>
> -/* Choose the transport for sending retransmit packet. */
> -struct sctp_transport *sctp_assoc_choose_alter_transport(
> - struct sctp_association *asoc, struct sctp_transport *last_sent_to)
> +struct sctp_transport *
> +sctp_assoc_choose_alter_transport(struct sctp_association *asoc,
> + struct sctp_transport *last_sent_to)
> {
> /* If this is the first time packet is sent, use the active path,
> * else use the retran path. If the last packet was sent over the
> * retran path, update the retran path and use it.
> */
> - if (!last_sent_to)
> + if (last_sent_to == NULL) {
> return asoc->peer.active_path;
> - else {
> + } else {
> if (last_sent_to == asoc->peer.retran_path)
> sctp_assoc_update_retran_path(asoc);
> +
> return asoc->peer.retran_path;
> }
> }
>
^ permalink raw reply
* Re: BUG: ip6tables IPv6-REDIRECT over bridges
From: Florian Westphal @ 2014-02-20 19:32 UTC (permalink / raw)
To: Artie Hamilton
Cc: Pablo Neira Ayuso, Patrick McHardy, Jozsef Kadlecsik,
"David S. Miller", Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, netfilter-devel@vger.kernel.org,
netfilter@vger.kernel.org, coreteam@netfilter.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1392920071.66303.YahooMailNeo@web172306.mail.ir2.yahoo.com>
Artie Hamilton <artiemhamilton@yahoo.com> wrote:
> Now the same thing should be done for IPv6. It should works quite similar
> (I just assume the above mentioned steps are already done):
>
> $ sysctl -w net.ipv6.conf.br0.accept_ra=2
> $ sysctl -w net.bridge.bridge-nf-call-ip6tables=1
> $ ip6tables -t nat -A PREROUTING -p tcp -m tcp --dport 8080 -j REDIRECT --to-ports 81
>
> But here is the problem: Connections will not be started. I see for example
> connections getting started to the service like this on the client:
Yes, because bridge layer does not detect when addresses have been
rewritten.
The check is only implemented for ipv4, see dnat_took_place use in br_netfilter.c
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net v2] net: sctp: rework multihoming retransmission path selection to rfc4960
From: Daniel Borkmann @ 2014-02-20 19:51 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-sctp, Gui Jianfeng
Problem statement: 1) both paths (primary path1 and alternate
path2) are up after the association has been established i.e.,
HB packets are normally exchanged, 2) path2 gets inactive after
path_max_retrans * max_rto timed out (i.e. path2 is down completely),
3) now, if a transmission times out on the only surviving/active
path1 (any ~1sec network service impact could cause this like
a channel bonding failover), then the retransmitted packets are
sent over the inactive path2; this happens with partial failover
and without it.
Besides not being optimal in the above scenario, a small failure
or timeout in the only existing path has the potential to cause
long delays in the retransmission (depending on RTO_MAX) until
the still active path is reselected. Further, when the T3-timeout
occurs, we have active_patch == retrans_path, and even though the
timeout occurred on the initial transmission of data, not a
retransmit, we end up updating retransmit path.
RFC4960, section 6.4. "Multi-Homed SCTP Endpoints" states under
6.4.1. "Failover from an Inactive Destination Address" the
following:
Some of the transport addresses of a multi-homed SCTP endpoint
may become inactive due to either the occurrence of certain
error conditions (see Section 8.2) or adjustments from the
SCTP user.
When there is outbound data to send and the primary path
becomes inactive (e.g., due to failures), or where the SCTP
user explicitly requests to send data to an inactive
destination transport address, before reporting an error to
its ULP, the SCTP endpoint should try to send the data to an
alternate __active__ destination transport address if one
exists.
When retransmitting data that timed out, if the endpoint is
multihomed, it should consider each source-destination address
pair in its retransmission selection policy. When retransmitting
timed-out data, the endpoint should attempt to pick the most
divergent source-destination pair from the original
source-destination pair to which the packet was transmitted.
Note: Rules for picking the most divergent source-destination
pair are an implementation decision and are not specified
within this document.
So, we should first reconsider to take the current active
retransmission transport if we cannot find an alternative
active one. If all of that fails, we can still round robin
through unkown, partial failover, and inactive ones in the
hope to find something still suitable.
Commit 4141ddc02a92 ("sctp: retran_path update bug fix") broke
that behaviour by selecting the next inactive transport when
no other active transport was found besides the current assoc's
peer.retran_path. Before commit 4141ddc02a92, we would have
traversed through the list until we reach our peer.retran_path
again, and in case that is still in state SCTP_ACTIVE, we would
take it and return. Only if that is not the case either, we
take the next inactive transport.
Besides all that, another issue is that transports in state
SCTP_UNKNOWN could be preferred over transports in state
SCTP_ACTIVE in case a SCTP_ACTIVE transport appears after
SCTP_UNKNOWN in the transport list yielding a weaker transport
state to be used in retransmission.
This patch mostly reverts 4141ddc02a92, but also rewrites
this function to introduce more clarity and strictness into
the code. A strict priority of transport states is enforced
in this patch, hence selection is active > unkown > partial
failover > inactive.
Fixes: 4141ddc02a92 ("sctp: retran_path update bug fix")
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Cc: Gui Jianfeng <guijianfeng@cn.fujitsu.com>
---
v1->v2:
- added short-cut as suggested by Vlad, thanks!
- rest stays as is
net/sctp/associola.c | 129 +++++++++++++++++++++++++++++++--------------------
1 file changed, 79 insertions(+), 50 deletions(-)
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index f558433..e55f3df 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1239,78 +1239,107 @@ void sctp_assoc_update(struct sctp_association *asoc,
}
/* Update the retran path for sending a retransmitted packet.
- * Round-robin through the active transports, else round-robin
- * through the inactive transports as this is the next best thing
- * we can try.
+ * See also RFC4960, 6.4. Multi-Homed SCTP Endpoints:
+ *
+ * When there is outbound data to send and the primary path
+ * becomes inactive (e.g., due to failures), or where the
+ * SCTP user explicitly requests to send data to an
+ * inactive destination transport address, before reporting
+ * an error to its ULP, the SCTP endpoint should try to send
+ * the data to an alternate active destination transport
+ * address if one exists.
+ *
+ * When retransmitting data that timed out, if the endpoint
+ * is multihomed, it should consider each source-destination
+ * address pair in its retransmission selection policy.
+ * When retransmitting timed-out data, the endpoint should
+ * attempt to pick the most divergent source-destination
+ * pair from the original source-destination pair to which
+ * the packet was transmitted.
+ *
+ * Note: Rules for picking the most divergent source-destination
+ * pair are an implementation decision and are not specified
+ * within this document.
+ *
+ * Our basic strategy is to round-robin transports in priorities
+ * according to sctp_state_prio_map[] e.g., if no such
+ * transport with state SCTP_ACTIVE exists, round-robin through
+ * SCTP_UNKNOWN, etc. You get the picture.
*/
-void sctp_assoc_update_retran_path(struct sctp_association *asoc)
+static const u8 sctp_trans_state_to_prio_map[] = {
+ [SCTP_ACTIVE] = 3, /* best case */
+ [SCTP_UNKNOWN] = 2,
+ [SCTP_PF] = 1,
+ [SCTP_INACTIVE] = 0, /* worst case */
+};
+
+static u8 sctp_trans_score(const struct sctp_transport *trans)
{
- struct sctp_transport *t, *next;
- struct list_head *head = &asoc->peer.transport_addr_list;
- struct list_head *pos;
+ return sctp_trans_state_to_prio_map[trans->state];
+}
- if (asoc->peer.transport_count == 1)
- return;
+static struct sctp_transport *sctp_trans_elect_best(struct sctp_transport *curr,
+ struct sctp_transport *best)
+{
+ if (best == NULL)
+ return curr;
- /* Find the next transport in a round-robin fashion. */
- t = asoc->peer.retran_path;
- pos = &t->transports;
- next = NULL;
+ return sctp_trans_score(curr) > sctp_trans_score(best) ? curr : best;
+}
- while (1) {
- /* Skip the head. */
- if (pos->next == head)
- pos = head->next;
- else
- pos = pos->next;
+void sctp_assoc_update_retran_path(struct sctp_association *asoc)
+{
+ struct sctp_transport *trans = asoc->peer.retran_path;
+ struct sctp_transport *trans_next = NULL;
- t = list_entry(pos, struct sctp_transport, transports);
+ /* We're done as we only have the one and only path. */
+ if (asoc->peer.transport_count == 1)
+ return;
+ /* If active_path and retran_path are the same and active,
+ * then this is the only active path. Use it.
+ */
+ if (asoc->peer.active_path == asoc->peer.retran_path &&
+ asoc->peer.active_path->state == SCTP_ACTIVE)
+ return;
- /* We have exhausted the list, but didn't find any
- * other active transports. If so, use the next
- * transport.
- */
- if (t == asoc->peer.retran_path) {
- t = next;
+ /* Iterate from retran_path's successor back to retran_path. */
+ for (trans = list_next_entry(trans, transports); 1;
+ trans = list_next_entry(trans, transports)) {
+ /* Manually skip the head element. */
+ if (&trans->transports == &asoc->peer.transport_addr_list)
+ continue;
+ if (trans->state == SCTP_UNCONFIRMED)
+ continue;
+ trans_next = sctp_trans_elect_best(trans, trans_next);
+ /* Active is good enough for immediate return. */
+ if (trans_next->state == SCTP_ACTIVE)
break;
- }
-
- /* Try to find an active transport. */
-
- if ((t->state == SCTP_ACTIVE) ||
- (t->state == SCTP_UNKNOWN)) {
+ /* We've reached the end, time to update path. */
+ if (trans == asoc->peer.retran_path)
break;
- } else {
- /* Keep track of the next transport in case
- * we don't find any active transport.
- */
- if (t->state != SCTP_UNCONFIRMED && !next)
- next = t;
- }
}
- if (t)
- asoc->peer.retran_path = t;
- else
- t = asoc->peer.retran_path;
+ if (trans_next != NULL)
+ asoc->peer.retran_path = trans_next;
- pr_debug("%s: association:%p addr:%pISpc\n", __func__, asoc,
- &t->ipaddr.sa);
+ pr_debug("%s: association:%p updated new path to addr:%pISpc\n",
+ __func__, asoc, &asoc->peer.retran_path->ipaddr.sa);
}
-/* Choose the transport for sending retransmit packet. */
-struct sctp_transport *sctp_assoc_choose_alter_transport(
- struct sctp_association *asoc, struct sctp_transport *last_sent_to)
+struct sctp_transport *
+sctp_assoc_choose_alter_transport(struct sctp_association *asoc,
+ struct sctp_transport *last_sent_to)
{
/* If this is the first time packet is sent, use the active path,
* else use the retran path. If the last packet was sent over the
* retran path, update the retran path and use it.
*/
- if (!last_sent_to)
+ if (last_sent_to == NULL) {
return asoc->peer.active_path;
- else {
+ } else {
if (last_sent_to == asoc->peer.retran_path)
sctp_assoc_update_retran_path(asoc);
+
return asoc->peer.retran_path;
}
}
--
1.7.11.7
^ permalink raw reply related
* Re: [Xen-devel] [RFC v2 1/4] bridge: enable interfaces to opt out from becoming the root bridge
From: Luis R. Rodriguez @ 2014-02-20 20:01 UTC (permalink / raw)
To: Zoltan Kiss
Cc: Ian Campbell, kvm, netdev@vger.kernel.org, bridge,
linux-kernel@vger.kernel.org, Stephen Hemminger, xen-devel
In-Reply-To: <530600C5.3070107@citrix.com>
On Thu, Feb 20, 2014 at 5:19 AM, Zoltan Kiss <zoltan.kiss@citrix.com> wrote:
> How about this: netback sets the root_block flag and a random MAC by
> default. So the default behaviour won't change, DAD will be happy, and
> userspace don't have to do anything unless it's using netback for STP root
> bridge (I don't think there are too many toolstacks doing that), in which
> case it has to remove the root_block flag instead of setting a random MAC.
:D that's exactly what I ended up proposing too. I mentioned how
xen-netback could do this as well, we'd keep or rename the flag I
added, and then the bridge could would look at it and enable the root
block if the flag is set. Stephen however does not like having the
bridge code look at magic flags for this behavior and would prefer for
us to get the tools to ask for the root block. Let's follow more up on
that thread.
Luis
^ permalink raw reply
* [PATCH 1/1] TCP NewCWV for Linux
From: raffaello @ 2014-02-20 19:28 UTC (permalink / raw)
To: netdev; +Cc: ziaul.hossain, gorry
Hi,
This is a patch for newcwv a TCP sender-side modification,
currently a work item at TCPM (TCP Maintenance and Minor extensions)
at the IETF:
http://tools.ietf.org/search/draft-ietf-tcpm-newcwv-05
newcwv aims to supersede CWV (RFC2861) to provide better
congestion control for rate-limited applications that use TCP.
We implemented it as a module that uses tcp_congestion_ops.
The main changes are in "cong_avoid" before Reno cwnd control
and at the start and end of Fast Retransmit:
1) Before Reno algorithm we estimate at each ACK our pipeACK
(update_pipeack) and decide to increase or not cwnd based on pipeack.
2) At the start of FR we reset cwnd based on pipeACK, while
at the end we further reduce pipeACK by the number of retransmissions.
I posted it here for you consideration to be included in net-next.
---
net/ipv4/Kconfig | 17 +++
net/ipv4/Makefile | 1 +
net/ipv4/tcp_newcwv.c | 317
+++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 335 insertions(+)
create mode 100644 net/ipv4/tcp_newcwv.c
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 05c57f0..72294d8 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -556,6 +556,23 @@ config TCP_CONG_ILLINOIS
For further details see:
http://www.ews.uiuc.edu/~shaoliu/tcpillinois/index.html
+config TCP_CONG_NEWCWV
+ tristate "TCP New-CWV"
+ default n
+ ---help---
+ TCP new-CWV is a send-side modification of TCP to improve
+ congestion control for rate-limited applications. new-CWV allows
+ faster restarts after long idle periods and better congestion control
+ during periods the cwnd cannot be fully utilised.
+
+ If you select this congestion control method, it is recommended
+ to disable tcp_slow_start_after_idle:
+
+ echo "0" > /proc/sys/net/ipv4/tcp_slow_start_after_idle
+
+ For further details see:
+ http://tools.ietf.org/html/draft-ietf-tcpm-newcwv-05
+
choice
prompt "Default TCP congestion control"
default DEFAULT_CUBIC
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index f8c49ce..9424160 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
+obj-$(CONFIG_TCP_CONG_NEWCWV) += tcp_newcwv.o
obj-$(CONFIG_MEMCG_KMEM) += tcp_memcontrol.o
obj-$(CONFIG_NETLABEL) += cipso_ipv4.o
diff --git a/net/ipv4/tcp_newcwv.c b/net/ipv4/tcp_newcwv.c
new file mode 100644
index 0000000..6f669e4
--- /dev/null
+++ b/net/ipv4/tcp_newcwv.c
@@ -0,0 +1,317 @@
+/*
+ * New-CWV implementation for Linux: draft-ietf-tcpm-newcwv-05.txt
+ */
+
+#include <linux/module.h>
+#include <net/tcp.h>
+
+#define UNDEF_PIPEACK -1
+#define PIPEACK_INIT TCP_INFINITE_SSTHRESH
+#define TCP_RESTART_WINDOW 1
+#define FIVEMINS (HZ*300)
+#define NO_OF_BINS 4
+#define IS_VALID 0x0002
+#define IS_RECOVERY 0x0001
+#define nextbin(x) (((x)+1) & 0x03)
+#define prevbin(x) (((x)-1) & 0x03)
+
+/* contains newcwv state variables */
+struct newcwv {
+ int psample[NO_OF_BINS]; /* pipeACK samples circular buffer */
+ u32 time_stamp[NO_OF_BINS]; /* pipeACK sample timestamps */
+ int pipeack; /* pipeACK value after filtering */
+ u8 rsvd;
+ u8 head; /* index for psample array */
+ u16 flags;
+ u32 prior_in_flight; /* Packets in flight for cwnd reduction */
+ u32 prior_retrans; /* Retransmission before going into FR */
+ u32 prev_snd_una; /* snd_una when last record kept */
+ u32 prev_snd_nxt; /* snd_una when last record kept */
+ u32 cwnd_valid_ts; /* last time cwnd was found 'validated' */
+ u32 psp; /* pipeACK Sampling Period */
+};
+
+/* helper function for division */
+static u32 divide_or_zero(u32 dividend, u32 divisor)
+{
+ if (divisor == 0)
+ return 0;
+ else
+ return (u32) (dividend / divisor);
+}
+
+/* adds an element to the circular buffer for maximum filter */
+static void add_element(struct newcwv *nc, int val)
+{
+ nc->head = nextbin(nc->head);
+ nc->psample[nc->head] = val;
+ nc->time_stamp[nc->head] = tcp_time_stamp;
+}
+
+/* This fuction removes all the expired elements from the circular buffer
+ * and returns the maximum from the remaining elements
+ */
+static int remove_expired_element(struct newcwv *nc)
+{
+ int k = nc->head;
+ int tmp = nc->psample[nc->head];
+
+ while (nc->psample[k] != UNDEF_PIPEACK) {
+ /* remove expired */
+ if (nc->time_stamp[k] < tcp_time_stamp - nc->psp) {
+ nc->psample[k] = UNDEF_PIPEACK;
+ return tmp;
+ }
+
+ /* search the maximum */
+ if (nc->psample[k] > tmp)
+ tmp = nc->psample[k];
+
+ k = prevbin(k);
+ if (k == nc->head)
+ return tmp;
+ }
+
+ return tmp;
+}
+
+/* is TCP in the validated phase? */
+static inline bool tcp_is_in_vp(struct tcp_sock *tp, int pa)
+{
+ if (pa == UNDEF_PIPEACK)
+ return true;
+ else
+ return ((pa << 1) >= (tp->snd_cwnd * tp->mss_cache));
+}
+
+/* reduces the cwnd after 5mins of non-validated phase */
+static void datalim_closedown(struct sock *sk)
+{
+ struct newcwv *nc = inet_csk_ca(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
+ u32 nc_ts;
+
+ nc_ts = nc->cwnd_valid_ts;
+ while ((tcp_time_stamp - nc_ts) > FIVEMINS) {
+ nc_ts += FIVEMINS;
+ nc->cwnd_valid_ts = nc_ts;
+ tp->snd_ssthresh =
+ max((3 * tp->snd_cwnd) >> 2, tp->snd_ssthresh);
+ tp->snd_cwnd =
+ max_t(u32, tp->snd_cwnd >> 1, TCP_INIT_CWND);
+ }
+}
+
+
+/* updates pipeack when an ACK is received */
+static void update_pipeack(struct sock *sk)
+{
+ struct newcwv *nc = inet_csk_ca(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
+ int tmp_pipeack;
+
+ nc->psp = max(3 * (tp->srtt >> 3), (u32) HZ);
+
+ if (tp->snd_una >= nc->prev_snd_nxt) {
+
+ /* now get a new pipeack sample */
+ tmp_pipeack = tp->snd_una - nc->prev_snd_una;
+ nc->prev_snd_una = tp->snd_una;
+ nc->prev_snd_nxt = tp->snd_nxt;
+
+ /* create a new element at the end of current pmp */
+ if (tcp_time_stamp > nc->time_stamp[nc->head] + (nc->psp >> 2))
+ add_element(nc, tmp_pipeack);
+ else if (tmp_pipeack > nc->psample[nc->head])
+ nc->psample[nc->head] = tmp_pipeack;
+ }
+
+ nc->pipeack = remove_expired_element(nc);
+
+ /* check if cwnd is validated */
+ if (tcp_is_in_vp(tp, nc->pipeack)) {
+ nc->flags |= IS_VALID;
+ nc->cwnd_valid_ts = tcp_time_stamp;
+ } else {
+ nc->flags &= ~IS_VALID;
+ datalim_closedown(sk);
+ }
+}
+
+/* initialises newcwv variables */
+static void tcp_newcwv_init(struct sock *sk)
+{
+ struct newcwv *nc = inet_csk_ca(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ nc->prev_snd_una = tp->snd_una;
+ nc->prev_snd_nxt = tp->snd_nxt;
+
+ nc->cwnd_valid_ts = tcp_time_stamp;
+ nc->flags = IS_VALID;
+
+ nc->psp = max(3 * (tp->srtt >> 3), (u32) HZ);
+
+ nc->head = 0;
+ nc->psample[0] = UNDEF_PIPEACK;
+ nc->pipeack = UNDEF_PIPEACK;
+}
+
+
+/* cong_avoid action: non dubious ACK received */
+static void tcp_newcwv_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
+{
+ struct newcwv *nc = inet_csk_ca(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ nc->prior_in_flight = in_flight;
+ nc->prior_retrans = tp->total_retrans;
+
+ update_pipeack(sk);
+
+ /* Check if cwnd is validated */
+ if (!(nc->flags & IS_VALID) && !tcp_is_cwnd_limited(sk, in_flight))
+ return;
+
+ /* The following is the Reno behaviour */
+
+ /* In "safe" area, increase. */
+ if (tp->snd_cwnd <= tp->snd_ssthresh)
+ tcp_slow_start(tp);
+
+ /* In dangerous area, increase slowly. */
+ else
+ tcp_cong_avoid_ai(tp, tp->snd_cwnd);
+
+}
+
+/* newcwv actions in fast recovery */
+static void tcp_newcwv_enter_recovery(struct sock *sk)
+{
+ struct newcwv *nc = inet_csk_ca(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
+ u32 pipeack;
+
+ nc->flags |= IS_RECOVERY;
+
+ pipeack = (nc->pipeack == UNDEF_PIPEACK) ? 0 : (u32)
+ nc->pipeack;
+ pipeack = divide_or_zero(pipeack, (u32) tp->mss_cache);
+ tp->snd_cwnd = max(pipeack, nc->prior_in_flight) >> 1;
+
+ /* make sure the min. value for cwnd is 1 */
+ tp->snd_cwnd = (tp->snd_cwnd < 1) ? 1 : tp->snd_cwnd;
+
+}
+
+/* newcwv actions at the end of recovery */
+static void tcp_newcwv_end_recovery(struct sock *sk)
+{
+ struct newcwv *nc = inet_csk_ca(sk);
+ struct tcp_sock *tp = tcp_sk(sk);
+ u32 retrans, pipeack;
+
+ pipeack = (nc->pipeack == UNDEF_PIPEACK) ? 0 : (u32)
+ nc->pipeack;
+
+ pipeack = divide_or_zero(pipeack, (u32) tp->mss_cache);
+ retrans = tp->total_retrans - nc->prior_retrans;
+ tp->snd_cwnd = (max(pipeack, nc->prior_in_flight) - retrans) >> 1;
+ if (tp->snd_cwnd < TCP_RESTART_WINDOW)
+ tp->snd_cwnd = TCP_RESTART_WINDOW;
+
+ tp->snd_ssthresh = tp->snd_cwnd;
+ nc->flags &= ~IS_RECOVERY;
+
+ /* restart cwv machine */
+ tcp_newcwv_init(sk);
+
+}
+
+/* newcwv actions corresponding to event */
+static void tcp_newcwv_event(struct sock *sk, enum tcp_ca_event event)
+{
+ struct newcwv *nc = inet_csk_ca(sk);
+ const struct inet_connection_sock *icsk = inet_csk(sk);
+
+ switch (event) {
+ case CA_EVENT_TX_START:
+ datalim_closedown(sk);
+ break;
+
+ case CA_EVENT_COMPLETE_CWR:
+ if (!(nc->flags & IS_VALID))
+ tcp_newcwv_end_recovery(sk);
+ break;
+
+ case CA_EVENT_LOSS:
+ tcp_newcwv_init(sk);
+ break;
+
+ case CA_EVENT_SLOW_ACK:
+
+ switch (icsk->icsk_ca_state) {
+ case TCP_CA_Recovery:
+ if (!nc->flags)
+ tcp_newcwv_enter_recovery(sk);
+ break;
+
+ case TCP_CA_Open:
+ case TCP_CA_Disorder:
+ default:
+ break;
+ }
+ break;
+
+ case CA_EVENT_CWND_RESTART:
+ case CA_EVENT_FAST_ACK:
+ default:
+ break;
+ }
+
+}
+
+/* Slow start threshold resetting after loss */
+u32 tcp_newcwv_ssthresh(struct sock *sk)
+{
+ const struct tcp_sock *tp = tcp_sk(sk);
+
+ /* This is tcp_packets_in_flight */
+ u32 prior_in_flight =
+ tp->packets_out - tp->sacked_out - tp->lost_out + tp->retrans_out;
+
+ return max(prior_in_flight >> 1U, 2U);
+}
+
+struct tcp_congestion_ops tcp_newcwv = {
+ .flags = TCP_CONG_NON_RESTRICTED,
+ .name = "newcwv",
+ .init = tcp_newcwv_init,
+ .owner = THIS_MODULE,
+ .ssthresh = tcp_newcwv_ssthresh,
+ .cong_avoid = tcp_newcwv_cong_avoid,
+ .cwnd_event = tcp_newcwv_event,
+ .min_cwnd = tcp_reno_min_cwnd,
+};
+
+/* newcwv registered as congestion control in Linux */
+static int __init tcp_newcwv_register(void)
+{
+ BUILD_BUG_ON(sizeof(struct newcwv) > ICSK_CA_PRIV_SIZE);
+ tcp_register_congestion_control(&tcp_newcwv);
+
+ return 0;
+}
+
+/* unregister when module is disabled */
+static void __exit tcp_newcwv_unregister(void)
+{
+ tcp_unregister_congestion_control(&tcp_newcwv);
+}
+
+module_init(tcp_newcwv_register);
+module_exit(tcp_newcwv_unregister);
+
+MODULE_AUTHOR("Ziaul Hossain, Raffaello Secchi");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("NewCwv Reno variant");
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH net] net: sctp: fix multihoming retransmission path selection to rfc4960
From: Daniel Borkmann @ 2014-02-20 19:31 UTC (permalink / raw)
To: Vlad Yasevich; +Cc: davem, netdev, linux-sctp, Gui Jianfeng
In-Reply-To: <530656E7.7010404@gmail.com>
On 02/20/2014 08:26 PM, Vlad Yasevich wrote:
> On 02/20/2014 06:53 AM, Daniel Borkmann wrote:
>> Problem statement: 1) both paths (primary path1 and alternate
>> path2) are up after the association has been established i.e.,
>> HB packets are normally exchanged, 2) path2 gets inactive after
>> path_max_retrans * max_rto timed out (i.e. path2 is down completely),
>> 3) now, if a transmission times out on the only surviving/active
>> path1 (any ~1sec network service impact could cause this like
>> a channel bonding failover), then the retransmitted packets are
>> sent over the inactive path2; this happens with partial failover
>> and without it.
>
> Interesting. The problem above is actually triggered by
> sctp_retransmit(). When the T3-timeout occurs, we have
> active_patch == retrans_path, and even though the timeout
> occurred on the initial transmission of data, not a retransmit,
> we end up updating retransmit path.
>
> It might be worth adding adding this as a condition. See below.
>
>> Besides not being optimal in the above scenario, a small failure
>> or timeout in the only existing path has the potential to cause
>> long delays in the retransmission (depending on RTO_MAX) until
>> the still active path is reselected.
>>
>> RFC4960, section 6.4. "Multi-Homed SCTP Endpoints" states under
>> 6.4.1. "Failover from an Inactive Destination Address" the
>> following:
>>
>> Some of the transport addresses of a multi-homed SCTP endpoint
>> may become inactive due to either the occurrence of certain
>> error conditions (see Section 8.2) or adjustments from the
>> SCTP user.
>>
>> When there is outbound data to send and the primary path
>> becomes inactive (e.g., due to failures), or where the SCTP
>> user explicitly requests to send data to an inactive
>> destination transport address, before reporting an error to
>> its ULP, the SCTP endpoint should try to send the data to an
>> alternate *active* destination transport address if one exists.
>>
>> When retransmitting data that timed out, if the endpoint is
>> multihomed, it should consider each source-destination address
>> pair in its retransmission selection policy. When retransmitting
>> timed-out data, the endpoint should attempt to pick the most
>> divergent source-destination pair from the original
>> source-destination pair to which the packet was transmitted.
>>
>> Note: Rules for picking the most divergent source-destination
>> pair are an implementation decision and are not specified
>> within this document.
>>
>> So, we should first reconsider to take the current active
>> retransmission transport if we cannot find an alternative
>> active one, as otherwise, by sending a user message to an
>> inactive destination transport address while excluding an
>> active destination transport address, we would not comply
>> to RFC4960. If all of that fails, we can still round robin
>> through unkown, partial failover, and inactive ones in the
>> hope to find something still suitable/useful.
>>
>> Commit 4141ddc02a92 ("sctp: retran_path update bug fix") broke
>> that behaviour by selecting the next non-active transport when
>> no other active transport was found besides the current assoc's
>> peer.retran_path. Before commit 4141ddc02a92, we would have
>> traversed through the list until we reach our peer.retran_path
>> again, and in case that is still in state SCTP_ACTIVE, we would
>> take it and return. Only if that is not the case either, we
>> take the next inactive transport. Besides all that, another
>> issue is that transports in state SCTP_UNKNOWN could be preferred
>> over transports in state SCTP_ACTIVE in case a SCTP_ACTIVE
>> transport appears after SCTP_UNKNOWN in the transport list
>> yielding a "weaker" transport state to be used in retransmission.
>>
>> This patch mostly reverts 4141ddc02a92, but also rewrites
>> this function to introduce more clarity and strictness into
>> the code. A strict priority of transport states is enforced
>> in this patch, hence selection is active > unkown > partial
>> failover > inactive.
>>
>> Fixes: 4141ddc02a92 ("sctp: retran_path update bug fix")
>> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
>> Cc: Gui Jianfeng <guijianfeng@cn.fujitsu.com>
...
>> - t = list_entry(pos, struct sctp_transport, transports);
>> + /* We're done as we only have the one and only path. */
>> + if (asoc->peer.transport_count == 1)
>> + return;
>>
>
> I think we should to do one more short circuit here:
>
> /* If active_path and retrans_path are the same and active,
> * then this is the only active path. Use it.
> */
> if (asoc->peer.active_path == asoc->peer.retrans_path &&
> asoc->peer.active_path->state == SCTP_ACTIVE)
> return;
Ok, will add and resubmit, thanks Vlad.
>> - /* We have exhausted the list, but didn't find any
>> - * other active transports. If so, use the next
>> - * transport.
>> - */
>> - if (t == asoc->peer.retran_path) {
>> - t = next;
>> + /* Iterate from retran_path's successor back to retran_path. */
>> + for (trans = list_next_entry(trans, transports); 1;
>> + trans = list_next_entry(trans, transports)) {
>> + /* Manually skip the head element. */
>> + if (&trans->transports == &asoc->peer.transport_addr_list)
>> + continue;
>
> Alternative way would be:
> head = &asoc->peer.transport_addr_list;
> list_for_each_enty_from(trans, head, transport) {
> ... do the work...
>
> /* Manually skip head element if it's next */
> if (list_next_entry(trans, transports) == head)
> trans = list_first_entry(head);
> }
>
> It's up to you if you like this better or not.
I tested already the current version, so I'll go for that. ;)
Thanks for your feedback Vlad!
^ permalink raw reply
* Re: net/mlx4: Mellanox driver update 01-01-2014
From: Amir Vadai @ 2014-02-20 20:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev, yevgenyp, ogerlitz
In-Reply-To: <20140219.165049.1684072721398326970.davem@davemloft.net>
On 19/02/14 16:50 -0500, David Miller wrote:
> From: Amir Vadai <amirv@mellanox.com>
> Date: Wed, 19 Feb 2014 14:58:01 +0200
>
> > V0 of this patch was sent before previous net-next got closed, and
> > now we would like to resume it.
> >
> > Yuval has reworked the affinity hint patch, according to Ben's comments. The
> > patch was actually rewritten.
> > After a discussion with Yuval Mintz, use of netif_get_num_default_rss_queues()
> > is not reverted, but done in the right place. Instead of limiting the number of
> > IRQ's for the driver it will limit the number of queues in RSS.
> >
> > Patchset was applied and tested against commit: cb6e926 "ipv6:fix checkpatch
> > errors with assignment in if condition"
>
> Influencing IRQs to be allocated on the same NUMA code as the one where
> the card resides doesn't sound like an mlx4 specific desire to me.
>
> Other devices, both networking and non-networking, probably might like
> that as well.
>
> Therefore doing this by hand in a specific driver doesn't seem
> appropriate at all.
I agree. Will try to find a way to make it generic and resubmit this
patch.
Please continue with the review of the other patches by Ido, that will
fix the way netif_get_num_default_rss_queues() is used in Mellanox
driver.
Thanks,
Amir
^ permalink raw reply
* Re: [Xen-devel] [RFC v2 1/4] bridge: enable interfaces to opt out from becoming the root bridge
From: Luis R. Rodriguez @ 2014-02-20 20:24 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Ian Campbell, kvm, netdev@vger.kernel.org, bridge,
linux-kernel@vger.kernel.org, Zoltan Kiss, xen-devel
In-Reply-To: <20140220091958.62a8b444@nehalam.linuxnetplumber.net>
On Thu, Feb 20, 2014 at 9:19 AM, Stephen Hemminger
<stephen@networkplumber.org> wrote:
> On Wed, 19 Feb 2014 09:59:33 -0800 "Luis R. Rodriguez" <mcgrof@do-not-panic.com> wrote:
>> On Wed, Feb 19, 2014 at 9:08 AM, Stephen Hemminger <stephen@networkplumber.org> wrote:
>> >
>> > Please only use the netlink/sysfs flags fields that already exist
>> > for new features.
>>
>> Sure, but what if we know a driver in most cases wants the root block
>> and we'd want to make it the default, thereby only requiring userspace
>> for toggling it off.
>
> Something in userspace has to put the device into the bridge.
> Fix the port setup in that tool via the netlink or sysfs flags in
> the bridge. It should not have to be handled in the bridge looking
> at magic flags in the device.
Agreed that's the best strategy and I'll work on sending patches to
brctl to enable the root_block preference. This approach however also
requires a userspace upgrade. I'm trying to see if we can get an
old-nasty-cryptic-hack practice removed from the kernel and we'd try
to prevent future drivers from using it -- without requiring userspace
upgrade. In this case the bad practice is to using a high static MAC
address for mimicking a root block default preference. In order to
remove that *without* requiring a userspace upgrade the dev->priv_flag
approach is the only thing I can think of. If this would go in we'd
replace the high static MAC address with a random MAC address to
prevent IPv6 SLAAC / DAD conflicts. I'd document this flag and
indicate with preference for userspace to be the one tuning these
knobs.
Without this we'd have to keep the high static MAC address on upstream
drivers and let userspace do the random'ization if it confirms the
userspace knob to turn the root block flag is available. Is the
priv_flag approach worth the compromise to remove the root block hack
practice?
Luis
^ permalink raw reply
* Re: [Xen-devel] [RFC v2 1/4] bridge: enable interfaces to opt out from becoming the root bridge
From: Luis R. Rodriguez @ 2014-02-20 20:28 UTC (permalink / raw)
To: Zoltan Kiss
Cc: kvm, netdev@vger.kernel.org, bridge, linux-kernel@vger.kernel.org,
Stephen Hemminger, xen-devel
In-Reply-To: <5306156B.4070105@citrix.com>
On Thu, Feb 20, 2014 at 6:47 AM, Zoltan Kiss <zoltan.kiss@citrix.com> wrote:
> On 19/02/14 16:45, Luis R. Rodriguez wrote:
>
>> You seem to describe a case whereby it can make sense for xen-netback
>> interfaces to end up becoming the root port of a bridge. Can you
>> elaborate a little more on that as it was unclear the use case.
>
> Well, I might be wrong on that, but the scenario I was thinking: a guest
> (let's say domain 1) can have multiple interfaces on different Dom0 (or
> driver domain) bridges, let's say vif1.0 is plugged into xenbr0 and vif1.1
> is in xenbr1. If the guest wants to make a bridge of this two, then using
> STP makes sense.
The bridging would happen on the front end in that case no?
> I wanted to bring up CloudStack's virtual router as an
> example, but then I realized it's probably doesn't do such thing. However I
> don't think we should hardcode that a netback interface can't be RP ever.
My patch did allow for this but the root block flag that Stephen
mentioned can always be lifted.
Luis
^ permalink raw reply
* pull request: wireless-next 2014-02-20
From: John W. Linville @ 2014-02-20 20:30 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev
[-- Attachment #1: Type: text/plain, Size: 29605 bytes --]
Dave,
Please pull this batch of wireless updates intended for the 3.15
stream!
For the mac80211 bits, Johannes says:
"We have some cleanups and minor fixes as well as userspace API
improvements from a lot of people, extended VHT support for radiotap
from Emmanuel, CSA improvements from Andrei, Luca and Michal. I've also
included my work on hwsim to make dynamic registration of radios
possible."
Along with that, we get the usual round of updates to ath9k,
brcmfmac, mwifiex, wcn36xx, and the ti drivers -- nothing particularly
noteworthy, mostly just random updates and refactoring.
Also included is a pull of the wireless tree, intended to resolve
some potential merge issues.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit 010d3c3989706d800ae72253773fa6537cc9f74c:
bonding: fix bond_arp_rcv() race of curr_active_slave (2014-02-20 13:20:55 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next.git for-davem
for you to fetch changes up to 88daf80dcca19ff995cc263592426f734a9702f3:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem (2014-02-20 15:02:02 -0500)
----------------------------------------------------------------
Aaron Durbin (2):
mwifiex: balance dma map/unmap sizes
mwifiex: don't leak DMA command skbuffs
Amitkumar Karwar (7):
mwifiex: change beacon parameter structure
mwifiex: separate out response buffer parsing code
mwifiex: separate out next scan command queueing logic
mwifiex: implement extended scan feature
mwifiex: update beamforming capability field for HT
mwifiex: advertise correct beamforming information for VHT
mwifiex: cleanup in mwifiex_fill_cap_info()
Andrei Otcheretianski (1):
mac80211_hwsim: add channel switch support
Antonio Quartulli (1):
cfg80211: fix channel configuration in IBSS join
Ard Biesheuvel (1):
mac80211: drop unused param 'encrypted' from ccmp_special_blocks()
Arend van Spriel (7):
brcmfmac: move SDIO specific functions
brcmfmac: rename sdio_chip.[ch]
brcmfmac: make chip related functions host interface independent
brcmfmac: remove TRACE level debug message from brcmf_sdio_bus_sleep()
brcmfmac: remove unintended error logging
brcmfmac: get chip core information from the device
brcmfmac: CR4 takes precedence over CM3 in brcmf_chip_enter_download()
Ariej Marjieh (3):
iwlwifi: mvm: remove upper limit for error log base pointer
iwlwifi: 8000: add 11n only SKU of 8000 devices
iwlwifi: change number of PAPD groups in PHY DB
Arik Nemtsov (7):
iwlwifi: add very first D0i3 support
iwlwifi: mvm: add D0i3 ref/unref for scan
wlcore: cancel Tx watchdog on suspend and rearm on first Tx after
wlcore: AP: don't start mac80211 PS on non-peer HLIDs
wlcore: wl18xx: allow CCK rates for AP mode
wlcore: decrease warning verbosity during recovery
wlcore: add support for STA CSA with chan contexts
Avinash Patil (17):
mwifiex: handle AMPDU supported check for AP interface
mwifiex: make tos_to_tid_inv part of mwifiex_private structure
mwifiex: move station list functions to common code
mwifiex: add tdls_mgmt handler support
mwifiex: parse TDLS action frames during RX
mwifiex: add cfg80211 tdls_oper handler support
mwifiex: add cfg80211 add_station handler support
mwifiex: add cfg80211 change_station handler support
mwifiex: provision for holding and restoring packets during TDLS setup
mwifiex: tdls related handling for data packets addressed to TDLS peer
mwifiex: AMPDU support for TDLS link
mwifiex: pass ieee80211_vht_cap to mwifiex_fill_vht_cap_tlv
mwifiex: add VHT support for TDLS
mwifiex: separate BA params for TDLS link if 11ac is supported
mwifiex: disable all TDLS link during disconnection
mwifiex: parse API version from FW
mwifiex: add key material v2 support
Barak Bercovitz (2):
wlcore: block read/writes to FW during ELP
wlcore: don't stop sched_scan on interface removal
Bing Zhao (4):
mwifiex: make use of IEEE80211_VHT_MCS_NOT_SUPPORTED
mwifiex: make 11ac mcs rate tables global and const
mwifiex: improve readability in 11ac mcsmap to maxrate conversion
mwifiex: remove unsupported code in 11ac
Chun-Yeow Yeoh (1):
mac80211: fix the increment of mesh precedence value
Daniel Kim (2):
brcmfmac: enable firmware console logging functionality
brcmfmac: correct setting of WEP broadcast/unicast keys
David Spinadel (2):
iwlwifi: mvm: don't stop sched scan in restart
iwlwifi: mvm: notify scan completed even if no fw_restart
Eliad Peller (24):
iwlwifi: mvm: add basic bcast filtering implementation
iwlwifi: mvm: add predefined broadcast filter configuration
iwlwifi: mvm: add dest ip to bcast filter configuration
iwlwifi: mvm: add bcast_filtering debugfs entries
iwlwifi: add D0i3 references boiler plate
iwlwifi: add enter/exit D0i3 ops
iwlwifi: mvm: add D0i3 power configurations
iwlwifi: mvm: configure vifs upon D0i3 entry/exit
iwlwifi: mvm: allow transport sleep when FW is operational
iwlwifi: mvm: add D0i3 ref/unref for ROC commands
iwlwifi: mvm: add D0i3 ref/unref when ap, ibss or p2p_cli vifs are running
iwlwifi: mvm: add d0i3_refs debugfs file
iwlwifi: mvm: configure WOWLAN_CONFIGURATION on D0i3 entry
iwlwifi: mvm: get status on D0i3 exit
iwlwifi: mvm: add debugfs hook to take an mvm ref
iwlwifi: mvm: reserve sta_id 0 to station
wlcore/wl12xx/wl18xx: simplify fw_status handling
wlcore/wl12xx/wl18xx: configure num_links per-hw
wlcore/wl12xx/wl18xx: configure max_stations per-hw
wlcore/wl12xx/wl18xx: configure iface_combinations per-hw
wl18xx: move to new firmware (wl18xx-fw-3.bin)
wlcore: don't handle unsetting of default wep key
wlcore: consider multiple APs when checking active_link_count
wlcore: enable beacon filtering only after receiving a beacon
Emmanuel Grumbach (24):
iwlwifi: 7000: warn about old firmware
iwlwifi: remove obsolete TODO
iwlwifi: mvm: provide helper to fetch the iwl_mvm_sta from sta_id
iwlwifi: mvm: check ARRAY_SIZE(mvm->fw_id_to_mac_id) = IWL_MVM_STATION_COUNT
iwlwifi: pcie: fix unused variable gcc warning
iwlwifi: mvm: BT Coex - set low latency vif as primary
iwlwifi: mvm: BT Coex - change SMPS settings in AP mode
iwlwifi: mvm: change the format of the SRAM dump
iwlwifi: mvm: allow to force reduced tx power from debugfs
iwlwifi: mvm: add vif type in debugfs output
iwlwifi: fix kerneldoc format
iwlwifi: mvm: BT Coex - fix SYNC2SCO flags
iwlwifi: mvm: remove duplicate assignment to ap_ibss_active
iwlwifi: mvm: clean up in power code
iwlwifi: mvm: don't look at power commmand to decide if power is enabled
iwlwifi: mvm: don't send the beacon filtering command from iterator
iwlwifi: mvm: store latest power command for debugfs read
iwlwifi: mvm: remove support for legacy power API
iwlwifi: mvm: remove iwl_mvm_power_mac_disable
iwlwifi: mvm: refactor power code
mac80211: remove unused radiotap vendor fields in ieee80211_rx_status
mac80211: move VHT related RX_FLAG to another variable
mac80211: propagate STBC / LDPC flags to radiotap
iwlwifi: mvm: fix typo in WARNING in rs.c
Eran Harary (8):
iwlwifi: Add 8000 HW family support
iwlwifi: mvm: support NVM sections for family 8000
iwlwifi: pcie: disable APMG configurations for family 8000
iwlwifi: pcie: change CSR reset in family 8000
iwlwifi: pcie: Disable L0S exit timer for 8000 HW family
iwlwifi: pcie: fix secure section / dual cpu firmware loading
iwlwifi: mvm: support multiple firmware sections
iwlwifi: mvm: support alive notification api version2
Eyal Shapira (1):
mac80211: advertise BF STS according to AP support
Franky Lin (1):
brcmfmac: add owner info to sdio_driver structure
Geert Uytterhoeven (1):
ath9k: Fix uninitialized variable in ath9k_has_tx_pending()
Hante Meuleman (4):
brcmfmac: expand sta info to report dtim and beacon period.
brcmfmac: fix sdio sending of large buffers.
brcmfmac: simplify sdio code download routine.
brcmfmac: on sdio remove first detach bus then stop worker.
Ido Yariv (3):
iwlwifi: pcie: retrieve and parse ACPI power limitations
iwlwifi: mvm: handle platform PCIe power limitation
iwlwifi: 7265: add power limit/tx backoff translation table
Igal Chernobelsky (1):
wlcore: send EAPOL frames with voice priority
Ilan Peer (5):
iwlwifi: mvm: add the quota remainder to a data binding
iwlwifi: mvm: fix quota allocation
cfg80211: fix few minor issues in reg_process_hint()
mac80211: Fix ROC duration == 0 handling
iwlwifi: mvm: modify the tsf_id master/slave logic
Janusz Dziedzic (4):
nl80211: add Guard Interval support for set_bitrate_mask
cfg80211: set preset_chandef after channel switch
cfg80211: add helper reg_get_regdomain() function
cfg80211: regulatory introduce maximum bandwidth calculation
Johannes Berg (32):
iwlwifi: mvm: implement AP/GO uAPSD support
iwlwifi: pcie: make FH debugfs file code easier to understand
iwlwifi: mvm: add low-latency framework
iwlwifi: mvm: disable powersave in low-latency
iwlwifi: mvm: reserve bandwidth for low-latency interface
iwlwifi: mvm: limit non-low-latency binding scheduling duration
iwlwifi: rs: use const u16 for throughput tables
iwlwifi: mvm: remove unneeded calculations
iwlwifi: mvm: abort scheduled scan on scan request
iwlwifi: mvm: clean up iwl_mvm_bss_info_changed_ap_ibss
cfg80211: make connect ie param const
nl80211: check channel switch validity better
mac80211: mesh: remove mesh_id check
mac80211: use sdata mesh_id_len instead of wdev's
mac80211: fix agg_status debugfs file write
mac80211: make rate control ops const
mac80211: make cfg80211 ops and privid const
nl80211: make netlink attribute policies const
cfg80211: make device_type const
mac80211_hwsim: make netlink policy const
mac80211: minstrel_ht: sample_table can be __read_mostly
mac80211: remove module handling from rate control ops
mac80211_hwsim: make P2P-Device support optional
nl80211: check nla_parse() return values
mac80211: add length check in ieee80211_is_robust_mgmt_frame()
nl80211: send event when AP operation is stopped
nl80211: fix scheduled scan RSSI matchset attribute confusion
mac80211: remove set but unused variables
mac80211: fix bufferable MMPDU RX handling
wireless: sort and extend element ID list
mac80211: order IEs in probe request correctly
mac80211: order IEs in association request correctly
John W. Linville (4):
Merge git://git.kernel.org/.../iwlwifi/iwlwifi-next
Merge branch 'for-john' of git://git.kernel.org/.../jberg/mac80211-next
Merge branch 'master' of git://git.kernel.org/.../linville/wireless
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next into for-davem
Jouni Malinen (3):
cfg80211: Allow BSS hint to be provided for connect
cfg80211: Advertise maximum associated STAs in AP mode
cfg80211: Clean up connect params and channel fetching
Karl Beldan (1):
mac80211: send {ADD,DEL}BA on AC_VO like other mgmt frames, as per spec
Liad Kaufman (1):
iwlwifi: fix potential buffer overrun in fw name
Luciano Coelho (4):
mac80211: refactor ieee80211_mesh_process_chanswitch()
mac80211: align ieee80211_mesh_csa_beacon() with ieee80211_assign_beacon()
mac80211: only set CSA beacon when at least one beacon must be transmitted
mac80211: ibss: remove unnecessary call to release channel
Marek Kwaczynski (1):
mac80211: update opmode when adding new station
Masaki TAGAWA (1):
ath9k_htc: Add device ID for Buffalo WLI-UV-AG300P
Michal Kazior (7):
mac80211: batch CSA bss info notification
mac80211: fix possible memory leak on AP CSA failure
mac80211: move csa_active setting in STA CSA
mac80211: fix sdata->radar_required locking
mac80211: add missing CSA locking
cfg80211: consider existing DFS interfaces
ath9k: prepare for multi-interface CSA support
Nadim Zubidat (1):
wlcore: memset wl->rx_filter_enabled to zero after recovery
Oleksij Rempel (13):
ath: add last_rssi to ath_common
ath9k: move ath9k_process_rssi to common.c
ath9k: move ath9k_process_rate to common.c
ath9k: move ath9k_rx_accept to common.c
ath9k_htc: add rx header converter to make it usable by ath9k
ath9k_htc: use ath9k_cmn_process_rssi
ath9k_htc: use ath9k_cmn_process_rate
ath9k_htc: use ath9k_cmn_rx_accept
ath9k_htc: sync rx_status-> related code with ath9k
ath9k: move ath9k_rx_skb_postprocess to common.c
ath9k_htc: use ath9k_cmn_rx_skb_postprocess
ath9k_htc: remove useless memcpy
ath9k_htc: catch fw panic pattern
Pontus Fuchs (9):
wcn36xx: Fix copy paste error hal_exit_bmps -> hal_keep_alive
wcn36xx: Improve feature caps exchange
wcn36xx: Wait longer for SMD commands to complete
wcn36xx: Cache nv to avoid request_firmware on resume path
wcn36xx: Print FW capabilities
wcn36xx: Add support for 3680
wcn36xx: Rename wcn36xx_vif.ucast_dpu_signature to self_ucast_dpu_sign
wcn36xx: Track dpu signature per sta
wcn36xx: Update dtim period before starting BSS
Shaibal Dutta (2):
net: wireless: move regulatory timeout work to power efficient workqueue
net: rfkill: move poll work to power efficient workqueue
Simon Wunderlich (1):
mac80211: send ibss probe responses with noack flag
Stanislaw Gruszka (1):
rt2x00: move frequent messages to debug level
Stephen Rothwell (1):
Staging: rtl8812ae: remove modules field of rate_control_ops
Sujith Manoharan (9):
ath9k: Remove unnecessary check
ath9k: Remove ath9k rate control
ath9k: Fix IQ cal post processing for SoC
ath9k: Check explicitly for IQ calibration
ath9k: Rename ar9003_hw_tx_iqcal_load_avg_2_passes
ath9k: Fix magnitude/phase calculation
ath9k: Modify IQ calibration for AR955x
ath9k: Expand the IQ coefficient array
ath9k: Calculate IQ-CAL median
Yaniv Machani (1):
wlcore: increase timeout to 5000 msecs
ZHAO Gang (1):
b43: use kernel api to replace b43 specific helper function
andrea merello (2):
mac80211: add check on hw->max_signal value on ieee80211_register_hw
rtl818x: change misleading names for few register bit definitions
drivers/net/wireless/ath/ath.h | 2 +
drivers/net/wireless/ath/ath10k/txrx.c | 4 +-
drivers/net/wireless/ath/ath6kl/cfg80211.c | 27 +-
drivers/net/wireless/ath/ath9k/Kconfig | 12 -
drivers/net/wireless/ath/ath9k/Makefile | 1 -
drivers/net/wireless/ath/ath9k/ar9003_calib.c | 235 ++-
drivers/net/wireless/ath/ath9k/ath9k.h | 11 +-
drivers/net/wireless/ath/ath9k/beacon.c | 29 +-
drivers/net/wireless/ath/ath9k/common.c | 244 ++++
drivers/net/wireless/ath/ath9k/common.h | 19 +
drivers/net/wireless/ath/ath9k/debug.h | 1 -
drivers/net/wireless/ath/ath9k/dfs_debug.h | 2 +
drivers/net/wireless/ath/ath9k/hif_usb.c | 2 +
drivers/net/wireless/ath/ath9k/htc.h | 1 -
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 1 +
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 1 +
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 176 +--
drivers/net/wireless/ath/ath9k/htc_hst.c | 36 +
drivers/net/wireless/ath/ath9k/htc_hst.h | 12 +
drivers/net/wireless/ath/ath9k/hw.c | 1 -
drivers/net/wireless/ath/ath9k/init.c | 16 +-
drivers/net/wireless/ath/ath9k/mac.h | 9 +-
drivers/net/wireless/ath/ath9k/main.c | 16 +-
drivers/net/wireless/ath/ath9k/rc.c | 1495 --------------------
drivers/net/wireless/ath/ath9k/rc.h | 248 ----
drivers/net/wireless/ath/ath9k/recv.c | 266 +---
drivers/net/wireless/ath/ath9k/xmit.c | 2 +-
drivers/net/wireless/ath/wcn36xx/dxe.c | 10 +-
drivers/net/wireless/ath/wcn36xx/dxe.h | 4 +-
drivers/net/wireless/ath/wcn36xx/hal.h | 4 +-
drivers/net/wireless/ath/wcn36xx/main.c | 72 +-
drivers/net/wireless/ath/wcn36xx/smd.c | 64 +-
drivers/net/wireless/ath/wcn36xx/smd.h | 5 +-
drivers/net/wireless/ath/wcn36xx/txrx.c | 7 +-
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 10 +-
drivers/net/wireless/b43/main.h | 35 -
drivers/net/wireless/b43/xmit.c | 12 +-
drivers/net/wireless/brcm80211/brcmfmac/Makefile | 4 +-
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 8 +-
drivers/net/wireless/brcm80211/brcmfmac/chip.c | 1029 ++++++++++++++
drivers/net/wireless/brcm80211/brcmfmac/chip.h | 91 ++
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 536 ++++---
drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 5 +-
drivers/net/wireless/brcm80211/brcmfmac/fwil.h | 2 +-
.../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 972 -------------
.../net/wireless/brcm80211/brcmfmac/sdio_chip.h | 231 ---
.../net/wireless/brcm80211/brcmfmac/sdio_host.h | 89 ++
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 83 +-
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 3 +-
drivers/net/wireless/iwlegacy/3945-rs.c | 3 +-
drivers/net/wireless/iwlegacy/4965-rs.c | 3 +-
drivers/net/wireless/iwlwifi/Kconfig | 14 +
drivers/net/wireless/iwlwifi/Makefile | 2 +-
drivers/net/wireless/iwlwifi/dvm/rs.c | 23 +-
drivers/net/wireless/iwlwifi/dvm/rs.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-7000.c | 23 +-
drivers/net/wireless/iwlwifi/iwl-8000.c | 132 ++
drivers/net/wireless/iwlwifi/iwl-config.h | 18 +
drivers/net/wireless/iwlwifi/iwl-csr.h | 32 -
drivers/net/wireless/iwlwifi/iwl-debug.h | 2 +
drivers/net/wireless/iwlwifi/iwl-drv.c | 5 +-
drivers/net/wireless/iwlwifi/iwl-fw.h | 7 +-
drivers/net/wireless/iwlwifi/iwl-io.c | 15 +
drivers/net/wireless/iwlwifi/iwl-io.h | 2 +
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 6 +-
drivers/net/wireless/iwlwifi/iwl-op-mode.h | 24 +-
drivers/net/wireless/iwlwifi/iwl-phy-db.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-prph.h | 46 +
drivers/net/wireless/iwlwifi/iwl-trans.h | 38 +
drivers/net/wireless/iwlwifi/mvm/Makefile | 2 +-
drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 138 +-
drivers/net/wireless/iwlwifi/mvm/constants.h | 4 +
drivers/net/wireless/iwlwifi/mvm/d3.c | 31 +-
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | 112 +-
drivers/net/wireless/iwlwifi/mvm/debugfs.c | 285 +++-
drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h | 17 +-
drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | 6 +-
drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | 33 +-
drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h | 31 +-
drivers/net/wireless/iwlwifi/mvm/fw-api.h | 128 +-
drivers/net/wireless/iwlwifi/mvm/fw.c | 67 +-
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 76 +-
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 476 ++++++-
drivers/net/wireless/iwlwifi/mvm/mvm.h | 168 ++-
drivers/net/wireless/iwlwifi/mvm/nvm.c | 34 +-
drivers/net/wireless/iwlwifi/mvm/ops.c | 257 +++-
drivers/net/wireless/iwlwifi/mvm/power.c | 385 +++--
drivers/net/wireless/iwlwifi/mvm/power_legacy.c | 319 -----
drivers/net/wireless/iwlwifi/mvm/quota.c | 119 +-
drivers/net/wireless/iwlwifi/mvm/rs.c | 29 +-
drivers/net/wireless/iwlwifi/mvm/rs.h | 2 +-
drivers/net/wireless/iwlwifi/mvm/rx.c | 12 +-
drivers/net/wireless/iwlwifi/mvm/scan.c | 15 +-
drivers/net/wireless/iwlwifi/mvm/sta.c | 203 ++-
drivers/net/wireless/iwlwifi/mvm/sta.h | 62 +-
drivers/net/wireless/iwlwifi/mvm/time-event.c | 2 +
drivers/net/wireless/iwlwifi/mvm/tt.c | 7 +-
drivers/net/wireless/iwlwifi/mvm/tx.c | 23 +
drivers/net/wireless/iwlwifi/mvm/utils.c | 99 +-
drivers/net/wireless/iwlwifi/pcie/drv.c | 82 ++
drivers/net/wireless/iwlwifi/pcie/rx.c | 3 +-
drivers/net/wireless/iwlwifi/pcie/trans.c | 267 ++--
drivers/net/wireless/iwlwifi/pcie/tx.c | 5 +-
drivers/net/wireless/libertas/cfg.c | 3 +-
drivers/net/wireless/mac80211_hwsim.c | 90 +-
drivers/net/wireless/mac80211_hwsim.h | 2 +
drivers/net/wireless/mwifiex/11ac.c | 192 ++-
drivers/net/wireless/mwifiex/11ac.h | 2 +
drivers/net/wireless/mwifiex/11n.c | 51 +-
drivers/net/wireless/mwifiex/11n.h | 44 +-
drivers/net/wireless/mwifiex/11n_rxreorder.c | 27 +-
drivers/net/wireless/mwifiex/Makefile | 1 +
drivers/net/wireless/mwifiex/cfg80211.c | 184 ++-
drivers/net/wireless/mwifiex/cfp.c | 203 ++-
drivers/net/wireless/mwifiex/cmdevt.c | 54 +-
drivers/net/wireless/mwifiex/decl.h | 23 +
drivers/net/wireless/mwifiex/fw.h | 181 ++-
drivers/net/wireless/mwifiex/init.c | 5 +
drivers/net/wireless/mwifiex/ioctl.h | 22 +-
drivers/net/wireless/mwifiex/join.c | 14 +-
drivers/net/wireless/mwifiex/main.h | 90 +-
drivers/net/wireless/mwifiex/pcie.c | 138 +-
drivers/net/wireless/mwifiex/scan.c | 598 +++++---
drivers/net/wireless/mwifiex/sta_cmd.c | 373 ++++-
drivers/net/wireless/mwifiex/sta_cmdresp.c | 112 +-
drivers/net/wireless/mwifiex/sta_event.c | 12 +
drivers/net/wireless/mwifiex/sta_ioctl.c | 40 +-
drivers/net/wireless/mwifiex/sta_rx.c | 13 +-
drivers/net/wireless/mwifiex/sta_tx.c | 3 +
drivers/net/wireless/mwifiex/tdls.c | 1044 ++++++++++++++
drivers/net/wireless/mwifiex/uap_event.c | 118 --
drivers/net/wireless/mwifiex/util.c | 114 ++
drivers/net/wireless/mwifiex/util.h | 20 +-
drivers/net/wireless/mwifiex/wmm.c | 96 +-
drivers/net/wireless/mwifiex/wmm.h | 18 +
drivers/net/wireless/rndis_wlan.c | 4 +-
drivers/net/wireless/rt2x00/rt2800usb.c | 10 +-
drivers/net/wireless/rtl818x/rtl8180/dev.c | 8 +-
drivers/net/wireless/rtl818x/rtl8187/dev.c | 14 +-
drivers/net/wireless/rtl818x/rtl818x.h | 10 +-
drivers/net/wireless/rtlwifi/rc.c | 3 +-
drivers/net/wireless/rtlwifi/rtl8188ee/trx.c | 2 +-
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 2 +-
drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 2 +-
drivers/net/wireless/rtlwifi/rtl8723ae/trx.c | 2 +-
drivers/net/wireless/ti/wl12xx/main.c | 67 +-
drivers/net/wireless/ti/wl12xx/wl12xx.h | 53 +
drivers/net/wireless/ti/wl18xx/main.c | 85 +-
drivers/net/wireless/ti/wl18xx/tx.c | 4 +-
drivers/net/wireless/ti/wl18xx/wl18xx.h | 62 +-
drivers/net/wireless/ti/wlcore/acx.c | 7 +-
drivers/net/wireless/ti/wlcore/acx.h | 6 +-
drivers/net/wireless/ti/wlcore/cmd.c | 24 +-
drivers/net/wireless/ti/wlcore/cmd.h | 9 +-
drivers/net/wireless/ti/wlcore/event.c | 4 +-
drivers/net/wireless/ti/wlcore/hw_ops.h | 9 +
drivers/net/wireless/ti/wlcore/init.c | 6 +-
drivers/net/wireless/ti/wlcore/io.h | 8 +-
drivers/net/wireless/ti/wlcore/main.c | 192 +--
drivers/net/wireless/ti/wlcore/ps.c | 6 +-
drivers/net/wireless/ti/wlcore/rx.c | 19 +-
drivers/net/wireless/ti/wlcore/rx.h | 2 +-
drivers/net/wireless/ti/wlcore/tx.c | 45 +-
drivers/net/wireless/ti/wlcore/tx.h | 1 +
drivers/net/wireless/ti/wlcore/wlcore.h | 27 +-
drivers/net/wireless/ti/wlcore/wlcore_i.h | 86 +-
drivers/staging/rtl8821ae/rc.c | 1 -
include/linux/ieee80211.h | 199 ++-
include/net/cfg80211.h | 43 +-
include/net/ieee80211_radiotap.h | 4 +
include/net/mac80211.h | 52 +-
include/uapi/linux/nl80211.h | 52 +-
net/mac80211/agg-tx.c | 2 +-
net/mac80211/cfg.c | 198 ++-
net/mac80211/cfg.h | 2 +-
net/mac80211/chan.c | 2 +
net/mac80211/debugfs_sta.c | 2 +-
net/mac80211/ht.c | 2 +-
net/mac80211/ibss.c | 28 +-
net/mac80211/ieee80211_i.h | 14 +-
net/mac80211/iface.c | 2 +
net/mac80211/main.c | 9 +-
net/mac80211/mesh.c | 96 +-
net/mac80211/mlme.c | 41 +-
net/mac80211/rate.c | 46 +-
net/mac80211/rate.h | 2 +-
net/mac80211/rc80211_minstrel.c | 2 +-
net/mac80211/rc80211_minstrel.h | 2 +-
net/mac80211/rc80211_minstrel_ht.c | 7 +-
net/mac80211/rc80211_pid_algo.c | 2 +-
net/mac80211/rx.c | 101 +-
net/mac80211/sta_info.h | 2 +
net/mac80211/status.c | 3 +-
net/mac80211/tx.c | 33 +-
net/mac80211/util.c | 42 +-
net/mac80211/vht.c | 26 +-
net/mac80211/wpa.c | 9 +-
net/rfkill/core.c | 9 +-
net/wireless/ap.c | 3 +-
net/wireless/chan.c | 23 +-
net/wireless/core.c | 2 +-
net/wireless/core.h | 7 +-
net/wireless/ibss.c | 19 +-
net/wireless/mesh.c | 6 +-
net/wireless/mlme.c | 2 +-
net/wireless/nl80211.c | 229 ++-
net/wireless/nl80211.h | 2 +
net/wireless/reg.c | 188 ++-
net/wireless/reg.h | 2 +
net/wireless/trace.h | 23 +-
net/wireless/util.c | 5 +-
211 files changed, 9921 insertions(+), 6336 deletions(-)
delete mode 100644 drivers/net/wireless/ath/ath9k/rc.c
delete mode 100644 drivers/net/wireless/ath/ath9k/rc.h
create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/chip.c
create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/chip.h
delete mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
delete mode 100644 drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
create mode 100644 drivers/net/wireless/iwlwifi/iwl-8000.c
delete mode 100644 drivers/net/wireless/iwlwifi/mvm/power_legacy.c
create mode 100644 drivers/net/wireless/mwifiex/tdls.c
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [RFC v2 2/4] net: enables interface option to skip IP
From: Luis R. Rodriguez @ 2014-02-20 20:31 UTC (permalink / raw)
To: Dan Williams
Cc: Zoltan Kiss, netdev@vger.kernel.org, xen-devel, kvm,
linux-kernel@vger.kernel.org, David S. Miller, Alexey Kuznetsov,
James Morris, Hideaki YOSHIFUJI, Patrick McHardy
In-Reply-To: <1392857777.22693.14.camel@dcbw.local>
On Wed, Feb 19, 2014 at 4:56 PM, Dan Williams <dcbw@redhat.com> wrote:
> Note that there isn't yet a disable_ipv4 knob though, I was
> perhaps-too-subtly trying to get you to send a patch for it, since I can
> use it too :)
Sure, can you describe a little better the use case, as I could use
that for the commit log. My only current use case was the xen-netback
case but Zoltan has noted a few cases where an IPv4 or IPv6 address
*could* be used on the backend interfaces (which I'll still poke as
its unclear to me why they have 'em).
Luis
^ permalink raw reply
* Re: [RFC v2 2/4] net: enables interface option to skip IP
From: Luis R. Rodriguez @ 2014-02-20 20:39 UTC (permalink / raw)
To: Zoltan Kiss
Cc: Dan Williams, netdev@vger.kernel.org, xen-devel, kvm,
linux-kernel@vger.kernel.org, David S. Miller, Alexey Kuznetsov,
James Morris, Hideaki YOSHIFUJI, Patrick McHardy
In-Reply-To: <53050244.1020106@citrix.com>
On Wed, Feb 19, 2014 at 11:13 AM, Zoltan Kiss <zoltan.kiss@citrix.com> wrote:
> On 19/02/14 17:20, Luis R. Rodriguez wrote:
>>>> On 19/02/14 17:20, Luis R. Rodriguez also wrote:
>>>> Zoltan has noted though some use cases of IPv4 or IPv6 addresses on
>>>> backends though <...>
>>
>> As discussed in the other threads though there *is* some use cases
>> of assigning IPv4 or IPv6 addresses to the backend interfaces though:
>> routing them (although its unclear to me if iptables can be used
>> instead, Zoltan?).
>
> Not with OVS, it steals the packet before netfilter hooks.
Got it, thanks! Can't the route be added using a front-end IP address
instead on the host though ? I just tried that on a Xen system and it
seems to work. Perhaps I'm not understand the exact topology on the
routing case. So in my case I have the backend without any IPv4 or
IPv6 interfaces, the guest has IPv4, IPv6 addresses and even a TUN for
VPN and I can create routes on the host to the front end by not using
the backend device name but instead using the front-end target IP.
Luis
^ permalink raw reply
* [net-next 2/3] net: bcmgenet: fix warning on ndo_select_queue
From: Florian Fainelli @ 2014-02-20 20:53 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <1392929631-7685-1-git-send-email-f.fainelli@gmail.com>
Commit 99932d4 ("netdevice: add queue selection fallback handler for
ndo_select_queue") added a new argument to the ndo_select_queue callback,
but the BCMGENET driver was not updated accordingly and hence would
trigger a warning.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 8af5f07..7c023af 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -2276,7 +2276,8 @@ static int bcmgenet_set_mac_addr(struct net_device *dev, void *p)
}
static u16 bcmgenet_select_queue(struct net_device *dev,
- struct sk_buff *skb, void *accel_priv)
+ struct sk_buff *skb, void *accel_priv,
+ select_queue_fallback_t fallback)
{
return netif_is_multiqueue(dev) ? skb->queue_mapping : 0;
}
--
1.8.3.2
^ permalink raw reply related
* [net-next 1/3] net: bcmgenet: drop checks on priv->phydev
From: Florian Fainelli @ 2014-02-20 20:53 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <1392929631-7685-1-git-send-email-f.fainelli@gmail.com>
Drop all the checks on priv->phydev since we will refuse probing the
driver if we cannot attach to a PHY device. Drop all checks on
priv->phydev. This also fixes some smatch issues reported by Dan
Carpenter where smatch would complain that a pointer is not always
checked correctly.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 0ebc297..8af5f07 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -732,8 +732,7 @@ static void bcmgenet_power_down(struct bcmgenet_priv *priv,
switch (mode) {
case GENET_POWER_CABLE_SENSE:
- if (priv->phydev)
- phy_detach(priv->phydev);
+ phy_detach(priv->phydev);
break;
case GENET_POWER_PASSIVE:
@@ -1811,8 +1810,7 @@ static void bcmgenet_irq_task(struct work_struct *work)
/* Link UP/DOWN event */
if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
(priv->irq0_stat & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN))) {
- if (priv->phydev)
- phy_mac_interrupt(priv->phydev,
+ phy_mac_interrupt(priv->phydev,
(priv->irq0_stat & UMAC_IRQ_LINK_UP));
priv->irq0_stat &= ~(UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN);
}
@@ -1931,8 +1929,7 @@ static int bcmgenet_wol_resume(struct bcmgenet_priv *priv)
if (ret)
return ret;
- if (priv->phydev)
- phy_init_hw(priv->phydev);
+ phy_init_hw(priv->phydev);
/* Speed settings must be restored */
bcmgenet_mii_config(priv->dev);
@@ -2058,8 +2055,7 @@ static int bcmgenet_open(struct net_device *dev)
netif_tx_start_all_queues(dev);
- if (priv->phydev)
- phy_start(priv->phydev);
+ phy_start(priv->phydev);
return 0;
@@ -2134,8 +2130,7 @@ static int bcmgenet_close(struct net_device *dev)
netif_dbg(priv, ifdown, dev, "bcmgenet_close\n");
- if (priv->phydev)
- phy_stop(priv->phydev);
+ phy_stop(priv->phydev);
/* Disable MAC receive */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
--
1.8.3.2
^ permalink raw reply related
* [net-next 0/3] net: bcmgenet: warnings fixes
From: Florian Fainelli @ 2014-02-20 20:53 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
Hi David,
This small patchset fixes some warnings reported by static analysis tools
such as smatch and the 0-day test robot. Finally a patch removes some
dead code in the driver.
Thanks!
Florian Fainelli (3):
net: bcmgenet: drop checks on priv->phydev
net: bcmgenet: fix warning on ndo_select_queue
net: bcmgenet: remove commented code in bcmgenet_xmit()
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)
--
1.8.3.2
^ permalink raw reply
* [net-next 3/3] net: bcmgenet: remove commented code in bcmgenet_xmit()
From: Florian Fainelli @ 2014-02-20 20:53 UTC (permalink / raw)
To: netdev; +Cc: davem, Florian Fainelli
In-Reply-To: <1392929631-7685-1-git-send-email-f.fainelli@gmail.com>
This code is commented since it is unused, left-over from the very first
time this driver was merged.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 7c023af..67c9c44 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1145,10 +1145,6 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
- /* reclaim xmited skb every 8 packets. */
- /*if (ring->free_bds < ring->size - 8)*/
- /*__bcmgenet_tx_reclaim(dev, ring);*/
-
/* set the SKB transmit checksum */
if (priv->desc_64b_en) {
ret = bcmgenet_put_tx_csum(dev, skb);
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH 1/1] TCP NewCWV for Linux
From: David Miller @ 2014-02-20 21:10 UTC (permalink / raw)
To: raffaello; +Cc: netdev, ziaul.hossain, gorry
In-Reply-To: <bbf79368e5d6514fbe6704a77b473407.squirrel@blake.erg.abdn.ac.uk>
From: raffaello@erg.abdn.ac.uk
Date: Thu, 20 Feb 2014 19:28:56 -0000
> This is a patch for newcwv a TCP sender-side modification,
> currently a work item at TCPM (TCP Maintenance and Minor extensions)
> at the IETF:
>
> http://tools.ietf.org/search/draft-ietf-tcpm-newcwv-05
>
> newcwv aims to supersede CWV (RFC2861) to provide better
> congestion control for rate-limited applications that use TCP.
>
> We implemented it as a module that uses tcp_congestion_ops.
> The main changes are in "cong_avoid" before Reno cwnd control
> and at the start and end of Fast Retransmit:
>
> 1) Before Reno algorithm we estimate at each ACK our pipeACK
> (update_pipeack) and decide to increase or not cwnd based on pipeack.
>
> 2) At the start of FR we reset cwnd based on pipeACK, while
> at the end we further reduce pipeACK by the number of retransmissions.
>
> I posted it here for you consideration to be included in net-next.
You need to provide a proper signoff, please see
linux/Documentation/SubmittingPatches
^ permalink raw reply
* Re: net/mlx4: Mellanox driver update 01-01-2014
From: David Miller @ 2014-02-20 21:11 UTC (permalink / raw)
To: amirv; +Cc: netdev, yevgenyp, ogerlitz
In-Reply-To: <20140220201320.GA24686@mtl-eit-vdi-22.mtl.labs.mlnx>
From: Amir Vadai <amirv@mellanox.com>
Date: Thu, 20 Feb 2014 22:15:47 +0200
> Please continue with the review of the other patches by Ido, that will
> fix the way netif_get_num_default_rss_queues() is used in Mellanox
> driver.
Please resubmit the series with this contentious patch omitted if
you'd like us to do that, thank you.
^ permalink raw reply
* [PATCH net-next] bnx2x: Remove hidden flow control goto from BNX2X_ALLOC macros
From: Joe Perches @ 2014-02-20 21:25 UTC (permalink / raw)
To: Ariel Elior; +Cc: netdev, LKML
BNX2X_ALLOC macros use "goto alloc_mem_err"
so these labels appear unused in some functions.
Expand these macros in-place via coccinelle and
some typing.
Update the macros to use statement expressions
and remove the BNX2X_ALLOC macro.
This adds some > 80 char lines.
$ cat bnx2x_pci_alloc.cocci
@@
expression e1;
expression e2;
expression e3;
@@
- BNX2X_PCI_ALLOC(e1, e2, e3);
+ e1 = BNX2X_PCI_ALLOC(e2, e3); if (!e1) goto alloc_mem_err;
@@
expression e1;
expression e2;
expression e3;
@@
- BNX2X_PCI_FALLOC(e1, e2, e3);
+ e1 = BNX2X_PCI_FALLOC(e2, e3); if (!e1) goto alloc_mem_err;
@@
expression e1;
expression e2;
@@
- BNX2X_ALLOC(e1, e2);
+ e1 = kzalloc(e2, GFP_KERNEL); if (!e1) goto alloc_mem_err;
@@
expression e1;
expression e2;
expression e3;
@@
- kzalloc(sizeof(e1) * e2, e3)
+ kcalloc(e2, sizeof(e1), e3)
@@
expression e1;
expression e2;
expression e3;
@@
- kzalloc(e1 * sizeof(e2), e3)
+ kcalloc(e1, sizeof(e2), e3)
Signed-off-by: Joe Perches <joe@perches.com>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 77 ++++++++++++++---------
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 45 ++++++-------
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 69 +++++++++++++-------
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 36 +++++++----
4 files changed, 138 insertions(+), 89 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 5ee13af..89d75c2 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -2228,8 +2228,10 @@ static int bnx2x_alloc_fw_stats_mem(struct bnx2x *bp)
sizeof(struct per_queue_stats) * num_queue_stats +
sizeof(struct stats_counter);
- BNX2X_PCI_ALLOC(bp->fw_stats, &bp->fw_stats_mapping,
- bp->fw_stats_data_sz + bp->fw_stats_req_sz);
+ bp->fw_stats = BNX2X_PCI_ALLOC(&bp->fw_stats_mapping,
+ bp->fw_stats_data_sz + bp->fw_stats_req_sz);
+ if (!bp->fw_stats)
+ goto alloc_mem_err;
/* Set shortcuts */
bp->fw_stats_req = (struct bnx2x_fw_stats_req *)bp->fw_stats;
@@ -4357,14 +4359,17 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
if (!IS_FCOE_IDX(index)) {
/* status blocks */
- if (!CHIP_IS_E1x(bp))
- BNX2X_PCI_ALLOC(sb->e2_sb,
- &bnx2x_fp(bp, index, status_blk_mapping),
- sizeof(struct host_hc_status_block_e2));
- else
- BNX2X_PCI_ALLOC(sb->e1x_sb,
- &bnx2x_fp(bp, index, status_blk_mapping),
- sizeof(struct host_hc_status_block_e1x));
+ if (!CHIP_IS_E1x(bp)) {
+ sb->e2_sb = BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e2));
+ if (!sb->e2_sb)
+ goto alloc_mem_err;
+ } else {
+ sb->e1x_sb = BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, status_blk_mapping),
+ sizeof(struct host_hc_status_block_e1x));
+ if (!sb->e1x_sb)
+ goto alloc_mem_err;
+ }
}
/* FCoE Queue uses Default SB and doesn't ACK the SB, thus no need to
@@ -4383,35 +4388,49 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
"allocating tx memory of fp %d cos %d\n",
index, cos);
- BNX2X_ALLOC(txdata->tx_buf_ring,
- sizeof(struct sw_tx_bd) * NUM_TX_BD);
- BNX2X_PCI_ALLOC(txdata->tx_desc_ring,
- &txdata->tx_desc_mapping,
- sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+ txdata->tx_buf_ring = kcalloc(NUM_TX_BD,
+ sizeof(struct sw_tx_bd),
+ GFP_KERNEL);
+ if (!txdata->tx_buf_ring)
+ goto alloc_mem_err;
+ txdata->tx_desc_ring = BNX2X_PCI_ALLOC(&txdata->tx_desc_mapping,
+ sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+ if (!txdata->tx_desc_ring)
+ goto alloc_mem_err;
}
}
/* Rx */
if (!skip_rx_queue(bp, index)) {
/* fastpath rx rings: rx_buf rx_desc rx_comp */
- BNX2X_ALLOC(bnx2x_fp(bp, index, rx_buf_ring),
- sizeof(struct sw_rx_bd) * NUM_RX_BD);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_desc_ring),
- &bnx2x_fp(bp, index, rx_desc_mapping),
- sizeof(struct eth_rx_bd) * NUM_RX_BD);
+ bnx2x_fp(bp, index, rx_buf_ring) =
+ kcalloc(NUM_RX_BD, sizeof(struct sw_rx_bd), GFP_KERNEL);
+ if (!bnx2x_fp(bp, index, rx_buf_ring))
+ goto alloc_mem_err;
+ bnx2x_fp(bp, index, rx_desc_ring) =
+ BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, rx_desc_mapping),
+ sizeof(struct eth_rx_bd) * NUM_RX_BD);
+ if (!bnx2x_fp(bp, index, rx_desc_ring))
+ goto alloc_mem_err;
/* Seed all CQEs by 1s */
- BNX2X_PCI_FALLOC(bnx2x_fp(bp, index, rx_comp_ring),
- &bnx2x_fp(bp, index, rx_comp_mapping),
- sizeof(struct eth_fast_path_rx_cqe) *
- NUM_RCQ_BD);
+ bnx2x_fp(bp, index, rx_comp_ring) =
+ BNX2X_PCI_FALLOC(&bnx2x_fp(bp, index, rx_comp_mapping),
+ sizeof(struct eth_fast_path_rx_cqe) * NUM_RCQ_BD);
+ if (!bnx2x_fp(bp, index, rx_comp_ring))
+ goto alloc_mem_err;
/* SGE ring */
- BNX2X_ALLOC(bnx2x_fp(bp, index, rx_page_ring),
- sizeof(struct sw_rx_page) * NUM_RX_SGE);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_sge_ring),
- &bnx2x_fp(bp, index, rx_sge_mapping),
- BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ bnx2x_fp(bp, index, rx_page_ring) =
+ kcalloc(NUM_RX_SGE, sizeof(struct sw_rx_page),
+ GFP_KERNEL);
+ if (!bnx2x_fp(bp, index, rx_page_ring))
+ goto alloc_mem_err;
+ bnx2x_fp(bp, index, rx_sge_ring) =
+ BNX2X_PCI_ALLOC(&bnx2x_fp(bp, index, rx_sge_mapping),
+ BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+ if (!bnx2x_fp(bp, index, rx_sge_ring))
+ goto alloc_mem_err;
/* RX BD ring */
bnx2x_set_next_page_rx_bd(fp);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index ec02b15..05f4f5f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -47,31 +47,26 @@ extern int bnx2x_num_queues;
} \
} while (0)
-#define BNX2X_PCI_ALLOC(x, y, size) \
- do { \
- x = dma_zalloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
- if (x == NULL) \
- goto alloc_mem_err; \
- DP(NETIF_MSG_HW, "BNX2X_PCI_ALLOC: Physical %Lx Virtual %p\n", \
- (unsigned long long)(*y), x); \
- } while (0)
-
-#define BNX2X_PCI_FALLOC(x, y, size) \
- do { \
- x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
- if (x == NULL) \
- goto alloc_mem_err; \
- memset((void *)x, 0xFFFFFFFF, size); \
- DP(NETIF_MSG_HW, "BNX2X_PCI_FALLOC: Physical %Lx Virtual %p\n",\
- (unsigned long long)(*y), x); \
- } while (0)
-
-#define BNX2X_ALLOC(x, size) \
- do { \
- x = kzalloc(size, GFP_KERNEL); \
- if (x == NULL) \
- goto alloc_mem_err; \
- } while (0)
+#define BNX2X_PCI_ALLOC(y, size) \
+({ \
+ void *x = dma_zalloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
+ if (x) \
+ DP(NETIF_MSG_HW, \
+ "BNX2X_PCI_ALLOC: Physical %Lx Virtual %p\n", \
+ (unsigned long long)(*y), x); \
+ x; \
+})
+#define BNX2X_PCI_FALLOC(y, size) \
+({ \
+ void *x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
+ if (x) { \
+ memset(x, 0xff, size); \
+ DP(NETIF_MSG_HW, \
+ "BNX2X_PCI_FALLOC: Physical %Lx Virtual %p\n", \
+ (unsigned long long)(*y), x); \
+ } \
+ x; \
+})
/*********************** Interfaces ****************************
* Functions that need to be implemented by each driver version
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 8443915..230dea6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -8001,19 +8001,25 @@ void bnx2x_free_mem(struct bnx2x *bp)
int bnx2x_alloc_mem_cnic(struct bnx2x *bp)
{
- if (!CHIP_IS_E1x(bp))
+ if (!CHIP_IS_E1x(bp)) {
/* size = the status block + ramrod buffers */
- BNX2X_PCI_ALLOC(bp->cnic_sb.e2_sb, &bp->cnic_sb_mapping,
- sizeof(struct host_hc_status_block_e2));
- else
- BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb,
- &bp->cnic_sb_mapping,
- sizeof(struct
- host_hc_status_block_e1x));
+ bp->cnic_sb.e2_sb = BNX2X_PCI_ALLOC(&bp->cnic_sb_mapping,
+ sizeof(struct host_hc_status_block_e2));
+ if (!bp->cnic_sb.e2_sb)
+ goto alloc_mem_err;
+ } else {
+ bp->cnic_sb.e1x_sb = BNX2X_PCI_ALLOC(&bp->cnic_sb_mapping,
+ sizeof(struct host_hc_status_block_e1x));
+ if (!bp->cnic_sb.e1x_sb)
+ goto alloc_mem_err;
+ }
- if (CONFIGURE_NIC_MODE(bp) && !bp->t2)
+ if (CONFIGURE_NIC_MODE(bp) && !bp->t2) {
/* allocate searcher T2 table, as it wasn't allocated before */
- BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ);
+ bp->t2 = BNX2X_PCI_ALLOC(&bp->t2_mapping, SRC_T2_SZ);
+ if (!bp->t2)
+ goto alloc_mem_err;
+ }
/* write address to which L5 should insert its values */
bp->cnic_eth_dev.addr_drv_info_to_mcp =
@@ -8034,15 +8040,22 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
{
int i, allocated, context_size;
- if (!CONFIGURE_NIC_MODE(bp) && !bp->t2)
+ if (!CONFIGURE_NIC_MODE(bp) && !bp->t2) {
/* allocate searcher T2 table */
- BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ);
+ bp->t2 = BNX2X_PCI_ALLOC(&bp->t2_mapping, SRC_T2_SZ);
+ if (!bp->t2)
+ goto alloc_mem_err;
+ }
- BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping,
- sizeof(struct host_sp_status_block));
+ bp->def_status_blk = BNX2X_PCI_ALLOC(&bp->def_status_blk_mapping,
+ sizeof(struct host_sp_status_block));
+ if (!bp->def_status_blk)
+ goto alloc_mem_err;
- BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping,
- sizeof(struct bnx2x_slowpath));
+ bp->slowpath = BNX2X_PCI_ALLOC(&bp->slowpath_mapping,
+ sizeof(struct bnx2x_slowpath));
+ if (!bp->slowpath)
+ goto alloc_mem_err;
/* Allocate memory for CDU context:
* This memory is allocated separately and not in the generic ILT
@@ -8062,12 +8075,16 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
for (i = 0, allocated = 0; allocated < context_size; i++) {
bp->context[i].size = min(CDU_ILT_PAGE_SZ,
(context_size - allocated));
- BNX2X_PCI_ALLOC(bp->context[i].vcxt,
- &bp->context[i].cxt_mapping,
- bp->context[i].size);
+ bp->context[i].vcxt = BNX2X_PCI_ALLOC(&bp->context[i].cxt_mapping,
+ bp->context[i].size);
+ if (!bp->context[i].vcxt)
+ goto alloc_mem_err;
allocated += bp->context[i].size;
}
- BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES);
+ bp->ilt->lines = kcalloc(ILT_MAX_LINES, sizeof(struct ilt_line),
+ GFP_KERNEL);
+ if (!bp->ilt->lines)
+ goto alloc_mem_err;
if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC))
goto alloc_mem_err;
@@ -8076,11 +8093,15 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
goto alloc_mem_err;
/* Slow path ring */
- BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE);
+ bp->spq = BNX2X_PCI_ALLOC(&bp->spq_mapping, BCM_PAGE_SIZE);
+ if (!bp->spq)
+ goto alloc_mem_err;
/* EQ */
- BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping,
- BCM_PAGE_SIZE * NUM_EQ_PAGES);
+ bp->eq_ring = BNX2X_PCI_ALLOC(&bp->eq_mapping,
+ BCM_PAGE_SIZE * NUM_EQ_PAGES);
+ if (!bp->eq_ring)
+ goto alloc_mem_err;
return 0;
@@ -11954,7 +11975,7 @@ static int bnx2x_init_mcast_macs_list(struct bnx2x *bp,
{
int mc_count = netdev_mc_count(bp->dev);
struct bnx2x_mcast_list_elem *mc_mac =
- kzalloc(sizeof(*mc_mac) * mc_count, GFP_ATOMIC);
+ kcalloc(mc_count, sizeof(*mc_mac), GFP_ATOMIC);
struct netdev_hw_addr *ha;
if (!mc_mac)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 98b5367..61e6f60 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -2120,7 +2120,9 @@ int bnx2x_iov_alloc_mem(struct bnx2x *bp)
cxt->size = min_t(size_t, tot_size, CDU_ILT_PAGE_SZ);
if (cxt->size) {
- BNX2X_PCI_ALLOC(cxt->addr, &cxt->mapping, cxt->size);
+ cxt->addr = BNX2X_PCI_ALLOC(&cxt->mapping, cxt->size);
+ if (!cxt->addr)
+ goto alloc_mem_err;
} else {
cxt->addr = NULL;
cxt->mapping = 0;
@@ -2130,20 +2132,28 @@ int bnx2x_iov_alloc_mem(struct bnx2x *bp)
/* allocate vfs ramrods dma memory - client_init and set_mac */
tot_size = BNX2X_NR_VIRTFN(bp) * sizeof(struct bnx2x_vf_sp);
- BNX2X_PCI_ALLOC(BP_VFDB(bp)->sp_dma.addr, &BP_VFDB(bp)->sp_dma.mapping,
- tot_size);
+ BP_VFDB(bp)->sp_dma.addr = BNX2X_PCI_ALLOC(&BP_VFDB(bp)->sp_dma.mapping,
+ tot_size);
+ if (!BP_VFDB(bp)->sp_dma.addr)
+ goto alloc_mem_err;
BP_VFDB(bp)->sp_dma.size = tot_size;
/* allocate mailboxes */
tot_size = BNX2X_NR_VIRTFN(bp) * MBX_MSG_ALIGNED_SIZE;
- BNX2X_PCI_ALLOC(BP_VF_MBX_DMA(bp)->addr, &BP_VF_MBX_DMA(bp)->mapping,
- tot_size);
+ BP_VF_MBX_DMA(bp)->addr = BNX2X_PCI_ALLOC(&BP_VF_MBX_DMA(bp)->mapping,
+ tot_size);
+ if (!BP_VF_MBX_DMA(bp)->addr)
+ goto alloc_mem_err;
+
BP_VF_MBX_DMA(bp)->size = tot_size;
/* allocate local bulletin boards */
tot_size = BNX2X_NR_VIRTFN(bp) * BULLETIN_CONTENT_SIZE;
- BNX2X_PCI_ALLOC(BP_VF_BULLETIN_DMA(bp)->addr,
- &BP_VF_BULLETIN_DMA(bp)->mapping, tot_size);
+ BP_VF_BULLETIN_DMA(bp)->addr = BNX2X_PCI_ALLOC(&BP_VF_BULLETIN_DMA(bp)->mapping,
+ tot_size);
+ if (!BP_VF_BULLETIN_DMA(bp)->addr)
+ goto alloc_mem_err;
+
BP_VF_BULLETIN_DMA(bp)->size = tot_size;
return 0;
@@ -3825,12 +3835,16 @@ int bnx2x_vf_pci_alloc(struct bnx2x *bp)
mutex_init(&bp->vf2pf_mutex);
/* allocate vf2pf mailbox for vf to pf channel */
- BNX2X_PCI_ALLOC(bp->vf2pf_mbox, &bp->vf2pf_mbox_mapping,
- sizeof(struct bnx2x_vf_mbx_msg));
+ bp->vf2pf_mbox = BNX2X_PCI_ALLOC(&bp->vf2pf_mbox_mapping,
+ sizeof(struct bnx2x_vf_mbx_msg));
+ if (!bp->vf2pf_mbox)
+ goto alloc_mem_err;
/* allocate pf 2 vf bulletin board */
- BNX2X_PCI_ALLOC(bp->pf2vf_bulletin, &bp->pf2vf_bulletin_mapping,
- sizeof(union pf_vf_bulletin));
+ bp->pf2vf_bulletin = BNX2X_PCI_ALLOC(&bp->pf2vf_bulletin_mapping,
+ sizeof(union pf_vf_bulletin));
+ if (!bp->pf2vf_bulletin)
+ goto alloc_mem_err;
return 0;
^ permalink raw reply related
* Re: SMP Affinity and 3.12.7
From: Nieścierowicz Adam @ 2014-02-20 21:38 UTC (permalink / raw)
To: Netdev
In-Reply-To: <8f0f9783b81bab41bc19c2cae8f4fec1@justnet.pl>
Hello,
Can anyone help, or point the way what could be causing this?
Kernel error http://wklej.org/id/1238075/
---
Thanks,
Adam N.
W dniu 10.02.2014 10:18, Nieścierowicz Adam napisał(a):
> Hi,
> i use 3.12.7 kernel when i set smp_affinity for network device kernel
> hangs.
> SMP Affinity
> ---
> CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
> 67: 826 810 3962750 3962737 729 649 729 744 PCI-MSI-edge eth1
> 70: 4430 4476 4411 4431 4500 4466 3706636 3706649 PCI-MSI-edge eth4
>
> --
>
> My network device
> ---
> 05:00.0 Ethernet controller: Intel Corporation 80003ES2LAN Gigabit
> Ethernet Controller (Copper) (rev 01)
> 05:00.1 Ethernet controller: Intel Corporation 80003ES2LAN Gigabit
> Ethernet Controller (Copper) (rev 01)
> 0a:00.0 Ethernet controller: Intel Corporation 82571EB Gigabit Ethernet
> Controller (Copper) (rev 06)
> 0a:00.1 Ethernet controller: Intel Corporation 82571EB Gigabit Ethernet
> Controller (Copper) (rev 06)
> 0b:00.0 Ethernet controller: Intel Corporation 82571EB Gigabit Ethernet
> Controller (Copper) (rev 06)
> 0b:00.1 Ethernet controller: Intel Corporation 82571EB Gigabit Ethernet
> Controller (Copper) (rev 06)
> ---
>
> Can anyone help?
>
> ---
> Thanks,
> Adam N.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html [1]
Links:
------
[1] http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] net-tcp: fastopen: fix high order allocations
From: Yuchung Cheng @ 2014-02-20 21:47 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1392919758.2316.7.camel@edumazet-glaptop2.roam.corp.google.com>
On Thu, Feb 20, 2014 at 10:09 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> This patch fixes two bugs in fastopen :
>
> 1) The tcp_sendmsg(..., @size) argument was ignored.
>
> Code was relying on user not fooling the kernel with iovec mismatches
>
> 2) When MTU is about 64KB, tcp_send_syn_data() attempts order-5
> allocations, which are likely to fail when memory gets fragmented.
>
> Fixes: 783237e8daf13 ("net-tcp: Fast Open client - sending SYN-data")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Yuchung Cheng <ycheng@google.com>
Acked-by: Yuchung Cheng <ycheng@google.com>
Tested-by: Yuchung Cheng <ycheng@google.com>
I have tested this patch with packetdrill fast open tests. Thanks Eric!
> ---
> include/net/tcp.h | 3 ++-
> net/ipv4/tcp.c | 8 +++++---
> net/ipv4/tcp_output.c | 7 ++++++-
> 3 files changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/include/net/tcp.h b/include/net/tcp.h
> index 56fc366da6d5..8c4dd63134d4 100644
> --- a/include/net/tcp.h
> +++ b/include/net/tcp.h
> @@ -1303,7 +1303,8 @@ struct tcp_fastopen_request {
> /* Fast Open cookie. Size 0 means a cookie request */
> struct tcp_fastopen_cookie cookie;
> struct msghdr *data; /* data in MSG_FASTOPEN */
> - u16 copied; /* queued in tcp_connect() */
> + size_t size;
> + int copied; /* queued in tcp_connect() */
> };
> void tcp_free_fastopen_req(struct tcp_sock *tp);
>
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 9f3a2db9109e..97c8f5620c43 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -1044,7 +1044,8 @@ void tcp_free_fastopen_req(struct tcp_sock *tp)
> }
> }
>
> -static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *size)
> +static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
> + int *copied, size_t size)
> {
> struct tcp_sock *tp = tcp_sk(sk);
> int err, flags;
> @@ -1059,11 +1060,12 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *size)
> if (unlikely(tp->fastopen_req == NULL))
> return -ENOBUFS;
> tp->fastopen_req->data = msg;
> + tp->fastopen_req->size = size;
>
> flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0;
> err = __inet_stream_connect(sk->sk_socket, msg->msg_name,
> msg->msg_namelen, flags);
> - *size = tp->fastopen_req->copied;
> + *copied = tp->fastopen_req->copied;
> tcp_free_fastopen_req(tp);
> return err;
> }
> @@ -1083,7 +1085,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
>
> flags = msg->msg_flags;
> if (flags & MSG_FASTOPEN) {
> - err = tcp_sendmsg_fastopen(sk, msg, &copied_syn);
> + err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size);
> if (err == -EINPROGRESS && copied_syn > 0)
> goto out;
> else if (err)
> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index 3be16727f058..09805817627b 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -2908,7 +2908,12 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
> space = __tcp_mtu_to_mss(sk, inet_csk(sk)->icsk_pmtu_cookie) -
> MAX_TCP_OPTION_SPACE;
>
> - syn_data = skb_copy_expand(syn, skb_headroom(syn), space,
> + space = min_t(size_t, space, fo->size);
> +
> + /* limit to order-0 allocations */
> + space = min_t(size_t, space, SKB_MAX_HEAD(MAX_TCP_HEADER));
> +
> + syn_data = skb_copy_expand(syn, MAX_TCP_HEADER, space,
> sk->sk_allocation);
> if (syn_data == NULL)
> goto fallback;
>
>
^ permalink raw reply
* [PATCH v7] can: add Renesas R-Car CAN driver
From: Sergei Shtylyov @ 2014-02-20 23:22 UTC (permalink / raw)
To: netdev, wg, mkl, linux-can; +Cc: linux-sh, vksavl
Add support for the CAN controller found in Renesas R-Car SoCs.
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
---
The patch is against the 'linux-can-next.git' repo.
Changes in version 7:
- changed TX algorithm to use mode in which TX FIFO interrupt is generated every
time transmission completes, thus changed 3 fields of 'struct rcar_can_priv',
removed #define RCAR_CAN_MIER1_TXFIT, and renamed #define RCAR_CAN_N_ECHO_SKB
to RCAR_CAN_FIFO_DEPTH decreasing its value to 4;
- got the shifts in the BCR (24-bit register) field macros into the correct
range;
- removed extra write to CLKR in rcar_can_set_bittiming(), adding comment about
the register access peculiarities;
- restructured the loops polling STR.RSTST bit to avoid checkpatch.pl's errors;
- fixed heading comment format to avoid checkpatch.pl's warning.
Changes in version 6:
- removed '__packed' from 'struct rcar_can_mbox_regs' and 'struct
rcar_can_regs';
- added counter to the loops polling STR.RSTST bit and converted them to use
*for*;
- added error check and message in case of clk_[prepare_]enable() failure;
- fixed *goto* and error message in case of open_candev() failure;
- clarified check and added comment for calling netif_stop_queue();
- moved comments in theframe format decoding code to the right and so got rid of
the braces;
- removed internal *for* loop from rcar_can_rx_poll(). converting *while* loop
to *for*;
- converted 0xFF to lowercase;
- removed type cast in the 'ndev' variable initializer in rcar_can_interrupt();
- converted CLKR_* #define's to *enum*, used it in the platform data;
- changed the type of 'i' variable in tx_failure_cleanup() to *int*;
- fixed register_candev() error message to print the error code;
- added parens in the alloc_candev() error message;
- indented with tab the value of #define RCAR_CAN_NAPI_WEIGHT.
Changes in version 5:
- removed the code specific to the mailbox mode handling and added the code
for the FIFO mode, dropping support for CAN_CTRLMODE_ONE_SHOT;
- stop accumulating errors in the byte 1 of an error frame;
- added #define RCAR_CAN_CTLR_CANM for CTLR.CANM field, added 'CANM_' infix to
all its values;
- replaced ~RCAR_CAN_CTLR_CANM_FORCE_RESET with ~RCAR_CAN_CTLR_CANM;
- added polling for the CAN reset status bit when going from/to CAN reset.
Changes in version 4:
- added 'RCAR_CAN_' prefix to all #define's;
- replaced all BIT(N) invocations with (1 << N) which allowed to remove casts
to 'u8';
- called rcar_can_set_bittiming() from rcar_can_start() again and stopped
registering it as do_set_bittiming() method which allowed to remove clock
API calls and control register writes from this function and make it *void*;
- added #define RCAR_CAN_CTLR_IDFM for more clarity;
- clarified comment to #define RCAR_CAN_IER_TXMIE;
- did some whitespace cleanups.
Changes in version 3:
- replaced the register #define's with 'struct rcar_can_regs' fields, replaced
rcar_can_{read|write}[bwl]() with mere {read|write}[bwl]();
- removed hardware bus-off recovery support which allowed to also remove
rcar_can_start() prototype;
- added RX/TX error count to error data frame for error warning/passive;
- moved TX completion interrupt handling into separate function;
- added '__packed' to 'struct rcar_can_mbox_regs' and 'struct rcar_can_regs';
- removed unneeded type cast in the probe() method.
Changes in version 2:
- added function to clean up TX mailboxes after bus error and bus-off;
- added module parameter to enable hardware recovery from bus-off, added handler
for the bus-off recovery interrupt, and set the control register according to
the parameter value and the restart timer setting in rcar_can_start();
- changed the way CAN_ERR_CRTL_[RT]X_{PASSIVE|WARNING} flags are set to a more
realistic one;
- replaced MBX_* macros and rcar_can_mbx_{read|write}[bl]() functions with
'struct rcar_can_mbox_regs', 'struct rcar_can_regs', and {read|write}[bl](),
replaced 'reg_base' field of 'struct rcar_can_priv' with 'struct rcar_can_regs
__iomem *regs';
- added 'ier' field to 'struct rcar_can_priv' to cache the current value of the
interrupt enable register;
- added a check for enabled interrupts on entry to rcar_can_interrupt();
- limited transmit mailbox search loop in rcar_can_interrupt();
- decoupled TX byte count increment from can_get_echo_skb() call;
- removed netif_queue_stopped() call from rcar_can_interrupt();
- added clk_prepare_enable()/clk_disable_unprepare() to ndo_{open|close}(),
do_set_bittiming(), and do_get_berr_counter() methods, removed clk_enable()
call from the probe() method and clk_disable() call from the remove() method;
- allowed rcar_can_set_bittiming() to be called when the device is closed and
remove explicit call to it from rcar_can_start();
- switched to using mailbox number priority transmit mode, and switched to the
sequential mailbox use in ndo_start_xmit() method;
- stopped reading the message control registers in ndo_start_xmit() method;
- avoided returning NETDEV_TX_BUSY from ndo_start_xmit() method;
- stopped reading data when RTR bit is set in the CAN frame;
- made 'num_pkts' variable *int* and moved its check to the *while* condition in
rcar_can_rx_poll();
- used dev_get_platdata() in the probe() method;
- enabled bus error interrupt only if CAN_CTRLMODE_BERR_REPORTING flag is set;
- started reporting CAN_CTRLMODE_BERR_REPORTING support and stopped reporting
CAN_CTRLMODE_3_SAMPLES support;
- set CAN_ERR_ACK flag on ACK error;
- switched to incrementing bus error counter only once per bus error interrupt;
- started switching to CAN sleep mode in rcar_can_stop() and stopped switching
to it in the remove() method;
- removed netdev_err() calls on allocation failure in rcar_can_error() and
rcar_can_rx_pkt();
- removed "CANi" from the register offset macro comments.
drivers/net/can/Kconfig | 9
drivers/net/can/Makefile | 1
drivers/net/can/rcar_can.c | 858 ++++++++++++++++++++++++++++++++++
include/linux/can/platform/rcar_can.h | 17
4 files changed, 885 insertions(+)
Index: linux-can-next/drivers/net/can/Kconfig
===================================================================
--- linux-can-next.orig/drivers/net/can/Kconfig
+++ linux-can-next/drivers/net/can/Kconfig
@@ -125,6 +125,15 @@ config CAN_GRCAN
endian syntheses of the cores would need some modifications on
the hardware level to work.
+config CAN_RCAR
+ tristate "Renesas R-Car CAN controller"
+ ---help---
+ Say Y here if you want to use CAN controller found on Renesas R-Car
+ SoCs.
+
+ To compile this driver as a module, choose M here: the module will
+ be called rcar_can.
+
source "drivers/net/can/mscan/Kconfig"
source "drivers/net/can/sja1000/Kconfig"
Index: linux-can-next/drivers/net/can/Makefile
===================================================================
--- linux-can-next.orig/drivers/net/can/Makefile
+++ linux-can-next/drivers/net/can/Makefile
@@ -25,5 +25,6 @@ obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ica
obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
obj-$(CONFIG_PCH_CAN) += pch_can.o
obj-$(CONFIG_CAN_GRCAN) += grcan.o
+obj-$(CONFIG_CAN_RCAR) += rcar_can.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
Index: linux-can-next/drivers/net/can/rcar_can.c
===================================================================
--- /dev/null
+++ linux-can-next/drivers/net/can/rcar_can.c
@@ -0,0 +1,858 @@
+/* Renesas R-Car CAN device driver
+ *
+ * Copyright (C) 2013 Cogent Embedded, Inc. <source@cogentembedded.com>
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/can/led.h>
+#include <linux/can/dev.h>
+#include <linux/clk.h>
+#include <linux/can/platform/rcar_can.h>
+
+#define RCAR_CAN_DRV_NAME "rcar_can"
+
+/* Mailbox configuration:
+ * mailbox 60 - 63 - Rx FIFO mailboxes
+ * mailbox 56 - 59 - Tx FIFO mailboxes
+ * non-FIFO mailboxes are not used
+ */
+#define RCAR_CAN_N_MBX 64 /* Number of mailboxes in non-FIFO mode */
+#define RCAR_CAN_RX_FIFO_MBX 60 /* Mailbox - window to Rx FIFO */
+#define RCAR_CAN_TX_FIFO_MBX 56 /* Mailbox - window to Tx FIFO */
+#define RCAR_CAN_FIFO_DEPTH 4
+
+/* Mailbox registers structure */
+struct rcar_can_mbox_regs {
+ u32 id; /* IDE and RTR bits, SID and EID */
+ u8 stub; /* Not used */
+ u8 dlc; /* Data Length Code - bits [0..3] */
+ u8 data[8]; /* Data Bytes */
+ u8 tsh; /* Time Stamp Higher Byte */
+ u8 tsl; /* Time Stamp Lower Byte */
+};
+
+struct rcar_can_regs {
+ struct rcar_can_mbox_regs mb[RCAR_CAN_N_MBX]; /* Mailbox registers */
+ u32 mkr_2_9[8]; /* Mask Registers 2-9 */
+ u32 fidcr[2]; /* FIFO Received ID Compare Register */
+ u32 mkivlr1; /* Mask Invalid Register 1 */
+ u32 mier1; /* Mailbox Interrupt Enable Register 1 */
+ u32 mkr_0_1[2]; /* Mask Registers 0-1 */
+ u32 mkivlr0; /* Mask Invalid Register 0*/
+ u32 mier0; /* Mailbox Interrupt Enable Register 0 */
+ u8 pad_440[0x3c0];
+ u8 mctl[64]; /* Message Control Registers */
+ u16 ctlr; /* Control Register */
+ u16 str; /* Status register */
+ u8 bcr[3]; /* Bit Configuration Register */
+ u8 clkr; /* Clock Select Register */
+ u8 rfcr; /* Receive FIFO Control Register */
+ u8 rfpcr; /* Receive FIFO Pointer Control Register */
+ u8 tfcr; /* Transmit FIFO Control Register */
+ u8 tfpcr; /* Transmit FIFO Pointer Control Register */
+ u8 eier; /* Error Interrupt Enable Register */
+ u8 eifr; /* Error Interrupt Factor Judge Register */
+ u8 recr; /* Receive Error Count Register */
+ u8 tecr; /* Transmit Error Count Register */
+ u8 ecsr; /* Error Code Store Register */
+ u8 cssr; /* Channel Search Support Register */
+ u8 mssr; /* Mailbox Search Status Register */
+ u8 msmr; /* Mailbox Search Mode Register */
+ u16 tsr; /* Time Stamp Register */
+ u8 afsr; /* Acceptance Filter Support Register */
+ u8 pad_857;
+ u8 tcr; /* Test Control Register */
+ u8 pad_859[7];
+ u8 ier; /* Interrupt Enable Register */
+ u8 isr; /* Interrupt Status Register */
+ u8 pad_862;
+ u8 mbsmr; /* Mailbox Search Mask Register */
+};
+
+struct rcar_can_priv {
+ struct can_priv can; /* Must be the first member! */
+ struct net_device *ndev;
+ struct napi_struct napi;
+ struct rcar_can_regs __iomem *regs;
+ struct clk *clk;
+ u8 tx_dlc[RCAR_CAN_FIFO_DEPTH];
+ u8 echo_skb_head;
+ u8 echo_skb_tail;
+ u8 clock_select;
+ u8 ier;
+};
+
+static const struct can_bittiming_const rcar_can_bittiming_const = {
+ .name = RCAR_CAN_DRV_NAME,
+ .tseg1_min = 4,
+ .tseg1_max = 16,
+ .tseg2_min = 2,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 1024,
+ .brp_inc = 1,
+};
+
+/* Control Register bits */
+#define RCAR_CAN_CTLR_BOM (3 << 11) /* Bus-Off Recovery Mode Bits */
+#define RCAR_CAN_CTLR_BOM_ENT (1 << 11) /* Entry to halt mode */
+ /* at bus-off entry */
+#define RCAR_CAN_CTLR_SLPM (1 << 10)
+#define RCAR_CAN_CTLR_CANM (3 << 8) /* Operating Mode Select Bit */
+#define RCAR_CAN_CTLR_CANM_HALT (1 << 9)
+#define RCAR_CAN_CTLR_CANM_RESET (1 << 8)
+#define RCAR_CAN_CTLR_CANM_FORCE_RESET (3 << 8)
+#define RCAR_CAN_CTLR_MLM (1 << 3) /* Message Lost Mode Select */
+#define RCAR_CAN_CTLR_IDFM (3 << 1) /* ID Format Mode Select Bits */
+#define RCAR_CAN_CTLR_IDFM_MIXED (1 << 2) /* Mixed ID mode */
+#define RCAR_CAN_CTLR_MBM (1 << 0) /* Mailbox Mode select */
+
+/* Status Register bits */
+#define RCAR_CAN_STR_RSTST (1 << 8) /* Reset Status Bit */
+
+/* FIFO Received ID Compare Registers 0 and 1 bits */
+#define RCAR_CAN_FIDCR_IDE (1 << 31) /* ID Extension Bit */
+#define RCAR_CAN_FIDCR_RTR (1 << 30) /* Remote Transmission Request Bit */
+
+/* Receive FIFO Control Register bits */
+#define RCAR_CAN_RFCR_RFEST (1 << 7) /* Receive FIFO Empty Status Flag */
+#define RCAR_CAN_RFCR_RFE (1 << 0) /* Receive FIFO Enable */
+
+/* Transmit FIFO Control Register bits */
+#define RCAR_CAN_TFCR_TFUST (7 << 1) /* Transmit FIFO Unsent Message */
+ /* Number Status Bits */
+#define RCAR_CAN_TFCR_TFUST_SHIFT 1 /* Offset of Transmit FIFO Unsent */
+ /* Message Number Status Bits */
+#define RCAR_CAN_TFCR_TFE (1 << 0) /* Transmit FIFO Enable */
+
+#define RCAR_CAN_N_RX_MKREGS1 2 /* Number of mask registers */
+ /* for Rx mailboxes 0-31 */
+#define RCAR_CAN_N_RX_MKREGS2 8
+
+/* Bit Configuration Register settings */
+#define RCAR_CAN_BCR_TSEG1(x) (((x) & 0x0f) << 20)
+#define RCAR_CAN_BCR_BPR(x) (((x) & 0x3ff) << 8)
+#define RCAR_CAN_BCR_SJW(x) (((x) & 0x3) << 4)
+#define RCAR_CAN_BCR_TSEG2(x) ((x) & 0x07)
+
+/* Mailbox and Mask Registers bits */
+#define RCAR_CAN_IDE (1 << 31)
+#define RCAR_CAN_RTR (1 << 30)
+#define RCAR_CAN_SID_SHIFT 18
+
+/* Mailbox Interrupt Enable Register 1 bits */
+#define RCAR_CAN_MIER1_RXFIE (1 << 28) /* Receive FIFO Interrupt Enable */
+#define RCAR_CAN_MIER1_TXFIE (1 << 24) /* Transmit FIFO Interrupt Enable */
+
+/* Interrupt Enable Register bits */
+#define RCAR_CAN_IER_ERSIE (1 << 5) /* Error (ERS) Interrupt Enable Bit */
+#define RCAR_CAN_IER_RXFIE (1 << 4) /* Reception FIFO Interrupt */
+ /* Enable Bit */
+#define RCAR_CAN_IER_TXFIE (1 << 3) /* Transmission FIFO Interrupt */
+ /* Enable Bit */
+/* Interrupt Status Register bits */
+#define RCAR_CAN_ISR_ERSF (1 << 5) /* Error (ERS) Interrupt Status Bit */
+#define RCAR_CAN_ISR_RXFF (1 << 4) /* Reception FIFO Interrupt */
+ /* Status Bit */
+#define RCAR_CAN_ISR_TXFF (1 << 3) /* Transmission FIFO Interrupt */
+ /* Status Bit */
+
+/* Error Interrupt Enable Register bits */
+#define RCAR_CAN_EIER_BLIE (1 << 7) /* Bus Lock Interrupt Enable */
+#define RCAR_CAN_EIER_OLIE (1 << 6) /* Overload Frame Transmit */
+ /* Interrupt Enable */
+#define RCAR_CAN_EIER_ORIE (1 << 5) /* Receive Overrun Interrupt Enable */
+#define RCAR_CAN_EIER_BORIE (1 << 4) /* Bus-Off Recovery Interrupt Enable */
+#define RCAR_CAN_EIER_BOEIE (1 << 3) /* Bus-Off Entry Interrupt Enable */
+#define RCAR_CAN_EIER_EPIE (1 << 2) /* Error Passive Interrupt Enable */
+#define RCAR_CAN_EIER_EWIE (1 << 1) /* Error Warning Interrupt Enable */
+#define RCAR_CAN_EIER_BEIE (1 << 0) /* Bus Error Interrupt Enable */
+
+/* Error Interrupt Factor Judge Register bits */
+#define RCAR_CAN_EIFR_BLIF (1 << 7) /* Bus Lock Detect Flag */
+#define RCAR_CAN_EIFR_OLIF (1 << 6) /* Overload Frame Transmission */
+ /* Detect Flag */
+#define RCAR_CAN_EIFR_ORIF (1 << 5) /* Receive Overrun Detect Flag */
+#define RCAR_CAN_EIFR_BORIF (1 << 4) /* Bus-Off Recovery Detect Flag */
+#define RCAR_CAN_EIFR_BOEIF (1 << 3) /* Bus-Off Entry Detect Flag */
+#define RCAR_CAN_EIFR_EPIF (1 << 2) /* Error Passive Detect Flag */
+#define RCAR_CAN_EIFR_EWIF (1 << 1) /* Error Warning Detect Flag */
+#define RCAR_CAN_EIFR_BEIF (1 << 0) /* Bus Error Detect Flag */
+
+/* Error Code Store Register bits */
+#define RCAR_CAN_ECSR_EDPM (1 << 7) /* Error Display Mode Select Bit */
+#define RCAR_CAN_ECSR_ADEF (1 << 6) /* ACK Delimiter Error Flag */
+#define RCAR_CAN_ECSR_BE0F (1 << 5) /* Bit Error (dominant) Flag */
+#define RCAR_CAN_ECSR_BE1F (1 << 4) /* Bit Error (recessive) Flag */
+#define RCAR_CAN_ECSR_CEF (1 << 3) /* CRC Error Flag */
+#define RCAR_CAN_ECSR_AEF (1 << 2) /* ACK Error Flag */
+#define RCAR_CAN_ECSR_FEF (1 << 1) /* Form Error Flag */
+#define RCAR_CAN_ECSR_SEF (1 << 0) /* Stuff Error Flag */
+
+#define RCAR_CAN_NAPI_WEIGHT 4
+#define MAX_STR_READS 0x100
+
+static void tx_failure_cleanup(struct net_device *ndev)
+{
+ int i;
+
+ for (i = 0; i < RCAR_CAN_FIFO_DEPTH; i++)
+ can_free_echo_skb(ndev, i);
+}
+
+static void rcar_can_error(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u8 eifr, txerr = 0, rxerr = 0;
+
+ /* Propagate the error condition to the CAN stack */
+ skb = alloc_can_err_skb(ndev, &cf);
+ if (!skb)
+ return;
+
+ eifr = readb(&priv->regs->eifr);
+ if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) {
+ cf->can_id |= CAN_ERR_CRTL;
+ txerr = readb(&priv->regs->tecr);
+ rxerr = readb(&priv->regs->recr);
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+ if (eifr & RCAR_CAN_EIFR_BEIF) {
+ int rx_errors = 0, tx_errors = 0;
+ u8 ecsr;
+
+ netdev_dbg(priv->ndev, "Bus error interrupt:\n");
+ cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
+ cf->data[2] = CAN_ERR_PROT_UNSPEC;
+
+ ecsr = readb(&priv->regs->ecsr);
+ if (ecsr & RCAR_CAN_ECSR_ADEF) {
+ netdev_dbg(priv->ndev, "ACK Delimiter Error\n");
+ cf->data[3] |= CAN_ERR_PROT_LOC_ACK_DEL;
+ tx_errors++;
+ writeb(~RCAR_CAN_ECSR_ADEF, &priv->regs->ecsr);
+ }
+ if (ecsr & RCAR_CAN_ECSR_BE0F) {
+ netdev_dbg(priv->ndev, "Bit Error (dominant)\n");
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ tx_errors++;
+ writeb(~RCAR_CAN_ECSR_BE0F, &priv->regs->ecsr);
+ }
+ if (ecsr & RCAR_CAN_ECSR_BE1F) {
+ netdev_dbg(priv->ndev, "Bit Error (recessive)\n");
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ tx_errors++;
+ writeb(~RCAR_CAN_ECSR_BE1F, &priv->regs->ecsr);
+ }
+ if (ecsr & RCAR_CAN_ECSR_CEF) {
+ netdev_dbg(priv->ndev, "CRC Error\n");
+ cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+ rx_errors++;
+ writeb(~RCAR_CAN_ECSR_CEF, &priv->regs->ecsr);
+ }
+ if (ecsr & RCAR_CAN_ECSR_AEF) {
+ netdev_dbg(priv->ndev, "ACK Error\n");
+ cf->can_id |= CAN_ERR_ACK;
+ cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+ tx_errors++;
+ writeb(~RCAR_CAN_ECSR_AEF, &priv->regs->ecsr);
+ }
+ if (ecsr & RCAR_CAN_ECSR_FEF) {
+ netdev_dbg(priv->ndev, "Form Error\n");
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ rx_errors++;
+ writeb(~RCAR_CAN_ECSR_FEF, &priv->regs->ecsr);
+ }
+ if (ecsr & RCAR_CAN_ECSR_SEF) {
+ netdev_dbg(priv->ndev, "Stuff Error\n");
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ rx_errors++;
+ writeb(~RCAR_CAN_ECSR_SEF, &priv->regs->ecsr);
+ }
+
+ priv->can.can_stats.bus_error++;
+ ndev->stats.rx_errors += rx_errors;
+ ndev->stats.tx_errors += tx_errors;
+ writeb(~RCAR_CAN_EIFR_BEIF, &priv->regs->eifr);
+ }
+ if (eifr & RCAR_CAN_EIFR_EWIF) {
+ netdev_dbg(priv->ndev, "Error warning interrupt\n");
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ priv->can.can_stats.error_warning++;
+ cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_WARNING :
+ CAN_ERR_CRTL_RX_WARNING;
+ /* Clear interrupt condition */
+ writeb(~RCAR_CAN_EIFR_EWIF, &priv->regs->eifr);
+ }
+ if (eifr & RCAR_CAN_EIFR_EPIF) {
+ netdev_dbg(priv->ndev, "Error passive interrupt\n");
+ priv->can.state = CAN_STATE_ERROR_PASSIVE;
+ priv->can.can_stats.error_passive++;
+ cf->data[1] = txerr > rxerr ? CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ /* Clear interrupt condition */
+ writeb(~RCAR_CAN_EIFR_EPIF, &priv->regs->eifr);
+ }
+ if (eifr & RCAR_CAN_EIFR_BOEIF) {
+ netdev_dbg(priv->ndev, "Bus-off entry interrupt\n");
+ tx_failure_cleanup(ndev);
+ priv->ier = RCAR_CAN_IER_ERSIE;
+ writeb(priv->ier, &priv->regs->ier);
+ priv->can.state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ /* Clear interrupt condition */
+ writeb(~RCAR_CAN_EIFR_BOEIF, &priv->regs->eifr);
+ can_bus_off(ndev);
+ }
+ if (eifr & RCAR_CAN_EIFR_ORIF) {
+ netdev_dbg(priv->ndev, "Receive overrun error interrupt\n");
+ cf->can_id |= CAN_ERR_CRTL;
+ cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+ ndev->stats.rx_over_errors++;
+ ndev->stats.rx_errors++;
+ writeb(~RCAR_CAN_EIFR_ORIF, &priv->regs->eifr);
+ }
+ if (eifr & RCAR_CAN_EIFR_OLIF) {
+ netdev_dbg(priv->ndev,
+ "Overload Frame Transmission error interrupt\n");
+ cf->can_id |= CAN_ERR_PROT;
+ cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
+ ndev->stats.rx_over_errors++;
+ ndev->stats.rx_errors++;
+ writeb(~RCAR_CAN_EIFR_OLIF, &priv->regs->eifr);
+ }
+
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+static void rcar_can_tx_done(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+
+ stats->tx_packets++;
+ stats->tx_bytes += priv->tx_dlc[priv->echo_skb_tail];
+ priv->tx_dlc[priv->echo_skb_tail] = 0;
+ can_get_echo_skb(ndev, priv->echo_skb_tail);
+ if (++priv->echo_skb_tail >= RCAR_CAN_FIFO_DEPTH)
+ priv->echo_skb_tail = 0;
+ can_led_event(ndev, CAN_LED_EVENT_TX);
+ netif_wake_queue(ndev);
+}
+
+static irqreturn_t rcar_can_interrupt(int irq, void *dev_id)
+{
+ struct net_device *ndev = dev_id;
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u8 isr;
+
+ isr = readb(&priv->regs->isr);
+ if (!(isr & priv->ier))
+ return IRQ_NONE;
+
+ if (isr & RCAR_CAN_ISR_ERSF)
+ rcar_can_error(ndev);
+
+ if (isr & RCAR_CAN_ISR_TXFF) {
+ /* Clear interrupt */
+ writeb(isr & ~RCAR_CAN_ISR_TXFF, &priv->regs->isr);
+ rcar_can_tx_done(ndev);
+ }
+
+ if (isr & RCAR_CAN_ISR_RXFF) {
+ if (napi_schedule_prep(&priv->napi)) {
+ /* Disable Rx FIFO interrupts */
+ priv->ier &= ~RCAR_CAN_IER_RXFIE;
+ writeb(priv->ier, &priv->regs->ier);
+ __napi_schedule(&priv->napi);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void rcar_can_set_bittiming(struct net_device *dev)
+{
+ struct rcar_can_priv *priv = netdev_priv(dev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ u32 bcr;
+ u8 clkr;
+
+ /* Don't overwrite CLKR with 32-bit BCR access */
+ /* CLKR has 8-bit access */
+ clkr = readb(&priv->regs->clkr);
+ bcr = RCAR_CAN_BCR_TSEG1(bt->phase_seg1 + bt->prop_seg - 1) |
+ RCAR_CAN_BCR_BPR(bt->brp - 1) | RCAR_CAN_BCR_SJW(bt->sjw - 1) |
+ RCAR_CAN_BCR_TSEG2(bt->phase_seg2 - 1);
+ /* All the registers are big-endian but they get byte-swapped on 32-bit
+ * read/write (but not on 8-bit, contrary to the manuals)...
+ */
+ writel((bcr << 8) | clkr, &priv->regs->bcr);
+}
+
+static void rcar_can_start(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u16 ctlr;
+ int i;
+
+ /* Set controller to known mode:
+ * - FIFO mailbox mode
+ * - accept all messages
+ * - overrun mode
+ * CAN is in sleep mode after MCU hardware or software reset.
+ */
+ ctlr = readw(&priv->regs->ctlr);
+ ctlr &= ~RCAR_CAN_CTLR_SLPM;
+ writew(ctlr, &priv->regs->ctlr);
+ /* Go to reset mode */
+ ctlr |= RCAR_CAN_CTLR_CANM_FORCE_RESET;
+ writew(ctlr, &priv->regs->ctlr);
+ for (i = 0; i < MAX_STR_READS; i++) {
+ if (readw(&priv->regs->str) & RCAR_CAN_STR_RSTST)
+ break;
+ }
+ rcar_can_set_bittiming(ndev);
+ ctlr |= RCAR_CAN_CTLR_IDFM_MIXED; /* Select mixed ID mode */
+ ctlr |= RCAR_CAN_CTLR_BOM_ENT; /* Entry to halt mode automatically */
+ /* at bus-off */
+ ctlr |= RCAR_CAN_CTLR_MBM; /* Select FIFO mailbox mode */
+ ctlr |= RCAR_CAN_CTLR_MLM; /* Overrun mode */
+ writew(ctlr, &priv->regs->ctlr);
+
+ writeb(priv->clock_select, &priv->regs->clkr);
+
+ /* Accept all SID and EID */
+ writel(0, &priv->regs->mkr_2_9[6]);
+ writel(0, &priv->regs->mkr_2_9[7]);
+ /* In FIFO mailbox mode, write "0" to bits 24 to 31 */
+ writel(0, &priv->regs->mkivlr1);
+ /* Accept all frames */
+ writel(0, &priv->regs->fidcr[0]);
+ writel(RCAR_CAN_FIDCR_IDE | RCAR_CAN_FIDCR_RTR, &priv->regs->fidcr[1]);
+ /* Enable and configure FIFO mailbox interrupts */
+ writel(RCAR_CAN_MIER1_RXFIE | RCAR_CAN_MIER1_TXFIE, &priv->regs->mier1);
+
+ priv->ier = RCAR_CAN_IER_ERSIE | RCAR_CAN_IER_RXFIE |
+ RCAR_CAN_IER_TXFIE;
+ writeb(priv->ier, &priv->regs->ier);
+
+ /* Accumulate error codes */
+ writeb(RCAR_CAN_ECSR_EDPM, &priv->regs->ecsr);
+ /* Enable error interrupts */
+ writeb(RCAR_CAN_EIER_EWIE | RCAR_CAN_EIER_EPIE | RCAR_CAN_EIER_BOEIE |
+ (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING ?
+ RCAR_CAN_EIER_BEIE : 0) | RCAR_CAN_EIER_ORIE |
+ RCAR_CAN_EIER_OLIE, &priv->regs->eier);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ /* Go to operation mode */
+ writew(ctlr & ~RCAR_CAN_CTLR_CANM, &priv->regs->ctlr);
+ for (i = 0; i < MAX_STR_READS; i++) {
+ if (!(readw(&priv->regs->str) & RCAR_CAN_STR_RSTST))
+ break;
+ }
+ /* Enable Rx and Tx FIFO */
+ writeb(RCAR_CAN_RFCR_RFE, &priv->regs->rfcr);
+ writeb(RCAR_CAN_TFCR_TFE, &priv->regs->tfcr);
+}
+
+static int rcar_can_open(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ int err;
+
+ err = clk_prepare_enable(priv->clk);
+ if (err) {
+ netdev_err(ndev, "clk_prepare_enable() failed, error %d\n",
+ err);
+ goto out;
+ }
+ err = open_candev(ndev);
+ if (err) {
+ netdev_err(ndev, "open_candev() failed, error %d\n", err);
+ goto out_clock;
+ }
+ napi_enable(&priv->napi);
+ err = request_irq(ndev->irq, rcar_can_interrupt, 0, ndev->name, ndev);
+ if (err) {
+ netdev_err(ndev, "error requesting interrupt %x\n", ndev->irq);
+ goto out_close;
+ }
+ can_led_event(ndev, CAN_LED_EVENT_OPEN);
+ rcar_can_start(ndev);
+ netif_start_queue(ndev);
+ return 0;
+out_close:
+ napi_disable(&priv->napi);
+ close_candev(ndev);
+out_clock:
+ clk_disable_unprepare(priv->clk);
+out:
+ return err;
+}
+
+static void rcar_can_stop(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u16 ctlr;
+ int i;
+
+ /* Go to (force) reset mode */
+ ctlr = readw(&priv->regs->ctlr);
+ ctlr |= RCAR_CAN_CTLR_CANM_FORCE_RESET;
+ writew(ctlr, &priv->regs->ctlr);
+ for (i = 0; i < MAX_STR_READS; i++) {
+ if (readw(&priv->regs->str) & RCAR_CAN_STR_RSTST)
+ break;
+ }
+ writel(0, &priv->regs->mier0);
+ writel(0, &priv->regs->mier1);
+ writeb(0, &priv->regs->ier);
+ writeb(0, &priv->regs->eier);
+ /* Go to sleep mode */
+ ctlr |= RCAR_CAN_CTLR_SLPM;
+ writew(ctlr, &priv->regs->ctlr);
+ priv->can.state = CAN_STATE_STOPPED;
+}
+
+static int rcar_can_close(struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+
+ netif_stop_queue(ndev);
+ rcar_can_stop(ndev);
+ free_irq(ndev->irq, ndev);
+ napi_disable(&priv->napi);
+ clk_disable_unprepare(priv->clk);
+ close_candev(ndev);
+ can_led_event(ndev, CAN_LED_EVENT_STOP);
+ return 0;
+}
+
+static netdev_tx_t rcar_can_start_xmit(struct sk_buff *skb,
+ struct net_device *ndev)
+{
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ u32 data, i;
+ u8 tfcr;
+
+ if (can_dropped_invalid_skb(ndev, skb))
+ return NETDEV_TX_OK;
+ tfcr = readb(&priv->regs->tfcr);
+ /* Stop queue if we are to fill the last FIFO entry */
+ if ((tfcr & RCAR_CAN_TFCR_TFUST) >> RCAR_CAN_TFCR_TFUST_SHIFT >= 3)
+ netif_stop_queue(ndev);
+
+ if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */
+ data = (cf->can_id & CAN_EFF_MASK) | RCAR_CAN_IDE;
+ else /* Standard frame format */
+ data = (cf->can_id & CAN_SFF_MASK) << RCAR_CAN_SID_SHIFT;
+
+ if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */
+ data |= RCAR_CAN_RTR;
+
+ writel(data, &priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].id);
+
+ writeb(cf->can_dlc, &priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].dlc);
+
+ for (i = 0; i < cf->can_dlc; i++)
+ writeb(cf->data[i],
+ &priv->regs->mb[RCAR_CAN_TX_FIFO_MBX].data[i]);
+
+ priv->tx_dlc[priv->echo_skb_head] = cf->can_dlc;
+ can_put_echo_skb(skb, ndev, priv->echo_skb_head);
+ if (++priv->echo_skb_head >= RCAR_CAN_FIFO_DEPTH)
+ priv->echo_skb_head = 0;
+ /* Start Tx: write 0xff to the TFPCR register to increment
+ * the CPU-side pointer for the transmit FIFO to the next
+ * mailbox location
+ */
+ writeb(0xff, &priv->regs->tfpcr);
+
+ return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops rcar_can_netdev_ops = {
+ .ndo_open = rcar_can_open,
+ .ndo_stop = rcar_can_close,
+ .ndo_start_xmit = rcar_can_start_xmit,
+};
+
+static void rcar_can_rx_pkt(struct rcar_can_priv *priv)
+{
+ struct net_device_stats *stats = &priv->ndev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u32 data;
+ u8 dlc;
+
+ skb = alloc_can_skb(priv->ndev, &cf);
+ if (!skb) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ data = readl(&priv->regs->mb[RCAR_CAN_RX_FIFO_MBX].id);
+ if (data & RCAR_CAN_IDE)
+ cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG;
+ else
+ cf->can_id = (data >> RCAR_CAN_SID_SHIFT) & CAN_SFF_MASK;
+
+ dlc = readb(&priv->regs->mb[RCAR_CAN_RX_FIFO_MBX].dlc);
+ cf->can_dlc = get_can_dlc(dlc);
+ if (data & RCAR_CAN_RTR) {
+ cf->can_id |= CAN_RTR_FLAG;
+ } else {
+ for (dlc = 0; dlc < cf->can_dlc; dlc++)
+ cf->data[dlc] =
+ readb(&priv->regs->mb[RCAR_CAN_RX_FIFO_MBX].data[dlc]);
+ }
+
+ can_led_event(priv->ndev, CAN_LED_EVENT_RX);
+
+ netif_receive_skb(skb);
+ stats->rx_bytes += cf->can_dlc;
+ stats->rx_packets++;
+}
+
+static int rcar_can_rx_poll(struct napi_struct *napi, int quota)
+{
+ struct rcar_can_priv *priv = container_of(napi,
+ struct rcar_can_priv, napi);
+ int num_pkts;
+
+ for (num_pkts = 0; num_pkts < quota; num_pkts++) {
+ u8 rfcr, isr;
+
+ isr = readb(&priv->regs->isr);
+ /* Clear interrupt bit */
+ if (isr & RCAR_CAN_ISR_RXFF)
+ writeb(isr & ~RCAR_CAN_ISR_RXFF, &priv->regs->isr);
+ rfcr = readb(&priv->regs->rfcr);
+ if (rfcr & RCAR_CAN_RFCR_RFEST)
+ break;
+ rcar_can_rx_pkt(priv);
+ /* Write 0xff to the RFPCR register to increment
+ * the CPU-side pointer for the receive FIFO
+ * to the next mailbox location
+ */
+ writeb(0xff, &priv->regs->rfpcr);
+ }
+ /* All packets processed */
+ if (num_pkts < quota) {
+ napi_complete(napi);
+ priv->ier |= RCAR_CAN_IER_RXFIE;
+ writeb(priv->ier, &priv->regs->ier);
+ }
+ return num_pkts;
+}
+
+static int rcar_can_do_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+ switch (mode) {
+ case CAN_MODE_START:
+ rcar_can_start(ndev);
+ netif_wake_queue(ndev);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int rcar_can_get_berr_counter(const struct net_device *dev,
+ struct can_berr_counter *bec)
+{
+ struct rcar_can_priv *priv = netdev_priv(dev);
+ int err;
+
+ err = clk_prepare_enable(priv->clk);
+ if (err)
+ return err;
+ bec->txerr = readb(&priv->regs->tecr);
+ bec->rxerr = readb(&priv->regs->recr);
+ clk_disable_unprepare(priv->clk);
+ return 0;
+}
+
+static int rcar_can_probe(struct platform_device *pdev)
+{
+ struct rcar_can_platform_data *pdata;
+ struct rcar_can_priv *priv;
+ struct net_device *ndev;
+ struct resource *mem;
+ void __iomem *addr;
+ int err = -ENODEV;
+ int irq;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata) {
+ dev_err(&pdev->dev, "No platform data provided!\n");
+ goto fail;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (!irq) {
+ dev_err(&pdev->dev, "No IRQ resource\n");
+ goto fail;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ addr = devm_ioremap_resource(&pdev->dev, mem);
+ if (IS_ERR(addr)) {
+ err = PTR_ERR(addr);
+ goto fail;
+ }
+
+ ndev = alloc_candev(sizeof(struct rcar_can_priv), RCAR_CAN_FIFO_DEPTH);
+ if (!ndev) {
+ dev_err(&pdev->dev, "alloc_candev() failed\n");
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ priv = netdev_priv(ndev);
+
+ priv->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ err = PTR_ERR(priv->clk);
+ dev_err(&pdev->dev, "cannot get clock: %d\n", err);
+ goto fail_clk;
+ }
+
+ ndev->netdev_ops = &rcar_can_netdev_ops;
+ ndev->irq = irq;
+ ndev->flags |= IFF_ECHO;
+ priv->ndev = ndev;
+ priv->regs = addr;
+ priv->clock_select = pdata->clock_select;
+ priv->can.clock.freq = clk_get_rate(priv->clk);
+ priv->can.bittiming_const = &rcar_can_bittiming_const;
+ priv->can.do_set_mode = rcar_can_do_set_mode;
+ priv->can.do_get_berr_counter = rcar_can_get_berr_counter;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING;
+ platform_set_drvdata(pdev, ndev);
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ netif_napi_add(ndev, &priv->napi, rcar_can_rx_poll,
+ RCAR_CAN_NAPI_WEIGHT);
+ err = register_candev(ndev);
+ if (err) {
+ dev_err(&pdev->dev, "register_candev() failed, error %d\n",
+ err);
+ goto fail_candev;
+ }
+
+ devm_can_led_init(ndev);
+
+ dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%u)\n",
+ priv->regs, ndev->irq);
+
+ return 0;
+fail_candev:
+ netif_napi_del(&priv->napi);
+fail_clk:
+ free_candev(ndev);
+fail:
+ return err;
+}
+
+static int rcar_can_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+
+ unregister_candev(ndev);
+ netif_napi_del(&priv->napi);
+ free_candev(ndev);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rcar_can_suspend(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u16 ctlr;
+
+ if (netif_running(ndev)) {
+ netif_stop_queue(ndev);
+ netif_device_detach(ndev);
+ }
+ ctlr = readw(&priv->regs->ctlr);
+ ctlr |= RCAR_CAN_CTLR_CANM_HALT;
+ writew(ctlr, &priv->regs->ctlr);
+ ctlr |= RCAR_CAN_CTLR_SLPM;
+ writew(ctlr, &priv->regs->ctlr);
+ priv->can.state = CAN_STATE_SLEEPING;
+
+ clk_disable(priv->clk);
+ return 0;
+}
+
+static int rcar_can_resume(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct rcar_can_priv *priv = netdev_priv(ndev);
+ u16 ctlr;
+ int err;
+
+ err = clk_enable(priv->clk);
+ if (err) {
+ netdev_err(ndev, "clk_enable() failed, error %d\n", err);
+ return err;
+ }
+
+ ctlr = readw(&priv->regs->ctlr);
+ ctlr &= ~RCAR_CAN_CTLR_SLPM;
+ writew(ctlr, &priv->regs->ctlr);
+ ctlr &= ~RCAR_CAN_CTLR_CANM;
+ writew(ctlr, &priv->regs->ctlr);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_running(ndev)) {
+ netif_device_attach(ndev);
+ netif_start_queue(ndev);
+ }
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(rcar_can_pm_ops, rcar_can_suspend, rcar_can_resume);
+
+static struct platform_driver rcar_can_driver = {
+ .driver = {
+ .name = RCAR_CAN_DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &rcar_can_pm_ops,
+ },
+ .probe = rcar_can_probe,
+ .remove = rcar_can_remove,
+};
+
+module_platform_driver(rcar_can_driver);
+
+MODULE_AUTHOR("Cogent Embedded, Inc.");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CAN driver for Renesas R-Car SoC");
+MODULE_ALIAS("platform:" RCAR_CAN_DRV_NAME);
Index: linux-can-next/include/linux/can/platform/rcar_can.h
===================================================================
--- /dev/null
+++ linux-can-next/include/linux/can/platform/rcar_can.h
@@ -0,0 +1,17 @@
+#ifndef _CAN_PLATFORM_RCAR_CAN_H_
+#define _CAN_PLATFORM_RCAR_CAN_H_
+
+#include <linux/types.h>
+
+/* Clock Select Register settings */
+enum CLKR {
+ CLKR_CLKP1 = 0, /* Peripheral clock (clkp1) */
+ CLKR_CLKP2 = 1, /* Peripheral clock (clkp2) */
+ CLKR_CLKEXT = 3 /* Externally input clock */
+};
+
+struct rcar_can_platform_data {
+ enum CLKR clock_select; /* Clock source select */
+};
+
+#endif /* !_CAN_PLATFORM_RCAR_CAN_H_ */
^ permalink raw reply
* Re: pull request: wireless-next 2014-02-20
From: David Miller @ 2014-02-20 22:29 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, netdev
In-Reply-To: <20140220203005.GF3657@tuxdriver.com>
From: "John W. Linville" <linville@tuxdriver.com>
Date: Thu, 20 Feb 2014 15:30:05 -0500
> Please pull this batch of wireless updates intended for the 3.15
> stream!
>
> For the mac80211 bits, Johannes says:
>
> "We have some cleanups and minor fixes as well as userspace API
> improvements from a lot of people, extended VHT support for radiotap
> from Emmanuel, CSA improvements from Andrei, Luca and Michal. I've also
> included my work on hwsim to make dynamic registration of radios
> possible."
>
> Along with that, we get the usual round of updates to ath9k,
> brcmfmac, mwifiex, wcn36xx, and the ti drivers -- nothing particularly
> noteworthy, mostly just random updates and refactoring.
>
> Also included is a pull of the wireless tree, intended to resolve
> some potential merge issues.
>
> Please let me know if there are problems!
Pulled, but please address this:
drivers/staging/rtl8821ae/rtl8821ae/trx.c: In function ‘rtl8821ae_rx_query_desc’:
drivers/staging/rtl8821ae/rtl8821ae/trx.c:619:3: warning: passing argument 1 of ‘ieee80211_is_robust_mgmt_frame’ from incompatible pointer type [enabled by default]
I was going to do the easy transformation to the "_" prefixed variant
but noticed that this code doesn't validate the skb length, which is
precisely the reason why this routine now takes an skb.
^ permalink raw reply
* Re: [net-next 1/3] net: bcmgenet: drop checks on priv->phydev
From: Sergei Shtylyov @ 2014-02-20 23:54 UTC (permalink / raw)
To: Florian Fainelli, netdev; +Cc: davem
In-Reply-To: <1392929631-7685-2-git-send-email-f.fainelli@gmail.com>
Hello.
On 02/20/2014 11:53 PM, Florian Fainelli wrote:
> Drop all the checks on priv->phydev since we will refuse probing the
> driver if we cannot attach to a PHY device. Drop all checks on
> priv->phydev. This also fixes some smatch issues reported by Dan
> Carpenter where smatch would complain that a pointer is not always
> checked correctly.
> Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/net/ethernet/broadcom/genet/bcmgenet.c | 15 +++++----------
> 1 file changed, 5 insertions(+), 10 deletions(-)
> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> index 0ebc297..8af5f07 100644
> --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
[...]
> @@ -1811,8 +1810,7 @@ static void bcmgenet_irq_task(struct work_struct *work)
> /* Link UP/DOWN event */
> if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
> (priv->irq0_stat & (UMAC_IRQ_LINK_UP|UMAC_IRQ_LINK_DOWN))) {
> - if (priv->phydev)
> - phy_mac_interrupt(priv->phydev,
> + phy_mac_interrupt(priv->phydev,
> (priv->irq0_stat & UMAC_IRQ_LINK_UP));
Should probably realign this line (although it wasn't correctly aligned
before). Also () are not needed around &.
WBR, Sergei
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox