* Re: [PATCH 3/4] pass (host-endian) cmd length as explicit argument to l2cap_conf_req()
From: Marcel Holtmann @ 2007-07-27 14:41 UTC (permalink / raw)
To: Al Viro; +Cc: davem, linux-kernel, netdev
In-Reply-To: <E1IEPNm-0005Sn-7z@ZenIV.linux.org.uk>
Hi All,
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 2/4] l2cap: endianness annotations
From: Marcel Holtmann @ 2007-07-27 14:41 UTC (permalink / raw)
To: Al Viro; +Cc: davem, linux-kernel, netdev
In-Reply-To: <E1IEPNc-0005SI-7n@ZenIV.linux.org.uk>
Hi Al,
> no code changes, just documenting existing types
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 1/4] fix endianness bug in l2cap_sock_listen()
From: Marcel Holtmann @ 2007-07-27 14:41 UTC (permalink / raw)
To: Al Viro; +Cc: davem, linux-kernel, netdev
In-Reply-To: <E1IEPNS-0005RS-7o@ZenIV.linux.org.uk>
Hi Al,
> We loop through psm values, calling __l2cap_get_sock_by_addr(psm, ...)
> until we get NULL; then we set ->psm of our socket to htobs(psm).
> IOW, we find unused psm value and put it into our socket. So far, so
> good, but... __l2cap_get_sock_by_addr() compares its argument with
> ->psm of sockets. IOW, the entire thing works correctly only on
> little-endian. On big-endian we'll get "no socket with such psm"
> on the first iteration, since we won't find a socket with ->psm == 0x1001.
> We will happily conclude that 0x1001 is unused and slap htobs(0x1001)
> (i.e. 0x110) into ->psm of our socket. Of course, the next time around
> the same thing will repeat and we'll just get a fsckload of sockets
> with the same ->psm assigned.
>
> Fix: pass htobs(psm) to __l2cap_get_sock_by_addr() there. All other
> callers are already passing little-endian values and all places that
> store something in ->psm are storing little-endian.
>
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Dave, all four patches are good and should go in sooner than later. If
you want me to put them into my tree first, then I can do that or you
can apply them directly. You choice.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH 1/1]ixgbe: Driver for Intel 82598 based 10GbE PCI Express family of adapters
From: Jeff Garzik @ 2007-07-27 13:52 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Ayyappan Veeraiyan, netdev, arjan, akpm, auke-jan.h.kok, hch,
nhorman, inaky, mb, john.ronciak
In-Reply-To: <46A91EA5.9060005@linux-foundation.org>
Stephen Hemminger wrote:
> Using module parameter for per device settings is bad idea.
> Please extend existing interfaces like ethtool, etc rather than committing
> to a bad inflexible API.
I agreed with Stephen's comments here.
In general, net driver policy is to use ethtool (per-interface
granularity) rather than module options.
Jeff
^ permalink raw reply
* Re: sk98lin for 2.6.23-rc1
From: Stephen Hemminger @ 2007-07-27 13:06 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Kyle Rose, netdev
In-Reply-To: <46A9EC05.40503@garzik.org>
On Fri, 27 Jul 2007 08:58:45 -0400
Jeff Garzik <jeff@garzik.org> wrote:
> Stephen Hemminger wrote:
> > If anyone still has hang issues with sky2, please send me the hardware
> > information (lspci, dmesg output), and capture the debugfs state after hang.
> >
> > At present the known open skge, sky2 issues are:
>
> Did you add Chris Stromsoe's skge-hangs problem to the list?
>
> Jeff
That is the #1 on list, it is the dual port fiber problem.
Seems to be specific to dual port, since can't reproduce on my only
skge fiber board (single port) connected to e1000.
^ permalink raw reply
* Re: [RFC 0/1] lro: Generic Large Receive Offload for TCP traffic
From: Jeff Garzik @ 2007-07-27 13:00 UTC (permalink / raw)
To: Jan-Bernd Themann
Cc: Andrew Gallatin, netdev, Christoph Raisch, Jan-Bernd Themann,
linux-kernel, linux-ppc, Marcus Eder, Thomas Klein,
Stefan Roscher, David Miller, Evgeniy Polyakov
In-Reply-To: <200707271418.49781.ossthema@de.ibm.com>
Just to chime in...
In general, I like where this LRO effort is going, and I really
appreciate you guys working on it.
Jeff
^ permalink raw reply
* Re: sk98lin for 2.6.23-rc1
From: Jeff Garzik @ 2007-07-27 12:58 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Kyle Rose, netdev
In-Reply-To: <20070727091341.15681172@oldman>
Stephen Hemminger wrote:
> If anyone still has hang issues with sky2, please send me the hardware
> information (lspci, dmesg output), and capture the debugfs state after hang.
>
> At present the known open skge, sky2 issues are:
Did you add Chris Stromsoe's skge-hangs problem to the list?
Jeff
^ permalink raw reply
* [PATCH 4/4] l2cap: don't mangle cmd.len
From: Al Viro @ 2007-07-27 12:57 UTC (permalink / raw)
To: davem; +Cc: linux-kernel, netdev, marcel
Since nobody uses it after we convert it to host-endian,
no need to do that at all. At that point l2cap is endian-clean.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/bluetooth/l2cap.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 03309d2..c4e4ce4 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1754,7 +1754,6 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk
len -= L2CAP_CMD_HDR_SIZE;
cmd_len = le16_to_cpu(cmd.len);
- cmd.len = cmd_len;
BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident);
--
1.5.3.GIT
^ permalink raw reply related
* [PATCH 3/4] pass (host-endian) cmd length as explicit argument to l2cap_conf_req()
From: Al Viro @ 2007-07-27 12:57 UTC (permalink / raw)
To: davem; +Cc: linux-kernel, netdev, marcel
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/bluetooth/l2cap.c | 20 +++++++++++---------
1 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 09126bf..03309d2 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1530,7 +1530,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
return 0;
}
-static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
{
struct l2cap_conf_req *req = (struct l2cap_conf_req *) data;
u16 dcid, flags;
@@ -1550,7 +1550,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
goto unlock;
/* Reject if config buffer is too small. */
- len = cmd->len - sizeof(*req);
+ len = cmd_len - sizeof(*req);
if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
l2cap_build_conf_rsp(sk, rsp,
@@ -1748,15 +1748,17 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk
l2cap_raw_recv(conn, skb);
while (len >= L2CAP_CMD_HDR_SIZE) {
+ u16 cmd_len;
memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
data += L2CAP_CMD_HDR_SIZE;
len -= L2CAP_CMD_HDR_SIZE;
- cmd.len = __le16_to_cpu(cmd.len);
+ cmd_len = le16_to_cpu(cmd.len);
+ cmd.len = cmd_len;
- BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
+ BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, cmd.ident);
- if (cmd.len > len || !cmd.ident) {
+ if (cmd_len > len || !cmd.ident) {
BT_DBG("corrupted command");
break;
}
@@ -1775,7 +1777,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk
break;
case L2CAP_CONF_REQ:
- err = l2cap_config_req(conn, &cmd, data);
+ err = l2cap_config_req(conn, &cmd, cmd_len, data);
break;
case L2CAP_CONF_RSP:
@@ -1791,7 +1793,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk
break;
case L2CAP_ECHO_REQ:
- l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
+ l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data);
break;
case L2CAP_ECHO_RSP:
@@ -1820,8 +1822,8 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk
l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
}
- data += cmd.len;
- len -= cmd.len;
+ data += cmd_len;
+ len -= cmd_len;
}
kfree_skb(skb);
--
1.5.3.GIT
^ permalink raw reply related
* [PATCH 2/4] l2cap: endianness annotations
From: Al Viro @ 2007-07-27 12:57 UTC (permalink / raw)
To: davem; +Cc: linux-kernel, netdev, marcel
no code changes, just documenting existing types
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
include/net/bluetooth/l2cap.h | 50 ++++++++++++++++++++--------------------
net/bluetooth/l2cap.c | 27 +++++++++++----------
2 files changed, 39 insertions(+), 38 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 87df4e8..70e70f5 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -34,7 +34,7 @@
/* L2CAP socket address */
struct sockaddr_l2 {
sa_family_t l2_family;
- unsigned short l2_psm;
+ __le16 l2_psm;
bdaddr_t l2_bdaddr;
};
@@ -76,32 +76,32 @@ struct l2cap_conninfo {
/* L2CAP structures */
struct l2cap_hdr {
- __u16 len;
- __u16 cid;
+ __le16 len;
+ __le16 cid;
} __attribute__ ((packed));
#define L2CAP_HDR_SIZE 4
struct l2cap_cmd_hdr {
__u8 code;
__u8 ident;
- __u16 len;
+ __le16 len;
} __attribute__ ((packed));
#define L2CAP_CMD_HDR_SIZE 4
struct l2cap_cmd_rej {
- __u16 reason;
+ __le16 reason;
} __attribute__ ((packed));
struct l2cap_conn_req {
- __u16 psm;
- __u16 scid;
+ __le16 psm;
+ __le16 scid;
} __attribute__ ((packed));
struct l2cap_conn_rsp {
- __u16 dcid;
- __u16 scid;
- __u16 result;
- __u16 status;
+ __le16 dcid;
+ __le16 scid;
+ __le16 result;
+ __le16 status;
} __attribute__ ((packed));
/* connect result */
@@ -117,15 +117,15 @@ struct l2cap_conn_rsp {
#define L2CAP_CS_AUTHOR_PEND 0x0002
struct l2cap_conf_req {
- __u16 dcid;
- __u16 flags;
+ __le16 dcid;
+ __le16 flags;
__u8 data[0];
} __attribute__ ((packed));
struct l2cap_conf_rsp {
- __u16 scid;
- __u16 flags;
- __u16 result;
+ __le16 scid;
+ __le16 flags;
+ __le16 result;
__u8 data[0];
} __attribute__ ((packed));
@@ -149,23 +149,23 @@ struct l2cap_conf_opt {
#define L2CAP_CONF_MAX_SIZE 22
struct l2cap_disconn_req {
- __u16 dcid;
- __u16 scid;
+ __le16 dcid;
+ __le16 scid;
} __attribute__ ((packed));
struct l2cap_disconn_rsp {
- __u16 dcid;
- __u16 scid;
+ __le16 dcid;
+ __le16 scid;
} __attribute__ ((packed));
struct l2cap_info_req {
- __u16 type;
+ __le16 type;
__u8 data[0];
} __attribute__ ((packed));
struct l2cap_info_rsp {
- __u16 type;
- __u16 result;
+ __le16 type;
+ __le16 result;
__u8 data[0];
} __attribute__ ((packed));
@@ -207,7 +207,7 @@ struct l2cap_conn {
struct l2cap_pinfo {
struct bt_sock bt;
- __u16 psm;
+ __le16 psm;
__u16 dcid;
__u16 scid;
@@ -225,7 +225,7 @@ struct l2cap_pinfo {
__u8 ident;
- __u16 sport;
+ __le16 sport;
struct l2cap_conn *conn;
struct sock *next_c;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index b82cbdd..09126bf 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -353,7 +353,7 @@ static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16
}
/* ---- Socket interface ---- */
-static struct sock *__l2cap_get_sock_by_addr(u16 psm, bdaddr_t *src)
+static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
{
struct sock *sk;
struct hlist_node *node;
@@ -368,7 +368,7 @@ found:
/* Find socket with psm and source bdaddr.
* Returns closest match.
*/
-static struct sock *__l2cap_get_sock_by_psm(int state, u16 psm, bdaddr_t *src)
+static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
{
struct sock *sk = NULL, *sk1 = NULL;
struct hlist_node *node;
@@ -392,7 +392,7 @@ static struct sock *__l2cap_get_sock_by_psm(int state, u16 psm, bdaddr_t *src)
/* Find socket with given address (psm, src).
* Returns locked socket */
-static inline struct sock *l2cap_get_sock_by_psm(int state, u16 psm, bdaddr_t *src)
+static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
{
struct sock *s;
read_lock(&l2cap_sk_list.lock);
@@ -586,7 +586,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_
goto done;
}
- if (la->l2_psm > 0 && btohs(la->l2_psm) < 0x1001 &&
+ if (la->l2_psm && btohs(la->l2_psm) < 0x1001 &&
!capable(CAP_NET_BIND_SERVICE)) {
err = -EACCES;
goto done;
@@ -873,7 +873,7 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
if (sk->sk_type == SOCK_DGRAM)
- put_unaligned(l2cap_pi(sk)->psm, (u16 *) skb_put(skb, 2));
+ put_unaligned(l2cap_pi(sk)->psm, (__le16 *) skb_put(skb, 2));
if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
err = -EFAULT;
@@ -1256,11 +1256,11 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned
break;
case 2:
- *val = __le16_to_cpu(*((u16 *)opt->val));
+ *val = __le16_to_cpu(*((__le16 *)opt->val));
break;
case 4:
- *val = __le32_to_cpu(*((u32 *)opt->val));
+ *val = __le32_to_cpu(*((__le32 *)opt->val));
break;
default:
@@ -1287,11 +1287,11 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
break;
case 2:
- *((u16 *) opt->val) = cpu_to_le16(val);
+ *((__le16 *) opt->val) = cpu_to_le16(val);
break;
case 4:
- *((u32 *) opt->val) = cpu_to_le32(val);
+ *((__le32 *) opt->val) = cpu_to_le32(val);
break;
default:
@@ -1406,7 +1406,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
int result = 0, status = 0;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
- u16 psm = req->psm;
+ __le16 psm = req->psm;
BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
@@ -1863,7 +1863,7 @@ done:
return 0;
}
-static inline int l2cap_conless_channel(struct l2cap_conn *conn, u16 psm, struct sk_buff *skb)
+static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
{
struct sock *sk;
@@ -1893,7 +1893,8 @@ done:
static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct l2cap_hdr *lh = (void *) skb->data;
- u16 cid, psm, len;
+ u16 cid, len;
+ __le16 psm;
skb_pull(skb, L2CAP_HDR_SIZE);
cid = __le16_to_cpu(lh->cid);
@@ -1907,7 +1908,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
break;
case 0x0002:
- psm = get_unaligned((u16 *) skb->data);
+ psm = get_unaligned((__le16 *) skb->data);
skb_pull(skb, 2);
l2cap_conless_channel(conn, psm, skb);
break;
--
1.5.3.GIT
^ permalink raw reply related
* [PATCH 1/4] fix endianness bug in l2cap_sock_listen()
From: Al Viro @ 2007-07-27 12:57 UTC (permalink / raw)
To: davem; +Cc: linux-kernel, netdev, marcel
We loop through psm values, calling __l2cap_get_sock_by_addr(psm, ...)
until we get NULL; then we set ->psm of our socket to htobs(psm).
IOW, we find unused psm value and put it into our socket. So far, so
good, but... __l2cap_get_sock_by_addr() compares its argument with
->psm of sockets. IOW, the entire thing works correctly only on
little-endian. On big-endian we'll get "no socket with such psm"
on the first iteration, since we won't find a socket with ->psm == 0x1001.
We will happily conclude that 0x1001 is unused and slap htobs(0x1001)
(i.e. 0x110) into ->psm of our socket. Of course, the next time around
the same thing will repeat and we'll just get a fsckload of sockets
with the same ->psm assigned.
Fix: pass htobs(psm) to __l2cap_get_sock_by_addr() there. All other
callers are already passing little-endian values and all places that
store something in ->psm are storing little-endian.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/bluetooth/l2cap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 670ff95..b82cbdd 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -748,7 +748,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
write_lock_bh(&l2cap_sk_list.lock);
for (psm = 0x1001; psm < 0x1100; psm += 2)
- if (!__l2cap_get_sock_by_addr(psm, src)) {
+ if (!__l2cap_get_sock_by_addr(htobs(psm), src)) {
l2cap_pi(sk)->psm = htobs(psm);
l2cap_pi(sk)->sport = htobs(psm);
err = 0;
--
1.5.3.GIT
^ permalink raw reply related
* Re: [RFC 0/1] lro: Generic Large Receive Offload for TCP traffic
From: Jan-Bernd Themann @ 2007-07-27 12:18 UTC (permalink / raw)
To: Andrew Gallatin
Cc: netdev, Christoph Raisch, Jan-Bernd Themann, linux-kernel,
linux-ppc, Marcus Eder, Thomas Klein, Stefan Roscher,
David Miller, Jeff Garzik, Evgeniy Polyakov
In-Reply-To: <46A785C2.9090708@myri.com>
Hi Drew,
thanks a lot for your good feedback. See comments below.
I'll try to provide an updated version next week. It would
be nice if you could post a patch for your driver once
we have addressed the issues you mentioned. Then we would
have the eHEA driver for the SKB interface, and your driver
for the "receive in pages" interface.
Thanks,
Jan-Bernd
On Wednesday 25 July 2007 19:17, Andrew Gallatin wrote:
> Code review / comments:
> ===================
>
> 1) Checksum information for CHECKSUM_COMPLETE drivers.
>
> Our NIC passes partial checksums to our driver. In the current code,
> it seems impossible for page based CHECKSUM_COMPLETE drivers to behave
> correctly in the case of "rejected" frames. Eg, there is no way
> to pass the partial checksum to the LRO module so that it gets
> set in the skb header and passed up the stack.
>
> Further, there seems to be no (easy) way to use CHECKSUM_COMPLETE
> on an aggregated packet at LRO flush time. By the time a packet
> is aggregated, the partial checksum from the first segment is
> out of date.
>
> I think it would make sense to require that a CHECKSUM_COMPLETE style
> driver verify the checksum in its get_frag_header / get_skb_header
> callback. This allows the LRO code to unconditionally set
> CHECKSUM_UNNECESSARY.
I agree
> 2) Non-accelerated VLAN tags
>
> Our firmware currently does not do vlan tag insertion
> and removal. This causes a problem in __lro_proc_segment()
> where the tcp and ip headers are setup to point into the
> newly created skb. A frame containing an unstripped vlan
> tag will cause the headers to be garbage.
>
> The attached patch modifies __lro_proc_segment() to offset
> those pointers by VLAN_HLEN when required.
>
The modifications you propose are not sufficient to work with HW
which actually extracts the VLAN IDs but does not change the
eth protocol. Thus we have to add an additional field in
lro_mgr indicating how to interpret the eth protocol regarding
the VLAN header.
> 3) Padded frames.
>
> I may be missing something, but I don't see where you
> either strip padding from frames or reject padded frames.
> (see the pskb_trim_rcsum() in net/ipv4/ip_input.c:ip_rcv()
>
I think I missed something :-) Will fix that.
In lro_tcp_ip_check we check for the "SKB aggregation interface"
the skb->len against ip->tot_len. This catches padded frames as
eth_type_trans(skb, dev) reduces the length of the SKB.
However, the possible VLAN header is not taken into account.
And for the "receive in pages" interface a wrong length is passed
as argument as well.
I'd suggest to reject padded frames for aggregation as we do now
(when bugs are fixed) and thus keep the code simple.
I guess that padded frames don't occur too often in high load
situations. If we detect a real performance issue we can still
change that later.
> I did not add such a feature as I was confused about the intended
> use of len/true_size.
len: number of bytes received
true_size: used to fill the "truesize" field in the SKB. Thus this reflects
the amount of memory that is actually used by that SKB. If you
receive into pages und you have some space between packets, you
should take this into account. Example: you use 1 page for each
packet, then you pass 4096 as argument.
>
> Also, trimming is a pain when dealing with pure frags (without a
> containing skb). We have code in our out-of-kernel driver to deal
> with it which you are welcome to use.
>
>
> 4) LRO_MIN_PG_HLEN (== 80)
>
> This confuses me. Can you please explain what you're trying to do?
> Because of this, I kept getting crashes in the skb_pull() done by
> eth_type_trans() because I was passing segments which were 60 bytes
> and the skb->data_len of the skb constructed by lro_gen_skb() was -20.
> I added my own code to bump the length to a magic 80 bytes, and the
> panics disappeared. This may cause data corruption because of
> #3 above!
Yes, I see the point... I'm not sure in how far there are any requirements
that a certain amount of data (header) for other types of traffic
has to be in the skb->data field and not in frags. Maybe someone
can comment on this?
I suggest to remove LRO_MIN_PG_HLEN for tcp/ip packets that are aggregated,
but should we use a minimal length for other traffic (depending on the
number of received bytes)? Is that necessary?
>
> 5) NAPI/non-NAPI
>
> The LRO code assumes the underlying driver uses NAPI, and calls
> netif_receive_skb() rather than netif_rx(). Perhaps there should be a
> field in the lro_mgr struct to specify napi / non-napi.
>
Yes, if someone intends to use it without napi, we can add this.
> 6) The checks for when to stop aggregating and flush in
> __lro_proc_{segment|skb} need some improvement.
>
> The skb variant currently uses a pure count (max_aggr). In order to
> keep the resulting aggregated frame below 64KB, the underlying driver
> computes max_aggr as 0xffff / MTU. This reduces the effectiveness of
> LRO on mixed MTU networks. Eg, this causes packets coming from a
> source with a 1500b MTU to be aggregated after 7 frames when using a
> 9000b MTU on the receiver, rather than after 43 frames. As you can
> see from the differences in inet_lro's performance in the table
> above, this is a real problem.
>
> I believe that a hybrid byte / max_aggr model should be used. The
> __lro_proc_segment takes this approach. Note that there is a subtle
> bug in that the maximum aggregated bytes should not be be 0xffff.
> Rather, one must leave room for the next frame to arrive by setting
> the max aggregated bytes to 0xffff - dev->mtu. This is masked
> by the driver computing max_aggr as above.
This suggestions sounds good. Will add it.
^ permalink raw reply
* Please pull latest bcm43xx-mac80211 + ssb
From: Michael Buesch @ 2007-07-27 12:15 UTC (permalink / raw)
To: John Linville
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w
The following changes since commit 78d7c152a3a8880b7daab8a1be1f24199f9d80b9:
John W. Linville:
Merge branch 'upstream' of git://git.kernel.org/.../ivd/rt2x00
are found in the git repository at:
http://bu3sch.de/git/wireless-dev.git/ for-linville
Larry Finger:
bcm43xx-mac80211: Fix deviations from OFDM table specs
Michael Buesch:
bcm43xx-mac80211: Fix build for PCI-less systems.
bcm43xx-mac80211: Use round_jiffies() to round pwork interval.
ssb: Zero out invariants before pulling them.
ssb: Rename nr_buses variable to next_busnumber
bcm43xx-mac80211: Add optional verbose DMA debugging.
bcm43xx-mac80211: Use ieee80211_generic_frame_duration() to calculate durations.
bcm43xx-mac80211: Add sanity checks for the packet length in the RX handler.
bcm43xx-mac80211: Rewrite and simplify handling of the initialization status.
bcm43xx-mac80211: Rewrite message logging to associate logmessages to the wiphy.
bcm43xx-mac80211: Get rid of all stupid bitfields and use bool.
bcm43xx-mac80211: Fix nondebug build.
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-dev
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-dev
ssb: Fix typo in EXTIF_BASE define.
ssb: Address Andrew Morton's comments.
bcm43xx-mac80211: Always run promisc on old devices with broken MAC addr filter.
ssb: Remove ifdef __KERNEL__
ssb: A few fixes
ssb: Cleanup Makefile and Kconfig.
ssb: Add more comments.
Merge branch 'master' of git://git.kernel.org/.../linville/wireless-dev
bcm43xx-mac80211: Fix compilation, pass if_id to ieee80211_generic_frame_duration()
drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h | 113 +++---
.../wireless/bcm43xx-mac80211/bcm43xx_debugfs.c | 83 +----
.../wireless/bcm43xx-mac80211/bcm43xx_debugfs.h | 43 --
.../net/wireless/bcm43xx-mac80211/bcm43xx_dma.c | 108 ++++--
.../net/wireless/bcm43xx-mac80211/bcm43xx_dma.h | 8
drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c | 27 +
drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h | 4
.../net/wireless/bcm43xx-mac80211/bcm43xx_main.c | 400 +++++++++++++----------
.../net/wireless/bcm43xx-mac80211/bcm43xx_phy.c | 64 ++--
.../net/wireless/bcm43xx-mac80211/bcm43xx_phy.h | 4
.../net/wireless/bcm43xx-mac80211/bcm43xx_pio.c | 18 +
.../net/wireless/bcm43xx-mac80211/bcm43xx_pio.h | 6
.../net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c | 4
.../net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c | 23 +
drivers/ssb/Kconfig | 1
drivers/ssb/Makefile | 18 +
drivers/ssb/driver_chipcommon.c | 28 +
drivers/ssb/driver_mipscore.c | 38 +-
drivers/ssb/driver_pcicore.c | 30 +-
drivers/ssb/main.c | 90 ++---
drivers/ssb/pci.c | 4
drivers/ssb/pcmcia.c | 11 -
drivers/ssb/scan.c | 20 +
drivers/ssb/ssb_private.h | 26 -
include/linux/ssb/ssb.h | 29 +
include/linux/ssb/ssb_driver_chipcommon.h | 2
include/linux/ssb/ssb_driver_extif.h | 3
include/linux/ssb/ssb_driver_mips.h | 3
include/linux/ssb/ssb_driver_pci.h | 2
include/linux/ssb/ssb_regs.h | 12 -
30 files changed, 593 insertions(+), 629 deletions(-)
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h
index 2802fc0..49b471a 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx.h
@@ -23,8 +23,6 @@ #include "bcm43xx_lo.h"
#include "bcm43xx_phy.h"
-#define PFX KBUILD_MODNAME ": "
-
#define BCM43xx_IRQWAIT_MAX_RETRIES 50
#define BCM43xx_IO_SIZE 8192
@@ -441,11 +439,12 @@ # undef assert
#endif
#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
# define assert(expr) \
- do { \
- if (unlikely(!(expr))) { \
- printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \
- #expr, __FILE__, __LINE__, __FUNCTION__); \
- } \
+ do { \
+ if (unlikely(!(expr))) { \
+ printk(KERN_ERR KBUILD_MODNAME ": " \
+ "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \
+ #expr, __FILE__, __LINE__, __FUNCTION__); \
+ } \
} while (0)
# define BCM43xx_DEBUG 1
#else
@@ -453,31 +452,6 @@ # define assert(expr) do { /* nothing */
# define BCM43xx_DEBUG 0
#endif
-/* rate limited printk(). */
-#ifdef printkl
-# undef printkl
-#endif
-#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0)
-/* rate limited printk() for debugging */
-#ifdef dprintkl
-# undef dprintkl
-#endif
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
-# define dprintkl printkl
-#else
-# define dprintkl(f, x...) do { /* nothing */ } while (0)
-#endif
-
-/* debugging printk() */
-#ifdef dprintk
-# undef dprintk
-#endif
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
-# define dprintk(f, x...) do { printk(f ,##x); } while (0)
-#else
-# define dprintk(f, x...) do { /* nothing */ } while (0)
-#endif
-
struct net_device;
struct pci_dev;
@@ -499,7 +473,7 @@ struct bcm43xx_phy {
/* Possible PHYMODEs on this PHY */
u8 possible_phymodes;
/* GMODE bit enabled? */
- u8 gmode;
+ bool gmode;
/* Possible ieee80211 subsystem hwmodes for this PHY.
* Which mode is selected, depends on thr GMODE enabled bit */
#define BCM43xx_MAX_PHYHWMODES 2
@@ -517,14 +491,14 @@ #define BCM43xx_MAX_PHYHWMODES 2
u16 radio_ver; /* Radio version */
u8 radio_rev; /* Radio revision */
- u8 radio_on:1; /* Radio switched on/off */
- u8 locked:1; /* Only used in bcm43xx_phy_{un}lock() */
- u8 dyn_tssi_tbl:1; /* tssi2dbm is kmalloc()ed. */
+ bool radio_on; /* Radio switched on/off */
+ bool locked; /* Only used in bcm43xx_phy_{un}lock() */
+ bool dyn_tssi_tbl; /* tssi2dbm is kmalloc()ed. */
/* ACI (adjacent channel interference) flags. */
- u8 aci_enable:1;
- u8 aci_wlan_automatic:1;
- u8 aci_hw_rssi:1;
+ bool aci_enable;
+ bool aci_wlan_automatic;
+ bool aci_hw_rssi;
u16 minlowsig[2];
u16 minlowsigpos[2];
@@ -561,7 +535,7 @@ #define BCM43xx_MAX_PHYHWMODES 2
struct bcm43xx_rfatt rfatt;
u8 tx_control; /* BCM43xx_TXCTL_XXX */
#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
- u8 manual_txpower_control; /* Manual TX-power control enabled? */
+ bool manual_txpower_control; /* Manual TX-power control enabled? */
#endif
/* Current Interference Mitigation mode */
@@ -614,7 +588,7 @@ struct bcm43xx_pio {
/* Context information for a noise calculation (Link Quality). */
struct bcm43xx_noise_calculation {
u8 channel_at_start;
- u8 calculation_running:1;
+ bool calculation_running;
u8 nr_samples;
s8 samples[8][4];
};
@@ -627,7 +601,7 @@ struct bcm43xx_stats {
};
struct bcm43xx_key {
- u8 enabled;
+ bool enabled;
u8 algorithm;
u8 address[6];
};
@@ -663,11 +637,11 @@ struct bcm43xx_wl {
/* Counter of active monitor interfaces. */
int monitor;
/* Is the card operating in AP, STA or IBSS mode? */
- unsigned int operating:1;
+ bool operating;
/* Promisc mode active?
* Note that (monitor != 0) implies promisc.
*/
- unsigned int promisc:1;
+ bool promisc;
/* Stats about the wireless interface */
struct ieee80211_low_level_stats ieee_stats;
@@ -698,13 +672,13 @@ struct bcm43xx_firmware {
/* Device (802.11 core) initialization status. */
enum {
- BCM43xx_STAT_UNINIT, /* Uninitialized. */
- BCM43xx_STAT_INITIALIZING, /* bcm43xx_wireless_core_init() in progress. */
- BCM43xx_STAT_INITIALIZED, /* Initialized. Note that this doesn't mean it's started. */
+ BCM43xx_STAT_UNINIT = 0, /* Uninitialized. */
+ BCM43xx_STAT_INITIALIZED = 1, /* Initialized, but not started, yet. */
+ BCM43xx_STAT_STARTED = 2, /* Up and running. */
};
-#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
-#define bcm43xx_set_status(bcm, stat) do { \
- atomic_set(&(bcm)->init_status, (stat)); \
+#define bcm43xx_status(wldev) atomic_read(&(wldev)->__init_status)
+#define bcm43xx_set_status(wldev, stat) do { \
+ atomic_set(&(wldev)->__init_status, (stat)); \
smp_wmb(); \
} while (0)
@@ -721,19 +695,18 @@ struct bcm43xx_wldev {
struct ssb_device *dev;
struct bcm43xx_wl *wl;
- /* Driver initialization status BCM43xx_STAT_*** */
- atomic_t init_status;
- /* Interface started? (bcm43xx_wireless_core_start()) */
- u8 started;
+ /* The device initialization status.
+ * Use bcm43xx_status() to query. */
+ atomic_t __init_status;
+ /* Saved init status for handling suspend. */
+ int suspend_init_status;
- u16 was_initialized:1, /* for suspend/resume. */
- was_started:1, /* for suspend/resume. */
- __using_pio:1, /* Internal, use bcm43xx_using_pio(). */
- bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */
- reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */
- short_preamble:1, /* TRUE, if short preamble is enabled. */
- short_slot:1, /* TRUE, if short slot timing is enabled. */
- radio_hw_enable:1; /* saved state of radio hardware enabled state */
+ bool __using_pio; /* Internal, use bcm43xx_using_pio(). */
+ bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */
+ bool reg124_set_0x4; /* Some variable to keep track of IRQ stuff. */
+ bool short_preamble; /* TRUE, if short preamble is enabled. */
+ bool short_slot; /* TRUE, if short slot timing is enabled. */
+ bool radio_hw_enable; /* saved state of radio hardware enabled state */
/* PHY/Radio device. */
struct bcm43xx_phy phy;
@@ -863,6 +836,22 @@ void bcm43xx_write32(struct bcm43xx_wlde
ssb_write32(dev->dev, offset, value);
}
+
+/* Message printing */
+void bcminfo(struct bcm43xx_wl *wl, const char *fmt, ...)
+ __attribute__((format(printf, 2, 3)));
+void bcmerr(struct bcm43xx_wl *wl, const char *fmt, ...)
+ __attribute__((format(printf, 2, 3)));
+void bcmwarn(struct bcm43xx_wl *wl, const char *fmt, ...)
+ __attribute__((format(printf, 2, 3)));
+#if BCM43xx_DEBUG
+void bcmdbg(struct bcm43xx_wl *wl, const char *fmt, ...)
+ __attribute__((format(printf, 2, 3)));
+#else /* DEBUG */
+# define bcmdbg(wl, fmt...) do { /* nothing */ } while (0)
+#endif /* DEBUG */
+
+
/** Limit a value between two limits */
#ifdef limit_value
# undef limit_value
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.c
index 3ea9d08..9ca4625 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.c
@@ -92,7 +92,7 @@ static ssize_t tsf_read_file(struct file
mutex_lock(&big_buffer_mutex);
mutex_lock(&dev->wl->mutex);
spin_lock_irqsave(&dev->wl->irq_lock, flags);
- if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) {
+ if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
fappend("Board not initialized.\n");
goto out;
}
@@ -128,13 +128,13 @@ static ssize_t tsf_write_file(struct fil
}
mutex_lock(&dev->wl->mutex);
spin_lock_irqsave(&dev->wl->irq_lock, flags);
- if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) {
- printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
+ if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
+ bcmerr(dev->wl, "debugfs: Board not initialized.\n");
res = -EFAULT;
goto out_unlock;
}
if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1) {
- printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n");
+ bcmerr(dev->wl, "debugfs: invalid values for \"tsf\"\n");
res = -EINVAL;
goto out_unlock;
}
@@ -234,8 +234,8 @@ static ssize_t restart_write_file(struct
}
mutex_lock(&dev->wl->mutex);
spin_lock_irqsave(&dev->wl->irq_lock, flags);
- if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) {
- printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
+ if (bcm43xx_status(dev) < BCM43xx_STAT_INITIALIZED) {
+ bcmerr(dev->wl, "debugfs: Board not initialized.\n");
res = -EFAULT;
goto out_unlock;
}
@@ -267,8 +267,7 @@ static ssize_t txpower_g_read_file(struc
mutex_lock(&big_buffer_mutex);
mutex_lock(&dev->wl->mutex);
spin_lock_irqsave(&dev->wl->irq_lock, flags);
- if ((bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) ||
- !dev->started) {
+ if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
fappend("Not initialized\n");
goto out;
}
@@ -322,14 +321,13 @@ static ssize_t txpower_g_write_file(stru
}
mutex_lock(&dev->wl->mutex);
spin_lock_irqsave(&dev->wl->irq_lock, flags);
- if ((bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) ||
- !dev->started) {
- printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
+ if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
+ bcmerr(dev->wl, "debugfs: Board not initialized.\n");
res = -ENODEV;
goto out_unlock;
}
if (dev->phy.type != BCM43xx_PHYTYPE_G) {
- printk(KERN_ERR PFX "debugfs: Device is not a G-PHY\n");
+ bcmerr(dev->wl, "debugfs: Device is not a G-PHY\n");
res = -ENODEV;
goto out_unlock;
}
@@ -342,7 +340,7 @@ static ssize_t txpower_g_write_file(stru
/* Manual control */
if (sscanf(buf, "%d %d %d %d %d", &bbatt, &rfatt,
&txmix, &pa2db, &pa3db) != 5) {
- printk(KERN_INFO PFX "debugfs: invalid value for \"tx_power_g\"\n");
+ bcmerr(dev->wl, "debugfs: invalid value for \"tx_power_g\"\n");
res = -EINVAL;
goto out_unlock;
}
@@ -437,6 +435,7 @@ #define add_dyn_dbg(name, id, initstate)
add_dyn_dbg("debug_xmitpower", BCM43xx_DBG_XMITPOWER, 0);
add_dyn_dbg("debug_dmaoverflow", BCM43xx_DBG_DMAOVERFLOW, 0);
+ add_dyn_dbg("debug_dmaverbose", BCM43xx_DBG_DMAVERBOSE, 0);
add_dyn_dbg("debug_pwork_fast", BCM43xx_DBG_PWORK_FAST, 0);
add_dyn_dbg("debug_pwork_stop", BCM43xx_DBG_PWORK_STOP, 0);
@@ -452,7 +451,7 @@ void bcm43xx_debugfs_add_device(struct b
assert(dev);
e = kzalloc(sizeof(*e), GFP_KERNEL);
if (!e) {
- printk(KERN_ERR PFX "debugfs: add device OOM\n");
+ bcmerr(dev->wl, "debugfs: add device OOM\n");
return;
}
e->dev = dev;
@@ -461,7 +460,7 @@ void bcm43xx_debugfs_add_device(struct b
sizeof(struct bcm43xx_txstatus),
GFP_KERNEL);
if (!log->log) {
- printk(KERN_ERR PFX "debugfs: add device txstatus OOM\n");
+ bcmerr(dev->wl, "debugfs: add device txstatus OOM\n");
kfree(e);
return;
}
@@ -557,57 +556,3 @@ void bcm43xx_debugfs_exit(void)
debugfs_remove(fs.dentry_driverinfo);
debugfs_remove(fs.root);
}
-
-void bcm43xx_printk_dump(const char *data,
- size_t size,
- const char *description)
-{
- unsigned int i;
- char c;
-
- printk(KERN_INFO PFX "Data dump (%s, %lu bytes):",
- description, (unsigned long)size);
- for (i = 0; i < size; i++) {
- c = data[i];
- if (i % 8 == 0)
- printk("\n" KERN_INFO PFX "0x%08x: 0x%02x, ", i, c & 0xff);
- else
- printk("0x%02x, ", c & 0xff);
- }
- printk("\n");
-}
-
-void bcm43xx_printk_bitdump(const unsigned char *data,
- size_t bytes, int msb_to_lsb,
- const char *description)
-{
- unsigned int i;
- int j;
- const unsigned char *d;
-
- printk(KERN_INFO PFX "*** Bitdump (%s, %lu bytes, %s) ***",
- description, (unsigned long)bytes,
- msb_to_lsb ? "MSB to LSB" : "LSB to MSB");
- for (i = 0; i < bytes; i++) {
- d = data + i;
- if (i % 8 == 0)
- printk("\n" KERN_INFO PFX "0x%08x: ", i);
- if (msb_to_lsb) {
- for (j = 7; j >= 0; j--) {
- if (*d & (1 << j))
- printk("1");
- else
- printk("0");
- }
- } else {
- for (j = 0; j < 8; j++) {
- if (*d & (1 << j))
- printk("1");
- else
- printk("0");
- }
- }
- printk(" ");
- }
- printk("\n");
-}
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.h
index 892299d..65f6b1f 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_debugfs.h
@@ -7,6 +7,7 @@ struct bcm43xx_txstatus;
enum bcm43xx_dyndbg { /* Dynamic debugging features */
BCM43xx_DBG_XMITPOWER,
BCM43xx_DBG_DMAOVERFLOW,
+ BCM43xx_DBG_DMAVERBOSE,
BCM43xx_DBG_PWORK_FAST,
BCM43xx_DBG_PWORK_STOP,
__BCM43xx_NR_DYNDBG,
@@ -59,22 +60,6 @@ void bcm43xx_debugfs_remove_device(struc
void bcm43xx_debugfs_log_txstat(struct bcm43xx_wldev *dev,
const struct bcm43xx_txstatus *status);
-/* Debug helper: Dump binary data through printk. */
-void bcm43xx_printk_dump(const char *data,
- size_t size,
- const char *description);
-/* Debug helper: Dump bitwise binary data through printk. */
-void bcm43xx_printk_bitdump(const unsigned char *data,
- size_t bytes, int msb_to_lsb,
- const char *description);
-#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \
- do { \
- bcm43xx_printk_bitdump((const unsigned char *)(pointer), \
- sizeof(*(pointer)), \
- (msb_to_lsb), \
- (description)); \
- } while (0)
-
#else /* CONFIG_BCM43XX_MAC80211_DEBUG*/
static inline
@@ -95,20 +80,6 @@ static inline
void bcm43xx_debugfs_log_txstat(struct bcm43xx_wldev *dev,
const struct bcm43xx_txstatus *status) { }
-static inline
-void bcm43xx_printk_dump(const char *data,
- size_t size,
- const char *description)
-{
-}
-static inline
-void bcm43xx_printk_bitdump(const unsigned char *data,
- size_t bytes, int msb_to_lsb,
- const char *description)
-{
-}
-#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0)
-
#endif /* CONFIG_BCM43XX_MAC80211_DEBUG*/
/* Ugly helper macros to make incomplete code more verbose on runtime */
@@ -116,18 +87,18 @@ #ifdef TODO
# undef TODO
#endif
#define TODO() \
- do { \
- printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \
- __FUNCTION__, __FILE__, __LINE__); \
+ do { \
+ bcminfo(NULL, "TODO: Incomplete code in %s() at %s:%d\n", \
+ __FUNCTION__, __FILE__, __LINE__); \
} while (0)
#ifdef FIXME
# undef FIXME
#endif
#define FIXME() \
- do { \
- printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \
- __FUNCTION__, __FILE__, __LINE__); \
+ do { \
+ bcminfo(NULL, "FIXME: Possibly broken code in %s() at %s:%d\n", \
+ __FUNCTION__, __FILE__, __LINE__); \
} while (0)
#endif /* BCM43xx_DEBUGFS_H_ */
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.c
index c8b5cdd..5476250 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.c
@@ -259,6 +259,28 @@ static inline int prev_slot(struct bcm43
return slot - 1;
}
+#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
+static void update_max_used_slots(struct bcm43xx_dmaring *ring,
+ int current_used_slots)
+{
+ if (current_used_slots <= ring->max_used_slots)
+ return;
+ ring->max_used_slots = current_used_slots;
+ if (bcm43xx_debug(ring->dev, BCM43xx_DBG_DMAVERBOSE)) {
+ bcmdbg(ring->dev->wl,
+ "max_used_slots increased to %d on %s ring %d\n",
+ ring->max_used_slots,
+ ring->tx ? "TX" : "RX",
+ ring->index);
+ }
+}
+#else
+static inline
+void update_max_used_slots(struct bcm43xx_dmaring *ring,
+ int current_used_slots)
+{ }
+#endif /* DEBUG */
+
/* Request a slot for usage. */
static inline
int request_slot(struct bcm43xx_dmaring *ring)
@@ -273,23 +295,11 @@ int request_slot(struct bcm43xx_dmaring
ring->current_slot = slot;
ring->used_slots++;
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
- if (ring->used_slots > ring->max_used_slots)
- ring->max_used_slots = ring->used_slots;
-#endif /* CONFIG_BCM43XX_MAC80211_DEBUG*/
+ update_max_used_slots(ring, ring->used_slots);
return slot;
}
-/* Return a slot to the free slots. */
-static inline
-void return_slot(struct bcm43xx_dmaring *ring, int slot)
-{
- assert(ring->tx);
-
- ring->used_slots--;
-}
-
/* Mac80211-queue to bcm43xx-ring mapping */
static struct bcm43xx_dmaring * priority_to_txring(struct bcm43xx_wldev *dev,
int queue_priority)
@@ -450,7 +460,7 @@ static int alloc_ringmemory(struct bcm43
ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
&(ring->dmabase), GFP_KERNEL);
if (!ring->descbase) {
- printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
+ bcmerr(ring->dev->wl, "DMA ringmemory allocation failed\n");
return -ENOMEM;
}
memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
@@ -497,7 +507,7 @@ int bcm43xx_dmacontroller_rx_reset(struc
msleep(1);
}
if (i != -1) {
- printk(KERN_ERR PFX "ERROR: DMA RX reset timed out\n");
+ bcmerr(dev->wl, "DMA RX reset timed out\n");
return -ENODEV;
}
@@ -553,7 +563,7 @@ int bcm43xx_dmacontroller_tx_reset(struc
msleep(1);
}
if (i != -1) {
- printk(KERN_ERR PFX "ERROR: DMA TX reset timed out\n");
+ bcmerr(dev->wl, "DMA TX reset timed out\n");
return -ENODEV;
}
/* ensure the reset is completed. */
@@ -624,7 +634,8 @@ static int alloc_initial_descbuffers(str
err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
if (err) {
- printk(KERN_ERR PFX "Failed to allocate initial descbuffers\n");
+ bcmerr(ring->dev->wl,
+ "Failed to allocate initial descbuffers\n");
goto err_unwind;
}
}
@@ -903,11 +914,11 @@ static void bcm43xx_destroy_dmaring(stru
if (!ring)
return;
- dprintk(KERN_INFO PFX "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
- (ring->dma64) ? "64" : "32",
- ring->mmio_base,
- (ring->tx) ? "TX" : "RX",
- ring->max_used_slots, ring->nr_slots);
+ bcmdbg(ring->dev->wl, "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
+ (ring->dma64) ? "64" : "32",
+ ring->mmio_base,
+ (ring->tx) ? "TX" : "RX",
+ ring->max_used_slots, ring->nr_slots);
/* Device IRQs are disabled prior entering this function,
* so no need to take care of concurrency with rx handler stuff.
*/
@@ -962,13 +973,13 @@ int bcm43xx_dma_init(struct bcm43xx_wlde
err = ssb_dma_set_mask(dev->dev, dmamask);
if (err) {
#ifdef BCM43XX_MAC80211_PIO
- printk(KERN_WARNING PFX "DMA for this device not supported. "
- "Falling back to PIO\n");
+ bcmwarn(dev->wl, "DMA for this device not supported. "
+ "Falling back to PIO\n");
dev->__using_pio = 1;
return -EAGAIN;
#else
- printk(KERN_ERR PFX "DMA for this device not supported and "
- "no PIO support compiled in\n");
+ bcmerr(dev->wl, "DMA for this device not supported and "
+ "no PIO support compiled in\n");
return -EOPNOTSUPP;
#endif
}
@@ -1018,9 +1029,9 @@ #endif
dma->rx_ring3 = ring;
}
- dprintk(KERN_INFO PFX "%d-bit DMA initialized\n",
- (dmamask == DMA_64BIT_MASK) ? 64 :
- (dmamask == DMA_32BIT_MASK) ? 32 : 30);
+ bcmdbg(dev->wl, "%d-bit DMA initialized\n",
+ (dmamask == DMA_64BIT_MASK) ? 64 :
+ (dmamask == DMA_32BIT_MASK) ? 32 : 30);
err = 0;
out:
return err;
@@ -1213,8 +1224,9 @@ #ifdef CONFIG_BCM43XX_MAC80211_DEBUG
next_overflow = ring->last_injected_overflow + HZ;
if (time_after(jiffies, next_overflow)) {
ring->last_injected_overflow = jiffies;
- dprintk(KERN_DEBUG PFX "Injecting TX ring overflow on "
- "DMA controller %d\n", ring->index);
+ bcmdbg(ring->dev->wl,
+ "Injecting TX ring overflow on "
+ "DMA controller %d\n", ring->index);
return 1;
}
}
@@ -1234,7 +1246,7 @@ int bcm43xx_dma_tx(struct bcm43xx_wldev
spin_lock_irqsave(&ring->lock, flags);
assert(ring->tx);
if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
- printkl(KERN_ERR PFX "DMA queue overflow\n");
+ bcmwarn(dev->wl, "DMA queue overflow\n");
err = -ENOSPC;
goto out_unlock;
}
@@ -1245,7 +1257,7 @@ int bcm43xx_dma_tx(struct bcm43xx_wldev
err = dma_tx_fragment(ring, skb, ctl);
if (unlikely(err)) {
- printkl(KERN_ERR PFX "DMA tx mapping failure\n");
+ bcmerr(dev->wl, "DMA tx mapping failure\n");
goto out_unlock;
}
ring->nr_tx_packets++;
@@ -1254,6 +1266,10 @@ int bcm43xx_dma_tx(struct bcm43xx_wldev
/* This TX ring is full. */
ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring));
ring->stopped = 1;
+ if (bcm43xx_debug(dev, BCM43xx_DBG_DMAVERBOSE)) {
+ bcmdbg(dev->wl, "Stopped TX ring %d\n",
+ ring->index);
+ }
}
out_unlock:
spin_unlock_irqrestore(&ring->lock, flags);
@@ -1305,10 +1321,9 @@ void bcm43xx_dma_handle_txstatus(struct
*/
assert(meta->skb == NULL);
}
- /* Everything belonging to the slot is unmapped
- * and freed, so we can return it.
- */
- return_slot(ring, slot);
+
+ /* Everything unmapped and free'd. So it's not used anymore. */
+ ring->used_slots--;
if (meta->is_last_fragment)
break;
@@ -1319,6 +1334,10 @@ void bcm43xx_dma_handle_txstatus(struct
assert(free_slots(ring) >= SLOTS_PER_PACKET);
ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring));
ring->stopped = 0;
+ if (bcm43xx_debug(dev, BCM43xx_DBG_DMAVERBOSE)) {
+ bcmdbg(dev->wl, "Woke up TX ring %d\n",
+ ring->index);
+ }
}
spin_unlock(&ring->lock);
@@ -1417,16 +1436,16 @@ static void dma_rx(struct bcm43xx_dmarin
if (tmp <= 0)
break;
}
- printkl(KERN_ERR PFX "DMA RX buffer too small "
- "(len: %u, buffer: %u, nr-dropped: %d)\n",
- len, ring->rx_buffersize, cnt);
+ bcmerr(ring->dev->wl, "DMA RX buffer too small "
+ "(len: %u, buffer: %u, nr-dropped: %d)\n",
+ len, ring->rx_buffersize, cnt);
goto drop;
}
dmaaddr = meta->dmaaddr;
err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
if (unlikely(err)) {
- dprintkl(KERN_ERR PFX "DMA RX: setup_rx_descbuffer() failed\n");
+ bcmdbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n");
sync_descbuffer_for_device(ring, dmaaddr,
ring->rx_buffersize);
goto drop;
@@ -1445,9 +1464,7 @@ void bcm43xx_dma_rx(struct bcm43xx_dmari
{
const struct bcm43xx_dma_ops *ops = ring->ops;
int slot, current_slot;
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
int used_slots = 0;
-#endif
assert(!ring->tx);
current_slot = ops->get_current_rxslot(ring);
@@ -1456,10 +1473,7 @@ #endif
slot = ring->current_slot;
for ( ; slot != current_slot; slot = next_slot(ring, slot)) {
dma_rx(ring, &slot);
-#ifdef CONFIG_BCM43XX_MAC80211_DEBUG
- if (++used_slots > ring->max_used_slots)
- ring->max_used_slots = used_slots;
-#endif
+ update_max_used_slots(ring, ++used_slots);
}
ops->set_current_rxslot(ring, slot);
ring->current_slot = slot;
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.h
index 3d109b1..baabeed 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_dma.h
@@ -194,7 +194,7 @@ struct bcm43xx_dmadesc_meta {
/* DMA base bus-address of the descriptor buffer. */
dma_addr_t dmaaddr;
/* ieee80211 TX status. Only used once per 802.11 frag. */
- u8 is_last_fragment;
+ bool is_last_fragment;
struct ieee80211_tx_status txstat;
};
@@ -247,11 +247,11 @@ struct bcm43xx_dmaring {
/* DMA controller index number (0-5). */
int index;
/* Boolean. Is this a TX ring? */
- u8 tx;
+ bool tx;
/* Boolean. 64bit DMA if true, 32bit DMA otherwise. */
- u8 dma64;
+ bool dma64;
/* Boolean. Is this ring stopped at ieee80211 level? */
- u8 stopped;
+ bool stopped;
/* Lock, only used for TX. */
spinlock_t lock;
struct bcm43xx_wldev *dev;
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c
index aa1a298..b405779 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.c
@@ -47,8 +47,8 @@ static void bcm43xx_lo_write(struct bcm4
if (BCM43xx_DEBUG) {
if (unlikely(abs(control->i) > 16 ||
abs(control->q) > 16)) {
- printk(KERN_ERR PFX "ERROR: Invalid LO control pair "
- "(I: %d, Q: %d)\n",
+ bcmdbg(dev->wl, "Invalid LO control pair "
+ "(I: %d, Q: %d)\n",
control->i, control->q);
dump_stack();
return;
@@ -64,22 +64,21 @@ static void bcm43xx_lo_write(struct bcm4
static inline
int assert_rfatt_and_bbatt(const struct bcm43xx_rfatt *rfatt,
- const struct bcm43xx_bbatt *bbatt)
+ const struct bcm43xx_bbatt *bbatt,
+ struct bcm43xx_wldev *dev)
{
int err = 0;
/* Check the attenuation values against the LO control array sizes. */
#if BCM43xx_DEBUG
if (rfatt->att >= BCM43xx_NR_RF) {
- dprintk(KERN_ERR PFX
- "ERROR: rfatt(%u) >= size of LO array\n",
- rfatt->att);
+ bcmdbg(dev->wl, "rfatt(%u) >= size of LO array\n",
+ rfatt->att);
err = -EINVAL;
}
if (bbatt->att >= BCM43xx_NR_BB) {
- dprintk(KERN_ERR PFX
- "ERROR: bbatt(%u) >= size of LO array\n",
- bbatt->att);
+ bcmdbg(dev->wl, "bbatt(%u) >= size of LO array\n",
+ bbatt->att);
err = -EINVAL;
}
if (err)
@@ -97,7 +96,7 @@ struct bcm43xx_loctl * bcm43xx_get_lo_g_
struct bcm43xx_phy *phy = &dev->phy;
struct bcm43xx_txpower_lo_control *lo = phy->lo_control;
- if (assert_rfatt_and_bbatt(rfatt, bbatt))
+ if (assert_rfatt_and_bbatt(rfatt, bbatt, dev))
return &(lo->no_padmix[0][0]); /* Just prevent a crash */
return &(lo->no_padmix[bbatt->att][rfatt->att]);
}
@@ -109,7 +108,7 @@ struct bcm43xx_loctl * bcm43xx_get_lo_g_
struct bcm43xx_phy *phy = &dev->phy;
struct bcm43xx_txpower_lo_control *lo = phy->lo_control;
- if (assert_rfatt_and_bbatt(rfatt, bbatt))
+ if (assert_rfatt_and_bbatt(rfatt, bbatt, dev))
return &(lo->no_padmix[0][0]); /* Just prevent a crash */
if (rfatt->with_padmix)
return &(lo->with_padmix[bbatt->att][rfatt->att]);
@@ -1013,13 +1012,13 @@ #if BCM43xx_DEBUG
static void do_validate_loctl(struct bcm43xx_wldev *dev,
struct bcm43xx_loctl *control)
{
- const int is_initializing = (bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZING);
+ const int is_initializing = (bcm43xx_status(dev) == BCM43xx_STAT_UNINIT);
if (unlikely(abs(control->i) > 16 ||
abs(control->q) > 16 ||
(is_initializing && control->used))) {
- printk(KERN_ERR PFX "ERROR: LO control pair validation failed "
- "(first: %d, second: %d, used %u)\n",
+ bcmdbg(dev->wl, "ERROR: LO control pair validation failed "
+ "(first: %d, second: %d, used %u)\n",
control->i, control->q, control->used);
}
}
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h
index 71fbe3e..377bda4 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_lo.h
@@ -35,7 +35,7 @@ #define BCM43xx_NR_RF 16
/* Flag to indicate a complete rebuild of the two tables above
* to the LO measuring code. */
- u8 rebuild;
+ bool rebuild;
/* Lists of valid RF and BB attenuation values for this device. */
struct bcm43xx_rfatt_list rfatt_list;
@@ -47,7 +47,7 @@ #define BCM43xx_NR_RF 16
u8 tx_magn;
/* GPHY LO is measured. */
- u8 lo_measured;
+ bool lo_measured;
/* Saved device PowerVector */
u64 power_vector;
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_main.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_main.c
index eefc536..7a9dd02 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_main.c
@@ -194,6 +194,69 @@ static void bcm43xx_wireless_core_stop(s
static int bcm43xx_wireless_core_start(struct bcm43xx_wldev *dev);
+static int bcm43xx_ratelimit(struct bcm43xx_wl *wl)
+{
+ if (!wl || !wl->current_dev)
+ return 1;
+ if (bcm43xx_status(wl->current_dev) < BCM43xx_STAT_STARTED)
+ return 1;
+ /* We are up and running.
+ * Ratelimit the messages to avoid DoS over the net. */
+ return net_ratelimit();
+}
+
+void bcminfo(struct bcm43xx_wl *wl, const char *fmt, ...)
+{
+ va_list args;
+
+ if (!bcm43xx_ratelimit(wl))
+ return;
+ va_start(args, fmt);
+ printk(KERN_INFO "bcm43xx-%s: ",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
+ vprintk(fmt, args);
+ va_end(args);
+}
+
+void bcmerr(struct bcm43xx_wl *wl, const char *fmt, ...)
+{
+ va_list args;
+
+ if (!bcm43xx_ratelimit(wl))
+ return;
+ va_start(args, fmt);
+ printk(KERN_ERR "bcm43xx-%s ERROR: ",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
+ vprintk(fmt, args);
+ va_end(args);
+}
+
+void bcmwarn(struct bcm43xx_wl *wl, const char *fmt, ...)
+{
+ va_list args;
+
+ if (!bcm43xx_ratelimit(wl))
+ return;
+ va_start(args, fmt);
+ printk(KERN_WARNING "bcm43xx-%s warning: ",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
+ vprintk(fmt, args);
+ va_end(args);
+}
+
+#if BCM43xx_DEBUG
+void bcmdbg(struct bcm43xx_wl *wl, const char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ printk(KERN_DEBUG "bcm43xx-%s debug: ",
+ (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
+ vprintk(fmt, args);
+ va_end(args);
+}
+#endif /* DEBUG */
+
static void bcm43xx_ram_write(struct bcm43xx_wldev *dev, u16 offset, u32 val)
{
u32 status;
@@ -772,7 +835,7 @@ static int bcm43xx_key_write(struct bcm4
}
}
if (index < 0) {
- dprintk(KERN_ERR PFX "Out of hw key memory\n");
+ bcmerr(dev->wl, "Out of hardware key memory\n");
return -ENOBUFS;
}
} else
@@ -1080,21 +1143,13 @@ static void bcm43xx_write_probe_resp_plc
{
struct bcm43xx_plcp_hdr4 plcp;
u32 tmp;
- u16 packet_time;
+ __le16 dur;
plcp.data = 0;
bcm43xx_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
- /*
- * 144 + 48 + 10 = preamble + PLCP + SIFS,
- * taken from mac80211 timings calculation.
- *
- * FIXME: long preamble assumed!
- *
- */
- packet_time = 202 + (size + FCS_LEN) * 16 / rate;
- if ((size + FCS_LEN) * 16 % rate >= rate / 2)
- ++packet_time;
-
+ dur = ieee80211_generic_frame_duration(dev->wl->hw,
+ dev->wl->if_id, size,
+ BCM43xx_RATE_TO_BASE100KBPS(rate));
/* Write PLCP in two parts and timing for packet transfer */
tmp = le32_to_cpu(plcp.data);
bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, shm_offset,
@@ -1102,7 +1157,7 @@ static void bcm43xx_write_probe_resp_plc
bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, shm_offset + 2,
tmp >> 16);
bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, shm_offset + 6,
- packet_time);
+ le16_to_cpu(dur));
}
/* Instead of using custom probe response template, this function
@@ -1116,15 +1171,17 @@ static u8 * bcm43xx_generate_probe_resp(
{
const u8 *src_data;
u8 *dest_data;
- u16 src_size, elem_size, src_pos, dest_pos, tmp;
+ u16 src_size, elem_size, src_pos, dest_pos;
+ __le16 dur;
+ struct ieee80211_hdr *hdr;
assert(dev->cached_beacon);
src_size = dev->cached_beacon->len;
src_data = (const u8*)dev->cached_beacon->data;
if (unlikely(src_size < 0x24)) {
- dprintk(KERN_ERR PFX "bcm43xx_generate_probe_resp: "
- "invalid beacon\n");
+ bcmdbg(dev->wl, "bcm43xx_generate_probe_resp: "
+ "invalid beacon\n");
return NULL;
}
@@ -1146,26 +1203,15 @@ static u8 * bcm43xx_generate_probe_resp(
}
}
*dest_size = dest_pos;
+ hdr = (struct ieee80211_hdr *)dest_data;
/* Set the frame control. */
- dest_data[0] = (IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_PROBE_RESP);
- dest_data[1] = 0;
-
- /* Set the duration field.
- *
- * 144 + 48 + 10 = preamble + PLCP + SIFS,
- * taken from mac80211 timings calculation.
- *
- * FIXME: long preamble assumed!
- *
- */
- tmp = 202 + (14 + FCS_LEN) * 16 / rate;
- if ((14 + FCS_LEN) * 16 % rate >= rate / 2)
- ++tmp;
-
- dest_data[2] = tmp & 0xFF;
- dest_data[3] = (tmp >> 8) & 0xFF;
+ hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_PROBE_RESP);
+ dur = ieee80211_generic_frame_duration(dev->wl->hw,
+ dev->wl->if_id, *dest_size,
+ BCM43xx_RATE_TO_BASE100KBPS(rate));
+ hdr->duration_id = dur;
return dest_data;
}
@@ -1328,8 +1374,7 @@ static void bcm43xx_interrupt_tasklet(st
spin_lock_irqsave(&dev->wl->irq_lock, flags);
- assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
- assert(dev->started);
+ assert(bcm43xx_status(dev) == BCM43xx_STAT_STARTED);
reason = dev->irq_reason;
for (i = 0; i < ARRAY_SIZE(dma_reason); i++) {
@@ -1338,32 +1383,32 @@ static void bcm43xx_interrupt_tasklet(st
}
if (unlikely(reason & BCM43xx_IRQ_MAC_TXERR))
- printkl(KERN_ERR PFX "MAC transmission error\n");
+ bcmerr(dev->wl, "MAC transmission error\n");
if (unlikely(reason & BCM43xx_IRQ_PHY_TXERR))
- printkl(KERN_ERR PFX "PHY transmission error\n");
+ bcmerr(dev->wl, "PHY transmission error\n");
if (unlikely(merged_dma_reason & (BCM43xx_DMAIRQ_FATALMASK |
BCM43xx_DMAIRQ_NONFATALMASK))) {
if (merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK) {
- printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
- "0x%08X, 0x%08X, 0x%08X, "
- "0x%08X, 0x%08X, 0x%08X\n",
- dma_reason[0], dma_reason[1],
- dma_reason[2], dma_reason[3],
- dma_reason[4], dma_reason[5]);
+ bcmerr(dev->wl, "Fatal DMA error: "
+ "0x%08X, 0x%08X, 0x%08X, "
+ "0x%08X, 0x%08X, 0x%08X\n",
+ dma_reason[0], dma_reason[1],
+ dma_reason[2], dma_reason[3],
+ dma_reason[4], dma_reason[5]);
bcm43xx_controller_restart(dev, "DMA error");
mmiowb();
spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
return;
}
if (merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK) {
- printkl(KERN_ERR PFX "DMA error: "
- "0x%08X, 0x%08X, 0x%08X, "
- "0x%08X, 0x%08X, 0x%08X\n",
- dma_reason[0], dma_reason[1],
- dma_reason[2], dma_reason[3],
- dma_reason[4], dma_reason[5]);
+ bcmerr(dev->wl, "DMA error: "
+ "0x%08X, 0x%08X, 0x%08X, "
+ "0x%08X, 0x%08X, 0x%08X\n",
+ dma_reason[0], dma_reason[1],
+ dma_reason[2], dma_reason[3],
+ dma_reason[4], dma_reason[5]);
}
}
@@ -1458,7 +1503,7 @@ static void bcm43xx_interrupt_ack(struct
/* Interrupt handler top-half */
static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id)
{
- irqreturn_t ret = IRQ_HANDLED;
+ irqreturn_t ret = IRQ_NONE;
struct bcm43xx_wldev *dev = dev_id;
u32 reason;
@@ -1467,18 +1512,17 @@ static irqreturn_t bcm43xx_interrupt_han
spin_lock(&dev->wl->irq_lock);
+ if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED)
+ goto out;
reason = bcm43xx_read32(dev, BCM43xx_MMIO_GEN_IRQ_REASON);
- if (reason == 0xffffffff) {
- /* irq not for us (shared irq) */
- ret = IRQ_NONE;
+ if (reason == 0xffffffff) /* shared IRQ */
goto out;
- }
+ ret = IRQ_HANDLED;
reason &= bcm43xx_read32(dev, BCM43xx_MMIO_GEN_IRQ_MASK);
if (!reason)
goto out;
- assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
- assert(dev->started);
+ assert(bcm43xx_status(dev) == BCM43xx_STAT_STARTED);
dev->dma_reason[0] = bcm43xx_read32(dev, BCM43xx_MMIO_DMA0_REASON)
& 0x0001DC00;
@@ -1531,9 +1575,8 @@ static int bcm43xx_request_firmware(stru
modparam_fwpostfix);
err = request_firmware(&dev->fw.ucode, buf, dev->dev->dev);
if (err) {
- printk(KERN_ERR PFX
- "Error: Microcode \"%s\" not available or load failed.\n",
- buf);
+ bcmerr(dev->wl, "Microcode \"%s\" not "
+ "available or load failed.\n", buf);
goto error;
}
}
@@ -1545,9 +1588,8 @@ static int bcm43xx_request_firmware(stru
modparam_fwpostfix);
err = request_firmware(&dev->fw.pcm, buf, dev->dev->dev);
if (err) {
- printk(KERN_ERR PFX
- "Error: PCM \"%s\" not available or load failed.\n",
- buf);
+ bcmerr(dev->wl, "PCM \"%s\" not available "
+ "or load failed.\n", buf);
goto error;
}
}
@@ -1585,13 +1627,12 @@ static int bcm43xx_request_firmware(stru
err = request_firmware(&dev->fw.initvals0, buf, dev->dev->dev);
if (err) {
- printk(KERN_ERR PFX
- "Error: InitVals \"%s\" not available or load failed.\n",
- buf);
+ bcmerr(dev->wl, "InitVals \"%s\" not available "
+ "or load failed.\n", buf);
goto error;
}
if (dev->fw.initvals0->size % sizeof(struct bcm43xx_initval)) {
- printk(KERN_ERR PFX "InitVals fileformat error.\n");
+ bcmerr(dev->wl, "InitVals fileformat error.\n");
goto error;
}
}
@@ -1620,13 +1661,12 @@ static int bcm43xx_request_firmware(stru
err = request_firmware(&dev->fw.initvals1, buf, dev->dev->dev);
if (err) {
- printk(KERN_ERR PFX
- "Error: InitVals \"%s\" not available or load failed.\n",
- buf);
+ bcmerr(dev->wl, "InitVals \"%s\" not available "
+ "or load failed.\n", buf);
goto error;
}
if (dev->fw.initvals1->size % sizeof(struct bcm43xx_initval)) {
- printk(KERN_ERR PFX "InitVals fileformat error.\n");
+ bcmerr(dev->wl, "InitVals fileformat error.\n");
goto error;
}
}
@@ -1638,7 +1678,7 @@ error:
bcm43xx_release_firmware(dev);
goto out;
err_noinitval:
- printk(KERN_ERR PFX "Error: No InitVals available!\n");
+ bcmerr(dev->wl, "No InitVals available\n");
err = -ENOENT;
goto error;
}
@@ -1687,7 +1727,7 @@ static int bcm43xx_upload_microcode(stru
break;
i++;
if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
- printk(KERN_ERR PFX "Microcode not responding\n");
+ bcmerr(dev->wl, "Microcode not responding\n");
err = -ENODEV;
goto out;
}
@@ -1706,15 +1746,15 @@ static int bcm43xx_upload_microcode(stru
BCM43xx_SHM_SH_UCODETIME);
if (fwrev <= 0x128) {
- printk(KERN_ERR PFX "YOUR FIRMWARE IS TOO OLD. Firmware from "
+ bcmerr(dev->wl, "YOUR FIRMWARE IS TOO OLD. Firmware from "
"binary drivers older than version 4.x is unsupported. "
"You must upgrade your firmware files.\n");
bcm43xx_write32(dev, BCM43xx_MMIO_STATUS_BITFIELD, 0);
err = -EOPNOTSUPP;
goto out;
}
- printk(KERN_DEBUG PFX "Loading firmware version %u.%u "
- "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
+ bcmdbg(dev->wl, "Loading firmware version %u.%u "
+ "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
fwrev, fwpatch,
(fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
(fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
@@ -1754,8 +1794,8 @@ static int bcm43xx_write_initvals(struct
return 0;
err_format:
- printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. "
- "Please fix your bcm43xx firmware files.\n");
+ bcmerr(dev->wl, "InitVals (bcm43xx_initvalXX.fw) file-format error. "
+ "Please fix your bcm43xx firmware files.\n");
return -EPROTO;
}
@@ -1882,7 +1922,7 @@ void bcm43xx_mac_suspend(struct bcm43xx_
goto out;
udelay(1);
}
- printkl(KERN_ERR PFX "MAC suspend failed\n");
+ bcmerr(dev->wl, "MAC suspend failed\n");
}
out:
dev->mac_suspended++;
@@ -1928,6 +1968,11 @@ static void bcm43xx_adjust_opmode(struct
}
if (wl->promisc)
ctl |= BCM43xx_MACCTL_PROMISC;
+ /* Workaround: On old hardware the HW-MAC-address-filter
+ * doesn't work properly, so always run promisc in filter
+ * it in software. */
+ if (dev->dev->id.revision <= 4)
+ ctl |= BCM43xx_MACCTL_PROMISC;
bcm43xx_write32(dev, BCM43xx_MMIO_MACCTL, ctl);
@@ -2068,8 +2113,8 @@ static int bcm43xx_chip_init(struct bcm4
goto err_gpio_cleanup;
bcm43xx_radio_turn_on(dev);
dev->radio_hw_enable = bcm43xx_is_hw_radio_enabled(dev);
- dprintk(KERN_INFO PFX "Radio %s by hardware\n",
- (dev->radio_hw_enable == 0) ? "disabled" : "enabled");
+ bcmdbg(dev->wl, "Radio %s by hardware\n",
+ (dev->radio_hw_enable == 0) ? "disabled" : "enabled");
bcm43xx_write16(dev, 0x03E6, 0x0000);
err = bcm43xx_phy_init(dev);
@@ -2144,7 +2189,7 @@ static int bcm43xx_chip_init(struct bcm4
dev->dev->bus->chipco.fast_pwrup_delay);
assert(err == 0);
- dprintk(KERN_INFO PFX "Chip initialized\n");
+ bcmdbg(dev->wl, "Chip initialized\n");
out:
return err;
@@ -2222,8 +2267,8 @@ static void bcm43xx_periodic_every1sec(s
radio_hw_enable = bcm43xx_is_hw_radio_enabled(dev);
if (unlikely(dev->radio_hw_enable != radio_hw_enable)) {
dev->radio_hw_enable = radio_hw_enable;
- dprintk(KERN_INFO PFX "Radio hardware status changed to %s\n",
- (radio_hw_enable == 0) ? "disabled" : "enabled");
+ bcmdbg(dev->wl, "Radio hardware status changed to %s\n",
+ (radio_hw_enable == 0) ? "disabled" : "enabled");
bcm43xx_leds_update(dev, 0);
}
}
@@ -2275,9 +2320,7 @@ static void bcm43xx_periodic_work_handle
mutex_lock(&dev->wl->mutex);
- if (unlikely(bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED))
- goto out;
- if (unlikely(!dev->started))
+ if (unlikely(bcm43xx_status(dev) != BCM43xx_STAT_STARTED))
goto out;
if (bcm43xx_debug(dev, BCM43xx_DBG_PWORK_STOP))
goto out_requeue;
@@ -2312,9 +2355,10 @@ static void bcm43xx_periodic_work_handle
}
dev->periodic_state++;
out_requeue:
- delay = HZ;
if (bcm43xx_debug(dev, BCM43xx_DBG_PWORK_FAST))
delay = msecs_to_jiffies(50);
+ else
+ delay = round_jiffies(HZ);
queue_delayed_work(dev->wl->hw->workqueue,
&dev->periodic_work, delay);
out:
@@ -2330,7 +2374,6 @@ static void bcm43xx_periodic_tasks_setup
{
struct delayed_work *work = &dev->periodic_work;
- assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
dev->periodic_state = 0;
INIT_DELAYED_WORK(work, bcm43xx_periodic_work_handler);
queue_delayed_work(dev->wl->hw->workqueue, work, 0);
@@ -2362,7 +2405,7 @@ static int bcm43xx_validate_chipaccess(s
return 0;
error:
- printk(KERN_ERR PFX "Failed to validate the chipaccess\n");
+ bcmerr(dev->wl, "Failed to validate the chipaccess\n");
return -ENODEV;
}
@@ -2419,7 +2462,7 @@ static int bcm43xx_rng_init(struct bcm43
err = hwrng_register(&wl->rng);
if (err) {
wl->rng_initialized = 0;
- printk(KERN_ERR PFX "Failed to register the random "
+ bcmerr(wl, "Failed to register the random "
"number generator (%d)\n", err);
}
@@ -2435,11 +2478,11 @@ static int bcm43xx_tx(struct ieee80211_h
int err = -ENODEV;
unsigned long flags;
- /* DMA-TX is done without a global lock. */
if (unlikely(!dev))
goto out;
- assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
- assert(dev->started);
+ if (unlikely(bcm43xx_status(dev) < BCM43xx_STAT_STARTED))
+ goto out;
+ /* DMA-TX is done without a global lock. */
if (bcm43xx_using_pio(dev)) {
spin_lock_irqsave(&wl->irq_lock, flags);
err = bcm43xx_pio_tx(dev, skb, ctl);
@@ -2470,7 +2513,7 @@ static int bcm43xx_get_tx_stats(struct i
if (!dev)
goto out;
spin_lock_irqsave(&wl->irq_lock, flags);
- if (likely(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED)) {
+ if (likely(bcm43xx_status(dev) >= BCM43xx_STAT_STARTED)) {
if (bcm43xx_using_pio(dev))
bcm43xx_pio_get_tx_stats(dev, stats);
else
@@ -2528,7 +2571,7 @@ static const char * phymode_to_string(un
static int find_wldev_for_phymode(struct bcm43xx_wl *wl,
unsigned int phymode,
struct bcm43xx_wldev **dev,
- int *gmode)
+ bool *gmode)
{
struct bcm43xx_wldev *d;
@@ -2569,41 +2612,37 @@ static void bcm43xx_put_phy_into_reset(s
msleep(1);
}
+/* Expects wl->mutex locked */
static int bcm43xx_switch_phymode(struct bcm43xx_wl *wl,
unsigned int new_mode)
{
struct bcm43xx_wldev *up_dev;
struct bcm43xx_wldev *down_dev;
int err;
- int gmode = -1;
- int old_was_started = 0;
- int old_was_inited = 0;
+ bool gmode = 0;
+ int prev_status;
err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode);
if (err) {
- printk(KERN_INFO PFX "Could not find a device for %s-PHY mode\n",
+ bcmerr(wl, "Could not find a device for %s-PHY mode\n",
phymode_to_string(new_mode));
return err;
}
- assert(gmode == 0 || gmode == 1);
if ((up_dev == wl->current_dev) &&
- (wl->current_dev->phy.gmode == gmode)) {
+ (!!wl->current_dev->phy.gmode == !!gmode)) {
/* This device is already running. */
return 0;
}
- dprintk(KERN_INFO PFX "Reconfiguring PHYmode to %s-PHY\n",
- phymode_to_string(new_mode));
+ bcmdbg(wl, "Reconfiguring PHYmode to %s-PHY\n",
+ phymode_to_string(new_mode));
down_dev = wl->current_dev;
+ prev_status = bcm43xx_status(down_dev);
/* Shutdown the currently running core. */
- if (down_dev->started) {
- old_was_started = 1;
+ if (prev_status >= BCM43xx_STAT_STARTED)
bcm43xx_wireless_core_stop(down_dev);
- }
- if (bcm43xx_status(down_dev) == BCM43xx_STAT_INITIALIZED) {
- old_was_inited = 1;
+ if (prev_status >= BCM43xx_STAT_INITIALIZED)
bcm43xx_wireless_core_exit(down_dev);
- }
if (down_dev != up_dev) {
/* We switch to a different core, so we put PHY into
@@ -2613,30 +2652,34 @@ static int bcm43xx_switch_phymode(struct
/* Now start the new core. */
up_dev->phy.gmode = gmode;
- if (old_was_inited) {
+ if (prev_status >= BCM43xx_STAT_INITIALIZED) {
err = bcm43xx_wireless_core_init(up_dev);
if (err) {
- printk(KERN_INFO PFX "Fatal: Could not initialize device for "
- "new selected %s-PHY mode\n",
+ bcmerr(wl, "Fatal: Could not initialize device for "
+ "newly selected %s-PHY mode\n",
phymode_to_string(new_mode));
- return err;
+ goto init_failure;
}
}
- if (old_was_started) {
- assert(old_was_inited);
+ if (prev_status >= BCM43xx_STAT_STARTED) {
err = bcm43xx_wireless_core_start(up_dev);
if (err) {
- printk(KERN_INFO PFX "Fatal: Coult not start device for "
- "new selected %s-PHY mode\n",
+ bcmerr(wl, "Fatal: Coult not start device for "
+ "newly selected %s-PHY mode\n",
phymode_to_string(new_mode));
bcm43xx_wireless_core_exit(up_dev);
- return err;
+ goto init_failure;
}
}
+ assert(bcm43xx_status(up_dev) == prev_status);
wl->current_dev = up_dev;
return 0;
+init_failure:
+ /* Whoops, failed to init the new core. No core is operating now. */
+ wl->current_dev = NULL;
+ return err;
}
static int bcm43xx_antenna_from_ieee80211(u8 antenna)
@@ -2695,8 +2738,7 @@ static int bcm43xx_dev_config(struct iee
* This makes it possible to drop the spinlock throughout
* the reconfiguration process. */
spin_lock_irqsave(&wl->irq_lock, flags);
- if ((bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED) ||
- !dev->started) {
+ if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
spin_unlock_irqrestore(&wl->irq_lock, flags);
goto out_unlock_mutex;
}
@@ -2869,11 +2911,11 @@ out_unlock:
mutex_unlock(&wl->mutex);
out:
if (!err) {
- dprintk(KERN_DEBUG PFX "Using %s based encryption for keyidx: %d, "
- "mac: " MAC_FMT "\n",
- (key->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) ?
- "software" : "hardware",
- key->keyidx, MAC_ARG(addr));
+ bcmdbg(wl, "Using %s based encryption for keyidx: %d, "
+ "mac: " MAC_FMT "\n",
+ (key->flags & IEEE80211_KEY_FORCE_SW_ENCRYPT) ?
+ "software" : "hardware",
+ key->keyidx, MAC_ARG(addr));
}
return err;
}
@@ -2932,9 +2974,9 @@ static void bcm43xx_wireless_core_stop(s
struct bcm43xx_wl *wl = dev->wl;
unsigned long flags;
- if (!dev->started)
+ if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED)
return;
- dev->started = 0;
+ bcm43xx_set_status(dev, BCM43xx_STAT_INITIALIZED);
mutex_unlock(&wl->mutex);
/* Must unlock as it would otherwise deadlock. No races here. */
@@ -2953,32 +2995,32 @@ static void bcm43xx_wireless_core_stop(s
bcm43xx_mac_suspend(dev);
free_irq(dev->dev->irq, dev);
- dprintk(KERN_INFO PFX "Wireless interface stopped\n");
+ bcmdbg(wl, "Wireless interface stopped\n");
}
/* Locking: wl->mutex */
static int bcm43xx_wireless_core_start(struct bcm43xx_wldev *dev)
{
- struct bcm43xx_wl *wl = dev->wl;
int err;
- assert(!dev->started);
+ assert(bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED);
drain_txstatus_queue(dev);
err = request_irq(dev->dev->irq, bcm43xx_interrupt_handler,
IRQF_SHARED, KBUILD_MODNAME, dev);
if (err) {
- printk(KERN_ERR PFX "Cannot request IRQ-%d\n",
+ bcmerr(dev->wl, "Cannot request IRQ-%d\n",
dev->dev->irq);
goto out;
}
- dev->started = 1;
bcm43xx_interrupt_enable(dev, dev->irq_savedstate);
bcm43xx_mac_enable(dev);
- ieee80211_start_queues(wl->hw);
bcm43xx_periodic_tasks_setup(dev);
- dprintk(KERN_INFO PFX "Wireless interface started\n");
+
+ ieee80211_start_queues(dev->wl->hw);
+ bcm43xx_set_status(dev, BCM43xx_STAT_STARTED);
+ bcmdbg(dev->wl, "Wireless interface started\n");
out:
return err;
}
@@ -3018,13 +3060,13 @@ static int bcm43xx_phy_versioning(struct
unsupported = 1;
};
if (unsupported) {
- printk(KERN_ERR PFX "FOUND UNSUPPORTED PHY "
+ bcmerr(dev->wl, "FOUND UNSUPPORTED PHY "
"(Analog %u, Type %u, Revision %u)\n",
analog_type, phy_type, phy_rev);
return -EOPNOTSUPP;
}
- dprintk(KERN_INFO PFX "Found PHY: Analog %u, Type %u, Revision %u\n",
- analog_type, phy_type, phy_rev);
+ bcmdbg(dev->wl, "Found PHY: Analog %u, Type %u, Revision %u\n",
+ analog_type, phy_type, phy_rev);
/* Get RADIO versioning */
@@ -3068,13 +3110,13 @@ static int bcm43xx_phy_versioning(struct
assert(0);
}
if (unsupported) {
- printk(KERN_ERR PFX "FOUND UNSUPPORTED RADIO "
+ bcmerr(dev->wl, "FOUND UNSUPPORTED RADIO "
"(Manuf 0x%X, Version 0x%X, Revision %u)\n",
radio_manuf, radio_ver, radio_rev);
return -EOPNOTSUPP;
}
- dprintk(KERN_INFO PFX "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
- radio_manuf, radio_ver, radio_rev);
+ bcmdbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
+ radio_manuf, radio_ver, radio_rev);
phy->radio_manuf = radio_manuf;
@@ -3205,6 +3247,7 @@ static void bcm43xx_wireless_core_exit(s
{
struct bcm43xx_phy *phy = &dev->phy;
+ assert(bcm43xx_status(dev) <= BCM43xx_STAT_INITIALIZED);
if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED)
return;
@@ -3234,7 +3277,6 @@ static int bcm43xx_wireless_core_init(st
u32 hf, tmp;
assert(bcm43xx_status(dev) == BCM43xx_STAT_UNINIT);
- bcm43xx_set_status(dev, BCM43xx_STAT_INITIALIZING);
err = ssb_bus_powerup(bus, 0);
if (err)
@@ -3355,7 +3397,7 @@ err_kfree_lo_control:
phy->lo_control = NULL;
err_busdown:
ssb_bus_may_powerdown(bus);
- bcm43xx_set_status(dev, BCM43xx_STAT_UNINIT);
+ assert(bcm43xx_status(dev) == BCM43xx_STAT_UNINIT);
return err;
}
@@ -3373,16 +3415,16 @@ static int bcm43xx_add_interface(struct
wl->operating)
goto out_mutex_unlock;
- dprintk(KERN_INFO PFX "Adding Interface type %d\n", conf->type);
+ bcmdbg(wl, "Adding Interface type %d\n", conf->type);
dev = wl->current_dev;
- if (bcm43xx_status(dev) == BCM43xx_STAT_UNINIT) {
+ if (bcm43xx_status(dev) < BCM43xx_STAT_INITIALIZED) {
err = bcm43xx_wireless_core_init(dev);
if (err)
goto out_mutex_unlock;
did_init = 1;
}
- if (!dev->started) {
+ if (bcm43xx_status(dev) < BCM43xx_STAT_STARTED) {
err = bcm43xx_wireless_core_start(dev);
if (err) {
if (did_init)
@@ -3419,7 +3461,7 @@ static void bcm43xx_remove_interface(str
struct bcm43xx_wldev *dev;
unsigned long flags;
- dprintk(KERN_INFO PFX "Removing Interface type %d\n", conf->type);
+ bcmdbg(wl, "Removing Interface type %d\n", conf->type);
mutex_lock(&wl->mutex);
if (conf->type == IEEE80211_IF_TYPE_MNTR) {
@@ -3433,7 +3475,7 @@ static void bcm43xx_remove_interface(str
dev = wl->current_dev;
if (!wl->operating && wl->monitor == 0) {
/* No interface left. */
- if (dev->started)
+ if (bcm43xx_status(dev) >= BCM43xx_STAT_STARTED)
bcm43xx_wireless_core_stop(dev);
bcm43xx_wireless_core_exit(dev);
} else {
@@ -3470,30 +3512,25 @@ static void bcm43xx_chip_reset(struct wo
struct bcm43xx_wldev *dev =
container_of(work, struct bcm43xx_wldev, restart_work);
struct bcm43xx_wl *wl = dev->wl;
- int err;
- int was_started = 0;
- int was_inited = 0;
+ int err = 0;
+ int prev_status;
mutex_lock(&wl->mutex);
+ prev_status = bcm43xx_status(dev);
/* Bring the device down... */
- if (dev->started) {
- was_started = 1;
+ if (prev_status >= BCM43xx_STAT_STARTED)
bcm43xx_wireless_core_stop(dev);
- }
- if (bcm43xx_status(dev) == BCM43xx_STAT_INITIALIZED) {
- was_inited = 1;
+ if (prev_status >= BCM43xx_STAT_INITIALIZED)
bcm43xx_wireless_core_exit(dev);
- }
/* ...and up again. */
- if (was_inited) {
+ if (prev_status >= BCM43xx_STAT_INITIALIZED) {
err = bcm43xx_wireless_core_init(dev);
if (err)
goto out;
}
- if (was_started) {
- assert(was_inited);
+ if (prev_status >= BCM43xx_STAT_STARTED) {
err = bcm43xx_wireless_core_start(dev);
if (err) {
bcm43xx_wireless_core_exit(dev);
@@ -3503,9 +3540,9 @@ static void bcm43xx_chip_reset(struct wo
out:
mutex_unlock(&wl->mutex);
if (err)
- printk(KERN_ERR PFX "Controller restart FAILED\n");
+ bcmerr(wl, "Controller restart FAILED\n");
else
- printk(KERN_INFO PFX "Controller restarted\n");
+ bcminfo(wl, "Controller restarted\n");
}
static int bcm43xx_setup_modes(struct bcm43xx_wldev *dev,
@@ -3718,7 +3755,7 @@ static int bcm43xx_one_core_attach(struc
((pdev->device != 0x4321) &&
(pdev->device != 0x4313) &&
(pdev->device != 0x431A))) {
- dprintk(KERN_INFO PFX "Ignoring unconnected 802.11 core\n");
+ bcmdbg(wl, "Ignoring unconnected 802.11 core\n");
return -ENODEV;
}
}
@@ -3792,7 +3829,7 @@ static int bcm43xx_wireless_init(struct
hw = ieee80211_alloc_hw(sizeof(*wl), &bcm43xx_hw_ops);
if (!hw) {
- printk(KERN_ERR PFX "Could not allocate ieee80211 device\n");
+ bcmerr(NULL, "Could not allocate ieee80211 device\n");
goto out;
}
@@ -3821,7 +3858,7 @@ static int bcm43xx_wireless_init(struct
INIT_LIST_HEAD(&wl->devlist);
ssb_set_devtypedata(dev, wl);
- printk(KERN_INFO PFX "Broadcom %04X WLAN found\n", dev->bus->chip_id);
+ bcminfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
err = 0;
out:
return err;
@@ -3892,7 +3929,7 @@ void bcm43xx_controller_restart(struct b
{
if (bcm43xx_status(dev) != BCM43xx_STAT_INITIALIZED)
return;
- printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
+ bcminfo(dev->wl, "Controller RESET (%s) ...\n", reason);
queue_work(dev->wl->hw->workqueue, &dev->restart_work);
}
@@ -3903,19 +3940,17 @@ static int bcm43xx_suspend(struct ssb_de
struct bcm43xx_wldev *wldev = ssb_get_drvdata(dev);
struct bcm43xx_wl *wl = wldev->wl;
- dprintk(KERN_INFO PFX "Suspending...\n");
+ bcmdbg(wl, "Suspending...\n");
mutex_lock(&wl->mutex);
- wldev->was_started = !!wldev->started;
- wldev->was_initialized = (bcm43xx_status(wldev) == BCM43xx_STAT_INITIALIZED);
- if (wldev->started)
+ wldev->suspend_init_status = bcm43xx_status(wldev);
+ if (wldev->suspend_init_status >= BCM43xx_STAT_STARTED)
bcm43xx_wireless_core_stop(wldev);
- if (bcm43xx_status(wldev) == BCM43xx_STAT_INITIALIZED)
+ if (wldev->suspend_init_status >= BCM43xx_STAT_INITIALIZED)
bcm43xx_wireless_core_exit(wldev);
-
mutex_unlock(&wl->mutex);
- dprintk(KERN_INFO PFX "Device suspended.\n");
+ bcmdbg(wl, "Device suspended.\n");
return 0;
}
@@ -3923,27 +3958,30 @@ static int bcm43xx_suspend(struct ssb_de
static int bcm43xx_resume(struct ssb_device *dev)
{
struct bcm43xx_wldev *wldev = ssb_get_drvdata(dev);
+ struct bcm43xx_wl *wl = wldev->wl;
int err = 0;
- dprintk(KERN_INFO PFX "Resuming...\n");
+ bcmdbg(wl, "Resuming...\n");
- if (wldev->was_initialized) {
+ mutex_lock(&wl->mutex);
+ if (wldev->suspend_init_status >= BCM43xx_STAT_INITIALIZED) {
err = bcm43xx_wireless_core_init(wldev);
if (err) {
- printk(KERN_ERR PFX "Resume failed at core init\n");
+ bcmerr(wl, "Resume failed at core init\n");
goto out;
}
}
- if (wldev->was_started) {
- assert(wldev->was_initialized);
+ if (wldev->suspend_init_status >= BCM43xx_STAT_STARTED) {
err = bcm43xx_wireless_core_start(wldev);
if (err) {
- printk(KERN_ERR PFX "Resume failed at core start\n");
+ bcm43xx_wireless_core_exit(wldev);
+ bcmerr(wl, "Resume failed at core start\n");
goto out;
}
}
+ mutex_unlock(&wl->mutex);
- dprintk(KERN_INFO PFX "Device resumed.\n");
+ bcmdbg(wl, "Device resumed.\n");
out:
return err;
}
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.c
index 53a34f6..24855d6 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.c
@@ -248,7 +248,8 @@ void bcm43xx_raw_phy_unlock(struct bcm43
* This adjusts (and does sanity checks on) the routing flags.
*/
static inline u16 adjust_phyreg_for_phytype(struct bcm43xx_phy *phy,
- u16 offset)
+ u16 offset,
+ struct bcm43xx_wldev *dev)
{
if (phy->type == BCM43xx_PHYTYPE_A) {
/* OFDM registers are base-registers for the A-PHY. */
@@ -257,9 +258,9 @@ static inline u16 adjust_phyreg_for_phyt
if (offset & BCM43xx_PHYROUTE_EXT_GPHY) {
/* Ext-G registers are only available on G-PHYs */
if (phy->type != BCM43xx_PHYTYPE_G) {
- dprintk(KERN_ERR PFX "EXT-G PHY access at "
- "0x%04X on %u type PHY\n",
- offset, phy->type);
+ bcmdbg(dev->wl, "EXT-G PHY access at "
+ "0x%04X on %u type PHY\n",
+ offset, phy->type);
}
}
@@ -270,7 +271,7 @@ u16 bcm43xx_phy_read(struct bcm43xx_wlde
{
struct bcm43xx_phy *phy = &dev->phy;
- offset = adjust_phyreg_for_phytype(phy, offset);
+ offset = adjust_phyreg_for_phytype(phy, offset, dev);
bcm43xx_write16(dev, BCM43xx_MMIO_PHY_CONTROL, offset);
return bcm43xx_read16(dev, BCM43xx_MMIO_PHY_DATA);
}
@@ -279,7 +280,7 @@ void bcm43xx_phy_write(struct bcm43xx_wl
{
struct bcm43xx_phy *phy = &dev->phy;
- offset = adjust_phyreg_for_phytype(phy, offset);
+ offset = adjust_phyreg_for_phytype(phy, offset, dev);
bcm43xx_write16(dev, BCM43xx_MMIO_PHY_CONTROL, offset);
mmiowb();
bcm43xx_write16(dev, BCM43xx_MMIO_PHY_DATA, val);
@@ -311,10 +312,10 @@ void bcm43xx_set_txpower_g(struct bcm43x
memcpy(&phy->bbatt, bbatt, sizeof(*bbatt));
if (bcm43xx_debug(dev, BCM43xx_DBG_XMITPOWER)) {
- dprintk(KERN_DEBUG PFX "Tuning TX-power to bbatt(%u), "
- "rfatt(%u), tx_control(0x%02X), "
- "tx_bias(0x%02X), tx_magn(0x%02X)\n",
- bb, rf, tx_control, tx_bias, tx_magn);
+ bcmdbg(dev->wl, "Tuning TX-power to bbatt(%u), "
+ "rfatt(%u), tx_control(0x%02X), "
+ "tx_bias(0x%02X), tx_magn(0x%02X)\n",
+ bb, rf, tx_control, tx_bias, tx_magn);
}
bcm43xx_phy_set_baseband_attenuation(dev, bb);
@@ -739,9 +740,9 @@ static void bcm43xx_phy_init_pctl(struct
if (BCM43xx_DEBUG) {
/* Current-Idle-TSSI sanity check. */
if (abs(phy->cur_idle_tssi - phy->tgt_idle_tssi) >= 20) {
- dprintk(KERN_ERR PFX "!WARNING! Idle-TSSI phy->cur_idle_tssi "
- "measuring failed. (cur=%d, tgt=%d). Disabling TX power "
- "adjustment.\n", phy->cur_idle_tssi, phy->tgt_idle_tssi);
+ bcmdbg(dev->wl, "!WARNING! Idle-TSSI phy->cur_idle_tssi "
+ "measuring failed. (cur=%d, tgt=%d). Disabling TX power "
+ "adjustment.\n", phy->cur_idle_tssi, phy->tgt_idle_tssi);
phy->cur_idle_tssi = 0;
}
}
@@ -957,12 +958,8 @@ static void bcm43xx_phy_setupg(struct bc
if (phy->rev == 1) {
for (i = 0; i < BCM43xx_TAB_RETARD_SIZE; i++)
bcm43xx_ofdmtab_write32(dev, 0x2400, i, bcm43xx_tab_retard[i]);
- for (i = 0; i < 4; i++) {
- bcm43xx_ofdmtab_write16(dev, 0x5404, i, 0x0020);
- bcm43xx_ofdmtab_write16(dev, 0x5408, i, 0x0020);
- bcm43xx_ofdmtab_write16(dev, 0x540C, i, 0x0020);
- bcm43xx_ofdmtab_write16(dev, 0x5410, i, 0x0020);
- }
+ for (i = 4; i < 20; i++)
+ bcm43xx_ofdmtab_write16(dev, 0x5400, i, 0x0020);
bcm43xx_phy_agcsetup(dev);
if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
@@ -973,7 +970,7 @@ static void bcm43xx_phy_setupg(struct bc
bcm43xx_ofdmtab_write16(dev, 0x5001, 0, 0x0002);
bcm43xx_ofdmtab_write16(dev, 0x5002, 0, 0x0001);
} else {
- for (i = 0; i <= 0x2F; i++)
+ for (i = 0; i < 0x20; i++)
bcm43xx_ofdmtab_write16(dev, 0x1000, i, 0x0820);
bcm43xx_phy_agcsetup(dev);
bcm43xx_phy_read(dev, 0x0400); /* dummy read */
@@ -2065,7 +2062,7 @@ #endif
(phy->type == BCM43xx_PHYTYPE_G))
max_pwr -= 0x3;
if (unlikely(max_pwr <= 0)) {
- printk(KERN_ERR PFX "Invalid max-TX-power value in SPROM.\n");
+ bcmwarn(dev->wl, "Invalid max-TX-power value in SPROM.\n");
max_pwr = 60; /* fake it */
dev->dev->bus->sprom.r1.maxpwr_bg = max_pwr;
}
@@ -2079,10 +2076,9 @@ #endif
/* Convert the desired_pwr to Q5.2 and limit it. */
desired_pwr = limit_value((desired_pwr << 2), 0, max_pwr);
if (bcm43xx_debug(dev, BCM43xx_DBG_XMITPOWER)) {
- dprintk(KERN_DEBUG PFX
- "Current TX power output: " Q52_FMT " dBm, "
- "Desired TX power output: " Q52_FMT " dBm\n",
- Q52_ARG(estimated_pwr), Q52_ARG(desired_pwr));
+ bcmdbg(dev->wl, "Current TX power output: " Q52_FMT " dBm, "
+ "Desired TX power output: " Q52_FMT " dBm\n",
+ Q52_ARG(estimated_pwr), Q52_ARG(desired_pwr));
}
pwr_adjust = desired_pwr - estimated_pwr;
@@ -2210,15 +2206,15 @@ int bcm43xx_phy_init_tssi2dbm_table(stru
}
dyn_tssi2dbm = kmalloc(64, GFP_KERNEL);
if (dyn_tssi2dbm == NULL) {
- printk(KERN_ERR PFX "Could not allocate memory"
- "for tssi2dbm table\n");
+ bcmerr(dev->wl, "Could not allocate memory"
+ "for tssi2dbm table\n");
return -ENOMEM;
}
for (idx = 0; idx < 64; idx++)
if (bcm43xx_tssi2dbm_entry(dyn_tssi2dbm, idx, pab0, pab1, pab2)) {
phy->tssi2dbm = NULL;
- printk(KERN_ERR PFX "Could not generate "
- "tssi2dBm table\n");
+ bcmerr(dev->wl, "Could not generate "
+ "tssi2dBm table\n");
kfree(dyn_tssi2dbm);
return -ENODEV;
}
@@ -2230,8 +2226,8 @@ int bcm43xx_phy_init_tssi2dbm_table(stru
case BCM43xx_PHYTYPE_A:
/* APHY needs a generated table. */
phy->tssi2dbm = NULL;
- printk(KERN_ERR PFX "Could not generate tssi2dBm "
- "table (wrong SPROM info)!\n");
+ bcmerr(dev->wl, "Could not generate tssi2dBm "
+ "table (wrong SPROM info)!\n");
return -ENODEV;
case BCM43xx_PHYTYPE_B:
phy->tgt_idle_tssi = 0x34;
@@ -2285,7 +2281,7 @@ int bcm43xx_phy_init(struct bcm43xx_wlde
break;
}
if (err)
- printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n");
+ bcmerr(dev->wl, "Unknown PHYTYPE found\n");
return err;
}
@@ -4342,7 +4338,7 @@ void bcm43xx_radio_turn_on(struct bcm43x
assert(0);
}
phy->radio_on = 1;
- dprintk(KERN_INFO PFX "Radio turned on\n");
+ bcmdbg(dev->wl, "Radio turned on\n");
}
void bcm43xx_radio_turn_off(struct bcm43xx_wldev *dev)
@@ -4361,5 +4357,5 @@ void bcm43xx_radio_turn_off(struct bcm43
} else
bcm43xx_phy_write(dev, 0x0015, 0xAA00);
phy->radio_on = 0;
- dprintk(KERN_INFO PFX "Radio turned off\n");
+ bcmdbg(dev->wl, "Radio turned off\n");
}
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.h
index 75cea5a..8660103 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_phy.h
@@ -232,8 +232,8 @@ #define has_loopback_gain(phy) \
/* Radio Attenuation (RF Attenuation) */
struct bcm43xx_rfatt {
- u8 att; /* Attenuation value */
- u8 with_padmix; /* Flag, PAD Mixer enabled. */
+ u8 att; /* Attenuation value */
+ bool with_padmix; /* Flag, PAD Mixer enabled. */
};
struct bcm43xx_rfatt_list {
/* Attenuation values list */
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.c
index 3ae5ef5..16779c2 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.c
@@ -231,8 +231,8 @@ static int pio_tx_packet(struct bcm43xx_
octets = (u16)skb->len + sizeof(struct bcm43xx_txhdr_fw4);
if (queue->tx_devq_size < octets) {
- printkl(KERN_WARNING PFX "PIO queue too small. "
- "Dropping packet.\n");
+ bcmwarn(queue->dev->wl, "PIO queue too small. "
+ "Dropping packet.\n");
/* Drop it silently (return success) */
free_txpacket(packet, 1);
return 0;
@@ -340,13 +340,13 @@ struct bcm43xx_pioqueue * bcm43xx_setup_
qsize = bcm43xx_read16(dev, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE);
if (qsize == 0) {
- printk(KERN_ERR PFX "ERROR: This card does not support PIO "
- "operation mode. Please use DMA mode "
- "(module parameter pio=0).\n");
+ bcmerr(dev->wl, "This card does not support PIO "
+ "operation mode. Please use DMA mode "
+ "(module parameter pio=0).\n");
goto err_freequeue;
}
if (qsize <= BCM43xx_PIO_TXQADJUST) {
- printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n",
+ bcmerr(dev->wl, "PIO tx device-queue too small (%u)\n",
qsize);
goto err_freequeue;
}
@@ -432,7 +432,7 @@ int bcm43xx_pio_init(struct bcm43xx_wlde
if (dev->dev->id.revision < 3)
dev->irq_savedstate |= BCM43xx_IRQ_PIO_WORKAROUND;
- dprintk(KERN_INFO PFX "PIO initialized\n");
+ bcmdbg(dev->wl, "PIO initialized\n");
err = 0;
out:
return err;
@@ -522,7 +522,7 @@ static void pio_rx_error(struct bcm43xx_
{
int i;
- printkl("PIO RX error: %s\n", error);
+ bcmerr(queue->dev->wl, "PIO RX error: %s\n", error);
bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
BCM43xx_PIO_RXCTL_READY);
if (clear_buffers) {
@@ -554,7 +554,7 @@ void bcm43xx_pio_rx(struct bcm43xx_pioqu
goto data_ready;
udelay(10);
}
- dprintkl(KERN_ERR PFX "PIO RX timed out\n");
+ bcmdbg(queue->dev->wl, "PIO RX timed out\n");
return;
data_ready:
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.h
index b9d919b..9d112f0 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.h
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_pio.h
@@ -51,9 +51,9 @@ struct bcm43xx_pioqueue {
struct bcm43xx_wldev *dev;
u16 mmio_base;
- u8 tx_suspended:1,
- tx_frozen:1,
- need_workarounds:1; /* Workarounds needed for core.rev < 3 */
+ bool tx_suspended;
+ bool tx_frozen;
+ bool need_workarounds; /* Workarounds needed for core.rev < 3 */
/* Adjusted size of the device internal TX buffer. */
u16 tx_devq_size;
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c
index eed688f..611f688 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_sysfs.c
@@ -137,8 +137,8 @@ static ssize_t bcm43xx_attr_interfmode_s
err = bcm43xx_radio_set_interference_mitigation(wldev, mode);
if (err) {
- printk(KERN_ERR PFX "Interference Mitigation not "
- "supported by device\n");
+ bcmerr(wldev->wl, "Interference Mitigation not "
+ "supported by device\n");
}
mmiowb();
spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
diff --git a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c
index 469c9e0..8ca35d2 100644
--- a/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c
+++ b/drivers/net/wireless/bcm43xx-mac80211/bcm43xx_xmit.c
@@ -467,12 +467,19 @@ void bcm43xx_rx(struct bcm43xx_wldev *de
/* Skip PLCP and padding */
padding = (macstat & BCM43xx_RX_MAC_PADDING) ? 2 : 0;
+ if (unlikely(skb->len < (sizeof(struct bcm43xx_plcp_hdr6) + padding))) {
+ bcmdbg(dev->wl, "RX: Packet size underrun (1)\n");
+ goto drop;
+ }
plcp = (struct bcm43xx_plcp_hdr6 *)(skb->data + padding);
skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6) + padding);
/* The skb contains the Wireless Header + payload data now */
+ if (unlikely(skb->len < (2+2+6/*minimum hdr*/ + FCS_LEN))) {
+ bcmdbg(dev->wl, "RX: Packet size underrun (2)\n");
+ goto drop;
+ }
wlhdr = (struct ieee80211_hdr *)(skb->data);
fctl = le16_to_cpu(wlhdr->frame_control);
-
skb_trim(skb, skb->len - FCS_LEN);
if ((macstat & BCM43xx_RX_MAC_DEC) &&
@@ -497,6 +504,10 @@ void bcm43xx_rx(struct bcm43xx_wldev *de
wlhdr->frame_control = cpu_to_le16(fctl);
wlhdr_len = ieee80211_get_hdrlen(fctl);
+ if (unlikely(skb->len < (wlhdr_len + 3))) {
+ bcmdbg(dev->wl, "RX: Packet size underrun (3)\n");
+ goto drop;
+ }
if (skb->data[wlhdr_len + 3] & (1 << 5)) {
/* The Ext-IV Bit is set in the "KeyID"
* octet of the IV.
@@ -507,7 +518,10 @@ void bcm43xx_rx(struct bcm43xx_wldev *de
iv_len = 4;
icv_len = 4;
}
-
+ if (unlikely(skb->len < (wlhdr_len + iv_len + icv_len))) {
+ bcmdbg(dev->wl, "RX: Packet size underrun (4)\n");
+ goto drop;
+ }
/* Remove the IV */
memmove(skb->data + iv_len, skb->data, wlhdr_len);
skb_pull(skb, iv_len);
@@ -554,6 +568,11 @@ void bcm43xx_rx(struct bcm43xx_wldev *de
dev->stats.last_rx = jiffies;
ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
+
+ return;
+drop:
+ bcmdbg(dev->wl, "RX: Packet dropped\n");
+ dev_kfree_skb_any(skb);
}
void bcm43xx_handle_txstatus(struct bcm43xx_wldev *dev,
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index 03c4945..34a9411 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -58,7 +58,6 @@ config SSB_SERIAL
config SSB_DRIVER_PCICORE
bool "SSB PCI core driver"
depends on SSB && SSB_PCIHOST
- default y
help
Driver for the Sonics Silicon Backplane attached
Broadcom PCI core.
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
index 9a2b379..045aff0 100644
--- a/drivers/ssb/Makefile
+++ b/drivers/ssb/Makefile
@@ -1,11 +1,13 @@
-ssb-builtin-drivers-y += driver_chipcommon.o
-ssb-builtin-drivers-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o
-ssb-builtin-drivers-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
+# core
+ssb-y += main.o scan.o
-ssb-hostsupport-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o
-ssb-hostsupport-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o
+# host support
+ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o
+ssb-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o
-obj-$(CONFIG_SSB) += ssb.o
+# built-in drivers
+ssb-y += driver_chipcommon.o
+ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o
+ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
-ssb-objs := main.o scan.o \
- $(ssb-hostsupport-y) $(ssb-builtin-drivers-y)
+obj-$(CONFIG_SSB) += ssb.o
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index a283de9..8e5491c 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -16,7 +16,7 @@ #include "ssb_private.h"
/* Clock sources */
-enum {
+enum ssb_clksrc {
/* PCI clock */
SSB_CHIPCO_CLKSRC_PCI,
/* Crystal slow clock oscillator */
@@ -85,15 +85,15 @@ void ssb_chipco_set_clockmode(struct ssb
ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
break;
default:
- assert(0);
+ SSB_WARN_ON(1);
}
}
/* Get the Slow Clock Source */
-static int chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc)
+static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc)
{
struct ssb_bus *bus = cc->dev->bus;
- u32 tmp = 0;
+ u32 uninitialized_var(tmp);
if (cc->dev->id.revision < 6) {
if (bus->bustype == SSB_BUSTYPE_SSB ||
@@ -123,9 +123,9 @@ static int chipco_pctl_get_slowclksrc(st
/* Get maximum or minimum (depending on get_max flag) slowclock frequency. */
static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max)
{
- int limit;
- int clocksrc;
- int divisor;
+ int uninitialized_var(limit);
+ enum ssb_clksrc clocksrc;
+ int divisor = 1;
u32 tmp;
clocksrc = chipco_pctl_get_slowclksrc(cc);
@@ -138,13 +138,11 @@ static int chipco_pctl_clockfreqlimit(st
divisor = 32;
break;
default:
- assert(0);
- divisor = 1;
+ SSB_WARN_ON(1);
}
} else if (cc->dev->id.revision < 10) {
switch (clocksrc) {
case SSB_CHIPCO_CLKSRC_LOPWROS:
- divisor = 1;
break;
case SSB_CHIPCO_CLKSRC_XTALOS:
case SSB_CHIPCO_CLKSRC_PCI:
@@ -152,9 +150,6 @@ static int chipco_pctl_clockfreqlimit(st
divisor = (tmp >> 16) + 1;
divisor *= 4;
break;
- default:
- assert(0);
- divisor = 1;
}
} else {
tmp = chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL);
@@ -181,9 +176,6 @@ static int chipco_pctl_clockfreqlimit(st
else
limit = 25000000;
break;
- default:
- assert(0);
- limit = 0;
}
limit /= divisor;
@@ -235,7 +227,7 @@ static void calc_fast_powerup_delay(stru
minfreq = chipco_pctl_clockfreqlimit(cc, 0);
pll_on_delay = chipco_read32(cc, SSB_CHIPCO_PLLONDELAY);
tmp = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq;
- assert((tmp & ~0xFFFF) == 0);
+ SSB_WARN_ON(tmp & ~0xFFFF);
cc->fast_pwrup_delay = tmp;
}
@@ -355,7 +347,7 @@ int ssb_chipco_serial_init(struct ssb_ch
div = 2; /* Minimum divisor */
chipco_write32(cc, SSB_CHIPCO_CLKDIV,
(chipco_read32(cc, SSB_CHIPCO_CLKDIV)
- & ~SSB_CHIPCO_CLKDIV_UART) | div);
+ & ~SSB_CHIPCO_CLKDIV_UART) | div);
} else {
/* Fixed internal backplane clock */
baud_base = 88000000;
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index 67d1017..3f09598 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -13,7 +13,7 @@ #include <linux/ssb/ssb.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
-#include <asm/time.h>
+#include <linux/time.h>
#include "ssb_private.h"
@@ -224,7 +224,6 @@ #if 0
tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
W_REG(&eir->prog_waitcount, tmp);
}
- else... chipcommon
#endif
if (bus->chipco.dev)
ssb_chipco_timing_init(&bus->chipco, ns);
@@ -233,23 +232,24 @@ #endif
for (irq = 2, i = 0; i < bus->nr_devices; i++) {
dev = &(bus->devices[i]);
dev->irq = ssb_mips_irq(dev) + 2;
- switch(dev->id.coreid) {
- case SSB_DEV_USB11_HOST:
- /* shouldn't need a separate irq line for non-4710, most of them have a proper
- * external usb controller on the pci */
- if ((bus->chip_id == 0x4710) && (irq <= 4)) {
- set_irq(dev, irq++);
- break;
- }
- case SSB_DEV_PCI:
- case SSB_DEV_ETHERNET:
- case SSB_DEV_80211:
- case SSB_DEV_USB20_HOST:
- /* These devices get their own IRQ line if available, the rest goes on IRQ0 */
- if (irq <= 4) {
- set_irq(dev, irq++);
- break;
- }
+ switch (dev->id.coreid) {
+ case SSB_DEV_USB11_HOST:
+ /* shouldn't need a separate irq line for non-4710, most of them have a proper
+ * external usb controller on the pci */
+ if ((bus->chip_id == 0x4710) && (irq <= 4)) {
+ set_irq(dev, irq++);
+ break;
+ }
+ /* fallthrough */
+ case SSB_DEV_PCI:
+ case SSB_DEV_ETHERNET:
+ case SSB_DEV_80211:
+ case SSB_DEV_USB20_HOST:
+ /* These devices get their own IRQ line if available, the rest goes on IRQ0 */
+ if (irq <= 4) {
+ set_irq(dev, irq++);
+ break;
+ }
}
}
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index 841847b..76a9a51 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -34,8 +34,10 @@ void pcicore_write32(struct ssb_pcicore
#ifdef CONFIG_SSB_PCICORE_HOSTMODE
#include <asm/paccess.h>
-/* Read the bus and catch bus exceptions. This is MIPS specific. */
-#define mips_busprobe(val, addr) get_dbe((val), (addr))
+/* Probe a 32bit value on the bus and catch bus exceptions.
+ * Returns nonzero on a bus exception.
+ * This is MIPS specific */
+#define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr)))
/* Assume one-hot slot wiring */
#define SSB_PCI_SLOT_MAX 16
@@ -54,7 +56,8 @@ int pcibios_plat_dev_init(struct pci_dev
int pos, size;
u32 *base;
- printk("PCI: Fixing up device %s\n", pci_name(d));
+ ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
+ pci_name(d));
/* Fix up resource bases */
for (pos = 0; pos < 6; pos++) {
@@ -85,7 +88,7 @@ static void __init ssb_fixup_pcibridge(s
if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
return;
- printk("PCI: fixing up bridge\n");
+ ssb_printk(KERN_INFO "PCI: fixing up bridge\n");
/* Enable PCI bridge bus mastering and memory space */
pci_set_master(dev);
@@ -147,7 +150,7 @@ static int ssb_extpci_read_config(struct
u32 addr, val;
void __iomem *mmio;
- assert(pc->hostmode);
+ SSB_WARN_ON(!pc->hostmode);
if (unlikely(len != 1 && len != 2 && len != 4))
goto out;
addr = get_cfgspace_addr(pc, bus, dev, func, off);
@@ -158,7 +161,7 @@ static int ssb_extpci_read_config(struct
if (!mmio)
goto out;
- if (mips_busprobe(val, (u32 *) mmio)) {
+ if (mips_busprobe32(val, mmio)) {
val = 0xffffffff;
goto unmap;
}
@@ -193,7 +196,7 @@ static int ssb_extpci_write_config(struc
u32 addr, val = 0;
void __iomem *mmio;
- assert(pc->hostmode);
+ SSB_WARN_ON(!pc->hostmode);
if (unlikely(len != 1 && len != 2 && len != 4))
goto out;
addr = get_cfgspace_addr(pc, bus, dev, func, off);
@@ -204,7 +207,7 @@ static int ssb_extpci_write_config(struc
if (!mmio)
goto out;
- if (mips_busprobe(val, (u32 *) mmio)) {
+ if (mips_busprobe32(val, mmio)) {
val = 0xffffffff;
goto unmap;
}
@@ -291,10 +294,8 @@ static void ssb_pcicore_init_hostmode(st
{
u32 val;
- if (extpci_core) {
- WARN_ON(1);
+ if (WARN_ON(extpci_core))
return;
- }
extpci_core = pc;
ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n");
@@ -364,7 +365,7 @@ static int pcicore_is_in_hostmode(struct
if (bus->chip_id == 0x5350)
return 0;
- return !mips_busprobe(tmp, (u32 *) (bus->mmio + (pc->dev->core_index * SSB_CORE_SIZE)));
+ return !mips_busprobe32(tmp, (bus->mmio + (pc->dev->core_index * SSB_CORE_SIZE)));
}
#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
@@ -458,7 +459,8 @@ static void ssb_commit_settings(struct s
struct ssb_device *dev;
dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
- assert(dev);
+ if (WARN_ON(!dev))
+ return;
/* This forces an update of the cached registers. */
ssb_broadcast_value(dev, 0xFD8, 0);
}
@@ -531,7 +533,7 @@ int ssb_pcicore_dev_irqvecs_enable(struc
pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
}
} else {
- assert(pdev->id.coreid == SSB_DEV_PCIE);
+ WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
//TODO: Better make defines for all these magic PCIE values.
if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
/* TLP Workaround register. */
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index f84ee37..9cc4985 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -14,27 +14,36 @@ #include <linux/delay.h>
#include <linux/ssb/ssb.h>
#include <linux/ssb/ssb_regs.h>
-#ifdef CONFIG_SSB_PCIHOST
-# include <linux/pci.h>
-#endif
+#include <linux/pci.h>
-#ifdef CONFIG_SSB_PCMCIAHOST
-# include <pcmcia/cs_types.h>
-# include <pcmcia/cs.h>
-# include <pcmcia/cistpl.h>
-# include <pcmcia/ds.h>
-#endif
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
MODULE_DESCRIPTION("Sonics Silicon Backplane driver");
MODULE_LICENSE("GPL");
+/* Temporary list of yet-to-be-attached buses */
static LIST_HEAD(attach_queue);
+/* List if running buses */
static LIST_HEAD(buses);
-static int nr_buses;
+/* Software ID counter */
+static unsigned int next_busnumber;
+/* buses_mutes locks the two buslists and the next_busnumber.
+ * Don't lock this directly, but use ssb_buses_[un]lock() below. */
static DEFINE_MUTEX(buses_mutex);
+/* There are differences in the codeflow, if the bus is
+ * initialized from early boot, as various needed services
+ * are not available early. This is a mechanism to delay
+ * these initializations to after early boot has finished.
+ * It's also used to avoid mutex locking, as that's not
+ * available and needed early. */
+static bool ssb_is_early_boot = 1;
+
static void ssb_buses_lock(void);
static void ssb_buses_unlock(void);
@@ -272,7 +281,7 @@ static int ssb_bus_match(struct device *
}
static struct bus_type ssb_bustype = {
- .name = NULL, /* Intentionally NULL to indicate early boot */
+ .name = "ssb",
.match = ssb_bus_match,
.probe = ssb_device_probe,
.remove = ssb_device_remove,
@@ -281,17 +290,15 @@ static struct bus_type ssb_bustype = {
.resume = ssb_device_resume,
};
-#define is_early_boot() (ssb_bustype.name == NULL)
-
static void ssb_buses_lock(void)
{
- if (!is_early_boot())
+ if (!ssb_is_early_boot)
mutex_lock(&buses_mutex);
}
static void ssb_buses_unlock(void)
{
- if (!is_early_boot())
+ if (!ssb_is_early_boot)
mutex_unlock(&buses_mutex);
}
@@ -365,7 +372,7 @@ static int ssb_devices_register(struct s
dev->release = ssb_release_dev;
dev->bus = &ssb_bustype;
snprintf(dev->bus_id, sizeof(dev->bus_id),
- "ssb%d:%d", bus->busnumber, dev_idx);
+ "ssb%u:%d", bus->busnumber, dev_idx);
switch (bus->bustype) {
case SSB_BUSTYPE_PCI:
@@ -467,6 +474,7 @@ static void ssb_ssb_write32(struct ssb_d
writel(value, bus->mmio + offset);
}
+/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
static const struct ssb_bus_ops ssb_ssb_ops = {
.read16 = ssb_ssb_read16,
.read32 = ssb_ssb_read32,
@@ -475,12 +483,12 @@ static const struct ssb_bus_ops ssb_ssb_
};
static int ssb_fetch_invariants(struct ssb_bus *bus,
- int (*get_invariants)(struct ssb_bus *bus,
- struct ssb_init_invariants *iv))
+ ssb_invariants_func_t get_invariants)
{
struct ssb_init_invariants iv;
int err;
+ memset(&iv, 0, sizeof(iv));
err = get_invariants(bus, &iv);
if (err)
goto out;
@@ -491,8 +499,7 @@ out:
}
static int ssb_bus_register(struct ssb_bus *bus,
- int (*get_invariants)(struct ssb_bus *bus,
- struct ssb_init_invariants *iv),
+ ssb_invariants_func_t get_invariants,
unsigned long baseaddr)
{
int err;
@@ -505,7 +512,7 @@ static int ssb_bus_register(struct ssb_b
if (err)
goto out;
ssb_buses_lock();
- bus->busnumber = nr_buses;
+ bus->busnumber = next_busnumber;
/* Scan for devices (cores) */
err = ssb_bus_scan(bus, baseaddr);
if (err)
@@ -529,13 +536,13 @@ static int ssb_bus_register(struct ssb_b
/* Queue it for attach */
list_add_tail(&bus->list, &attach_queue);
- if (!is_early_boot()) {
+ if (!ssb_is_early_boot) {
/* This is not early boot, so we must attach the bus now */
err = ssb_attach_queued_buses();
if (err)
goto err_dequeue;
}
- nr_buses++;
+ next_busnumber++;
ssb_buses_unlock();
out:
@@ -600,8 +607,7 @@ #endif /* CONFIG_SSB_PCMCIAHOST */
int ssb_bus_ssbbus_register(struct ssb_bus *bus,
unsigned long baseaddr,
- int (*get_invariants)(struct ssb_bus *bus,
- struct ssb_init_invariants *iv))
+ ssb_invariants_func_t get_invariants)
{
int err;
@@ -694,13 +700,13 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
case SSB_PLLTYPE_2: /* 48Mhz, 4 dividers */
n1 += SSB_CHIPCO_CLK_T2_BIAS;
n2 += SSB_CHIPCO_CLK_T2_BIAS;
- assert((n1 >= 2) && (n1 <= 7));
- assert((n2 >= 5) && (n2 <= 23));
+ SSB_WARN_ON(!((n1 >= 2) && (n1 <= 7)));
+ SSB_WARN_ON(!((n2 >= 5) && (n2 <= 23)));
break;
case SSB_PLLTYPE_5: /* 25Mhz, 4 dividers */
return 100000000;
default:
- assert(0);
+ SSB_WARN_ON(1);
}
switch (plltype) {
@@ -749,9 +755,9 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
m1 += SSB_CHIPCO_CLK_T2_BIAS;
m2 += SSB_CHIPCO_CLK_T2M2_BIAS;
m3 += SSB_CHIPCO_CLK_T2_BIAS;
- assert((m1 >= 2) && (m1 <= 7));
- assert((m2 >= 3) && (m2 <= 10));
- assert((m3 >= 2) && (m3 <= 7));
+ SSB_WARN_ON(!((m1 >= 2) && (m1 <= 7)));
+ SSB_WARN_ON(!((m2 >= 3) && (m2 <= 10)));
+ SSB_WARN_ON(!((m3 >= 2) && (m3 <= 7)));
if (!(mc & SSB_CHIPCO_CLK_T2MC_M1BYP))
clock /= m1;
@@ -761,7 +767,7 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
clock /= m3;
return clock;
default:
- assert(0);
+ SSB_WARN_ON(1);
}
return 0;
}
@@ -803,7 +809,7 @@ static u32 ssb_tmslow_reject_bitmask(str
case SSB_IDLOW_SSBREV_23:
return SSB_TMSLOW_REJECT_23;
default:
- assert(0);
+ WARN_ON(1);
}
return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
}
@@ -912,7 +918,7 @@ EXPORT_SYMBOL(ssb_device_disable);
u32 ssb_dma_translation(struct ssb_device *dev)
{
- switch(dev->bus->bustype) {
+ switch (dev->bus->bustype) {
case SSB_BUSTYPE_SSB:
return 0;
case SSB_BUSTYPE_PCI:
@@ -963,7 +969,7 @@ error:
}
EXPORT_SYMBOL(ssb_bus_may_powerdown);
-int ssb_bus_powerup(struct ssb_bus *bus, int dynamic_pctl)
+int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
{
struct ssb_chipcommon *cc;
int err;
@@ -992,15 +998,15 @@ u32 ssb_admatch_base(u32 adm)
base = (adm & SSB_ADM_BASE0);
break;
case SSB_ADM_TYPE1:
- assert(!(adm & SSB_ADM_NEG)); /* unsupported */
+ SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
base = (adm & SSB_ADM_BASE1);
break;
case SSB_ADM_TYPE2:
- assert(!(adm & SSB_ADM_NEG)); /* unsupported */
+ SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
base = (adm & SSB_ADM_BASE2);
break;
default:
- assert(0);
+ SSB_WARN_ON(1);
}
return base;
@@ -1016,15 +1022,15 @@ u32 ssb_admatch_size(u32 adm)
size = ((adm & SSB_ADM_SZ0) >> SSB_ADM_SZ0_SHIFT);
break;
case SSB_ADM_TYPE1:
- assert(!(adm & SSB_ADM_NEG)); /* unsupported */
+ SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
size = ((adm & SSB_ADM_SZ1) >> SSB_ADM_SZ1_SHIFT);
break;
case SSB_ADM_TYPE2:
- assert(!(adm & SSB_ADM_NEG)); /* unsupported */
+ SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
size = ((adm & SSB_ADM_SZ2) >> SSB_ADM_SZ2_SHIFT);
break;
default:
- assert(0);
+ SSB_WARN_ON(1);
}
size = (1 << (size + 1));
@@ -1036,7 +1042,7 @@ static int __init ssb_modinit(void)
{
int err;
- ssb_bustype.name = "ssb";
+ ssb_is_early_boot = 0;
err = bus_register(&ssb_bustype);
if (err)
return err;
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index f9dc28f..6767fd2 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -23,6 +23,7 @@ #include <linux/delay.h>
#include "ssb_private.h"
+/* Lowlevel coreswitching */
int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
{
int err;
@@ -74,6 +75,7 @@ int ssb_pci_switch_core(struct ssb_bus *
return err;
}
+/* Enable/disable the on board crystal oscillator and/or PLL. */
int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
{
int err;
@@ -158,7 +160,9 @@ err_pci:
goto out;
}
+/* Get the word-offset for a SSB_SPROM_XXX define. */
#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16))
+/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
#define SPEX(_outvar, _offset, _mask, _shift) \
out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index b908563..f72afd8 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -112,7 +112,7 @@ int ssb_pcmcia_switch_segment(struct ssb
conf_reg_t reg;
int res, err = 0;
- assert(seg == 0 || seg == 1);
+ SSB_WARN_ON((seg != 0) && (seg != 1));
reg.Offset = 0x34;
reg.Function = 0;
spin_lock_irqsave(&bus->bar_lock, flags);
@@ -145,6 +145,9 @@ error:
goto out_unlock;
}
+/* These are the main device register access functions.
+ * do_select_core is inline to have the likely hotpath inline.
+ * All unlikely codepaths are out-of-line. */
static inline int do_select_core(struct ssb_bus *bus,
struct ssb_device *dev,
u16 *offset)
@@ -176,7 +179,7 @@ static u16 ssb_pcmcia_read16(struct ssb_
if (unlikely(do_select_core(bus, dev, &offset)))
return 0xFFFF;
x = readw(bus->mmio + offset);
-//printk("R16 0x%04X, 0x%04X\n", offset, x);
+
return x;
}
@@ -188,7 +191,7 @@ static u32 ssb_pcmcia_read32(struct ssb_
if (unlikely(do_select_core(bus, dev, &offset)))
return 0xFFFFFFFF;
x = readl(bus->mmio + offset);
-//printk("R32 0x%04X, 0x%08X\n", offset, x);
+
return x;
}
@@ -198,7 +201,6 @@ static void ssb_pcmcia_write16(struct ss
if (unlikely(do_select_core(bus, dev, &offset)))
return;
-//printk("W16 0x%04X, 0x%04X\n", offset, value);
writew(value, bus->mmio + offset);
}
@@ -208,7 +210,6 @@ static void ssb_pcmcia_write32(struct ss
if (unlikely(do_select_core(bus, dev, &offset)))
return;
-//printk("W32 0x%04X, 0x%08X\n", offset, value);
readw(bus->mmio + offset);
writew(value >> 16, bus->mmio + offset + 2);
readw(bus->mmio + offset);
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index feaf1e5..9c33425 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -15,14 +15,12 @@
#include <linux/ssb/ssb.h>
#include <linux/ssb/ssb_regs.h>
#include <linux/pci.h>
-#include <asm/io.h>
+#include <linux/io.h>
-#ifdef CONFIG_SSB_PCMCIAHOST
-# include <pcmcia/cs_types.h>
-# include <pcmcia/cs.h>
-# include <pcmcia/cistpl.h>
-# include <pcmcia/ds.h>
-#endif
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
#include "ssb_private.h"
@@ -202,7 +200,11 @@ void ssb_iounmap(struct ssb_bus *bus)
iounmap(bus->mmio);
break;
case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
pci_iounmap(bus->host_pci, bus->mmio);
+#else
+ SSB_BUG_ON(1); /* Can't reach this code. */
+#endif
break;
}
bus->mmio = NULL;
@@ -222,7 +224,11 @@ static void __iomem * ssb_ioremap(struct
mmio = ioremap(baseaddr, SSB_CORE_SIZE);
break;
case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
mmio = pci_iomap(bus->host_pci, 0, ~0UL);
+#else
+ SSB_BUG_ON(1); /* Can't reach this code. */
+#endif
break;
}
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index d00d186..8e2e310 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -3,7 +3,6 @@ #define LINUX_SSB_PRIVATE_H_
#include <linux/ssb/ssb.h>
#include <linux/types.h>
-#include <asm/io.h>
#define PFX "ssb: "
@@ -16,32 +15,19 @@ #endif /* CONFIG_SSB_SILENT */
/* dprintk: Debugging printk; vanishes for non-debug compilation */
#ifdef CONFIG_SSB_DEBUG
-# define ssb_dprintk(fmt, x...) ssb_printk(fmt ,##x)
+# define ssb_dprintk(fmt, x...) ssb_printk(fmt , ##x)
#else
# define ssb_dprintk(fmt, x...) do { /* nothing */ } while (0)
#endif
-/* printkl: Rate limited printk */
-#define ssb_printkl(fmt, x...) do { \
- if (printk_ratelimit()) \
- ssb_printk(fmt ,##x); \
- } while (0)
-
-/* dprintkl: Rate limited debugging printk */
#ifdef CONFIG_SSB_DEBUG
-# define ssb_dprintkl ssb_printkl
+# define SSB_WARN_ON(x) WARN_ON(x)
+# define SSB_BUG_ON(x) BUG_ON(x)
#else
-# define ssb_dprintkl(fmt, x...) do { /* nothing */ } while (0)
+# define SSB_WARN_ON(x) do { /* nothing */ } while (0)
+# define SSB_BUG_ON(x) do { /* nothing */ } while (0)
#endif
-#define assert(cond) do { \
- if (unlikely(!(cond))) { \
- ssb_dprintk(KERN_ERR PFX "BUG: Assertion failed (%s) " \
- "at: %s:%d:%s()\n", \
- #cond, __FILE__, __LINE__, __func__); \
- } \
- } while (0)
-
/* pci.c */
#ifdef CONFIG_SSB_PCIHOST
@@ -128,10 +114,8 @@ extern void ssb_iounmap(struct ssb_bus *
/* core.c */
extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m);
-#ifdef CONFIG_SSB_PCIHOST
extern int ssb_devices_freeze(struct ssb_bus *bus);
extern int ssb_devices_thaw(struct ssb_bus *bus);
extern struct ssb_bus * ssb_pci_dev_to_bus(struct pci_dev *pdev);
-#endif /* CONFIG_SSB_PCIHOST */
#endif /* LINUX_SSB_PRIVATE_H_ */
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 709e2fa..a3c63ae 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -1,14 +1,11 @@
#ifndef LINUX_SSB_H_
#define LINUX_SSB_H_
-#ifdef __KERNEL__
#include <linux/device.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/spinlock.h>
-#ifdef CONFIG_SSB_PCIHOST
-# include <linux/pci.h>
-#endif
+#include <linux/pci.h>
#include <linux/ssb/ssb_regs.h>
@@ -296,6 +293,7 @@ struct ssb_bus {
struct pcmcia_device *host_pcmcia;
#ifdef CONFIG_SSB_PCIHOST
+ /* Mutex to protect the SPROM writing. */
struct mutex pci_sprom_mutex;
#endif
@@ -312,7 +310,7 @@ #endif
u8 suspend_cnt;
/* Software ID number for this bus. */
- int busnumber;
+ unsigned int busnumber;
/* The ChipCommon device (if available). */
struct ssb_chipcommon chipco;
@@ -342,6 +340,9 @@ struct ssb_init_invariants {
struct ssb_boardinfo boardinfo;
struct ssb_sprom sprom;
};
+/* Type of function to fetch the invariants. */
+typedef int (*ssb_invariants_func_t)(struct ssb_bus *bus,
+ struct ssb_init_invariants *iv);
/* Register a SSB system bus. get_invariants() is called after the
* basic system devices are initialized.
@@ -349,8 +350,7 @@ struct ssb_init_invariants {
* Put the invariants into the struct pointed to by iv. */
extern int ssb_bus_ssbbus_register(struct ssb_bus *bus,
unsigned long baseaddr,
- int (*get_invariants)(struct ssb_bus *bus,
- struct ssb_init_invariants *iv));
+ ssb_invariants_func_t get_invariants);
#ifdef CONFIG_SSB_PCIHOST
extern int ssb_bus_pcibus_register(struct ssb_bus *bus,
struct pci_dev *host_pci);
@@ -365,8 +365,12 @@ extern void ssb_bus_unregister(struct ss
extern u32 ssb_clockspeed(struct ssb_bus *bus);
+/* Is the device enabled in hardware? */
int ssb_device_is_enabled(struct ssb_device *dev);
+/* Enable a device and pass device-specific SSB_TMSLOW flags.
+ * If no device-specific flags are available, use 0. */
void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags);
+/* Disable a device in hardware and pass SSB_TMSLOW flags (if any). */
void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags);
@@ -408,9 +412,15 @@ static inline void ssb_pcihost_unregiste
#endif /* CONFIG_SSB_PCIHOST */
-/* Bus-Power handling functions. */
+/* If a driver is shutdown or suspended, call this to signal
+ * that the bus may be completely powered down. SSB will decide,
+ * if it's really time to power down the bus, based on if there
+ * are other devices that want to run. */
extern int ssb_bus_may_powerdown(struct ssb_bus *bus);
-extern int ssb_bus_powerup(struct ssb_bus *bus, int dynamic_pctl);
+/* Before initializing and enabling a device, call this to power-up the bus.
+ * If you want to allow use of dynamic-power-control, pass the flag.
+ * Otherwise static always-on powercontrol will be used. */
+extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
/* Various helper functions */
@@ -418,5 +428,4 @@ extern u32 ssb_admatch_base(u32 adm);
extern u32 ssb_admatch_size(u32 adm);
-#endif /* __KERNEL__ */
#endif /* LINUX_SSB_H_ */
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index 8856590..d58c24b 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -12,7 +12,6 @@ #define LINUX_SSB_CHIPCO_H_
*
* Licensed under the GPL version 2. See COPYING for details.
*/
-#ifdef __KERNEL__
/** ChipCommon core registers. **/
@@ -383,5 +382,4 @@ extern int ssb_chipco_serial_init(struct
struct ssb_serial_port *ports);
#endif /* CONFIG_SSB_SERIAL */
-#endif /* __KERNEL__ */
#endif /* LINUX_SSB_CHIPCO_H_ */
diff --git a/include/linux/ssb/ssb_driver_extif.h b/include/linux/ssb/ssb_driver_extif.h
index 278a637..00de749 100644
--- a/include/linux/ssb/ssb_driver_extif.h
+++ b/include/linux/ssb/ssb_driver_extif.h
@@ -20,8 +20,6 @@
#ifndef LINUX_SSB_EXTIFCORE_H_
#define LINUX_SSB_EXTIFCORE_H_
-#ifdef __KERNEL__
-
struct ssb_extif {
struct ssb_device *dev;
};
@@ -159,5 +157,4 @@ #define SSB_FLASH_WCNT_3_SHIFT 24
#define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */
-#endif /* __KERNEL__ */
#endif /* LINUX_SSB_EXTIFCORE_H_ */
diff --git a/include/linux/ssb/ssb_driver_mips.h b/include/linux/ssb/ssb_driver_mips.h
index 91f2373..cdbb985 100644
--- a/include/linux/ssb/ssb_driver_mips.h
+++ b/include/linux/ssb/ssb_driver_mips.h
@@ -1,8 +1,6 @@
#ifndef LINUX_SSB_MIPSCORE_H_
#define LINUX_SSB_MIPSCORE_H_
-#ifdef __KERNEL__
-
#ifdef CONFIG_SSB_DRIVER_MIPS
struct ssb_device;
@@ -43,5 +41,4 @@ void ssb_mipscore_init(struct ssb_mipsco
#endif /* CONFIG_SSB_DRIVER_MIPS */
-#endif /* __KERNEL__ */
#endif /* LINUX_SSB_MIPSCORE_H_ */
diff --git a/include/linux/ssb/ssb_driver_pci.h b/include/linux/ssb/ssb_driver_pci.h
index 5132f26..9cfffb7 100644
--- a/include/linux/ssb/ssb_driver_pci.h
+++ b/include/linux/ssb/ssb_driver_pci.h
@@ -1,6 +1,5 @@
#ifndef LINUX_SSB_PCICORE_H_
#define LINUX_SSB_PCICORE_H_
-#ifdef __KERNEL__
#ifdef CONFIG_SSB_DRIVER_PCICORE
@@ -104,5 +103,4 @@ int ssb_pcicore_dev_irqvecs_enable(struc
}
#endif /* CONFIG_SSB_DRIVER_PCICORE */
-#endif /* __KERNEL__ */
#endif /* LINUX_SSB_PCICORE_H_ */
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index 1fa4bf8..66751a6 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -1,6 +1,5 @@
#ifndef LINUX_SSB_REGS_H_
#define LINUX_SSB_REGS_H_
-#ifdef __KERNEL__
/* SiliconBackplane Address Map.
@@ -22,10 +21,10 @@ #define SSB_FLASH1_SZ 0x00400000 /* Siz
#define SSB_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */
#define SSB_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */
-#define SSB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
-#define SSB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
-#define SSB_EUART (SB_EXTIF_BASE + 0x00800000)
-#define SSB_LED (SB_EXTIF_BASE + 0x00900000)
+#define SSB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
+#define SSB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
+#define SSB_EUART (SSB_EXTIF_BASE + 0x00800000)
+#define SSB_LED (SSB_EXTIF_BASE + 0x00900000)
/* Enumeration space constants */
@@ -268,7 +267,7 @@ enum {
SSB_SPROM1CCODE_NONE,
};
-/* Address-Match values and masks (SSB_ADMATCH?) */
+/* Address-Match values and masks (SSB_ADMATCHxxx) */
#define SSB_ADM_TYPE 0x00000003 /* Address type */
#define SSB_ADM_TYPE0 0
#define SSB_ADM_TYPE1 1
@@ -290,5 +289,4 @@ #define SSB_ADM_BASE2 0xFFFF0000 /* Ty
#define SSB_ADM_BASE2_SHIFT 16
-#endif /* __KERNEL__ */
#endif /* LINUX_SSB_REGS_H_ */
--
Greetings Michael.
^ permalink raw reply related
* Re: D-Link DFE-580TX 4 port NIC problems
From: Clemens Koller @ 2007-07-27 12:08 UTC (permalink / raw)
To: Mario Doering; +Cc: linux-kernel, netdev
In-Reply-To: <20070727113044.76630826@snibbles.dedenet.de>
Hi, Mario!
Mario Doering schrieb:
> Hello,
>
> are there any news or questions on this issue?
Can you try the latest kernel to see if the same problem
persists?
Is there any kernel version where it was working fine?
> On Wed, 9 May 2007 03:27:00 -0700
> Andrew Morton <akpm@linux-foundation.org> wrote:
>
>> On Wed, 9 May 2007 12:01:42 +0200 Mario Doering <mario@dedenet.de>
>> wrote:
>>
>>> Hello,
>>>
>>> we have a D-Link DFE-580TX 4 port network card in our main router.
>>>
>>> It works pretty well most of the time, even though an error
>>> message pops up in dmesg every now and then (sometimes once a day
>>> sometimes once every few hours).
>>>
>>>
>>> But every few weeks those error messages increase rapidly, spamming
>>> dmesg. When this happens the system does not react anymore and
>>> pushing the reset button is the only option left.
>>>
>>> I googled around and found out that other users have same problem,
>>> but no solution to this.
>>>
>>>
>>> Part of the message log is located here:
>>> http://test.dedenet.de/messages.gz
>>> or
>>> http://test.dedenet.de/messages.txt
>>>
>>>
>>> uname -a
>>> Linux router1 2.6.19-gentoo-r5 #1 Sat Feb 17 17:04:03 CET 2007 i686
>>> AMD Athlon(tm) XP AuthenticAMD GNU/Linux
>>>
>>>
>>> driver:
>>> [ 17.364707] sundance.c:v1.2 11-Sep-2006 Written by Donald Becker
>>> [ 17.364711] http://www.scyld.com/network/sundance.html
>>> [ 17.364844] ACPI: PCI Interrupt 0000:03:04.0[A] -> GSI 17 (level,
>>> low) -> IRQ 17 [ 17.365396] eth1: D-Link DFE-580TX 4 port Server
>>> Adapter at 0001bc00, 00:0d:88:cc:a5:f0, IRQ 17. [ 17.366350] eth1:
>>> MII PHY found at address 1, status 0x7829 advertising 01e1.
>>> [ 17.676491] ACPI: PCI Interrupt 0000:03:05.0[A] -> GSI 18 (level,
>>> low) -> IRQ 18 [ 17.676912] eth2: D-Link DFE-580TX 4 port Server
>>> Adapter at 0001b800, 00:0d:88:cc:a5:f1, IRQ 18. [ 17.677864] eth2:
>>> MII PHY found at address 1, status 0x7809 advertising 01e1.
>>> [ 17.987730] ACPI: PCI Interrupt 0000:03:06.0[A] -> GSI 19 (level,
>>> low) -> IRQ 16 [ 17.988107] eth3: D-Link DFE-580TX 4 port Server
>>> Adapter at 0001b400, 00:0d:88:cc:a5:f2, IRQ 16. [ 17.989059] eth3:
>>> MII PHY found at address 1, status 0x7829 advertising 01e1.
>>> [ 18.298910] ACPI: PCI Interrupt 0000:03:07.0[A] -> GSI 16 (level,
>>> low) -> IRQ 19 [ 18.299320] eth4: D-Link DFE-580TX 4 port Server
>>> Adapter at 0001b000, 00:0d:88:cc:a5:f3, IRQ 19. [ 18.300272] eth4:
>>> MII PHY found at address 1, status 0x7809 advertising 01e1.
>>>
>>>
>>> No such error message appears for about 7-10 days after a reboot.
>>> Maybe there is some kind of buffer running full?
>>>
>>> Do you need any additional info?
>>>
>>> Please CC me :-)
>> (cc netdev)
Regards,
--
Clemens Koller
__________________________________
R&D Imaging Devices
Anagramm GmbH
Rupert-Mayer-Straße 45/1
Linhof Werksgelände
D-81379 München
Tel.089-741518-50
Fax 089-741518-19
http://www.anagramm-technology.com
^ permalink raw reply
* Re: D-Link DFE-580TX 4 port NIC problems
From: Mario Doering @ 2007-07-27 9:30 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev
In-Reply-To: <20070509032700.569789a0.akpm@linux-foundation.org>
Hello,
are there any news or questions on this issue?
Mario.
On Wed, 9 May 2007 03:27:00 -0700
Andrew Morton <akpm@linux-foundation.org> wrote:
> On Wed, 9 May 2007 12:01:42 +0200 Mario Doering <mario@dedenet.de>
> wrote:
>
> > Hello,
> >
> > we have a D-Link DFE-580TX 4 port network card in our main router.
> >
> > It works pretty well most of the time, even though an error
> > message pops up in dmesg every now and then (sometimes once a day
> > sometimes once every few hours).
> >
> >
> > But every few weeks those error messages increase rapidly, spamming
> > dmesg. When this happens the system does not react anymore and
> > pushing the reset button is the only option left.
> >
> > I googled around and found out that other users have same problem,
> > but no solution to this.
> >
> >
> > Part of the message log is located here:
> > http://test.dedenet.de/messages.gz
> > or
> > http://test.dedenet.de/messages.txt
> >
> >
> > uname -a
> > Linux router1 2.6.19-gentoo-r5 #1 Sat Feb 17 17:04:03 CET 2007 i686
> > AMD Athlon(tm) XP AuthenticAMD GNU/Linux
> >
> >
> > driver:
> > [ 17.364707] sundance.c:v1.2 11-Sep-2006 Written by Donald Becker
> > [ 17.364711] http://www.scyld.com/network/sundance.html
> > [ 17.364844] ACPI: PCI Interrupt 0000:03:04.0[A] -> GSI 17 (level,
> > low) -> IRQ 17 [ 17.365396] eth1: D-Link DFE-580TX 4 port Server
> > Adapter at 0001bc00, 00:0d:88:cc:a5:f0, IRQ 17. [ 17.366350] eth1:
> > MII PHY found at address 1, status 0x7829 advertising 01e1.
> > [ 17.676491] ACPI: PCI Interrupt 0000:03:05.0[A] -> GSI 18 (level,
> > low) -> IRQ 18 [ 17.676912] eth2: D-Link DFE-580TX 4 port Server
> > Adapter at 0001b800, 00:0d:88:cc:a5:f1, IRQ 18. [ 17.677864] eth2:
> > MII PHY found at address 1, status 0x7809 advertising 01e1.
> > [ 17.987730] ACPI: PCI Interrupt 0000:03:06.0[A] -> GSI 19 (level,
> > low) -> IRQ 16 [ 17.988107] eth3: D-Link DFE-580TX 4 port Server
> > Adapter at 0001b400, 00:0d:88:cc:a5:f2, IRQ 16. [ 17.989059] eth3:
> > MII PHY found at address 1, status 0x7829 advertising 01e1.
> > [ 18.298910] ACPI: PCI Interrupt 0000:03:07.0[A] -> GSI 16 (level,
> > low) -> IRQ 19 [ 18.299320] eth4: D-Link DFE-580TX 4 port Server
> > Adapter at 0001b000, 00:0d:88:cc:a5:f3, IRQ 19. [ 18.300272] eth4:
> > MII PHY found at address 1, status 0x7809 advertising 01e1.
> >
> >
> >
> > No such error message appears for about 7-10 days after a reboot.
> > Maybe there is some kind of buffer running full?
> >
> > Do you need any additional info?
> >
> >
> > Please CC me :-)
>
> (cc netdev)
^ permalink raw reply
* source interface ping bug ?
From: nano bug @ 2007-07-27 8:30 UTC (permalink / raw)
To: netdev
Hello there,
I'm facing the following issue : when I try to ping using source
interface instead of a source ip address the ping utility starts to
send arp requests instead of icmp requests though the ip address I'm
pinging it's not in the subnets directly connected to my linux box.
I've noticed this situation since I upgraded from kernel 2.6.20 to
2.6.21. On 2.6.20 and lower I haven't had this problem. Now I upgraded
to 2.6.22 but it's the same. I'm using latest iproute and iputils.
Here is an output of tcpdump when I try to ping an outside ip address,
like for example www.yahoo.com, using source interface :
root@darkstar:~# uname -a
Linux darkstar 2.6.22 #1 Thu Jul 26 21:22:11 EEST 2007 i686 Pentium II
(Deschutes) GenuineIntel GNU/Linux
root@darkstar:~# ip -V
ip utility, iproute2-ss070710
root@darkstar:~#
root@darkstar:~# ip address show dev eth2
3: eth2: <BROADCAST,MULTICAST,NOTRAILERS,UP,LOWER_UP> mtu 1500 qdisc
pfifo_fast qlen 1000
link/ether 00:90:27:0f:79:f3 brd ff:ff:ff:ff:ff:ff
inet 86.106.19.75/23 brd 86.106.19.255 scope global eth2
root@darkstar:~# ip route get 87.248.113.14 from 86.106.19.75 oif eth2
87.248.113.14 from 86.106.19.75 via 86.106.18.1 dev eth2
cache mtu 1500 advmss 1460 hoplimit 64
root@darkstar:~#
root@darkstar:~/iputils# ./ping -V
ping utility, iputils-sss20070202
root@darkstar:~/iputils# ./ping -I 86.106.19.75 87.248.113.14 -c 2
PING 87.248.113.14 (87.248.113.14) from 86.106.19.75 : 56(84) bytes of data.
64 bytes from 87.248.113.14: icmp_seq=1 ttl=51 time=60.5 ms
64 bytes from 87.248.113.14: icmp_seq=2 ttl=51 time=63.2 ms
--- 87.248.113.14 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 60.574/61.924/63.274/1.350 ms
root@darkstar:~/iputils#
root@darkstar:~# tcpdump -i eth2 -vvv -n host 87.248.113.14 and host
86.106.19.75
tcpdump: listening on eth2, link-type EN10MB (Ethernet), capture size 96 bytes
01:18:09.572603 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF],
proto: ICMP (1), length: 84) 86.106.19.75 > 87.248.113.14: ICMP echo
request, id 27166, seq 1, length 64
01:18:09.632861 IP (tos 0x0, ttl 51, id 6100, offset 0, flags [none],
proto: ICMP (1), length: 84) 87.248.113.14 > 86.106.19.75: ICMP echo
reply, id 27166, seq 1, length 64
01:18:10.572746 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF],
proto: ICMP (1), length: 84) 86.106.19.75 > 87.248.113.14: ICMP echo
request, id 27166, seq 2, length 64
01:18:10.634951 IP (tos 0x0, ttl 51, id 8790, offset 0, flags [none],
proto: ICMP (1), length: 84) 87.248.113.14 > 86.106.19.75: ICMP echo
reply, id 27166, seq 2, length 64
using source interface :
root@darkstar:~/iputils# ./ping -I eth2 87.248.113.14
PING 87.248.113.14 (87.248.113.14) from 86.106.19.75 eth2: 56(84) bytes of data.
>From 86.106.19.75 icmp_seq=1 Destination Host Unreachable
>From 86.106.19.75 icmp_seq=2 Destination Host Unreachable
>From 86.106.19.75 icmp_seq=3 Destination Host Unreachable
>From 86.106.19.75 icmp_seq=5 Destination Host Unreachable
>From 86.106.19.75 icmp_seq=6 Destination Host Unreachable
>From 86.106.19.75 icmp_seq=7 Destination Host Unreachable
>From 86.106.19.75 icmp_seq=9 Destination Host Unreachable
>From 86.106.19.75 icmp_seq=10 Destination Host Unreachable
>From 86.106.19.75 icmp_seq=11 Destination Host Unreachable
--- 87.248.113.14 ping statistics ---
13 packets transmitted, 0 received, +9 errors, 100% packet loss, time 12006ms
, pipe 3
root@darkstar:~/iputils#
root@darkstar:~# tcpdump -i eth2 -vvv -n host 87.248.113.14 and host
86.106.19.75
tcpdump: listening on eth2, link-type EN10MB (Ethernet), capture size 96 bytes
01:19:24.292911 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:25.292897 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:26.292901 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:27.302906 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:28.302911 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:29.302912 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:31.302917 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:32.302921 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:33.302923 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:35.302932 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:36.302932 arp who-has 87.248.113.14 tell 86.106.19.75
01:19:37.302939 arp who-has 87.248.113.14 tell 86.106.19.75
12 packets captured
12 packets received by filter
0 packets dropped by kernel
root@darkstar:~#
There is one exception though, it works when using eth0. I'm
administrating multiple linux boxes with 2 or 3 ethernet cards and if
I try pinging with eth0 it does send icmp like it should but when
specifying eth1 or eth2 is sends arp requests. The distro I'm using is
Slackware 12.0. I already reported this to the iputils maintainer and
he recommended to report it here. Thanks in advance.
Regards.
^ permalink raw reply
* Re: Multicast issues with RTL8110SC in r8169.c
From: Glen Gray @ 2007-07-27 8:13 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <20070726213020.GB14306@electric-eye.fr.zoreil.com>
Francois Romieu wrote:
> Glen Gray <glen@lincor.com> :
>> Hey Francois,
>> I've CC'd the netdev list as requested
>
> Your PR is not lost (nor are the pending ones btw...). I'm simply trying
> to find a real explanation for
> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=242572
>
Ah, apologies. When I couldn't see my follow up posts hitting the list,
I figured I'd sign up and post it again.
The linked bug entry indicates issues with the driver initializing
certain cards etc. As previously stated, my issue was mainly in
multicast. I was able to get the machine up and on the network without
issue in the 2.6.21 kernel from F7. Though there's obviously issues with
the newer Realtek cards and the post 2.6.20 kernels.
FYI, The Realtek driver release 1.06 (r1000.ko), although not officially
supporting the 2.6 kernel (the Makefile just needed modification) works
extremely well for us here.
If I can help test experimental patchs or anything, please don't
hesitate to let me know.
--
Glen Gray <glen@lincor.com> Digital Depot, Thomas Street
Senior Software Engineer Dublin 8, Ireland
Lincor Solutions Ltd. Ph: +353 (0) 1 4893682
^ permalink raw reply
* Re: sk98lin for 2.6.23-rc1
From: Stephen Hemminger @ 2007-07-27 8:13 UTC (permalink / raw)
To: Kyle Rose; +Cc: netdev
In-Reply-To: <46A8F3EE.3070102@krose.org>
If anyone still has hang issues with sky2, please send me the hardware
information (lspci, dmesg output), and capture the debugfs state after hang.
At present the known open skge, sky2 issues are:
1) Skge doesn't work with dual port fiber
2) Sky2 (and vendor sk98lin) don't work on some MSI motherboards
due to PCI issues
3) Skge and sky2 trigger problems with motherboards that don't
do >4GB DMA correctly. Not a driver but a PCI quirk problem.
4) Sky2 does polling for lost irq even when interface not up
5) Sky2 polling rate for lost irq maybe greater than TCP timeout so
connection may be lost even after link recovers
6) Sky2 Yukon extreme support is still experimental and fragile,
but this hardware isn't in the wild yet
7) Sky2 Yukon EC-U not powering up PHY correctly on some revisions
8) Sky2 suspend to ram not working right on some chips
Hardware nuisances that are being masked:
a) hardware can't DMA to unaligned address
b) polling for lost irq is a hack, but until the root cause
is found it will have to stay.
^ permalink raw reply
* [RFT 4/4] fib_trie: whitespace cleanup
From: Stephen Hemminger @ 2007-07-27 7:59 UTC (permalink / raw)
To: David S. Miller; +Cc: akpm, netdev
In-Reply-To: <20070727075917.470055328@linux-foundation.org>
[-- Attachment #1: fib-whitespace.patch --]
[-- Type: text/plain, Size: 38000 bytes --]
Try and be consistent with whitespace and line wrapping.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/net/ipv4/fib_trie.c 2007-07-27 08:57:53.000000000 +0100
+++ b/net/ipv4/fib_trie.c 2007-07-27 08:57:54.000000000 +0100
@@ -154,7 +154,8 @@ struct trie {
};
static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
-static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
+static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n,
+ int wasfull);
static struct node *resize(struct trie *t, struct tnode *tn);
static struct tnode *inflate(struct trie *t, struct tnode *tn);
static struct tnode *halve(struct trie *t, struct tnode *tn);
@@ -222,7 +223,7 @@ static inline int tkey_mismatch(t_key a,
if (!diff)
return 0;
- while ((diff << i) >> (KEYLENGTH-1) == 0)
+ while ((diff << i) >> (KEYLENGTH - 1) == 0)
i++;
return i;
}
@@ -284,7 +285,6 @@ static inline int tkey_mismatch(t_key a,
The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into
n's child array, and will of course be different for each child.
-
The rest of the bits, from (n->pos + n->bits) onward, are completely unknown
at this point.
@@ -292,7 +292,7 @@ static inline int tkey_mismatch(t_key a,
static inline void check_tnode(const struct tnode *tn)
{
- WARN_ON(tn && tn->pos+tn->bits > 32);
+ WARN_ON(tn && tn->pos + tn->bits > 32);
}
static int halve_threshold = 25;
@@ -300,7 +300,6 @@ static int inflate_threshold = 50;
static int halve_threshold_root = 8;
static int inflate_threshold_root = 15;
-
static void __alias_free_mem(struct rcu_head *head)
{
struct fib_alias *fa = container_of(head, struct fib_alias, rcu);
@@ -334,7 +333,7 @@ static struct tnode *tnode_alloc(unsigne
if (size <= PAGE_SIZE)
return kcalloc(size, 1, GFP_KERNEL);
- pages = alloc_pages(GFP_KERNEL|__GFP_ZERO, get_order(size));
+ pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(size));
if (!pages)
return NULL;
@@ -345,7 +344,7 @@ static void __tnode_free_rcu(struct rcu_
{
struct tnode *tn = container_of(head, struct tnode, rcu);
unsigned int size = sizeof(struct tnode) +
- (1 << tn->bits) * sizeof(struct node *);
+ (1 << tn->bits) * sizeof(struct node *);
if (size <= PAGE_SIZE)
kfree(tn);
@@ -356,7 +355,7 @@ static void __tnode_free_rcu(struct rcu_
static inline void tnode_free(struct tnode *tn)
{
if (IS_LEAF(tn)) {
- struct leaf *l = (struct leaf *) tn;
+ struct leaf *l = (struct leaf *)tn;
call_rcu_bh(&l->rcu, __leaf_free_rcu);
} else
call_rcu(&tn->rcu, __tnode_free_rcu);
@@ -364,7 +363,7 @@ static inline void tnode_free(struct tno
static struct leaf *leaf_new(void)
{
- struct leaf *l = kmalloc(sizeof(struct leaf), GFP_KERNEL);
+ struct leaf *l = kmalloc(sizeof(struct leaf), GFP_KERNEL);
if (l) {
l->parent = T_LEAF;
INIT_HLIST_HEAD(&l->list);
@@ -374,7 +373,7 @@ static struct leaf *leaf_new(void)
static struct leaf_info *leaf_info_new(int plen)
{
- struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL);
+ struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL);
if (li) {
li->plen = plen;
INIT_LIST_HEAD(&li->falh);
@@ -382,9 +381,9 @@ static struct leaf_info *leaf_info_new(i
return li;
}
-static struct tnode* tnode_new(t_key key, int pos, int bits)
+static struct tnode *tnode_new(t_key key, int pos, int bits)
{
- int nchildren = 1<<bits;
+ int nchildren = 1 << bits;
int sz = sizeof(struct tnode) + nchildren * sizeof(struct node *);
struct tnode *tn = tnode_alloc(sz);
@@ -395,11 +394,11 @@ static struct tnode* tnode_new(t_key key
tn->bits = bits;
tn->key = key;
tn->full_children = 0;
- tn->empty_children = 1<<bits;
+ tn->empty_children = 1 << bits;
}
- pr_debug("AT %p s=%u %u\n", tn, (unsigned int) sizeof(struct tnode),
- (unsigned int) (sizeof(struct node) * 1<<bits));
+ pr_debug("AT %p s=%u %u\n", tn, (unsigned int)sizeof(struct tnode),
+ (unsigned int)(sizeof(struct node) * 1 << bits));
return tn;
}
@@ -413,10 +412,11 @@ static inline int tnode_full(const struc
if (n == NULL || IS_LEAF(n))
return 0;
- return ((struct tnode *) n)->pos == tn->pos + tn->bits;
+ return ((struct tnode *)n)->pos == tn->pos + tn->bits;
}
-static inline void put_child(struct trie *t, struct tnode *tn, int i, struct node *n)
+static inline void put_child(struct trie *t, struct tnode *tn, int i,
+ struct node *n)
{
tnode_put_child_reorg(tn, i, n, -1);
}
@@ -426,13 +426,13 @@ static inline void put_child(struct trie
* Update the value of full_children and empty_children.
*/
-static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull)
+static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n,
+ int wasfull)
{
struct node *chi = tn->child[i];
int isfull;
- BUG_ON(i >= 1<<tn->bits);
-
+ BUG_ON(i >= 1 << tn->bits);
/* update emptyChildren */
if (n == NULL && chi != NULL)
@@ -565,9 +565,10 @@ static struct node *resize(struct trie *
err = 0;
max_resize = 10;
- while ((tn->full_children > 0 && max_resize-- &&
- 50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >=
- inflate_threshold_use * tnode_child_length(tn))) {
+ while ((tn->full_children > 0 && max_resize-- &&
+ 50 * (tn->full_children + tnode_child_length(tn) -
+ tn->empty_children) >=
+ inflate_threshold_use * tnode_child_length(tn))) {
old_tn = tn;
tn = inflate(t, tn);
@@ -582,10 +583,12 @@ static struct node *resize(struct trie *
if (max_resize < 0) {
if (!tn->parent)
- printk(KERN_WARNING "Fix inflate_threshold_root. Now=%d size=%d bits\n",
+ printk(KERN_WARNING
+ "Fix inflate_threshold_root. Now=%d size=%d bits\n",
inflate_threshold_root, tn->bits);
else
- printk(KERN_WARNING "Fix inflate_threshold. Now=%d size=%d bits\n",
+ printk(KERN_WARNING
+ "Fix inflate_threshold. Now=%d size=%d bits\n",
inflate_threshold, tn->bits);
}
@@ -596,7 +599,6 @@ static struct node *resize(struct trie *
* node is above threshold.
*/
-
/* Keep root node larger */
if (!tn->parent)
@@ -606,7 +608,7 @@ static struct node *resize(struct trie *
err = 0;
max_resize = 10;
- while (tn->bits > 1 && max_resize-- &&
+ while (tn->bits > 1 && max_resize-- &&
100 * (tnode_child_length(tn) - tn->empty_children) <
halve_threshold_use * tnode_child_length(tn)) {
@@ -623,10 +625,12 @@ static struct node *resize(struct trie *
if (max_resize < 0) {
if (!tn->parent)
- printk(KERN_WARNING "Fix halve_threshold_root. Now=%d size=%d bits\n",
+ printk(KERN_WARNING
+ "Fix halve_threshold_root. Now=%d size=%d bits\n",
halve_threshold_root, tn->bits);
else
- printk(KERN_WARNING "Fix halve_threshold. Now=%d size=%d bits\n",
+ printk(KERN_WARNING
+ "Fix halve_threshold. Now=%d size=%d bits\n",
halve_threshold, tn->bits);
}
@@ -646,7 +650,7 @@ static struct node *resize(struct trie *
return n;
}
- return (struct node *) tn;
+ return (struct node *)tn;
}
static struct tnode *inflate(struct trie *t, struct tnode *tn)
@@ -670,7 +674,8 @@ static struct tnode *inflate(struct trie
*/
for (i = 0; i < olen; i++) {
- struct tnode *inode = (struct tnode *) tnode_get_child(oldtnode, i);
+ struct tnode *inode =
+ (struct tnode *)tnode_get_child(oldtnode, i);
if (inode &&
IS_TNODE(inode) &&
@@ -679,12 +684,12 @@ static struct tnode *inflate(struct trie
struct tnode *left, *right;
t_key m = ~0U << (KEYLENGTH - 1) >> inode->pos;
- left = tnode_new(inode->key&(~m), inode->pos + 1,
+ left = tnode_new(inode->key & (~m), inode->pos + 1,
inode->bits - 1);
if (!left)
goto nomem;
- right = tnode_new(inode->key|m, inode->pos + 1,
+ right = tnode_new(inode->key | m, inode->pos + 1,
inode->bits - 1);
if (!right) {
@@ -692,8 +697,8 @@ static struct tnode *inflate(struct trie
goto nomem;
}
- put_child(t, tn, 2*i, (struct node *) left);
- put_child(t, tn, 2*i+1, (struct node *) right);
+ put_child(t, tn, 2 * i, (struct node *)left);
+ put_child(t, tn, 2 * i + 1, (struct node *)right);
}
}
@@ -708,22 +713,22 @@ static struct tnode *inflate(struct trie
/* A leaf or an internal node with skipped bits */
- if (IS_LEAF(node) || ((struct tnode *) node)->pos >
- tn->pos + tn->bits - 1) {
- if (tkey_extract_bits(node->key, oldtnode->pos + oldtnode->bits,
- 1) == 0)
- put_child(t, tn, 2*i, node);
+ if (IS_LEAF(node) || ((struct tnode *)node)->pos >
+ tn->pos + tn->bits - 1) {
+ if (!tkey_extract_bits(node->key,
+ oldtnode->pos + oldtnode->bits, 1))
+ put_child(t, tn, 2 * i, node);
else
- put_child(t, tn, 2*i+1, node);
+ put_child(t, tn, 2 * i + 1, node);
continue;
}
/* An internal node with two children */
- inode = (struct tnode *) node;
+ inode = (struct tnode *)node;
if (inode->bits == 1) {
- put_child(t, tn, 2*i, inode->child[0]);
- put_child(t, tn, 2*i+1, inode->child[1]);
+ put_child(t, tn, 2 * i, inode->child[0]);
+ put_child(t, tn, 2 * i + 1, inode->child[1]);
tnode_free(inode);
continue;
@@ -752,13 +757,13 @@ static struct tnode *inflate(struct trie
* bit to zero.
*/
- left = (struct tnode *) tnode_get_child(tn, 2*i);
- put_child(t, tn, 2*i, NULL);
+ left = (struct tnode *)tnode_get_child(tn, 2 * i);
+ put_child(t, tn, 2 * i, NULL);
BUG_ON(!left);
- right = (struct tnode *) tnode_get_child(tn, 2*i+1);
- put_child(t, tn, 2*i+1, NULL);
+ right = (struct tnode *)tnode_get_child(tn, 2 * i + 1);
+ put_child(t, tn, 2 * i + 1, NULL);
BUG_ON(!right);
@@ -767,8 +772,8 @@ static struct tnode *inflate(struct trie
put_child(t, left, j, inode->child[j]);
put_child(t, right, j, inode->child[j + size]);
}
- put_child(t, tn, 2*i, resize(t, left));
- put_child(t, tn, 2*i+1, resize(t, right));
+ put_child(t, tn, 2 * i, resize(t, left));
+ put_child(t, tn, 2 * i + 1, resize(t, right));
tnode_free(inode);
}
@@ -812,7 +817,7 @@ static struct tnode *halve(struct trie *
for (i = 0; i < olen; i += 2) {
left = tnode_get_child(oldtnode, i);
- right = tnode_get_child(oldtnode, i+1);
+ right = tnode_get_child(oldtnode, i + 1);
/* Two nonempty children */
if (left && right) {
@@ -823,7 +828,7 @@ static struct tnode *halve(struct trie *
if (!newn)
goto nomem;
- put_child(t, tn, i/2, (struct node *)newn);
+ put_child(t, tn, i / 2, (struct node *)newn);
}
}
@@ -832,27 +837,27 @@ static struct tnode *halve(struct trie *
struct tnode *newBinNode;
left = tnode_get_child(oldtnode, i);
- right = tnode_get_child(oldtnode, i+1);
+ right = tnode_get_child(oldtnode, i + 1);
/* At least one of the children is empty */
if (left == NULL) {
- if (right == NULL) /* Both are empty */
+ if (right == NULL) /* Both are empty */
continue;
- put_child(t, tn, i/2, right);
+ put_child(t, tn, i / 2, right);
continue;
}
if (right == NULL) {
- put_child(t, tn, i/2, left);
+ put_child(t, tn, i / 2, left);
continue;
}
/* Two nonempty children */
- newBinNode = (struct tnode *) tnode_get_child(tn, i/2);
- put_child(t, tn, i/2, NULL);
+ newBinNode = (struct tnode *)tnode_get_child(tn, i / 2);
+ put_child(t, tn, i / 2, NULL);
put_child(t, newBinNode, 0, left);
put_child(t, newBinNode, 1, right);
- put_child(t, tn, i/2, resize(t, newBinNode));
+ put_child(t, tn, i / 2, resize(t, newBinNode));
}
tnode_free(oldtnode);
return tn;
@@ -894,13 +899,13 @@ static struct leaf_info *find_leaf_info(
struct leaf_info *li;
hlist_for_each_entry_rcu(li, node, head, hlist)
- if (li->plen == plen)
- return li;
+ if (li->plen == plen)
+ return li;
return NULL;
}
-static inline struct list_head * get_fa_head(struct leaf *l, int plen)
+static inline struct list_head *get_fa_head(struct leaf *l, int plen)
{
struct leaf_info *li = find_leaf_info(l, plen);
@@ -933,8 +938,7 @@ static void insert_leaf_info(struct hlis
/* rcu_read_lock needs to be hold by caller from readside */
-static struct leaf *
-fib_find_node(struct trie *t, u32 key)
+static struct leaf *fib_find_node(struct trie *t, u32 key)
{
int pos;
struct tnode *tn;
@@ -944,7 +948,7 @@ fib_find_node(struct trie *t, u32 key)
n = rcu_dereference(t->trie);
while (n && IS_TNODE(n)) {
- tn = (struct tnode *) n;
+ tn = (struct tnode *)n;
check_tnode(tn);
@@ -971,10 +975,11 @@ static struct node *trie_rebalance(struc
while (tn && (tp = node_parent((struct node *)tn)) ) {
cindex = tkey_extract_bits(key, tp->pos, tp->bits);
wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
- tn = (struct tnode *) resize (t, (struct tnode *)tn);
- tnode_put_child_reorg((struct tnode *)tp, cindex,(struct node*)tn, wasfull);
+ tn = (struct tnode *)resize(t, (struct tnode *)tn);
+ tnode_put_child_reorg((struct tnode *)tp, cindex,
+ (struct node *)tn, wasfull);
- tp = node_parent((struct node *) tn);
+ tp = node_parent((struct node *)tn);
if (!tp)
break;
tn = tp;
@@ -982,15 +987,15 @@ static struct node *trie_rebalance(struc
/* Handle last (top) tnode */
if (IS_TNODE(tn))
- tn = (struct tnode*) resize(t, (struct tnode *)tn);
+ tn = (struct tnode *)resize(t, (struct tnode *)tn);
- return (struct node*) tn;
+ return (struct node *)tn;
}
/* only used from updater-side */
-static struct list_head *
-fib_insert_node(struct trie *t, int *err, u32 key, int plen)
+static struct list_head *fib_insert_node(struct trie *t, int *err, u32 key,
+ int plen)
{
int pos, newpos;
struct tnode *tp = NULL, *tn = NULL;
@@ -1023,7 +1028,7 @@ fib_insert_node(struct trie *t, int *err
*/
while (n && IS_TNODE(n)) {
- tn = (struct tnode *) n;
+ tn = (struct tnode *)n;
check_tnode(tn);
@@ -1048,7 +1053,7 @@ fib_insert_node(struct trie *t, int *err
/* Case 1: n is a leaf. Compare prefixes */
if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) {
- struct leaf *nl = (struct leaf *) n;
+ struct leaf *nl = (struct leaf *)n;
li = leaf_info_new(plen);
@@ -1073,7 +1078,7 @@ fib_insert_node(struct trie *t, int *err
li = leaf_info_new(plen);
if (!li) {
- tnode_free((struct tnode *) l);
+ tnode_free((struct tnode *)l);
*err = -ENOMEM;
goto err;
}
@@ -1096,7 +1101,7 @@ fib_insert_node(struct trie *t, int *err
*/
if (tp)
- pos = tp->pos+tp->bits;
+ pos = tp->pos + tp->bits;
else
pos = 0;
@@ -1105,12 +1110,12 @@ fib_insert_node(struct trie *t, int *err
tn = tnode_new(n->key, newpos, 1);
} else {
newpos = 0;
- tn = tnode_new(key, newpos, 1); /* First tnode */
+ tn = tnode_new(key, newpos, 1); /* First tnode */
}
if (!tn) {
free_leaf_info(li);
- tnode_free((struct tnode *) l);
+ tnode_free((struct tnode *)l);
*err = -ENOMEM;
goto err;
}
@@ -1119,20 +1124,22 @@ fib_insert_node(struct trie *t, int *err
missbit = tkey_extract_bits(key, newpos, 1);
put_child(t, tn, missbit, (struct node *)l);
- put_child(t, tn, 1-missbit, n);
+ put_child(t, tn, 1 - missbit, n);
if (tp) {
cindex = tkey_extract_bits(key, tp->pos, tp->bits);
- put_child(t, (struct tnode *)tp, cindex, (struct node *)tn);
+ put_child(t, (struct tnode *)tp, cindex,
+ (struct node *)tn);
} else {
- rcu_assign_pointer(t->trie, (struct node *)tn); /* First tnode */
+ rcu_assign_pointer(t->trie, (struct node *)tn); /* First tnode */
tp = tn;
}
}
if (tp && tp->pos + tp->bits > 32)
- printk(KERN_WARNING "fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
- tp, tp->pos, tp->bits, key, plen);
+ printk(KERN_WARNING
+ "fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n", tp,
+ tp->pos, tp->bits, key, plen);
/* Rebalance the trie */
@@ -1148,7 +1155,7 @@ err:
*/
static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
{
- struct trie *t = (struct trie *) tb->tb_data;
+ struct trie *t = (struct trie *)tb->tb_data;
struct fib_alias *fa, *new_fa;
struct list_head *fa_head = NULL;
struct fib_info *fi;
@@ -1228,7 +1235,7 @@ static int fn_trie_insert(struct fib_tab
if (state & FA_S_ACCESSED)
rt_cache_flush(-1);
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
- tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
+ tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
goto succeeded;
}
@@ -1276,8 +1283,7 @@ static int fn_trie_insert(struct fib_tab
goto out_free_new_fa;
}
- list_add_tail_rcu(&new_fa->fa_list,
- (fa ? &fa->fa_list : fa_head));
+ list_add_tail_rcu(&new_fa->fa_list, (fa ? &fa->fa_list : fa_head));
rt_cache_flush(-1);
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
@@ -1293,7 +1299,6 @@ err:
return err;
}
-
/* should be called with rcu_read_lock */
static inline int check_leaf(struct trie *t, struct leaf *l,
t_key key, int *plen, const struct flowi *flp,
@@ -1311,7 +1316,9 @@ static inline int check_leaf(struct trie
if (l->key != (key & ntohl(mask)))
continue;
- if ((err = fib_semantic_match(&li->falh, flp, res, htonl(l->key), mask, i)) <= 0) {
+ err = fib_semantic_match(&li->falh, flp, res, htonl(l->key),
+ mask, i);
+ if (err <= 0) {
*plen = i;
#ifdef CONFIG_IP_FIB_TRIE_STATS
t->stats.semantic_match_passed++;
@@ -1326,9 +1333,10 @@ static inline int check_leaf(struct trie
}
static int
-fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
+ struct fib_result *res)
{
- struct trie *t = (struct trie *) tb->tb_data;
+ struct trie *t = (struct trie *)tb->tb_data;
int plen, ret = 0;
struct node *n;
struct tnode *pn;
@@ -1353,11 +1361,12 @@ fn_trie_lookup(struct fib_table *tb, con
/* Just a leaf? */
if (IS_LEAF(n)) {
- if ((ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res)) <= 0)
+ ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res);
+ if (ret <= 0)
goto found;
goto failed;
}
- pn = (struct tnode *) n;
+ pn = (struct tnode *)n;
chopped_off = 0;
while (pn) {
@@ -1365,7 +1374,7 @@ fn_trie_lookup(struct fib_table *tb, con
bits = pn->bits;
if (!chopped_off)
- cindex = tkey_extract_bits(mask_pfx(key, current_prefix_length),
+ cindex = tkey_extract_bits(mask_pfx (key, current_prefix_length),
pos, bits);
n = tnode_get_child(pn, cindex);
@@ -1378,12 +1387,12 @@ fn_trie_lookup(struct fib_table *tb, con
}
if (IS_LEAF(n)) {
- if ((ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res)) <= 0)
+ ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res);
+ if (ret <= 0)
goto found;
else
goto backtrace;
}
-
#define HL_OPTIMIZE
#ifdef HL_OPTIMIZE
cn = (struct tnode *)n;
@@ -1416,10 +1425,10 @@ fn_trie_lookup(struct fib_table *tb, con
/* NOTA BENE: CHECKING ONLY SKIPPED BITS FOR THE NEW NODE HERE */
- if (current_prefix_length < pos+bits) {
+ if (current_prefix_length < pos + bits) {
if (tkey_extract_bits(cn->key, current_prefix_length,
- cn->pos - current_prefix_length) != 0 ||
- !(cn->child[0]))
+ cn->pos - current_prefix_length) != 0
+ || !(cn->child[0]))
goto backtrace;
}
@@ -1454,19 +1463,19 @@ fn_trie_lookup(struct fib_table *tb, con
node_prefix = mask_pfx(cn->key, cn->pos);
key_prefix = mask_pfx(key, cn->pos);
- pref_mismatch = key_prefix^node_prefix;
+ pref_mismatch = key_prefix ^ node_prefix;
mp = 0;
/* In short: If skipped bits in this node do not match the search
* key, enter the "prefix matching" state.directly.
*/
if (pref_mismatch) {
- while (!(pref_mismatch & (1<<(KEYLENGTH-1)))) {
+ while (!(pref_mismatch & (1 << (KEYLENGTH - 1)))) {
mp++;
- pref_mismatch = pref_mismatch <<1;
+ pref_mismatch = pref_mismatch << 1;
}
- key_prefix = tkey_extract_bits(cn->key, mp, cn->pos-mp);
+ key_prefix = tkey_extract_bits(cn->key, mp, cn->pos - mp);
if (key_prefix != 0)
goto backtrace;
@@ -1474,7 +1483,7 @@ fn_trie_lookup(struct fib_table *tb, con
current_prefix_length = mp;
}
#endif
- pn = (struct tnode *)n; /* Descend */
+ pn = (struct tnode *)n; /* Descend */
chopped_off = 0;
continue;
@@ -1482,12 +1491,14 @@ backtrace:
chopped_off++;
/* As zero don't change the child key (cindex) */
- while ((chopped_off <= pn->bits) && !(cindex & (1<<(chopped_off-1))))
+ while (chopped_off <= pn->bits
+ && !(cindex & (1 << (chopped_off - 1))))
chopped_off++;
/* Decrease current_... with bits chopped off */
if (current_prefix_length > pn->pos + pn->bits - chopped_off)
- current_prefix_length = pn->pos + pn->bits - chopped_off;
+ current_prefix_length =
+ pn->pos + pn->bits - chopped_off;
/*
* Either we do the actual chop off according or if we have
@@ -1495,14 +1506,15 @@ backtrace:
*/
if (chopped_off <= pn->bits) {
- cindex &= ~(1 << (chopped_off-1));
+ cindex &= ~(1 << (chopped_off - 1));
} else {
- struct tnode *parent = node_parent((struct node *) pn);
+ struct tnode *parent = node_parent((struct node *)pn);
if (!parent)
goto failed;
/* Get Child's index */
- cindex = tkey_extract_bits(pn->key, parent->pos, parent->bits);
+ cindex = tkey_extract_bits(pn->key,
+ parent->pos, parent->bits);
pn = parent;
chopped_off = 0;
@@ -1535,13 +1547,13 @@ static int trie_leaf_remove(struct trie
*/
while (n != NULL && IS_TNODE(n)) {
- struct tnode *tn = (struct tnode *) n;
+ struct tnode *tn = (struct tnode *)n;
check_tnode(tn);
- n = tnode_get_child(tn ,tkey_extract_bits(key, tn->pos, tn->bits));
+ n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits));
BUG_ON(n && node_parent(n) != tn);
}
- l = (struct leaf *) n;
+ l = (struct leaf *)n;
if (!n || !tkey_equals(l->key, key))
return 0;
@@ -1555,7 +1567,7 @@ static int trie_leaf_remove(struct trie
t->size--;
tp = node_parent(n);
- tnode_free((struct tnode *) n);
+ tnode_free((struct tnode *)n);
if (tp) {
cindex = tkey_extract_bits(key, tp->pos, tp->bits);
@@ -1572,7 +1584,7 @@ static int trie_leaf_remove(struct trie
*/
static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
{
- struct trie *t = (struct trie *) tb->tb_data;
+ struct trie *t = (struct trie *)tb->tb_data;
u32 key, mask;
int plen = cfg->fc_dst_len;
u8 tos = cfg->fc_tos;
@@ -1692,7 +1704,7 @@ static int trie_flush_leaf(struct trie *
static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf)
{
- struct node *c = (struct node *) thisleaf;
+ struct node *c = (struct node *)thisleaf;
struct tnode *p;
int idx;
struct node *trie = rcu_dereference(t->trie);
@@ -1701,10 +1713,10 @@ static struct leaf *nextleaf(struct trie
if (trie == NULL)
return NULL;
- if (IS_LEAF(trie)) /* trie w. just a leaf */
- return (struct leaf *) trie;
+ if (IS_LEAF(trie)) /* trie w. just a leaf */
+ return (struct leaf *)trie;
- p = (struct tnode*) trie; /* Start */
+ p = (struct tnode *)trie; /* Start */
} else
p = node_parent(c);
@@ -1718,7 +1730,7 @@ static struct leaf *nextleaf(struct trie
pos = 0;
last = 1 << p->bits;
- for (idx = pos; idx < last ; idx++) {
+ for (idx = pos; idx < last; idx++) {
c = rcu_dereference(p->child[idx]);
if (!c)
@@ -1726,26 +1738,28 @@ static struct leaf *nextleaf(struct trie
/* Decend if tnode */
while (IS_TNODE(c)) {
- p = (struct tnode *) c;
+ p = (struct tnode *)c;
idx = 0;
/* Rightmost non-NULL branch */
if (p && IS_TNODE(p))
while (!(c = rcu_dereference(p->child[idx]))
- && idx < (1<<p->bits)) idx++;
+ && idx < (1 << p->bits))
+ idx++;
/* Done with this tnode? */
if (idx >= (1 << p->bits) || !c)
goto up;
}
- return (struct leaf *) c;
+ return (struct leaf *)c;
}
up:
/* No more children go up one step */
- c = (struct node *) p;
+ c = (struct node *)p;
p = node_parent(c);
}
- return NULL; /* Ready. Root of trie */
+
+ return NULL; /* Ready. Root of trie */
}
/*
@@ -1753,7 +1767,7 @@ up:
*/
static int fn_trie_flush(struct fib_table *tb)
{
- struct trie *t = (struct trie *) tb->tb_data;
+ struct trie *t = (struct trie *)tb->tb_data;
struct leaf *ll = NULL, *l = NULL;
int found = 0, h;
@@ -1777,9 +1791,10 @@ static int fn_trie_flush(struct fib_tabl
static int trie_last_dflt = -1;
static void
-fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+fn_trie_select_default(struct fib_table *tb, const struct flowi *flp,
+ struct fib_result *res)
{
- struct trie *t = (struct trie *) tb->tb_data;
+ struct trie *t = (struct trie *)tb->tb_data;
int order, last_idx;
struct fib_info *fi = NULL;
struct fib_info *last_resort;
@@ -1807,8 +1822,7 @@ fn_trie_select_default(struct fib_table
list_for_each_entry_rcu(fa, fa_head, fa_list) {
struct fib_info *next_fi = fa->fa_info;
- if (fa->fa_scope != res->scope ||
- fa->fa_type != RTN_UNICAST)
+ if (fa->fa_scope != res->scope || fa->fa_type != RTN_UNICAST)
continue;
if (next_fi->fib_priority > res->fi->fib_priority)
@@ -1854,12 +1868,13 @@ fn_trie_select_default(struct fib_table
atomic_inc(&last_resort->fib_clntref);
}
trie_last_dflt = last_idx;
- out:;
+out:
rcu_read_unlock();
}
-static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fib_table *tb,
- struct sk_buff *skb, struct netlink_callback *cb)
+static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
+ struct fib_table *tb, struct sk_buff *skb,
+ struct netlink_callback *cb)
{
int i, s_i;
struct fib_alias *fa;
@@ -1884,10 +1899,7 @@ static int fn_trie_dump_fa(t_key key, in
tb->tb_id,
fa->fa_type,
fa->fa_scope,
- xkey,
- plen,
- fa->fa_tos,
- fa->fa_info, 0) < 0) {
+ xkey, plen, fa->fa_tos, fa->fa_info, 0) < 0) {
cb->args[4] = i;
return -1;
}
@@ -1897,8 +1909,8 @@ static int fn_trie_dump_fa(t_key key, in
return skb->len;
}
-static int fn_trie_dump_plen(struct trie *t, int plen, struct fib_table *tb, struct sk_buff *skb,
- struct netlink_callback *cb)
+static int fn_trie_dump_plen(struct trie *t, int plen, struct fib_table *tb,
+ struct sk_buff *skb, struct netlink_callback *cb)
{
int h, s_h;
struct list_head *fa_head;
@@ -1911,7 +1923,7 @@ static int fn_trie_dump_plen(struct trie
continue;
if (h > s_h)
memset(&cb->args[4], 0,
- sizeof(cb->args) - 4*sizeof(cb->args[0]));
+ sizeof(cb->args) - 4 * sizeof(cb->args[0]));
fa_head = get_fa_head(l, plen);
@@ -1921,7 +1933,7 @@ static int fn_trie_dump_plen(struct trie
if (list_empty(fa_head))
continue;
- if (fn_trie_dump_fa(l->key, plen, fa_head, tb, skb, cb)<0) {
+ if (fn_trie_dump_fa(l->key, plen, fa_head, tb, skb, cb) < 0) {
cb->args[3] = h;
return -1;
}
@@ -1930,10 +1942,11 @@ static int fn_trie_dump_plen(struct trie
return skb->len;
}
-static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb)
+static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb,
+ struct netlink_callback *cb)
{
int m, s_m;
- struct trie *t = (struct trie *) tb->tb_data;
+ struct trie *t = (struct trie *)tb->tb_data;
s_m = cb->args[2];
@@ -1943,9 +1956,9 @@ static int fn_trie_dump(struct fib_table
continue;
if (m > s_m)
memset(&cb->args[3], 0,
- sizeof(cb->args) - 3*sizeof(cb->args[0]));
+ sizeof(cb->args) - 3 * sizeof(cb->args[0]));
- if (fn_trie_dump_plen(t, 32-m, tb, skb, cb)<0) {
+ if (fn_trie_dump_plen(t, 32 - m, tb, skb, cb) < 0) {
cb->args[2] = m;
goto out;
}
@@ -1961,9 +1974,9 @@ out:
/* Fix more generic FIB names for init later */
#ifdef CONFIG_IP_MULTIPLE_TABLES
-struct fib_table * fib_hash_init(u32 id)
+struct fib_table *fib_hash_init(u32 id)
#else
-struct fib_table * __init fib_hash_init(u32 id)
+struct fib_table *__init fib_hash_init(u32 id)
#endif
{
struct fib_table *tb;
@@ -1972,8 +1985,7 @@ struct fib_table * __init fib_hash_init(
if (fn_alias_kmem == NULL)
fn_alias_kmem = kmem_cache_create("ip_fib_alias",
sizeof(struct fib_alias),
- 0, SLAB_HWCACHE_ALIGN,
- NULL);
+ 0, SLAB_HWCACHE_ALIGN, NULL);
tb = kmalloc(sizeof(struct fib_table) + sizeof(struct trie),
GFP_KERNEL);
@@ -1989,7 +2001,7 @@ struct fib_table * __init fib_hash_init(
tb->tb_dump = fn_trie_dump;
memset(tb->tb_data, 0, sizeof(struct trie));
- t = (struct trie *) tb->tb_data;
+ t = (struct trie *)tb->tb_data;
trie_init(t);
@@ -1999,7 +2011,8 @@ struct fib_table * __init fib_hash_init(
trie_main = t;
if (id == RT_TABLE_LOCAL)
- printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);
+ printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n",
+ VERSION);
return tb;
}
@@ -2026,7 +2039,7 @@ static struct node *fib_trie_get_next(st
pr_debug("get_next iter={node=%p index=%d depth=%d}\n",
iter->tnode, iter->index, iter->depth);
rescan:
- while (cindex < (1<<tn->bits)) {
+ while (cindex < (1 << tn->bits)) {
struct node *n = tnode_get_child(tn, cindex);
if (n) {
@@ -2035,7 +2048,7 @@ rescan:
iter->index = cindex + 1;
} else {
/* push down one level */
- iter->tnode = (struct tnode *) n;
+ iter->tnode = (struct tnode *)n;
iter->index = 0;
++iter->depth;
}
@@ -2048,7 +2061,7 @@ rescan:
/* Current node exhausted, pop back up */
p = node_parent((struct node *)tn);
if (p) {
- cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1;
+ cindex = tkey_extract_bits(tn->key, p->pos, p->bits) + 1;
tn = p;
--iter->depth;
goto rescan;
@@ -2061,7 +2074,7 @@ rescan:
static struct node *fib_trie_get_first(struct fib_trie_iter *iter,
struct trie *t)
{
- struct node *n ;
+ struct node *n;
if (!t)
return NULL;
@@ -2073,13 +2086,13 @@ static struct node *fib_trie_get_first(s
if (n) {
if (IS_TNODE(n)) {
- iter->tnode = (struct tnode *) n;
+ iter->tnode = (struct tnode *)n;
iter->trie = t;
iter->index = 0;
iter->depth = 1;
} else {
iter->tnode = NULL;
- iter->trie = t;
+ iter->trie = t;
iter->index = 0;
iter->depth = 0;
}
@@ -2096,22 +2109,21 @@ static void trie_collect_stats(struct tr
memset(s, 0, sizeof(*s));
rcu_read_lock();
- for (n = fib_trie_get_first(&iter, t); n;
- n = fib_trie_get_next(&iter)) {
+ for (n = fib_trie_get_first(&iter, t); n; n = fib_trie_get_next(&iter)) {
if (IS_LEAF(n)) {
s->leaves++;
s->totdepth += iter.depth;
if (iter.depth > s->maxdepth)
s->maxdepth = iter.depth;
} else {
- const struct tnode *tn = (const struct tnode *) n;
+ const struct tnode *tn = (const struct tnode *)n;
int i;
s->tnodes++;
if (tn->bits < MAX_STAT_DEPTH)
s->nodesizes[tn->bits]++;
- for (i = 0; i < (1<<tn->bits); i++)
+ for (i = 0; i < (1 << tn->bits); i++)
if (!tn->child[i])
s->nullpointers++;
}
@@ -2127,11 +2139,12 @@ static void trie_show_stats(struct seq_f
unsigned i, max, pointers, bytes, avdepth;
if (stat->leaves)
- avdepth = stat->totdepth*100 / stat->leaves;
+ avdepth = stat->totdepth * 100 / stat->leaves;
else
avdepth = 0;
- seq_printf(seq, "\tAver depth: %d.%02d\n", avdepth / 100, avdepth % 100 );
+ seq_printf(seq, "\tAver depth: %d.%02d\n", avdepth / 100,
+ avdepth % 100);
seq_printf(seq, "\tMax depth: %u\n", stat->maxdepth);
seq_printf(seq, "\tLeaves: %u\n", stat->leaves);
@@ -2141,14 +2154,14 @@ static void trie_show_stats(struct seq_f
bytes += sizeof(struct tnode) * stat->tnodes;
max = MAX_STAT_DEPTH;
- while (max > 0 && stat->nodesizes[max-1] == 0)
+ while (max > 0 && stat->nodesizes[max - 1] == 0)
max--;
pointers = 0;
for (i = 1; i <= max; i++)
if (stat->nodesizes[i] != 0) {
- seq_printf(seq, " %d: %d", i, stat->nodesizes[i]);
- pointers += (1<<i) * stat->nodesizes[i];
+ seq_printf(seq, " %d: %d", i, stat->nodesizes[i]);
+ pointers += (1 << i) * stat->nodesizes[i];
}
seq_putc(seq, '\n');
seq_printf(seq, "\tPointers: %d\n", pointers);
@@ -2159,12 +2172,15 @@ static void trie_show_stats(struct seq_f
#ifdef CONFIG_IP_FIB_TRIE_STATS
seq_printf(seq, "Counters:\n---------\n");
- seq_printf(seq,"gets = %d\n", t->stats.gets);
- seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
- seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
- seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
- seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
- seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
+ seq_printf(seq, "gets = %d\n", t->stats.gets);
+ seq_printf(seq, "backtracks = %d\n", t->stats.backtrack);
+ seq_printf(seq, "semantic match passed = %d\n",
+ t->stats.semantic_match_passed);
+ seq_printf(seq, "semantic match miss = %d\n",
+ t->stats.semantic_match_miss);
+ seq_printf(seq, "null node hit= %d\n", t->stats.null_node_hit);
+ seq_printf(seq, "skipped node resize = %d\n",
+ t->stats.resize_node_skipped);
#ifdef CLEAR_STATS
memset(&(t->stats), 0, sizeof(t->stats));
#endif
@@ -2179,7 +2195,8 @@ static int fib_triestat_seq_show(struct
if (!stat)
return -ENOMEM;
- seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
+ seq_printf(seq,
+ "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
sizeof(struct leaf), sizeof(struct tnode));
if (trie_local) {
@@ -2211,8 +2228,7 @@ static const struct file_operations fib_
.release = single_release,
};
-static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
- loff_t pos)
+static struct node *fib_trie_get_idx(struct fib_trie_iter *iter, loff_t pos)
{
loff_t idx = 0;
struct node *n;
@@ -2231,7 +2247,7 @@ static struct node *fib_trie_get_idx(str
return NULL;
}
-static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
+static void *fib_trie_seq_start(struct seq_file *seq, loff_t * pos)
{
rcu_read_lock();
if (*pos == 0)
@@ -2239,7 +2255,7 @@ static void *fib_trie_seq_start(struct s
return fib_trie_get_idx(seq->private, *pos - 1);
}
-static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t * pos)
{
struct fib_trie_iter *iter = seq->private;
void *l = v;
@@ -2267,7 +2283,8 @@ static void fib_trie_seq_stop(struct seq
static void seq_indent(struct seq_file *seq, int n)
{
- while (n-- > 0) seq_puts(seq, " ");
+ while (n-- > 0)
+ seq_puts(seq, " ");
}
static inline const char *rtn_scope(enum rt_scope_t s)
@@ -2275,11 +2292,16 @@ static inline const char *rtn_scope(enum
static char buf[32];
switch (s) {
- case RT_SCOPE_UNIVERSE: return "universe";
- case RT_SCOPE_SITE: return "site";
- case RT_SCOPE_LINK: return "link";
- case RT_SCOPE_HOST: return "host";
- case RT_SCOPE_NOWHERE: return "nowhere";
+ case RT_SCOPE_UNIVERSE:
+ return "universe";
+ case RT_SCOPE_SITE:
+ return "site";
+ case RT_SCOPE_LINK:
+ return "link";
+ case RT_SCOPE_HOST:
+ return "host";
+ case RT_SCOPE_NOWHERE:
+ return "nowhere";
default:
snprintf(buf, sizeof(buf), "scope=%d", s);
return buf;
@@ -2328,16 +2350,16 @@ static int fib_trie_seq_show(struct seq_
}
if (IS_TNODE(n)) {
- struct tnode *tn = (struct tnode *) n;
+ struct tnode *tn = (struct tnode *)n;
__be32 prf = htonl(mask_pfx(tn->key, tn->pos));
- seq_indent(seq, iter->depth-1);
+ seq_indent(seq, iter->depth - 1);
seq_printf(seq, " +-- %d.%d.%d.%d/%d %d %d %d\n",
NIPQUAD(prf), tn->pos, tn->bits, tn->full_children,
tn->empty_children);
} else {
- struct leaf *l = (struct leaf *) n;
+ struct leaf *l = (struct leaf *)n;
int i;
__be32 val = htonl(l->key);
@@ -2348,7 +2370,7 @@ static int fib_trie_seq_show(struct seq_
if (li) {
struct fib_alias *fa;
list_for_each_entry_rcu(fa, &li->falh, fa_list) {
- seq_indent(seq, iter->depth+1);
+ seq_indent(seq, iter->depth + 1);
seq_printf(seq, " /%d %s %s", i,
rtn_scope(fa->fa_scope),
rtn_type(fa->fa_type));
@@ -2384,7 +2406,7 @@ static int fib_trie_seq_open(struct inod
if (rc)
goto out_kfree;
- seq = file->private_data;
+ seq = file->private_data;
seq->private = s;
memset(s, 0, sizeof(*s));
out:
@@ -2405,7 +2427,8 @@ static const struct file_operations fib_
static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
{
static unsigned type2flags[RTN_MAX + 1] = {
- [7] = RTF_REJECT, [8] = RTF_REJECT,
+ [7] = RTF_REJECT,
+ [8] = RTF_REJECT,
};
unsigned flags = type2flags[type];
@@ -2442,7 +2465,7 @@ static int fib_route_seq_show(struct seq
if (IS_TNODE(l))
return 0;
- for (i=32; i>=0; i--) {
+ for (i = 32; i >= 0; i--) {
struct leaf_info *li = find_leaf_info(l, i);
struct fib_alias *fa;
__be32 mask, prefix;
@@ -2469,7 +2492,7 @@ static int fib_route_seq_show(struct seq
fi->fib_nh->nh_gw, flags, 0, 0,
fi->fib_priority,
mask,
- (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
+ fi->fib_advmss ? fi->fib_advmss + 40 : 0,
fi->fib_window,
fi->fib_rtt >> 3);
else
@@ -2505,7 +2528,7 @@ static int fib_route_seq_open(struct ino
if (rc)
goto out_kfree;
- seq = file->private_data;
+ seq = file->private_data;
seq->private = s;
memset(s, 0, sizeof(*s));
out:
--
^ permalink raw reply
* [RFT 2/4] fib_trie: convert macros to inline
From: Stephen Hemminger @ 2007-07-27 7:59 UTC (permalink / raw)
To: David S. Miller; +Cc: akpm, netdev
In-Reply-To: <20070727075917.470055328@linux-foundation.org>
[-- Attachment #1: trie-demacro.patch --]
[-- Type: text/plain, Size: 3347 bytes --]
Get rid of some of the macro's in this code. If only used once, just
expand the usage in that spot. Otherwise convert to inline.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/net/ipv4/fib_trie.c 2007-07-27 08:00:30.000000000 +0100
+++ b/net/ipv4/fib_trie.c 2007-07-27 08:41:22.000000000 +0100
@@ -85,16 +85,12 @@
#define MAX_STAT_DEPTH 32
#define KEYLENGTH (8*sizeof(t_key))
-#define MASK_PFX(k, l) (((l)==0)?0:(k >> (KEYLENGTH-l)) << (KEYLENGTH-l))
-#define TKEY_GET_MASK(offset, bits) (((bits)==0)?0:((t_key)(-1) << (KEYLENGTH - bits) >> offset))
typedef unsigned int t_key;
#define T_TNODE 0
#define T_LEAF 1
#define NODE_TYPE_MASK 0x1UL
-#define NODE_TYPE(node) ((node)->parent & NODE_TYPE_MASK)
-
#define IS_TNODE(n) (!(n->parent & T_LEAF))
#define IS_LEAF(n) (n->parent & T_LEAF)
@@ -175,7 +171,8 @@ static inline struct tnode *node_parent(
static inline void node_set_parent(struct node *node, struct tnode *ptr)
{
- rcu_assign_pointer(node->parent, (unsigned long)ptr | NODE_TYPE(node));
+ rcu_assign_pointer(node->parent,
+ (unsigned long)ptr | (node->parent & NODE_TYPE_MASK));
}
/* rcu_read_lock needs to be hold by caller from readside */
@@ -192,6 +189,11 @@ static inline int tnode_child_length(con
return 1 << tn->bits;
}
+static inline t_key mask_pfx(t_key k, unsigned short l)
+{
+ return (l == 0) ? 0 : k >> (KEYLENGTH - l) << (KEYLENGTH - l);
+}
+
static inline t_key tkey_extract_bits(t_key a, int offset, int bits)
{
if (offset < KEYLENGTH)
@@ -676,7 +678,7 @@ static struct tnode *inflate(struct trie
inode->pos == oldtnode->pos + oldtnode->bits &&
inode->bits > 1) {
struct tnode *left, *right;
- t_key m = TKEY_GET_MASK(inode->pos, 1);
+ t_key m = ~0U << (KEYLENGTH - 1) >> inode->pos;
left = tnode_new(inode->key&(~m), inode->pos + 1,
inode->bits - 1);
@@ -942,7 +944,7 @@ fib_find_node(struct trie *t, u32 key)
pos = 0;
n = rcu_dereference(t->trie);
- while (n != NULL && NODE_TYPE(n) == T_TNODE) {
+ while (n && IS_TNODE(n)) {
tn = (struct tnode *) n;
check_tnode(tn);
@@ -1021,7 +1023,7 @@ fib_insert_node(struct trie *t, int *err
* If it doesn't, we need to replace it with a T_TNODE.
*/
- while (n != NULL && NODE_TYPE(n) == T_TNODE) {
+ while (n && IS_TNODE(n)) {
tn = (struct tnode *) n;
check_tnode(tn);
@@ -1364,7 +1366,8 @@ fn_trie_lookup(struct fib_table *tb, con
bits = pn->bits;
if (!chopped_off)
- cindex = tkey_extract_bits(MASK_PFX(key, current_prefix_length), pos, bits);
+ cindex = tkey_extract_bits(mask_pfx(key, current_prefix_length),
+ pos, bits);
n = tnode_get_child(pn, cindex);
@@ -1450,8 +1453,8 @@ fn_trie_lookup(struct fib_table *tb, con
* to find a matching prefix.
*/
- node_prefix = MASK_PFX(cn->key, cn->pos);
- key_prefix = MASK_PFX(key, cn->pos);
+ node_prefix = mask_pfx(cn->key, cn->pos);
+ key_prefix = mask_pfx(key, cn->pos);
pref_mismatch = key_prefix^node_prefix;
mp = 0;
@@ -2327,7 +2330,7 @@ static int fib_trie_seq_show(struct seq_
if (IS_TNODE(n)) {
struct tnode *tn = (struct tnode *) n;
- __be32 prf = htonl(MASK_PFX(tn->key, tn->pos));
+ __be32 prf = htonl(mask_pfx(tn->key, tn->pos));
seq_indent(seq, iter->depth-1);
seq_printf(seq, " +-- %d.%d.%d.%d/%d %d %d %d\n",
--
^ permalink raw reply
* [RFT 3/4] fib_trie: fix sparse warnings
From: Stephen Hemminger @ 2007-07-27 7:59 UTC (permalink / raw)
To: David S. Miller; +Cc: akpm, netdev
In-Reply-To: <20070727075917.470055328@linux-foundation.org>
[-- Attachment #1: fib-trie-sparse.patch --]
[-- Type: text/plain, Size: 1265 bytes --]
There were a couple of places where sparse found declarations that covered
earlier declarations.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/net/ipv4/fib_trie.c 2007-07-27 08:41:46.000000000 +0100
+++ b/net/ipv4/fib_trie.c 2007-07-27 08:47:05.000000000 +0100
@@ -651,7 +651,6 @@ static struct node *resize(struct trie *
static struct tnode *inflate(struct trie *t, struct tnode *tn)
{
- struct tnode *inode;
struct tnode *oldtnode = tn;
int olen = tnode_child_length(tn);
int i;
@@ -700,7 +699,7 @@ static struct tnode *inflate(struct trie
for (i = 0; i < olen; i++) {
struct node *node = tnode_get_child(oldtnode, i);
- struct tnode *left, *right;
+ struct tnode *left, *right, *inode;
int size, j;
/* An empty child */
@@ -1049,7 +1048,7 @@ fib_insert_node(struct trie *t, int *err
/* Case 1: n is a leaf. Compare prefixes */
if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) {
- struct leaf *l = (struct leaf *) n;
+ struct leaf *nl = (struct leaf *) n;
li = leaf_info_new(plen);
@@ -1059,7 +1058,7 @@ fib_insert_node(struct trie *t, int *err
}
fa_head = &li->falh;
- insert_leaf_info(&l->list, li);
+ insert_leaf_info(&nl->list, li);
goto done;
}
t->size++;
--
^ permalink raw reply
* [RFT 1/4] fib_trie: use inline for node_parent references
From: Stephen Hemminger @ 2007-07-27 7:59 UTC (permalink / raw)
To: David S. Miller; +Cc: akpm, netdev
In-Reply-To: <20070727075917.470055328@linux-foundation.org>
[-- Attachment #1: trie-cleanup.patch --]
[-- Type: text/plain, Size: 5740 bytes --]
The use of macro's for set/referencing node parent causes issues with
the rcu macros. Convert them to inline and fix a couple of spots
where node_parent() was being called multiple times which added unneeded
barriers.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/net/ipv4/fib_trie.c 2007-07-27 07:34:25.000000000 +0100
+++ b/net/ipv4/fib_trie.c 2007-07-27 08:00:30.000000000 +0100
@@ -93,15 +93,8 @@ typedef unsigned int t_key;
#define T_TNODE 0
#define T_LEAF 1
#define NODE_TYPE_MASK 0x1UL
-#define NODE_PARENT(node) \
- ((struct tnode *)rcu_dereference(((node)->parent & ~NODE_TYPE_MASK)))
-
#define NODE_TYPE(node) ((node)->parent & NODE_TYPE_MASK)
-#define NODE_SET_PARENT(node, ptr) \
- rcu_assign_pointer((node)->parent, \
- ((unsigned long)(ptr)) | NODE_TYPE(node))
-
#define IS_TNODE(n) (!(n->parent & T_LEAF))
#define IS_LEAF(n) (n->parent & T_LEAF)
@@ -174,6 +167,16 @@ static void tnode_free(struct tnode *tn)
static struct kmem_cache *fn_alias_kmem __read_mostly;
static struct trie *trie_local = NULL, *trie_main = NULL;
+static inline struct tnode *node_parent(struct node *node)
+{
+ struct tnode *parent = (struct tnode *)(node->parent & ~NODE_TYPE_MASK);
+ return rcu_dereference(parent);
+}
+
+static inline void node_set_parent(struct node *node, struct tnode *ptr)
+{
+ rcu_assign_pointer(node->parent, (unsigned long)ptr | NODE_TYPE(node));
+}
/* rcu_read_lock needs to be hold by caller from readside */
@@ -446,7 +449,7 @@ static void tnode_put_child_reorg(struct
tn->full_children++;
if (n)
- NODE_SET_PARENT(n, tn);
+ node_set_parent(n, tn);
rcu_assign_pointer(tn->child[i], n);
}
@@ -481,7 +484,7 @@ static struct node *resize(struct trie *
continue;
/* compress one level */
- NODE_SET_PARENT(n, NULL);
+ node_set_parent(n, NULL);
tnode_free(tn);
return n;
}
@@ -636,7 +639,7 @@ static struct node *resize(struct trie *
/* compress one level */
- NODE_SET_PARENT(n, NULL);
+ node_set_parent(n, NULL);
tnode_free(tn);
return n;
}
@@ -961,24 +964,21 @@ fib_find_node(struct trie *t, u32 key)
static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
{
int wasfull;
- t_key cindex, key;
- struct tnode *tp = NULL;
-
- key = tn->key;
+ t_key cindex, key = tn->key;
+ struct tnode *tp;
- while (tn != NULL && NODE_PARENT(tn) != NULL) {
-
- tp = NODE_PARENT(tn);
+ while (tn && (tp = node_parent((struct node *)tn)) ) {
cindex = tkey_extract_bits(key, tp->pos, tp->bits);
wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
tn = (struct tnode *) resize (t, (struct tnode *)tn);
tnode_put_child_reorg((struct tnode *)tp, cindex,(struct node*)tn, wasfull);
- if (!NODE_PARENT(tn))
+ tp = node_parent((struct node *) tn);
+ if (!tp)
break;
-
- tn = NODE_PARENT(tn);
+ tn = tp;
}
+
/* Handle last (top) tnode */
if (IS_TNODE(tn))
tn = (struct tnode*) resize(t, (struct tnode *)tn);
@@ -1031,7 +1031,7 @@ fib_insert_node(struct trie *t, int *err
pos = tn->pos + tn->bits;
n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits));
- BUG_ON(n && NODE_PARENT(n) != tn);
+ BUG_ON(n && node_parent(n) != tn);
} else
break;
}
@@ -1083,7 +1083,7 @@ fib_insert_node(struct trie *t, int *err
if (t->trie && n == NULL) {
/* Case 2: n is NULL, and will just insert a new leaf */
- NODE_SET_PARENT(l, tp);
+ node_set_parent((struct node *)l, tp);
cindex = tkey_extract_bits(key, tp->pos, tp->bits);
put_child(t, (struct tnode *)tp, cindex, (struct node *)l);
@@ -1114,7 +1114,7 @@ fib_insert_node(struct trie *t, int *err
goto err;
}
- NODE_SET_PARENT(tn, tp);
+ node_set_parent((struct node *)tn, tp);
missbit = tkey_extract_bits(key, newpos, 1);
put_child(t, tn, missbit, (struct node *)l);
@@ -1495,12 +1495,13 @@ backtrace:
if (chopped_off <= pn->bits) {
cindex &= ~(1 << (chopped_off-1));
} else {
- if (NODE_PARENT(pn) == NULL)
+ struct tnode *parent = node_parent((struct node *) pn);
+ if (!parent)
goto failed;
/* Get Child's index */
- cindex = tkey_extract_bits(pn->key, NODE_PARENT(pn)->pos, NODE_PARENT(pn)->bits);
- pn = NODE_PARENT(pn);
+ cindex = tkey_extract_bits(pn->key, parent->pos, parent->bits);
+ pn = parent;
chopped_off = 0;
#ifdef CONFIG_IP_FIB_TRIE_STATS
@@ -1536,7 +1537,7 @@ static int trie_leaf_remove(struct trie
check_tnode(tn);
n = tnode_get_child(tn ,tkey_extract_bits(key, tn->pos, tn->bits));
- BUG_ON(n && NODE_PARENT(n) != tn);
+ BUG_ON(n && node_parent(n) != tn);
}
l = (struct leaf *) n;
@@ -1551,7 +1552,7 @@ static int trie_leaf_remove(struct trie
t->revision++;
t->size--;
- tp = NODE_PARENT(n);
+ tp = node_parent(n);
tnode_free((struct tnode *) n);
if (tp) {
@@ -1703,7 +1704,7 @@ static struct leaf *nextleaf(struct trie
p = (struct tnode*) trie; /* Start */
} else
- p = (struct tnode *) NODE_PARENT(c);
+ p = node_parent(c);
while (p) {
int pos, last;
@@ -1740,7 +1741,7 @@ static struct leaf *nextleaf(struct trie
up:
/* No more children go up one step */
c = (struct node *) p;
- p = (struct tnode *) NODE_PARENT(p);
+ p = node_parent(c);
}
return NULL; /* Ready. Root of trie */
}
@@ -2043,7 +2044,7 @@ rescan:
}
/* Current node exhausted, pop back up */
- p = NODE_PARENT(tn);
+ p = node_parent((struct node *)tn);
if (p) {
cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1;
tn = p;
@@ -2317,7 +2318,7 @@ static int fib_trie_seq_show(struct seq_
if (v == SEQ_START_TOKEN)
return 0;
- if (!NODE_PARENT(n)) {
+ if (!node_parent(n)) {
if (iter->trie == trie_local)
seq_puts(seq, "<local>:\n");
else
--
^ permalink raw reply
* [RFT 0/4] fib_trie cleanup patches
From: Stephen Hemminger @ 2007-07-27 7:59 UTC (permalink / raw)
To: David S. Miller; +Cc: akpm, netdev
Here is a slightly revised version of the FIB trie cleanup patches.
I don't have a machine with anywhere near enough routes to test this,
so would someone with many routes give it a go and make sure nothing
got busted in the process.
--
^ permalink raw reply
* Re: [RFC] fib_trie: whitespace cleanup
From: Andrew Morton @ 2007-07-27 4:56 UTC (permalink / raw)
To: paulmck
Cc: Stephen Hemminger, Adrian Bunk, Robert Olsson, Ingo Molnar,
Josh Triplett, netdev
In-Reply-To: <20070726154421.GB24650@linux.vnet.ibm.com>
On Thu, 26 Jul 2007 08:44:21 -0700 "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> wrote:
> On Thu, Jul 26, 2007 at 11:49:42AM +0100, Stephen Hemminger wrote:
> > Whitespace cleanup run code through lindent then cleanup results.
> > Applys after other two patches.
> >
> > --- a/net/ipv4/fib_trie.c 2007-07-26 10:17:21.000000000 +0100
> > +++ b/net/ipv4/fib_trie.c 2007-07-26 11:47:52.000000000 +0100
> > @@ -156,7 +156,8 @@ struct trie {
> > };
> >
> > static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
> > -static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
> > +static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n,
> > + int wasfull);
> > static struct node *resize(struct trie *t, struct tnode *tn);
> > static struct tnode *inflate(struct trie *t, struct tnode *tn);
> > static struct tnode *halve(struct trie *t, struct tnode *tn);
> > @@ -167,13 +168,12 @@ static struct trie *trie_local = NULL, *
> >
> > static inline struct tnode *node_parent(struct node *node)
> > {
> > - return rcu_dereference((struct tnode *) (node->parent & ~NODE_TYPE_MASK));
> > + return rcu_dereference((struct tnode *)(node->parent & ~NODE_TYPE_MASK));
>
> The potential issue is applying rcu_dereference() to an rvalue
> as opposed to an lvalue. So how about the following?
>
I did this:
static inline struct tnode *node_parent(struct node *node)
{
struct tnode *ret;
ret = (struct tnode *)(node->parent & ~NODE_TYPE_MASK);
return rcu_dereference(ret);
}
^ permalink raw reply
* Re: [PATCH 1/2] [POWERPC] Add support of platforms without PHY to gianfar driver
From: Kumar Gala @ 2007-07-27 4:16 UTC (permalink / raw)
To: Jeff Garzik; +Cc: Vitaly Bordug, linuxppc-dev, netdev, linux-kernel
In-Reply-To: <46A7BEE2.8020504@garzik.org>
On Jul 25, 2007, at 4:21 PM, Jeff Garzik wrote:
> I'll let paulus and linuxppc merge this one (or not)...
That would most likely be me, than paulus. Since this is for a
Freescale PPC SoC.
- k
^ 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