* [Patch 1/1] AF_UNIX Datagram getpeersec (with minor fix)
From: Catherine Zhang @ 2006-06-18 6:17 UTC (permalink / raw)
To: netdev, davem, jmorris, chrisw, herbert, sds, tjaeger, akpm
Cc: latten, sergeh, gcwilson, czhang.us
Hi,
I added one file (include/linux/selinux.h) which was omitted from the
previous patch, and removed a couple of unnecessary changes.
Again, comments are welcome!
thanks,
Catherine
--
From: cxzhang@watson.ibm.com
This patch implements an API whereby an application can determine the
label of its peer's Unix datagram sockets via the auxiliary data mechanism of
recvmsg.
Patch purpose:
This patch enables a security-aware application to retrieve the
security context of the peer of a Unix datagram socket. The application
can then use this security context to determine the security context for
processing on behalf of the peer who sent the packet.
Patch design and implementation:
The design and implementation is very similar to the UDP case for INET
sockets. Basically we build upon the existing Unix domain socket API for
retrieving user credentials. Linux offers the API for obtaining user
credentials via ancillary messages (i.e., out of band/control messages
that are bundled together with a normal message). To retrieve the security
context, the application first indicates to the kernel such desire by
setting the SO_PASSSEC option via getsockopt. Then the application
retrieves the security context using the auxiliary data mechanism.
An example server application for Unix datagram socket should look like this:
toggle = 1;
toggle_len = sizeof(toggle);
setsockopt(sockfd, SOL_SOCKET, SO_PASSSEC, &toggle, &toggle_len);
recvmsg(sockfd, &msg_hdr, 0);
if (msg_hdr.msg_controllen > sizeof(struct cmsghdr)) {
cmsg_hdr = CMSG_FIRSTHDR(&msg_hdr);
if (cmsg_hdr->cmsg_len <= CMSG_LEN(sizeof(scontext)) &&
cmsg_hdr->cmsg_level == SOL_SOCKET &&
cmsg_hdr->cmsg_type == SCM_SECURITY) {
memcpy(&scontext, CMSG_DATA(cmsg_hdr), sizeof(scontext));
}
}
sock_setsockopt is enhanced with a new socket option SOCK_PASSSEC to allow
a server socket to receive security context of the peer.
Testing:
We have tested the patch by setting up Unix datagram client and server
applications. We verified that the server can retrieve the security context
using the auxiliary data mechanism of recvmsg.
---
include/asm-alpha/socket.h | 1 +
include/asm-arm/socket.h | 1 +
include/asm-arm26/socket.h | 1 +
include/asm-cris/socket.h | 1 +
include/asm-frv/socket.h | 1 +
include/asm-h8300/socket.h | 1 +
include/asm-i386/socket.h | 1 +
include/asm-ia64/socket.h | 1 +
include/asm-m32r/socket.h | 1 +
include/asm-m68k/socket.h | 1 +
include/asm-mips/socket.h | 1 +
include/asm-parisc/socket.h | 1 +
include/asm-powerpc/socket.h | 1 +
include/asm-s390/socket.h | 1 +
include/asm-sh/socket.h | 1 +
include/asm-sparc/socket.h | 1 +
include/asm-sparc64/socket.h | 1 +
include/asm-v850/socket.h | 1 +
include/asm-x86_64/socket.h | 1 +
include/asm-xtensa/socket.h | 1 +
include/linux/net.h | 1 +
include/linux/selinux.h | 15 +++++++++++++++
include/net/af_unix.h | 2 ++
include/net/scm.h | 14 ++++++++++++++
net/core/sock.c | 11 +++++++++++
net/unix/af_unix.c | 2 ++
security/selinux/exports.c | 11 +++++++++++
27 files changed, 76 insertions(+)
diff -puN include/asm-i386/socket.h~lsm-secpeer-unix include/asm-i386/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-i386/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-i386/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-x86_64/socket.h~lsm-secpeer-unix include/asm-x86_64/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-x86_64/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-x86_64/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-ia64/socket.h~lsm-secpeer-unix include/asm-ia64/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-ia64/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-ia64/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -57,5 +57,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_IA64_SOCKET_H */
diff -puN include/asm-powerpc/socket.h~lsm-secpeer-unix include/asm-powerpc/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-powerpc/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-powerpc/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -55,5 +55,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_POWERPC_SOCKET_H */
diff -puN include/asm-h8300/socket.h~lsm-secpeer-unix include/asm-h8300/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-h8300/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-h8300/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-s390/socket.h~lsm-secpeer-unix include/asm-s390/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-s390/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-s390/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -56,5 +56,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-mips/socket.h~lsm-secpeer-unix include/asm-mips/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-mips/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-mips/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -69,6 +69,7 @@ To add: #define SO_REUSEPORT 0x0200 /* A
#define SO_PEERSEC 30
#define SO_SNDBUFFORCE 31
#define SO_RCVBUFFORCE 33
+#define SO_PASSSEC 34
#ifdef __KERNEL__
diff -puN include/asm-alpha/socket.h~lsm-secpeer-unix include/asm-alpha/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-alpha/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-alpha/socket.h 2006-06-16 16:02:55.000000000 -0400
@@ -51,6 +51,7 @@
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_PEERSEC 30
+#define SO_PASSSEC 34
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 19
diff -puN include/asm-v850/socket.h~lsm-secpeer-unix include/asm-v850/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-v850/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-v850/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* __V850_SOCKET_H__ */
diff -puN include/asm-sh/socket.h~lsm-secpeer-unix include/asm-sh/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-sh/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-sh/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* __ASM_SH_SOCKET_H */
diff -puN include/asm-m68k/socket.h~lsm-secpeer-unix include/asm-m68k/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-m68k/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-m68k/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-arm/socket.h~lsm-secpeer-unix include/asm-arm/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-arm/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-arm/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-cris/socket.h~lsm-secpeer-unix include/asm-cris/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-cris/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-cris/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -50,6 +50,7 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-arm26/socket.h~lsm-secpeer-unix include/asm-arm26/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-arm26/socket.h~lsm-secpeer-unix 2006-06-12 17:56:06.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-arm26/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-frv/socket.h~lsm-secpeer-unix include/asm-frv/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-frv/socket.h~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-frv/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,6 +48,7 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-xtensa/socket.h~lsm-secpeer-unix include/asm-xtensa/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-xtensa/socket.h~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-xtensa/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -59,5 +59,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _XTENSA_SOCKET_H */
diff -puN include/asm-m32r/socket.h~lsm-secpeer-unix include/asm-m32r/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-m32r/socket.h~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-m32r/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 30
#define SO_PEERSEC 31
+#define SO_PASSSEC 34
#endif /* _ASM_M32R_SOCKET_H */
diff -puN include/asm-parisc/socket.h~lsm-secpeer-unix include/asm-parisc/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-parisc/socket.h~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-parisc/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,5 +48,6 @@
#define SO_ACCEPTCONN 0x401c
#define SO_PEERSEC 0x401d
+#define SO_PASSSEC 0x401e
#endif /* _ASM_SOCKET_H */
diff -puN include/asm-sparc/socket.h~lsm-secpeer-unix include/asm-sparc/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-sparc/socket.h~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-sparc/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,6 +48,7 @@
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_PEERSEC 0x001e
+#define SO_PASSSEC 0x001f
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
diff -puN include/asm-sparc64/socket.h~lsm-secpeer-unix include/asm-sparc64/socket.h
--- linux-2.6.17-rc6-mm2/include/asm-sparc64/socket.h~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/asm-sparc64/socket.h 2006-06-13 15:45:34.000000000 -0400
@@ -48,6 +48,7 @@
#define SCM_TIMESTAMP SO_TIMESTAMP
#define SO_PEERSEC 0x001e
+#define SO_PASSSEC 0x001f
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
diff -puN include/linux/net.h~lsm-secpeer-unix include/linux/net.h
--- linux-2.6.17-rc6-mm2/include/linux/net.h~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/linux/net.h 2006-06-13 15:45:34.000000000 -0400
@@ -61,6 +61,7 @@ typedef enum {
#define SOCK_ASYNC_WAITDATA 1
#define SOCK_NOSPACE 2
#define SOCK_PASSCRED 3
+#define SOCK_PASSSEC 4
#ifndef ARCH_HAS_SOCKET_TYPES
/**
diff -puN include/net/af_unix.h~lsm-secpeer-unix include/net/af_unix.h
--- linux-2.6.17-rc6-mm2/include/net/af_unix.h~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/net/af_unix.h 2006-06-13 15:45:34.000000000 -0400
@@ -53,10 +53,12 @@ struct unix_address {
struct unix_skb_parms {
struct ucred creds; /* Skb credentials */
struct scm_fp_list *fp; /* Passed files */
+ u32 sid; /* Security ID */
};
#define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb))
#define UNIXCREDS(skb) (&UNIXCB((skb)).creds)
+#define UNIXSID(skb) (&UNIXCB((skb)).sid)
#define unix_state_rlock(s) spin_lock(&unix_sk(s)->lock)
#define unix_state_runlock(s) spin_unlock(&unix_sk(s)->lock)
diff -puN include/net/scm.h~lsm-secpeer-unix include/net/scm.h
--- linux-2.6.17-rc6-mm2/include/net/scm.h~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/net/scm.h 2006-06-18 01:23:17.000000000 -0400
@@ -3,6 +3,9 @@
#include <linux/limits.h>
#include <linux/net.h>
+#include <linux/security.h>
+#include <linux/selinux.h>
+#include <net/sock.h>
/* Well, we should have at least one descriptor open
* to accept passed FDs 8)
@@ -19,6 +22,7 @@ struct scm_cookie
{
struct ucred creds; /* Skb credentials */
struct scm_fp_list *fp; /* Passed files */
+ u32 sid; /* Passed security ID */
unsigned long seq; /* Connection seqno */
};
@@ -42,6 +46,7 @@ static __inline__ int scm_send(struct so
scm->creds.gid = p->gid;
scm->creds.pid = p->tgid;
scm->fp = NULL;
+ selinux_get_sock_sid(sock, &scm->sid);
scm->seq = 0;
if (msg->msg_controllen <= 0)
return 0;
@@ -51,6 +56,9 @@ static __inline__ int scm_send(struct so
static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
struct scm_cookie *scm, int flags)
{
+ char *scontext;
+ int scontext_len, err;
+
if (!msg->msg_control)
{
if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
@@ -62,6 +70,12 @@ static __inline__ void scm_recv(struct s
if (test_bit(SOCK_PASSCRED, &sock->flags))
put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
+ if (test_bit(SOCK_PASSSEC, &sock->flags)) {
+ err = selinux_ctxid_to_string(scm->sid, &scontext, &scontext_len);
+ if (!err)
+ put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, scontext_len, scontext);
+ }
+
if (!scm->fp)
return;
diff -puN net/core/sock.c~lsm-secpeer-unix net/core/sock.c
--- linux-2.6.17-rc6-mm2/net/core/sock.c~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/net/core/sock.c 2006-06-13 15:45:34.000000000 -0400
@@ -565,6 +565,13 @@ set_rcvbuf:
ret = -ENONET;
break;
+ case SO_PASSSEC:
+ if (valbool)
+ set_bit(SOCK_PASSSEC, &sock->flags);
+ else
+ clear_bit(SOCK_PASSSEC, &sock->flags);
+ break;
+
/* We implement the SO_SNDLOWAT etc to
not be settable (1003.1g 5.3) */
default:
@@ -723,6 +730,10 @@ int sock_getsockopt(struct socket *sock,
v.val = sk->sk_state == TCP_LISTEN;
break;
+ case SO_PASSSEC:
+ v.val = test_bit(SOCK_PASSSEC, &sock->flags) ? 1 : 0;
+ break;
+
case SO_PEERSEC:
return security_socket_getpeersec_stream(sock, optval, optlen, len);
diff -puN net/unix/af_unix.c~lsm-secpeer-unix net/unix/af_unix.c
--- linux-2.6.17-rc6-mm2/net/unix/af_unix.c~lsm-secpeer-unix 2006-06-12 17:56:07.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/net/unix/af_unix.c 2006-06-13 15:45:34.000000000 -0400
@@ -1290,6 +1290,7 @@ static int unix_dgram_sendmsg(struct kio
memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
if (siocb->scm->fp)
unix_attach_fds(siocb->scm, skb);
+ memcpy(UNIXSID(skb), &siocb->scm->sid, sizeof(u32));
skb->h.raw = skb->data;
err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
@@ -1570,6 +1571,7 @@ static int unix_dgram_recvmsg(struct kio
memset(&tmp_scm, 0, sizeof(tmp_scm));
}
siocb->scm->creds = *UNIXCREDS(skb);
+ siocb->scm->sid = *UNIXSID(skb);
if (!(flags & MSG_PEEK))
{
diff -puN security/selinux/exports.c~lsm-secpeer-unix security/selinux/exports.c
--- linux-2.6.17-rc6-mm2/security/selinux/exports.c~lsm-secpeer-unix 2006-06-18 01:14:50.000000000 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/security/selinux/exports.c 2006-06-18 01:15:19.000000000 -0400
@@ -17,6 +17,7 @@
#include <linux/selinux.h>
#include <linux/fs.h>
#include <linux/ipc.h>
+#include <net/sock.h>
#include "security.h"
#include "objsec.h"
@@ -72,6 +73,16 @@ void selinux_get_task_sid(struct task_st
*sid = 0;
}
+void selinux_get_sock_sid(const struct socket *sock, u32 *sid)
+{
+ if (selinux_enabled) {
+ const struct inode *inode = SOCK_INODE(sock);
+ selinux_get_inode_sid(inode, sid);
+ return;
+ }
+ *sid = 0;
+}
+
int selinux_string_to_sid(char *str, u32 *sid)
{
if (selinux_enabled)
diff -puN include/linux/selinux.h~lsm-secpeer-unix include/linux/selinux.h
--- linux-2.6.17-rc6-mm2/include/linux/selinux.h~lsm-secpeer-unix 2006-06-18 01:44:44.198292264 -0400
+++ linux-2.6.17-rc6-mm2-cxzhang/include/linux/selinux.h 2006-06-18 01:29:36.000000000 -0400
@@ -18,6 +18,7 @@ struct selinux_audit_rule;
struct audit_context;
struct inode;
struct kern_ipc_perm;
+struct socket;
#ifdef CONFIG_SECURITY_SELINUX
@@ -119,6 +120,15 @@ void selinux_get_ipc_sid(const struct ke
void selinux_get_task_sid(struct task_struct *tsk, u32 *sid);
/**
+ * selinux_get_sock_sid - return the SID of socket
+ * @sock: the socket whose SID will be returned
+ * @sid: pointer to security context ID to be filled in.
+ *
+ * Returns nothing
+ */
+void selinux_get_sock_sid(const struct socket *sock, u32 *sid);
+
+/**
* selinux_string_to_sid - map a security context string to a security ID
* @str: the security context string to be mapped
* @sid: ID value returned via this.
@@ -193,6 +203,11 @@ static inline void selinux_get_task_sid(
*sid = 0;
}
+static inline void selinux_get_sock_sid(struct socket *sock, u32 *sid)
+{
+ *sid = 0;
+}
+
static inline int selinux_string_to_sid(const char *str, u32 *sid)
{
*sid = 0;
_
^ permalink raw reply
* Re: [Patch 1/1] AF_UNIX Datagram getpeersec (with minor fix)
From: James Morris @ 2006-06-18 8:04 UTC (permalink / raw)
To: Catherine Zhang
Cc: netdev, davem, jmorris, chrisw, herbert, sds, tjaeger, akpm,
latten, sergeh, gcwilson, czhang.us
In-Reply-To: <20060618061753.GA27681@jiayuguan.watson.ibm.com>
On Sun, 18 Jun 2006, Catherine Zhang wrote:
> Patch purpose:
>
> This patch enables a security-aware application to retrieve the
> security context of the peer of a Unix datagram socket. The application
> can then use this security context to determine the security context for
> processing on behalf of the peer who sent the packet.
I'd also mention here that this is to complement the SO_PEERSEC option for
stream sockets.
There's an implementation issue, which I'm sure has been mentioned
previously. This code should not be calling SELinux API functions.
> @@ -62,6 +70,12 @@ static __inline__ void scm_recv(struct s
> if (test_bit(SOCK_PASSCRED, &sock->flags))
> put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);
>
> + if (test_bit(SOCK_PASSSEC, &sock->flags)) {
> + err = selinux_ctxid_to_string(scm->sid, &scontext, &scontext_len);
The above is SELinux-specific code sitting in core networking code.
Look at the peersec stuff, it calls out to LSM hooks:
socket_getpeersec_stream
socket_getpeersec_dgram
These are the abstractions to be used for this in the core kernel, and the
SELinux code can then figure out specifically what to do based on the
protocol. Have a look at selinux_socket_getpeersec_stream() and see how
it behaves based on the protocol, to get an idea of the changes needed for
_dgram().
This needs to be reworked.
Look at ip_cmsg_recv_security() to see how this is done cleanly via an LSM
hook, without modifying core networking structures.
- James
--
James Morris
<jmorris@namei.org>
^ permalink raw reply
* Re: [PATCH] bcm43xx: enable shared key authentication
From: Michael Buesch @ 2006-06-18 9:31 UTC (permalink / raw)
To: Dan Williams; +Cc: Daniel Drake, linville, netdev
In-Reply-To: <1150599685.2519.7.camel@localhost.localdomain>
On Sunday 18 June 2006 05:01, Dan Williams wrote:
> On Fri, 2006-06-16 at 20:50 +0100, Daniel Drake wrote:
> > I recently patched softmac to enable shared key authentication. This small patch
> > will enable crazy or unfortunate bcm43xx users to use this new capability.
>
> Meaning that _until now_, softmac couldn't do Shared Key auth???
Yep.
--
Greetings Michael.
^ permalink raw reply
* Re: recommend a network card
From: bastard operater @ 2006-06-18 15:28 UTC (permalink / raw)
To: mb; +Cc: netdev
In-Reply-To: <200606172323.01781.mb@bu3sch.de>
>From: Michael Buesch <mb@bu3sch.de>
>To: "bastard operater" <bofh1234@hotmail.com>
>CC: netdev@vger.kernel.org
>Subject: Re: recommend a network card
>Date: Sat, 17 Jun 2006 23:23:01 +0200
>
>On Saturday 17 June 2006 23:12, bastard operater wrote:
> ^^^^^^^^^^^^^^^^
>People on this list like Real Names and are more
>motivated to help, if they know your name.
I forgot to change that. I will change it as soon as I send this email. My
name is Jason.
> > My 3Com 3C905B-TX is starting to malfunction and it is getting worse.
>So I
>
>I never had a malfunctioning NIC. What does it look like?
>Broken packages?
It loses its network connection (the systems says the card is unplugged) for
a second or two and then the connection comes back. Sometimes the
connection just stops working and I have to restart the network service.
> > I am in the market for a new NIC. The card has to work on Linux
>(natively)
> > and windows. I thought I would ask the experts if you have any
> > recommendations for a good 100MB PCI card?
>
>I have mostly RTL based cards (ranging from 10 to 1000 mbit).
>No problems so far. (But also no problem with my 3c905 since
>quite some time ;) )
How can I tell which cards use which chipset?
Thanks,
Jason
^ permalink raw reply
* Re: recommend a network card
From: Michael Buesch @ 2006-06-18 15:48 UTC (permalink / raw)
To: bastard operater; +Cc: netdev
In-Reply-To: <BAY101-F198A641697A687C99F13FEC8810@phx.gbl>
On Sunday 18 June 2006 17:28, bastard operater wrote:
> >I never had a malfunctioning NIC. What does it look like?
> >Broken packages?
>
> It loses its network connection (the systems says the card is unplugged) for
> a second or two and then the connection comes back. Sometimes the
> connection just stops working and I have to restart the network service.
uh, oh. Interresting.
Sure it is not a software bug in PCI hotplug or something?
(or something accidentally poking with fakephp)
I would test the card in another machine, before throwing it away.
> > > I am in the market for a new NIC. The card has to work on Linux
> >(natively)
> > > and windows. I thought I would ask the experts if you have any
> > > recommendations for a good 100MB PCI card?
> >
> >I have mostly RTL based cards (ranging from 10 to 1000 mbit).
> >No problems so far. (But also no problem with my 3c905 since
> >quite some time ;) )
>
> How can I tell which cards use which chipset?
Look at the chip ;)
One of my cards (100mbit) has a chip with the string
RTL8139D
printed on it.
There's usually only one or two chips on the card. You can't miss it.
It's the chip, which is connected directly to the PCI pins.
btw: This is not really the right list to ask such questions,
as it is not development related, but well... :)
--
Greetings Michael.
^ permalink raw reply
* Re: recommend a network card
From: Jason operater @ 2006-06-18 16:13 UTC (permalink / raw)
To: mb; +Cc: netdev
In-Reply-To: <200606181748.55398.mb@bu3sch.de>
>From: Michael Buesch <mb@bu3sch.de>
>To: "bastard operater" <bofh1234@hotmail.com>
>CC: netdev@vger.kernel.org
>Subject: Re: recommend a network card
>Date: Sun, 18 Jun 2006 17:48:55 +0200
>
>On Sunday 18 June 2006 17:28, bastard operater wrote:
> > >I never had a malfunctioning NIC. What does it look like?
> > >Broken packages?
> >
> > It loses its network connection (the systems says the card is unplugged)
>for
> > a second or two and then the connection comes back. Sometimes the
> > connection just stops working and I have to restart the network
>service.
>
>uh, oh. Interresting.
>Sure it is not a software bug in PCI hotplug or something?
>(or something accidentally poking with fakephp)
It worked great for the first 6 years. Only in the last year has it become
unstable. There have been no driver changes since 2001. My motherboard (7
years old, tyan tiger S1832D) does not support hotplug. I moved it to
another PC and it still has problems.
>I would test the card in another machine, before throwing it away.
>
> > > > I am in the market for a new NIC. The card has to work on Linux
> > >(natively)
> > > > and windows. I thought I would ask the experts if you have any
> > > > recommendations for a good 100MB PCI card?
> > >
> > >I have mostly RTL based cards (ranging from 10 to 1000 mbit).
> > >No problems so far. (But also no problem with my 3c905 since
> > >quite some time ;) )
> >
> > How can I tell which cards use which chipset?
>
>Look at the chip ;)
>One of my cards (100mbit) has a chip with the string
>RTL8139D
>printed on it.
>There's usually only one or two chips on the card. You can't miss it.
>It's the chip, which is connected directly to the PCI pins.
I don't have x-ray vision so I can't see through cardboard. :) Can you
recommand a specific card or groups of cards?
>btw: This is not really the right list to ask such questions,
> as it is not development related, but well... :)
Yeah, I know. I wanted to ask the experts. I don't want to buy a cheap
network card only to get it home and find it uses 75% of CPU during
transfers. Or even worse it is not supported by Linux. If you know of a
linux certified hardware list I would love to hear about it.
Thanks,
Jason
^ permalink raw reply
* [PATCH,RESEND] smc91x: support for logicpd pxa270 platform
From: Lennert Buytenhek @ 2006-06-18 17:16 UTC (permalink / raw)
To: netdev; +Cc: nico, peterb, mikee
This patch adds support for the smc91x on the LogicPD PXA270 to
the smc91x driver.
Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
--
This patch was previously submitted on March 28, but doesn't seem
to have made it into 2.6.17.
Index: linux-2.6.17/drivers/net/smc91x.h
===================================================================
--- linux-2.6.17.orig/drivers/net/smc91x.h
+++ linux-2.6.17/drivers/net/smc91x.h
@@ -129,6 +129,19 @@
#define SMC_insb(a, r, p, l) readsb((a) + (r), p, (l))
#define SMC_outsb(a, r, p, l) writesb((a) + (r), p, (l))
+#elif defined(CONFIG_MACH_LOGICPD_PXA270)
+
+#define SMC_CAN_USE_8BIT 0
+#define SMC_CAN_USE_16BIT 1
+#define SMC_CAN_USE_32BIT 0
+#define SMC_IO_SHIFT 0
+#define SMC_NOWAIT 1
+
+#define SMC_inw(a, r) readw((a) + (r))
+#define SMC_outw(v, a, r) writew(v, (a) + (r))
+#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
+
#elif defined(CONFIG_ARCH_INNOKOM) || \
defined(CONFIG_MACH_MAINSTONE) || \
defined(CONFIG_ARCH_PXA_IDP) || \
^ permalink raw reply
* Re: [RFT] Realtek 8168 ethernet support
From: Mourad De Clerck @ 2006-06-18 17:25 UTC (permalink / raw)
To: Francois Romieu; +Cc: netdev
In-Reply-To: <20060612222947.GC803@electric-eye.fr.zoreil.com>
[-- Attachment #1: Type: text/plain, Size: 1991 bytes --]
Hi,
sorry for the delayed response...
On 13/06/06 00:29, Francois Romieu wrote:
> wget goes faster, right ? Do you have some vmstat 1 output at hand
> for it ?
It does indeed go faster, and it seems a little bit more reliable, but
with big enough transfers it locks up too. See commandline-2.txt and
vmstat-2.txt - it gets through around 600-700MB before locking up. I
also noticed that at 3-4 points during the transfer it seemed to
"pause", and then continue.
> Ok but can you set correctly the link with the command which was told
> to fail in you first mail ? The patch could fix it.
Yes, indeed: doing "ethtool -s eth0 speed 10 autoneg off" switches it to
the slow speed, and keeps it there too (at 10Mb/s).
"ethtool eth0" still reports "Advertised auto-negotiation: Yes" and
"Auto-negotiation: on", which is probably not right. It also reports
"Advertised link modes: 10baseT/Full" only, which is probably correct.
It only actually restarts auto-negotiation when I issue the command
"ethtool -s eth0 autoneg on", at which point the speeds goes back up to
1000Mb/s - the expected behaviour. So it seems ethtool works better than
before wrt auto-negotiation.
> Can you try something like:
> dd if=/dev/zero bs=1024k count=1000 | ssh -c blowfish hell dd of=/tmp/1000m.bin
Well this transfer (from shuttle -> hell) completed successfully. See
commandline-3.txt and vmstat-3.txt; However I noticed the speed was only
around 7 MB/s and wondered if the link speed was maybe set to 100Mb/s,
so I immediately afterwards did a "wget"-test again, which locked up
after only 5%. The wget test however did confirm the link speed to be
1000Mb/s. See commandline-4.txt and vmstat-4.txt for that last, short test.
> May I assume that the freeze locks everything (keyboard, mouse, led) beyond
> the scp command itself ?
Yes indeed. My (usb) keyboard doesn't respond at all anymore, networking
is completely out, (usb) mouse freezes too. SysRq doesn't seem to help
much either.
-- Mourad
[-- Attachment #2: commandline-2.txt --]
[-- Type: text/plain, Size: 390 bytes --]
shuttle:~# wget http://hell/testfile.bin
--18:39:21-- http://hell/testfile.bin
=> `testfile.bin'
Resolving hell... 10.10.1.1
Connecting to hell|10.10.1.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1,073,741,824 (1.0G) [application/octet-stream]
56% [================================> ] 602,018,040 27.70M/s ETA 00:17
[-- Attachment #3: commandline-3.txt --]
[-- Type: text/plain, Size: 313 bytes --]
shuttle:~# dd if=/dev/zero bs=1024k count=1000 | ssh -c blowfish hell dd of=/tmp/1000m.bin
Password:
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 155.971 seconds, 6.7 MB/s
2047951+99 records in
2048000+0 records out
1048576000 bytes (1.0 GB) copied, 140.689 seconds, 7.5 MB/s
shuttle:~#
[-- Attachment #4: commandline-4.txt --]
[-- Type: text/plain, Size: 355 bytes --]
shuttle:~# wget http://hell/testfile.bin
--18:57:26-- http://hell/testfile.bin
=> `testfile.bin'
Resolving hell... 10.10.1.1
Connecting to hell|10.10.1.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1,073,741,824 (1.0G) [application/octet-stream]
5% [> ] 57,266,176 30.30M/s
[-- Attachment #5: vmstat-2.txt --]
[-- Type: text/plain, Size: 2170 bytes --]
shuttle:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 983108 4672 29140 0 0 33 11 452 64 1 6 92 1
0 0 0 983108 4672 29140 0 0 0 0 458 18 0 2 98 0
0 0 0 982556 4688 29588 0 0 464 0 492 65 1 2 90 7
0 0 0 981316 4692 30720 0 0 0 0 2029 162 0 2 98 0
0 0 0 951804 4724 59324 0 0 0 0 38927 3128 1 42 57 0
0 1 0 911380 4764 96528 0 0 4 66940 50360 10405 3 63 33 1
0 1 0 875916 4796 131716 0 0 0 0 41138 4251 5 69 0 26
1 1 0 842684 4828 164804 0 0 0 0 38724 4368 3 66 0 31
1 1 0 807468 4872 199296 0 0 0 204 43170 4254 4 59 9 28
1 0 0 772748 4908 232772 0 0 4 32516 39246 4071 3 67 22 8
0 2 0 737656 4940 266256 0 0 0 97720 38868 4612 4 66 30 0
0 2 0 737532 4940 266256 0 0 0 32768 663 23 0 5 0 95
0 2 0 738772 4940 266256 0 0 0 6724 551 19 0 3 0 97
1 1 0 718436 4972 288608 0 0 0 196 26291 2494 3 47 1 49
0 0 0 676276 5012 329108 0 0 0 0 54791 4380 3 59 2 36
0 2 0 639944 5048 362376 0 0 4 81856 44893 7185 2 54 9 35
0 2 0 640564 5048 362376 0 0 0 14268 618 19 0 2 0 98
0 2 0 641928 5048 362376 0 0 0 24 553 18 0 2 0 98
0 1 0 608944 5088 396016 0 0 0 128 45004 9135 4 52 6 38
0 1 0 571868 5124 431544 0 0 0 0 47833 9603 2 59 12 27
1 1 0 529212 5160 471104 0 0 0 84548 52399 4222 2 61 5 32
1 3 0 493500 5200 506492 0 0 4 16384 40790 4236 6 74 0 20
0 3 0 459276 5232 540684 0 0 0 7208 39859 4816 4 68 0 28
1 5 0 426400 5264 572964 0 0 0 276 37415 4565 6 61 0 33
0 2 0 400980 5296 598496 0 0 0 2672 30845 4263 4 50 1 45
[-- Attachment #6: vmstat-3.txt --]
[-- Type: text/plain, Size: 14231 bytes --]
shuttle:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 979352 11984 26012 0 0 123 29 437 118 2 3 92 3
0 0 0 979352 11984 26012 0 0 0 52 461 26 0 0 100 0
0 0 0 978540 11988 26316 0 0 308 0 471 53 0 1 95 4
0 0 0 978416 11988 26316 0 0 0 0 468 26 0 0 100 0
0 0 0 978416 11988 26328 0 0 12 0 466 25 1 0 98 1
0 0 0 978416 11988 26328 0 0 0 0 454 17 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 0 454 15 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 116 455 25 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 0 455 15 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 0 460 24 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 0 472 27 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 0 466 46 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 0 453 17 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 0 455 17 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 0 464 24 0 0 100 0
0 0 0 978416 11988 26328 0 0 0 0 469 27 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 622 79 1 0 99 0
0 0 0 978168 11988 26328 0 0 0 0 7304 808 3 3 94 0
0 0 0 978168 11988 26328 0 0 0 0 10653 1181 10 5 85 0
0 0 0 978168 11988 26328 0 0 0 0 10648 1223 29 7 64 0
0 0 0 978168 11988 26328 0 0 0 0 10474 1192 0 1 99 0
0 0 0 978168 11988 26328 0 0 0 0 10348 1172 24 4 73 0
0 0 0 978168 11988 26328 0 0 0 0 5704 625 9 2 89 0
1 0 0 978168 11988 26328 0 0 0 0 10385 1136 15 8 77 0
0 0 0 978168 11988 26328 0 0 0 0 10571 1182 15 4 81 0
0 0 0 978168 11988 26328 0 0 0 0 10443 1194 8 6 86 0
0 0 0 978168 11988 26328 0 0 0 0 10623 1205 20 2 78 0
0 0 0 978168 11988 26328 0 0 0 140 10600 1149 35 9 56 0
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 978168 11988 26328 0 0 0 0 10441 1217 21 7 72 0
0 0 0 978168 11988 26328 0 0 0 0 10424 1162 17 2 81 0
0 0 0 978168 11988 26328 0 0 0 0 10433 1146 5 1 94 0
0 0 0 978168 11988 26328 0 0 0 0 10576 1203 39 8 53 0
0 0 0 978168 11988 26328 0 0 0 0 10627 1217 44 4 52 0
0 0 0 978168 11988 26328 0 0 0 0 10529 1163 39 13 48 0
0 0 0 978168 11988 26328 0 0 0 0 10552 1215 18 5 77 0
1 0 0 978168 11988 26328 0 0 0 0 10459 1146 34 6 60 0
0 0 0 978168 11988 26328 0 0 0 0 10339 1127 3 6 91 0
0 0 0 978168 11988 26328 0 0 0 0 6178 673 13 4 83 0
0 0 0 978168 11988 26328 0 0 0 0 9142 1018 1 4 95 0
1 0 0 978168 11988 26328 0 0 0 0 6335 697 8 0 92 0
0 0 0 978168 11988 26328 0 0 0 0 5565 632 21 1 78 0
0 0 0 978168 11988 26328 0 0 0 0 454 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 455 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 453 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 458 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 453 15 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 455 19 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 453 15 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 19 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 2636 272 7 3 90 0
0 0 0 978168 11988 26328 0 0 0 0 10321 1159 14 2 84 0
0 0 0 978168 11988 26328 0 0 0 0 10597 1277 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 10545 1184 32 8 60 0
1 0 0 978168 11988 26328 0 0 0 0 9922 1104 19 6 75 0
0 0 0 978168 11988 26328 0 0 0 0 10417 1177 26 10 64 0
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 978168 11988 26328 0 0 0 0 10487 1200 15 17 68 0
0 0 0 978168 11988 26328 0 0 0 0 10436 1203 30 10 60 0
0 0 0 978168 11988 26328 0 0 0 0 10413 1191 12 3 85 0
0 0 0 978168 11988 26328 0 0 0 0 10496 1162 14 8 78 0
2 0 0 978168 11988 26328 0 0 0 0 10528 1164 20 11 69 0
0 0 0 978168 11988 26328 0 0 0 0 10586 1185 10 5 85 0
0 0 0 978168 11988 26328 0 0 0 0 10565 1163 1 4 95 0
0 0 0 978168 11988 26328 0 0 0 0 10610 1204 7 1 92 0
0 0 0 978168 11988 26328 0 0 0 0 10550 1170 25 5 70 0
1 0 0 978168 11988 26328 0 0 0 0 10530 1189 25 15 60 0
0 0 0 978168 11988 26328 0 0 0 0 8300 948 6 3 91 0
0 0 0 978168 11988 26328 0 0 0 0 8750 1036 4 15 81 0
1 0 0 978168 11988 26328 0 0 0 0 10626 1209 29 7 64 0
1 0 0 978168 11988 26328 0 0 0 0 10496 1170 16 10 74 0
0 0 0 978168 11988 26328 0 0 0 0 10455 1239 17 6 77 0
1 0 0 978168 11988 26328 0 0 0 0 9955 1105 10 2 88 0
0 0 0 978168 11988 26328 0 0 0 0 10361 1214 20 2 78 0
1 0 0 978168 11988 26328 0 0 0 0 10572 1192 14 3 83 0
0 0 0 978168 11988 26328 0 0 0 0 10490 1194 27 1 72 0
0 0 0 978168 11988 26328 0 0 0 0 10558 1308 2 3 95 0
0 0 0 978168 11988 26328 0 0 0 0 10543 1305 1 2 97 0
0 0 0 978168 11988 26328 0 0 0 0 9489 1084 10 2 88 0
1 0 0 978168 11988 26328 0 0 0 0 10428 1228 12 8 80 0
0 0 0 978168 11988 26328 0 0 0 0 10555 1200 12 3 85 0
0 0 0 978168 11988 26328 0 0 0 0 10477 1159 37 2 61 0
0 0 0 978168 11988 26328 0 0 0 0 10474 1175 38 6 56 0
0 0 0 978168 11988 26328 0 0 0 0 10544 1193 16 5 79 0
0 0 0 978168 11988 26328 0 0 0 0 10527 1157 18 2 80 0
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 978168 11988 26328 0 0 0 0 9445 1068 17 2 81 0
0 0 0 978168 11988 26328 0 0 0 0 10513 1209 36 4 60 0
0 0 0 978168 11988 26328 0 0 0 0 10530 1190 27 2 71 0
0 0 0 978168 11988 26328 0 0 0 0 7100 796 24 2 74 0
0 0 0 978168 11988 26328 0 0 0 0 9832 1109 15 14 71 0
0 0 0 978168 11988 26328 0 0 0 0 10455 1267 8 8 84 0
0 0 0 978168 11988 26328 0 0 0 0 10414 1224 2 3 95 0
0 0 0 978168 11988 26328 0 0 0 0 10336 1217 4 2 94 0
0 0 0 978168 11988 26328 0 0 0 0 10428 1176 9 5 86 0
1 0 0 978168 11988 26328 0 0 0 0 10411 1166 23 2 75 0
0 0 0 978168 11988 26328 0 0 0 0 7818 863 7 3 90 0
0 0 0 978168 11988 26328 0 0 0 0 454 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 15 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 453 19 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 455 15 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 453 19 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 15 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 455 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 453 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 455 16 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 453 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 15 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 19 0 0 100 0
1 0 0 978168 11988 26328 0 0 0 0 2096 211 7 2 91 0
0 0 0 978168 11988 26328 0 0 0 0 10167 1170 3 4 93 0
0 0 0 978168 11988 26328 0 0 0 0 10615 1197 3 2 95 0
0 0 0 978168 11988 26328 0 0 0 0 10404 1218 6 3 91 0
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 978168 11988 26328 0 0 0 0 10456 1153 35 8 57 0
0 0 0 978168 11988 26328 0 0 0 0 10497 1168 15 3 82 0
0 0 0 978168 11988 26328 0 0 0 0 10103 1146 19 8 73 0
1 0 0 978168 11988 26328 0 0 0 0 10472 1166 37 12 51 0
0 0 0 978168 11988 26328 0 0 0 0 10557 1163 44 2 54 0
1 0 0 978168 11988 26328 0 0 0 0 10531 1186 42 8 50 0
0 0 0 978168 11988 26328 0 0 0 0 10444 1191 41 9 50 0
1 0 0 978168 11988 26328 0 0 0 0 10562 1233 44 6 49 0
0 0 0 978168 11988 26328 0 0 0 0 10571 1205 16 4 80 0
0 0 0 978168 11988 26328 0 0 0 0 10582 1183 28 4 68 0
0 0 0 978168 11988 26328 0 0 0 0 10622 1179 22 8 70 0
0 0 0 978168 11988 26328 0 0 0 0 10615 1183 16 9 75 0
0 0 0 978168 11988 26328 0 0 0 0 10514 1180 15 4 81 0
1 0 0 978168 11988 26328 0 0 0 0 10371 1176 22 5 73 0
0 0 0 978168 11988 26328 0 0 0 0 9910 1088 23 6 71 0
0 0 0 978168 11988 26328 0 0 0 0 10480 1256 6 5 89 0
0 0 0 978168 11988 26328 0 0 0 0 10387 1278 0 1 99 0
1 0 0 978168 11988 26328 0 0 0 0 10572 1203 2 2 96 0
0 0 0 978168 11988 26328 0 0 0 0 10312 1200 8 0 92 0
0 0 0 978168 11988 26328 0 0 0 0 10462 1175 1 3 96 0
0 0 0 978168 11988 26328 0 0 0 0 10402 1225 1 1 98 0
1 0 0 978168 11988 26328 0 0 0 0 9556 1040 24 4 72 0
0 0 0 978168 11988 26328 0 0 0 0 10542 1184 10 8 82 0
0 0 0 978168 11988 26328 0 0 0 0 10575 1188 3 7 90 0
1 0 0 978168 11988 26328 0 0 0 0 10399 1166 15 0 85 0
0 0 0 978168 11988 26328 0 0 0 0 9151 1016 2 1 97 0
0 0 0 978168 11988 26328 0 0 0 0 7011 765 14 0 86 0
1 0 0 978168 11988 26328 0 0 0 0 10451 1171 22 5 73 0
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 978168 11988 26328 0 0 0 0 9359 1037 32 6 62 0
1 0 0 978168 11988 26328 0 0 0 0 9566 1071 34 11 55 0
2 0 0 978168 11988 26328 0 0 0 0 9284 1125 40 3 57 0
0 0 0 978168 11988 26328 0 0 0 0 6798 759 14 3 83 0
0 0 0 978168 11988 26328 0 0 0 0 455 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 15 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 19 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 453 15 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 19 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 454 15 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 455 19 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 455 17 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 6911 794 0 0 100 0
0 0 0 978168 11988 26328 0 0 0 0 10410 1149 32 2 66 0
0 0 0 978168 11988 26328 0 0 0 0 10557 1182 47 3 50 0
0 0 0 978168 11988 26328 0 0 0 0 10220 1164 12 6 82 0
0 0 0 978292 11988 26328 0 0 0 0 4756 521 5 9 86 0
0 0 0 978292 11988 26328 0 0 0 0 453 15 0 0 100 0
0 0 0 978308 11988 26328 0 0 0 0 455 19 0 0 100 0
0 0 0 978308 11988 26328 0 0 0 0 453 15 0 0 100 0
0 0 0 978432 11988 26328 0 0 0 0 455 17 0 0 100 0
0 0 0 978432 11988 26328 0 0 0 0 454 17 0 0 100 0
0 0 0 978432 11988 26328 0 0 0 0 454 17 0 0 100 0
0 0 0 978432 11988 26328 0 0 0 0 457 17 0 0 100 0
0 0 0 978432 11988 26328 0 0 0 0 453 17 0 0 100 0
shuttle:~#
[-- Attachment #7: vmstat-4.txt --]
[-- Type: text/plain, Size: 656 bytes --]
shuttle:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 0 978500 12136 26496 0 0 44 12 1629 191 3 2 94 1
0 0 0 977888 12144 26944 0 0 456 0 476 59 0 0 95 5
0 0 0 977888 12144 26944 0 0 0 0 456 17 0 0 100 0
0 0 0 977888 12144 26944 0 0 0 0 463 27 0 0 100 0
1 0 0 962140 12164 42048 0 0 0 0 20379 1810 2 23 75 0
1 1 0 919360 12204 81948 0 0 0 54492 52864 9317 2 62 36 0
^ permalink raw reply
* Re: [RFC] [patch 0/6] [Network namespace] introduction
From: Al Viro @ 2006-06-18 18:47 UTC (permalink / raw)
To: dlezcano; +Cc: linux-kernel, netdev, serue, haveblue, clg
In-Reply-To: <20060609210202.215291000@localhost.localdomain>
On Fri, Jun 09, 2006 at 11:02:02PM +0200, dlezcano@fr.ibm.com wrote:
> What is missing ?
> -----------------
> The routes are not yet isolated, that implies:
>
> - binding to another container's address is allowed
>
> - an outgoing packet which has an unset source address can
> potentially get another container's address
>
> - an incoming packet can be routed to the wrong container if there
> are several containers listening to the same addr:port
- renaming an interface in one "namespace" affects everyone.
^ permalink raw reply
* Re: [RFC] [patch 2/6] [Network namespace] Network device sharing by view
From: Al Viro @ 2006-06-18 18:53 UTC (permalink / raw)
To: dlezcano; +Cc: linux-kernel, netdev, serue, haveblue, clg
In-Reply-To: <20060609210625.144158000@localhost.localdomain>
On Fri, Jun 09, 2006 at 11:02:04PM +0200, dlezcano@fr.ibm.com wrote:
> + read_lock(&dev_base_lock);
> +
> + for (dev = dev_base; dev; dev = dev->next)
> + if (!strncmp(dev->name, devname, IFNAMSIZ))
> + break;
> +
> + if (!dev) {
> + ret = -ENODEV;
> + goto out;
> + }
> +
> + db = kmalloc(sizeof(*db), GFP_KERNEL);
deadlock.
Besides, holding references to net_device from userland is Not Good(tm).
^ permalink raw reply
* Re: [RFC] [patch 3/6] [Network namespace] Network devices isolation
From: Al Viro @ 2006-06-18 18:57 UTC (permalink / raw)
To: dlezcano; +Cc: linux-kernel, netdev, serue, haveblue, clg
In-Reply-To: <20060609210627.064168000@localhost.localdomain>
On Fri, Jun 09, 2006 at 11:02:05PM +0200, dlezcano@fr.ibm.com wrote:
> struct net_device *dev_get_by_name(const char *name)
> {
> + struct net_ns_dev_list *dev_list = &(net_ns()->dev_list);
> struct net_device *dev;
>
> - read_lock(&dev_base_lock);
> + read_lock(&dev_list->lock);
> dev = __dev_get_by_name(name);
> if (dev)
> dev_hold(dev);
> - read_unlock(&dev_base_lock);
> + read_unlock(&dev_list->lock);
> return dev;
And what would stop renames done via different lists from creating a
conflict? Incidentally, WTF protects the device name while we are
doing that lookup?
While we are at it, what are you going to do with sysfs?
ls /sys/class/net and watch the fun...
^ permalink raw reply
* Re: Network performance degradation from 2.6.11.12 to 2.6.16.20
From: Harry Edmon @ 2006-06-18 23:23 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Andrew Morton, linux-kernel, netdev
In-Reply-To: <4494C592.6090601@osdl.org>
Stephen Hemminger wrote:
>>
> Does this fix it?
> # sysctl -w net.ipv4.tcp_abc=0
Thanks for the suggestion. I will give it a try later tonight. Also Andrew -
sorry for the incorrect placement of my follow-up comments. I do appreciate
everyone's help in figuring this out.
--
Dr. Harry Edmon E-MAIL: harry@atmos.washington.edu
206-543-0547 harry@u.washington.edu
Dept of Atmospheric Sciences FAX: 206-543-0308
University of Washington, Box 351640, Seattle, WA 98195-1640
^ permalink raw reply
* System hangs after running 2.6.17rc6 with broadcom 4309 and device scape stack
From: Alex Davis @ 2006-06-19 0:18 UTC (permalink / raw)
To: netdev, linville
After running 2.6.17rc6 with device scape stack
(git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-dev.git)
for a few hours, my system hangs. Here is the last thing I see in my logs:
[4323255.189000] NETDEV WATCHDOG: wmaster0: transmit timed out
[4323255.189000] wmaster0: resetting interface.
[4323255.189000] bcm43xx_d80211: Controller RESET (IEEE reset) ...
[4323255.191000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2191:bcm43xx_mac_suspend()
[4323255.192000] ACPI: PCI interrupt for device 0000:02:03.0 disabled
[4323255.192000] ACPI: PCI Interrupt 0000:02:03.0[A] -> Link [LNKB] -> GSI 7 (level, low) -> IRQ 7
[4323255.198000] bcm43xx_d80211: Chip ID 0x4306, rev 0x3
[4323255.198000] bcm43xx_d80211: Number of cores: 5
[4323255.198000] bcm43xx_d80211: Core 0: ID 0x800, rev 0x4, vendor 0x4243, enabled
[4323255.198000] bcm43xx_d80211: Core 1: ID 0x812, rev 0x5, vendor 0x4243, disabled
[4323255.198000] bcm43xx_d80211: Core 2: ID 0x80d, rev 0x2, vendor 0x4243, enabled
[4323255.198000] bcm43xx_d80211: Core 3: ID 0x807, rev 0x2, vendor 0x4243, disabled
[4323255.198000] bcm43xx_d80211: Core 4: ID 0x804, rev 0x9, vendor 0x4243, enabled
[4323255.201000] bcm43xx_d80211: PHY connected
[4323255.201000] bcm43xx_d80211: Detected PHY: Version: 2, Type 2, Revision 2
[4323255.201000] bcm43xx_d80211: Detected Radio: ID: 2205017f (Manuf: 17f Ver: 2050 Rev: 2)
[4323255.201000] bcm43xx_d80211: Radio turned off
[4323255.201000] bcm43xx_d80211: Radio turned off
[4323255.201000] bcm43xx_d80211: Controller restarted
This has happened daily during the two days I've been running this version.
My log also has lots of these messages:
4322054.949000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2191:bcm43xx_mac_suspend()
[4322054.950000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2173:bcm43xx_mac_enable()
[4322114.953000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2191:bcm43xx_mac_suspend()
[4322114.970000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2173:bcm43xx_mac_enable()
[4322174.973000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2191:bcm43xx_mac_suspend()
[4322174.974000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2173:bcm43xx_mac_enable()
[4322234.977000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2191:bcm43xx_mac_suspend()
[4322234.994000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2173:bcm43xx_mac_enable()
[4322294.997000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2191:bcm43xx_mac_suspend()
The system hangs so hard not even alt-sysrq can wake it up.
This problem did not occur in the 2.6.17r4 or rc5 versions of the dscape stack.
System is a Dell Latitude D600 laptop.
#lsmod
rate_control 5312 0
bcm43xx_d80211 451456 0
80211 181512 2 rate_control,bcm43xx_d80211
snd_pcm_oss 43680 0
snd_mixer_oss 18688 1 snd_pcm_oss
ohci_hcd 21060 0
usbhid 41184 0
intel_agp 22044 1
uhci_hcd 23628 0
generic 4356 0 [permanent]
snd_intel8x0 32028 0
snd_ac97_codec 101408 1 snd_intel8x0
snd_ac97_bus 2240 1 snd_ac97_codec
snd_pcm 89668 3 snd_pcm_oss,snd_intel8x0,snd_ac97_codec
snd_timer 23172 1 snd_pcm
snd 52004 6
snd_pcm_oss,snd_mixer_oss,snd_intel8x0,snd_ac97_codec,snd_pcm,snd_timer
soundcore 8160 1 snd
snd_page_alloc 8904 2 snd_intel8x0,snd_pcm
8250_pci 20352 0
8250 26996 1 8250_pci
serial_core 19904 1 8250
tg3 114692 0
yenta_socket 26636 4
rsrc_nonstatic 12992 1 yenta_socket
pcmcia 35116 0
firmware_class 8768 2 bcm43xx_d80211,pcmcia
crc32 4096 1 pcmcia
pcmcia_core 40544 3 yenta_socket,rsrc_nonstatic,pcmcia
nls_iso8859_1 4032 1
ntfs 107828 1
usbkbd 6784 0
usbmouse 4992 0
agpgart 32236 1 intel_agp
usb_storage 35972 2
sd_mod 18496 3
scsi_mod 131624 2 usb_storage,sd_mod
ehci_hcd 31624 0
#lspci
02:03.0 Network controller: Broadcom Corporation BCM4309 802.11a/b/g (rev 03)
relevant part of .config:
CONFIG_BCM43XX_D80211=m
CONFIG_BCM43XX_D80211_DEBUG=y
CONFIG_BCM43XX_D80211_DMA=y
CONFIG_BCM43XX_D80211_PIO=y
CONFIG_BCM43XX_D80211_DMA_AND_PIO_MODE=y
# CONFIG_BCM43XX_D80211_DMA_MODE is not set
# CONFIG_BCM43XX_D80211_PIO_MODE is not set
Can test patches if necessary.
I code, therefore I am
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
^ permalink raw reply
* Re: System hangs after running 2.6.17rc6 with broadcom 4309 and device scape stack
From: Alex Davis @ 2006-06-19 1:25 UTC (permalink / raw)
To: netdev, linville
--- Alex Davis <alex14641@yahoo.com> wrote:
> After running 2.6.17rc6 with device scape stack
> (git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-dev.git)
> for a few hours, my system hangs. Here is the last thing I see in my logs:
>
> [4323255.189000] NETDEV WATCHDOG: wmaster0: transmit timed out
> [4323255.189000] wmaster0: resetting interface.
> [4323255.189000] bcm43xx_d80211: Controller RESET (IEEE reset) ...
> [4323255.191000] bcm43xx_d80211: ASSERTION FAILED (bcm->mac_suspended >= 0) at:
> drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:2191:bcm43xx_mac_suspend()
> [4323255.192000] ACPI: PCI interrupt for device 0000:02:03.0 disabled
> [4323255.192000] ACPI: PCI Interrupt 0000:02:03.0[A] -> Link [LNKB] -> GSI 7 (level, low) -> IRQ
> 7
> [4323255.198000] bcm43xx_d80211: Chip ID 0x4306, rev 0x3
> [4323255.198000] bcm43xx_d80211: Number of cores: 5
> [4323255.198000] bcm43xx_d80211: Core 0: ID 0x800, rev 0x4, vendor 0x4243, enabled
> [4323255.198000] bcm43xx_d80211: Core 1: ID 0x812, rev 0x5, vendor 0x4243, disabled
> [4323255.198000] bcm43xx_d80211: Core 2: ID 0x80d, rev 0x2, vendor 0x4243, enabled
> [4323255.198000] bcm43xx_d80211: Core 3: ID 0x807, rev 0x2, vendor 0x4243, disabled
> [4323255.198000] bcm43xx_d80211: Core 4: ID 0x804, rev 0x9, vendor 0x4243, enabled
> [4323255.201000] bcm43xx_d80211: PHY connected
> [4323255.201000] bcm43xx_d80211: Detected PHY: Version: 2, Type 2, Revision 2
> [4323255.201000] bcm43xx_d80211: Detected Radio: ID: 2205017f (Manuf: 17f Ver: 2050 Rev: 2)
> [4323255.201000] bcm43xx_d80211: Radio turned off
> [4323255.201000] bcm43xx_d80211: Radio turned off
> [4323255.201000] bcm43xx_d80211: Controller restarted
>
> This has happened daily during the two days I've been running this version.
[snip]
Some more info:
Here is dmesg output for module loading.
Jun 16 20:04:06 siafu kernel: [4294720.383000] bcm43xx_d80211 driver
Jun 16 20:04:06 siafu kernel: [4294720.393000] ACPI: PCI Interrupt 0000:02:03.0[A] -> Link [LNKB]
-> GSI 7 (level, low) -> IRQ 7
Jun 16 20:04:06 siafu kernel: [4294720.393000] bcm43xx_d80211: Chip ID 0x4306, rev 0x3
Jun 16 20:04:06 siafu kernel: [4294720.393000] bcm43xx_d80211: Number of cores: 5
Jun 16 20:04:06 siafu kernel: [4294720.393000] bcm43xx_d80211: Core 0: ID 0x800, rev 0x4, vendor
0x4243, enabled
Jun 16 20:04:06 siafu kernel: [4294720.393000] bcm43xx_d80211: Core 1: ID 0x812, rev 0x5, vendor
0x4243, disabled
Jun 16 20:04:06 siafu kernel: [4294720.393000] bcm43xx_d80211: Core 2: ID 0x80d, rev 0x2, vendor
0x4243, enabled
Jun 16 20:04:06 siafu kernel: [4294720.393000] bcm43xx_d80211: Core 3: ID 0x807, rev 0x2, vendor
0x4243, disabled
Jun 16 20:04:06 siafu kernel: [4294720.393000] bcm43xx_d80211: Core 4: ID 0x804, rev 0x9, vendor
0x4243, enabled
Jun 16 20:04:06 siafu kernel: [4294720.396000] bcm43xx_d80211: PHY connected
Jun 16 20:04:06 siafu kernel: [4294720.396000] bcm43xx_d80211: Detected PHY: Version: 2, Type 2,
Revision 2
Jun 16 20:04:06 siafu kernel: [4294720.396000] bcm43xx_d80211: Detected Radio: ID: 2205017f
(Manuf: 17f Ver: 2050 Rev: 2)
Jun 16 20:04:06 siafu kernel: [4294720.396000] bcm43xx_d80211: Radio turned off
Jun 16 20:04:06 siafu kernel: [4294720.396000] bcm43xx_d80211: Radio turned off
Jun 16 20:04:06 siafu kernel: [4294720.464000] wmaster0: Selected rate control algorithm 'simple'
Jun 16 20:04:06 siafu kernel: [4294720.505000] bcm43xx_d80211: Virtual interface added (type:
0x00000002, ID: 4, MAC: 00:90:96:ba:32:20)
Jun 16 20:04:06 siafu kernel: [4294720.511000] bcm43xx_d80211: PHY connected
Jun 16 20:04:07 siafu kernel: [4294720.779000] bcm43xx_d80211: Radio turned on
Jun 16 20:04:07 siafu kernel: [4294720.971000] bcm43xx_d80211: Chip initialized
Jun 16 20:04:07 siafu kernel: [4294720.972000] bcm43xx_d80211: DMA initialized
Jun 16 20:04:07 siafu kernel: [4294720.972000] bcm43xx_d80211: 80211 cores initialized
Jun 16 20:04:07 siafu kernel: [4294720.972000] bcm43xx_d80211: Keys cleared
Jun 16 20:04:07 siafu kernel: [4294720.988000] wmaster0: Does not support passive scan, disabled
Jun 16 20:04:09 siafu kernel: [4294723.027000] bcm43xx_d80211: ASSERTION FAILED
(bcm->interface.if_id == if_id) at:
drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c:4344:bcm43xx_config_interface()
Here is dmesg output while wpa_supplicant is starting:
Jun 16 20:04:14 siafu kernel: [4294728.406000] wlan0: starting scan
Jun 16 20:04:14 siafu kernel: [4294728.407000] HW CONFIG: channel=1 freq=2412 phymode=3
Jun 16 20:04:14 siafu kernel: [4294728.475000] HW CONFIG: channel=2 freq=2417 phymode=3
Jun 16 20:04:14 siafu kernel: [4294728.543000] HW CONFIG: channel=3 freq=2422 phymode=3
Jun 16 20:04:14 siafu kernel: [4294728.611000] HW CONFIG: channel=4 freq=2427 phymode=3
Jun 16 20:04:14 siafu kernel: [4294728.679000] HW CONFIG: channel=5 freq=2432 phymode=3
Jun 16 20:04:14 siafu kernel: [4294728.747000] HW CONFIG: channel=6 freq=2437 phymode=3
Jun 16 20:04:15 siafu kernel: [4294728.815000] HW CONFIG: channel=7 freq=2442 phymode=3
Jun 16 20:04:15 siafu kernel: [4294728.883000] HW CONFIG: channel=8 freq=2447 phymode=3
Jun 16 20:04:15 siafu kernel: [4294728.951000] HW CONFIG: channel=9 freq=2452 phymode=3
Jun 16 20:04:15 siafu kernel: [4294729.019000] HW CONFIG: channel=10 freq=2457 phymode=3
Jun 16 20:04:15 siafu kernel: [4294729.087000] HW CONFIG: channel=11 freq=2462 phymode=3
Jun 16 20:04:15 siafu kernel: [4294729.170000] HW CONFIG: channel=1 freq=2412 phymode=3
Jun 16 20:04:15 siafu kernel: [4294729.178000] wlan0: scan completed
Jun 16 20:04:15 siafu kernel: [4294729.178000] HW CONFIG: channel=6 freq=2437 phymode=3
Jun 16 20:04:15 siafu kernel: [4294729.186000] wlan0: Initial auth_alg=0
Jun 16 20:04:15 siafu kernel: [4294729.186000] wlan0: authenticate with AP xx:xx:xx:xx:xx:xx
Jun 16 20:04:15 siafu kernel: [4294729.187000] wlan0: RX authentication from XX:XX:XX:XX:XX:XX
(alg=0 transaction=2 status=0)
Jun 16 20:04:15 siafu kernel: [4294729.187000] wlan0: authenticated
Jun 16 20:04:15 siafu kernel: [4294729.187000] wlan0: associate with AP XX:XX:XX:XX:XX:XX
Jun 16 20:04:15 siafu kernel: [4294729.189000] wlan0: RX AssocResp from XX:XX:XX:XX:XX:XX
(capab=0x411 status=0 aid=4)
Jun 16 20:04:15 siafu kernel: [4294729.189000] wlan0: associated
Jun 16 20:04:15 siafu kernel: [4294729.190000] wmaster0: Added STA XX:XX:XX:XX:XX:XX
I am using WEP encryption.
I code, therefore I am
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
^ permalink raw reply
* Re: [PATCH] Right prototype of __raw_v4_lookup()
From: Al Viro @ 2006-06-19 1:34 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: David Miller, netdev
In-Reply-To: <20060607113839.GA7268@martell.zuzino.mipt.ru>
On Wed, Jun 07, 2006 at 03:38:39PM +0400, Alexey Dobriyan wrote:
> I think, yes. Al Viro is sitting on terabytes of endian annotations in
> networking code. See net-endian.b* branches at
> git://git.kernel.org/pub/scm/linux/kernel/git/viro/bird.git
> I don't know if he considers them ready.
I do not. I _am_ going to finish that in this cycle, though; this stuff
got stalled on some sparse modifications needed to teach the sucker how
to deal with the next biggest bunch of annotation problems. Need to
sort that out first; I do know how to deal with that mess, just need to
find time and do so.
^ permalink raw reply
* Re: [1/1] connector: export cn_already_initialized.
From: Evgeniy Polyakov @ 2006-06-19 5:30 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20060516.161406.23276754.davem@davemloft.net>
On Tue, May 16, 2006 at 04:14:06PM -0700, David S. Miller (davem@davemloft.net) wrote:
> From: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
> Date: Sat, 6 May 2006 12:40:45 +0400
>
> > Some external patches, which can be built both as static build and as
> > module just check that value, and thus will fail with unresolved symbol
> > when cn and module are built as modules.
> >
> > The right set of operations should be following:
> > If external module is loaded and cn is not loaded or compiled into the
> > kernel, insmod will just fail with unresolved symbol (cn_add_callback and others),
> > if cn is already loaded or was built into the tree, then it has been
> > initialized already and there is no need to check that value, external
> > module should be just loaded.
> >
> > I think the right solution is to call external init functions after cn
> > init function, but it's ordering is not always known.
>
> In-kernel build of connector subsystem can be handled by
> making cn_init a "subsystem_init()", it will then be setup
> before any possible static or modular reference as long as
> those modules use module_init().
>
> For modular case of connector, dependency of module on connector
> module should handle all ordering issues, making any ordering
> issue take care of itself.
Attached patch declares connector init function as subsys_init()
and returns -EAGAIN in case connector is not initialized yet.
Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 505677f..d1d964f 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -306,6 +306,9 @@ int cn_add_callback(struct cb_id *id, ch
int err;
struct cn_dev *dev = &cdev;
+ if (!cn_already_initialized)
+ return -EAGAIN;
+
err = cn_queue_add_callback(dev->cbdev, name, id, callback);
if (err)
return err;
@@ -433,7 +436,7 @@ static void cn_callback(void *data)
up(¬ify_lock);
}
-static int __init cn_init(void)
+static int __devinit cn_init(void)
{
struct cn_dev *dev = &cdev;
int err;
@@ -454,21 +458,22 @@ static int __init cn_init(void)
sock_release(dev->nls->sk_socket);
return -EINVAL;
}
+
+ cn_already_initialized = 1;
err = cn_add_callback(&dev->id, "connector", &cn_callback);
if (err) {
+ cn_already_initialized = 0;
cn_queue_free_dev(dev->cbdev);
if (dev->nls->sk_socket)
sock_release(dev->nls->sk_socket);
return -EINVAL;
}
- cn_already_initialized = 1;
-
return 0;
}
-static void __exit cn_fini(void)
+static void __devexit cn_fini(void)
{
struct cn_dev *dev = &cdev;
@@ -480,7 +485,7 @@ static void __exit cn_fini(void)
sock_release(dev->nls->sk_socket);
}
-module_init(cn_init);
+subsys_initcall(cn_init);
module_exit(cn_fini);
EXPORT_SYMBOL_GPL(cn_add_callback);
--
Evgeniy Polyakov
^ permalink raw reply related
* [PATCH] [PKT_SCHED]: PSCHED_TADD() and PSCHED_TADD2() can result,tv_usec >= 1000000
From: Shuya MAEDA @ 2006-06-19 7:05 UTC (permalink / raw)
To: netdev
I found two problems in PSCHED_TADD() and PSCHED_TADD2().
1) These function increment tv_sec if tv_usec > 1000000.
But I think it should "if tv_usec >= 1000000".
2) tv_usec became 1200000 or more when I used CBQ and
experimented it. It is not correct to exceed 1000000
because tv_usec is micro seconds.
To fix 2), I think that it should do "delta / 1000000",
add the quotient to tv_sec, and add the remainder to
tv_usec.
In both cases, because time when the transmission is restarted
reaches an illegal value, it is not possible to communicate at
the set rate.
To fix these problem I create following patch.
Are there any comments?
[Experiment]
* kernel: linux-2.6.15.5
* CBQ settings
----------------------------------------------------------
tc qdisc add dev $IF root handle 1:0 cbq bandwidth 100Mbit \
avpkt 1000 mpu 64 ewma 5 cell 8
tc class add dev $IF parent 1:0 classid 1:10 cbq rate 32Kbit \
prio 1 ewma 5 cell 8 avpkt 138 mpu 64 bandwidth 100Mbit \
minburst 25 maxburst 50 bounded isolated
tc filter add dev $IF parent 1:0 protocol ip prio 16 u32 match \
ip dport 4952 0xffff flowid 1:10
-----------------------------------------------------------
* Traffic
dst port 4952: 138byte per 20msec.
[Result]
* In cbq_ovl_classic():
cl->undertime = { tv_sec = 1150368540, tv_usec = 1208301 }
~~~~~~~~~~~~~~~~~~
q->now = { tv_sec = 1150368539, tv_usec = 878917 }
delay = 1329384
cl->avgidle = -14781
cl->offtime = 1295394
[Patch]
diff -Nur linux-2.6.17-rc6.orig/include/net/pkt_sched.h linux-2.6.17-rc6.mypatch/include/net/pkt_sched.h
--- linux-2.6.17-rc6.orig/include/net/pkt_sched.h 2006-06-06 09:57:02.000000000 +0900
+++ linux-2.6.17-rc6.mypatch/include/net/pkt_sched.h 2006-06-16 11:29:08.000000000 +0900
@@ -169,17 +169,31 @@
#define PSCHED_TADD2(tv, delta, tv_res) \
({ \
- int __delta = (tv).tv_usec + (delta); \
- (tv_res).tv_sec = (tv).tv_sec; \
- if (__delta > USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \
- (tv_res).tv_usec = __delta; \
+ int __delta = (delta); \
+ (tv_res) = (tv); \
+ if((delta) > USEC_PER_SEC) { \
+ (tv_res).tv_sec += (delta) / USEC_PER_SEC; \
+ __delta -= (delta) % USEC_PER_SEC; \
+ } \
+ (tv_res).tv_usec += __delta; \
+ if((tv_res).tv_usec >= USEC_PER_SEC) { \
+ (tv_res).tv_sec++; \
+ (tv_res).tv_usec -= USEC_PER_SEC; \
+ } \
})
#define PSCHED_TADD(tv, delta) \
({ \
- (tv).tv_usec += (delta); \
- if ((tv).tv_usec > USEC_PER_SEC) { (tv).tv_sec++; \
- (tv).tv_usec -= USEC_PER_SEC; } \
+ int __delta = (delta); \
+ if((delta) > USEC_PER_SEC) { \
+ (tv).tv_sec += (delta) / USEC_PER_SEC; \
+ __delta -= (delta) % USEC_PER_SEC; \
+ } \
+ (tv).tv_usec += __delta; \
+ if((tv).tv_usec >= USEC_PER_SEC) { \
+ (tv).tv_sec++; \
+ (tv).tv_usec -= USEC_PER_SEC; \
+ } \
})
/* Set/check that time is in the "past perfect";
--
Shuya Maeda
^ permalink raw reply
* Re: 2.6.17: networking bug??
From: Helge Hafting @ 2006-06-19 7:07 UTC (permalink / raw)
To: Mark Lord; +Cc: David Miller, jheffner, torvalds, linux-kernel, netdev
In-Reply-To: <448F32E1.8080002@rtr.ca>
Mark Lord wrote:
>
> Unilaterally following the standard is all well and good
> for those who know how to get around it when a site becomes
> inaccessible, but not for Joe User.
>
So lets enable it in the kernel, and let the distros turn it off.
The Joe User who isn't a kernel hacker won't be running 2.6.17
in a long time. He'll be running whatever his distro packages for him,
and they will know how to disable (or patch out) window scaling.
Someone who compiles his own kernel runs into all sorts of
issues, this is just one more of them.
> If it always fails, or always works, that's not such a big problem.
> I would never have complained if I had never been able to access
> the web sites in question. But since it IS working in 2.6.16,
> and got broken in 2.6.17, I'm bloody well going to complain.
Yes. And make sure you complain to those running the bad
box as well.
Helge Hafting
^ permalink raw reply
* [PATCH, RFT] bcm43xx: AccessPoint mode
From: Michael Buesch @ 2006-06-19 9:07 UTC (permalink / raw)
To: bcm43xx-dev; +Cc: netdev, Alexander Tsvyashchenko, Francois Barre
[-- Attachment #1: Type: text/plain, Size: 25787 bytes --]
Hi,
This patch enables the usage of a bcm43xx card as AP with
the Devicescape 802.11 stack.
Well, it does not work 100%, but at least it's very promising.
We are able to create a bssid and correctly send beacon frames out.
This patch is tested on BE and LE machines.
There seem to be issues with Devicescape and/or hostap.
Trying to authenticate from a STA to the AP does not work. The
packet is simply not processed. I was able to catch the auth
request on the AP (using the wonderful dscape virtual interfaces).
So the AP receives the packet, but loses it somewhere in the
stack or hostapd.
Well, thanks to Alexander Tsvyashchenko and the OpenWRT team for
the hard work to figure out how this all works.
My part on this patch is mainly endianess fixes.
Please give it a testrun.
Final note about hostapd:
"hostapd snapshot 0.5-2006-06-10" seems to "work" in the sense
that it is able to bring up the device.
"hostapd snapshot 0.5-2006-06-11" seems to fail.
I did not look into this more close, yet.
Important notes from Alexander Tsvyashchenko's initial mail follow:
------
1) This version deals with TIM in cleaner way (though, PS mode is still
not supported) - instead of patching dscape stack to skip TIM
generation, it strips TIM when writing probe response template and
leaves it when writing beacon template.
2) As in current dscape stack management interface seems to be no longer
passed to the driver, all interface handling is left as it is, no
changes there should be made anymore.
...
Known limitations:
1) PS mode is not supported.
Testing instructions:
Although my previous patch to hostapd to make it interoperable with
bcm43xx & dscape has been merged already in their CVS version, due to
the subsequent changes in dscape stack current hostapd is again
incompartible :-( So, to test this patch, the patch to hostapd should be
applied.
I used hostapd snapshot 0.5-2006-06-10, patch for it is attached.
The patch is very hacky and requires tricky way to bring everything up,
but as dscape stack is changed quite constantly, I just do not want to
waste time fixing it in "proper" way only to find a week later that
dscape handling of master interface was changed completely once more and
everything is broken again ;-)
The patch for dscape stack that is attached is not 100% necessary, but it
seems to allow operating clients that request PS mode to be enabled at
AP (verified with PDA client), the only thing it contains is disabling
actual PS handling in dscape.
So, the following sequence should be used to test AP mode:
1) take hostapd snapshot 0.5-2006-06-10 (other recent versions should
work OK also, though), apply the hostapd patch attached.
2) Insert modules (80211, rate_control and bcm43xx-d80211)
3) "iwconfig wlan0 mode master"
4) "ifconfig wlan0 up" (this should be done by hostapd actually, but
its operation with current dscape stack seems to be broken)
5) Start hostapd (f.e. "hostapd -B /etc/hostapd.conf"), config file can
look like:
=====
interface=wlan0
driver=devicescape
ssid=OpenWrt
channel=1
send_probe_response=0
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
debug=4
=====
6) "iwconfig wlan0 essid <your-SSID-name>" (this also should not be
required, but current combination of hostapd + dscape doesn't seem to
generate config_interface callback when setting beacon, so this is
required just to force call of config_interface).
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c 2006-06-17 21:26:10.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c 2006-06-18 23:36:31.000000000 +0200
@@ -152,7 +152,7 @@
u32 status;
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP))
+ if (status & BCM43xx_SBF_XFER_REG_BYTESWAP)
val = swab32(val);
bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
@@ -312,7 +312,7 @@
}
}
-void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
+static void bcm43xx_time_lock(struct bcm43xx_private *bcm)
{
u32 status;
@@ -320,7 +320,19 @@
status |= BCM43xx_SBF_TIME_UPDATE;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
mmiowb();
+}
+
+static void bcm43xx_time_unlock(struct bcm43xx_private *bcm)
+{
+ u32 status;
+
+ status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
+ status &= ~BCM43xx_SBF_TIME_UPDATE;
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
+}
+static void bcm43xx_tsf_write_locked(struct bcm43xx_private *bcm, u64 tsf)
+{
/* Be careful with the in-progress timer.
* First zero out the low register, so we have a full
* register-overflow duration to complete the operation.
@@ -350,10 +362,13 @@
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
}
+}
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- status &= ~BCM43xx_SBF_TIME_UPDATE;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
+void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
+{
+ bcm43xx_time_lock(bcm);
+ bcm43xx_tsf_write_locked(bcm, tsf);
+ bcm43xx_time_unlock(bcm);
}
static void bcm43xx_measure_channel_change_time(struct bcm43xx_private *bcm)
@@ -415,10 +430,11 @@
static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
{
static const u8 zero_addr[ETH_ALEN] = { 0 };
- const u8 *mac = NULL;
- const u8 *bssid = NULL;
+ const u8 *mac;
+ const u8 *bssid;
u8 mac_bssid[ETH_ALEN * 2];
int i;
+ u32 tmp;
bssid = bcm->interface.bssid;
if (!bssid)
@@ -431,12 +447,13 @@
memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
/* Write our MAC address and BSSID to template ram */
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i)));
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i)));
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i)));
+ for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) {
+ tmp = (u32)(mac_bssid[i + 0]);
+ tmp |= (u32)(mac_bssid[i + 1]) << 8;
+ tmp |= (u32)(mac_bssid[i + 2]) << 16;
+ tmp |= (u32)(mac_bssid[i + 3]) << 24;
+ bcm43xx_ram_write(bcm, 0x20 + i, tmp);
+ }
}
static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time)
@@ -460,49 +477,6 @@
bcm->short_slot = 0;
}
-/* FIXME: To get the MAC-filter working, we need to implement the
- * following functions (and rename them :)
- */
-#if 0
-static void bcm43xx_disassociate(struct bcm43xx_private *bcm)
-{
- bcm43xx_mac_suspend(bcm);
- bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
-
- bcm43xx_ram_write(bcm, 0x0026, 0x0000);
- bcm43xx_ram_write(bcm, 0x0028, 0x0000);
- bcm43xx_ram_write(bcm, 0x007E, 0x0000);
- bcm43xx_ram_write(bcm, 0x0080, 0x0000);
- bcm43xx_ram_write(bcm, 0x047E, 0x0000);
- bcm43xx_ram_write(bcm, 0x0480, 0x0000);
-
- if (bcm->current_core->rev < 3) {
- bcm43xx_write16(bcm, 0x0610, 0x8000);
- bcm43xx_write16(bcm, 0x060E, 0x0000);
- } else
- bcm43xx_write32(bcm, 0x0188, 0x80000000);
-
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
-
-#if 0
- if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G &&
- ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate))
- bcm43xx_short_slot_timing_enable(bcm);
-#endif
-
- bcm43xx_mac_enable(bcm);
-}
-
-static void bcm43xx_associate(struct bcm43xx_private *bcm,
- const u8 *mac)
-{
- bcm43xx_mac_suspend(bcm);
- bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac);
- bcm43xx_write_mac_bssid_templates(bcm);
- bcm43xx_mac_enable(bcm);
-}
-#endif
-
/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
* Returns the _previously_ enabled IRQ mask.
*/
@@ -758,12 +732,29 @@
return -ENODEV;
}
+#ifdef CONFIG_BCM947XX
+static void bcm43xx_aton(const char *str, char *dest)
+{
+ int i = 0;
+ u16 *d = (u16 *)dest;
+
+ for (;;) {
+ dest[i++] = (char)simple_strtoul(str, NULL, 16);
+ str += 2;
+ if (!*str++ || i == 6)
+ break;
+ }
+ for (i = 0; i < 3; i++)
+ d[i] = be16_to_cpu(d[i]);
+}
+#endif
+
static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
{
u16 value;
u16 *sprom;
#ifdef CONFIG_BCM947XX
- char *c;
+ const char *c;
#endif
sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16),
@@ -772,27 +763,46 @@
printk(KERN_ERR PFX "sprom_extract OOM\n");
return -ENOMEM;
}
-#ifdef CONFIG_BCM947XX
- sprom[BCM43xx_SPROM_BOARDFLAGS2] = atoi(nvram_get("boardflags2"));
- sprom[BCM43xx_SPROM_BOARDFLAGS] = atoi(nvram_get("boardflags"));
-
- if ((c = nvram_get("il0macaddr")) != NULL)
- e_aton(c, (char *) &(sprom[BCM43xx_SPROM_IL0MACADDR]));
-
- if ((c = nvram_get("et1macaddr")) != NULL)
- e_aton(c, (char *) &(sprom[BCM43xx_SPROM_ET1MACADDR]));
-
- sprom[BCM43xx_SPROM_PA0B0] = atoi(nvram_get("pa0b0"));
- sprom[BCM43xx_SPROM_PA0B1] = atoi(nvram_get("pa0b1"));
- sprom[BCM43xx_SPROM_PA0B2] = atoi(nvram_get("pa0b2"));
-
- sprom[BCM43xx_SPROM_PA1B0] = atoi(nvram_get("pa1b0"));
- sprom[BCM43xx_SPROM_PA1B1] = atoi(nvram_get("pa1b1"));
- sprom[BCM43xx_SPROM_PA1B2] = atoi(nvram_get("pa1b2"));
- sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev"));
-#else
bcm43xx_sprom_read(bcm, sprom);
+
+#ifdef CONFIG_BCM947XX
+ /* In the case some settings are found in nvram, use them
+ * to override those read from sprom.
+ */
+ c = nvram_get("boardflags2");
+ if (c)
+ sprom[BCM43xx_SPROM_BOARDFLAGS2] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("boardflags");
+ if (c)
+ sprom[BCM43xx_SPROM_BOARDFLAGS] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("il0macaddr");
+ if (c)
+ bcm43xx_aton(c, (char *)&(sprom[BCM43xx_SPROM_IL0MACADDR]));
+ c = nvram_get("et1macaddr");
+ if (c)
+ bcm43xx_aton(c, (char *)&(sprom[BCM43xx_SPROM_ET1MACADDR]));
+ c = nvram_get("pa0b0");
+ if (c)
+ sprom[BCM43xx_SPROM_PA0B0] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa0b1");
+ if (c)
+ sprom[BCM43xx_SPROM_PA0B1] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa0b2");
+ if (c)
+ sprom[BCM43xx_SPROM_PA0B2] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa1b0");
+ if (c)
+ sprom[BCM43xx_SPROM_PA1B0] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa1b1");
+ if (c)
+ sprom[BCM43xx_SPROM_PA1B1] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa1b2");
+ if (c)
+ sprom[BCM43xx_SPROM_PA1B2] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("boardrev");
+ if (c)
+ sprom[BCM43xx_SPROM_BOARDREV] = simple_strtoul(c, NULL, 0);
#endif
/* boardflags2 */
@@ -914,21 +924,21 @@
u16 value = 0;
u32 buffer[5] = {
0x00000000,
- 0x0000D400,
+ 0x00D40000,
0x00000000,
- 0x00000001,
+ 0x01000000,
0x00000000,
};
switch (phy->type) {
case BCM43xx_PHYTYPE_A:
max_loop = 0x1E;
- buffer[0] = 0xCC010200;
+ buffer[0] = 0x000201CC;
break;
case BCM43xx_PHYTYPE_B:
case BCM43xx_PHYTYPE_G:
max_loop = 0xFA;
- buffer[0] = 0x6E840B00;
+ buffer[0] = 0x000B846E;
break;
default:
assert(0);
@@ -1521,48 +1531,274 @@
bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002);
}
+static void bcm43xx_write_template_common(struct bcm43xx_private *bcm,
+ const u8* data, u16 size,
+ u16 ram_offset,
+ u16 shm_size_offset, u8 rate)
+{
+ u32 i, tmp;
+ struct bcm43xx_plcp_hdr4 plcp;
+
+ plcp.data = 0;
+ bcm43xx_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
+ bcm43xx_ram_write(bcm, ram_offset, le32_to_cpu(plcp.data));
+ ram_offset += sizeof(u32);
+ /* The PLCP is 6 bytes long, but we only wrote 4 bytes, yet.
+ * So leave the first two bytes of the next write blank.
+ */
+ tmp = (u32)(data[0]) << 16;
+ tmp |= (u32)(data[1]) << 24;
+ bcm43xx_ram_write(bcm, ram_offset, tmp);
+ ram_offset += sizeof(u32);
+ for (i = 2; i < size; i += sizeof(u32)) {
+ tmp = (u32)(data[i + 0]);
+ if (i + 1 < size)
+ tmp |= (u32)(data[i + 1]) << 8;
+ if (i + 2 < size)
+ tmp |= (u32)(data[i + 2]) << 16;
+ if (i + 3 < size)
+ tmp |= (u32)(data[i + 3]) << 24;
+ bcm43xx_ram_write(bcm, ram_offset + i, tmp);
+ }
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset,
+ size + sizeof(struct bcm43xx_plcp_hdr6));
+}
+
static void bcm43xx_write_beacon_template(struct bcm43xx_private *bcm,
u16 ram_offset,
- u16 shm_size_offset)
+ u16 shm_size_offset, u8 rate)
{
- u32 tmp;
- u16 i, size;
+ int len;
const u8 *data;
+ assert(bcm->cached_beacon);
+ len = min((size_t)bcm->cached_beacon->len,
+ 0x200 - sizeof(struct bcm43xx_plcp_hdr6));
data = (const u8 *)(bcm->cached_beacon->data);
- size = min(bcm->cached_beacon->len, (unsigned int)17);
+ bcm43xx_write_template_common(bcm, data,
+ len, ram_offset,
+ shm_size_offset, rate);
+}
- for (i = 0; i < size; i += sizeof(u32)) {
- tmp = (u32)((data + i)[0]);
- tmp |= (u32)((data + i)[1]) << 8;
- tmp |= (u32)((data + i)[2]) << 16;
- tmp |= (u32)((data + i)[3]) << 24;
- bcm43xx_ram_write(bcm, ram_offset + i, tmp);
+static void bcm43xx_write_probe_resp_plcp(struct bcm43xx_private *bcm,
+ u16 shm_offset, u16 size, u8 rate)
+{
+ struct bcm43xx_plcp_hdr4 plcp;
+ u32 tmp;
+ u16 packet_time;
+
+ plcp.data = 0;
+ bcm43xx_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
+ /*
+ * 144 + 48 + 10 = preamble + PLCP + SIFS,
+ * taken from d80211 timings calculation.
+ *
+ * FIXME: long preamble assumed!
+ *
+ */
+ packet_time = 202 + (size + FCS_LEN) * 16 / rate;
+ if ((size + FCS_LEN) * 16 % rate >= rate / 2)
+ ++packet_time;
+
+ /* Write PLCP in two parts and timing for packet transfer */
+ tmp = le32_to_cpu(plcp.data);
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_offset,
+ tmp & 0xFFFF);
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_offset + 2,
+ tmp >> 16);
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_offset + 6,
+ packet_time);
+}
+
+/* Instead of using custom probe response template, this function
+ * just patches custom beacon template by:
+ * 1) Changing packet type
+ * 2) Patching duration field
+ * 3) Stripping TIM
+ */
+static u8 * bcm43xx_generate_probe_resp(struct bcm43xx_private *bcm,
+ u16* dest_size, u8 rate)
+{
+ const u8 *src_data;
+ u8 *dest_data;
+ u16 src_size, elem_size, src_pos, dest_pos, tmp;
+
+ assert(bcm->cached_beacon);
+ src_size = bcm->cached_beacon->len;
+ src_data = (const u8*)bcm->cached_beacon->data;
+
+ if (unlikely(src_size < 0x24)) {
+ dprintk(KERN_ERR PFX "bcm43xx_generate_probe_resp: "
+ "invalid beacon\n");
+ return NULL;
+ }
+
+ dest_data = kmalloc(src_size, GFP_ATOMIC);
+ if (unlikely(!dest_data))
+ return NULL;
+
+ /* 0x24 is offset of first variable-len Information-Element
+ * in beacon frame.
+ */
+ memcpy(dest_data, src_data, 0x24);
+ src_pos = dest_pos = 0x24;
+ for ( ; src_pos < src_size - 2; src_pos += elem_size) {
+ elem_size = src_data[src_pos + 1] + 2;
+ if (src_data[src_pos] != 0x05) { /* TIM */
+ memcpy(dest_data + dest_pos, src_data + src_pos,
+ elem_size);
+ dest_pos += elem_size;
+ }
}
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size);
+ *dest_size = dest_pos;
+
+ /* Set the frame control. */
+ dest_data[0] = ((WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_PROBE_RESP << 4));
+ dest_data[1] = 0;
+
+ /* Set the duration field.
+ *
+ * 144 + 48 + 10 = preamble + PLCP + SIFS,
+ * taken from d80211 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;
+
+ return dest_data;
+}
+
+static void bcm43xx_write_probe_resp_template(struct bcm43xx_private *bcm,
+ u16 ram_offset,
+ u16 shm_size_offset, u8 rate)
+{
+ u8* probe_resp_data;
+ u16 size;
+
+ assert(bcm->cached_beacon);
+ size = bcm->cached_beacon->len;
+ probe_resp_data = bcm43xx_generate_probe_resp(bcm, &size, rate);
+ if (unlikely(!probe_resp_data))
+ return;
+
+ /* Looks like PLCP headers plus packet timings are stored for
+ * all possible basic rates
+ */
+ bcm43xx_write_probe_resp_plcp(bcm, 0x31A, size,
+ BCM43xx_CCK_RATE_1MB);
+ bcm43xx_write_probe_resp_plcp(bcm, 0x32C, size,
+ BCM43xx_CCK_RATE_2MB);
+ bcm43xx_write_probe_resp_plcp(bcm, 0x33E, size,
+ BCM43xx_CCK_RATE_5MB);
+ bcm43xx_write_probe_resp_plcp(bcm, 0x350, size,
+ BCM43xx_CCK_RATE_11MB);
+
+ size = min((size_t)size,
+ 0x200 - sizeof(struct bcm43xx_plcp_hdr6));
+ bcm43xx_write_template_common(bcm, probe_resp_data,
+ size, ram_offset,
+ shm_size_offset, rate);
+ kfree(probe_resp_data);
+}
+
+static int bcm43xx_refresh_cached_beacon(struct bcm43xx_private *bcm)
+{
+ struct ieee80211_tx_control control;
+
+ if (bcm->cached_beacon)
+ kfree_skb(bcm->cached_beacon);
+ bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev,
+ bcm->interface.if_id,
+ &control);
+ if (unlikely(!bcm->cached_beacon))
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void bcm43xx_update_templates(struct bcm43xx_private *bcm)
+{
+ u32 status;
+
+ assert(bcm->cached_beacon);
+
+ bcm43xx_write_beacon_template(bcm, 0x68, 0x18,
+ BCM43xx_CCK_RATE_1MB);
+ bcm43xx_write_beacon_template(bcm, 0x468, 0x1A,
+ BCM43xx_CCK_RATE_1MB);
+ bcm43xx_write_probe_resp_template(bcm, 0x268, 0x4A,
+ BCM43xx_CCK_RATE_11MB);
+
+ status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
+ status |= 0x03;
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
+}
+
+static void bcm43xx_refresh_templates(struct bcm43xx_private *bcm)
+{
+ int err;
+
+ err = bcm43xx_refresh_cached_beacon(bcm);
+ if (unlikely(err))
+ return;
+ bcm43xx_update_templates(bcm);
+ kfree_skb(bcm->cached_beacon);
+ bcm->cached_beacon = NULL;
+}
+
+static void bcm43xx_set_ssid(struct bcm43xx_private *bcm,
+ const u8 *ssid, u8 ssid_len)
+{
+ u32 tmp;
+ u16 i, len;
+
+ len = min((u16)ssid_len, (u16)0x100);
+ for (i = 0; i < len; i += sizeof(u32)) {
+ tmp = (u32)(ssid[i + 0]);
+ if (i + 1 < len)
+ tmp |= (u32)(ssid[i + 1]) << 8;
+ if (i + 2 < len)
+ tmp |= (u32)(ssid[i + 2]) << 16;
+ if (i + 3 < len)
+ tmp |= (u32)(ssid[i + 3]) << 24;
+ bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
+ 0x380 + i, tmp);
+ }
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
+ 0x48, len);
+}
+
+static void bcm43xx_set_beacon_int(struct bcm43xx_private *bcm, u16 beacon_int)
+{
+ bcm43xx_time_lock(bcm);
+ if (bcm->current_core->rev >= 3) {
+ bcm43xx_write32(bcm, 0x188, (beacon_int << 16));
+ } else {
+ bcm43xx_write16(bcm, 0x606, (beacon_int >> 6));
+ bcm43xx_write16(bcm, 0x610, beacon_int);
+ }
+ bcm43xx_time_unlock(bcm);
}
static void handle_irq_beacon(struct bcm43xx_private *bcm)
{
u32 status;
+ int err;
bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON;
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
if (!bcm->cached_beacon) {
- struct ieee80211_tx_control control;
-
- /* No cached template available, yet.
- * Request the 80211 subsystem to generate a new beacon
- * frame and use it as template.
- */
- bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev,
- bcm->interface.if_id,
- &control);
- if (unlikely(!bcm->cached_beacon)) {
- dprintkl(KERN_WARNING PFX "Could not generate beacon template.\n");
+ err = bcm43xx_refresh_cached_beacon(bcm);
+ if (unlikely(err))
goto ack;
- }
}
if ((status & 0x1) && (status & 0x2)) {
@@ -1571,18 +1807,20 @@
bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
BCM43xx_IRQ_BEACON);
bcm->irq_savedstate |= BCM43xx_IRQ_BEACON;
- if (likely(bcm->cached_beacon))
+ if (bcm->cached_beacon)
kfree_skb(bcm->cached_beacon);
bcm->cached_beacon = NULL;
return;
}
if (!(status & 0x1)) {
- bcm43xx_write_beacon_template(bcm, 0x68, 0x18);
+ bcm43xx_write_beacon_template(bcm, 0x68, 0x18,
+ BCM43xx_CCK_RATE_1MB);
status |= 0x1;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
}
if (!(status & 0x2)) {
- bcm43xx_write_beacon_template(bcm, 0x468, 0x1A);
+ bcm43xx_write_beacon_template(bcm, 0x468, 0x1A,
+ BCM43xx_CCK_RATE_1MB);
status |= 0x2;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
}
@@ -4114,6 +4352,17 @@
radio->power_level = conf->power_level;
bcm43xx_phy_xmitpower(bcm);
}
+
+ if (conf->ssid_hidden) {
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+ bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
+ | BCM43xx_SBF_NO_SSID_BCAST);
+ } else {
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+ bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
+ & ~BCM43xx_SBF_NO_SSID_BCAST);
+ }
+
//FIXME: This does not seem to wake up:
#if 0
if (conf->power_level == 0) {
@@ -4128,6 +4377,11 @@
//TODO: phymode
//TODO: antennas
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP)) {
+ bcm43xx_set_beacon_int(bcm, conf->beacon_int);
+ bcm43xx_refresh_templates(bcm);
+ }
+
bcm43xx_unlock_irqonly(bcm, flags);
return 0;
@@ -4293,8 +4547,11 @@
bcm->interface.mac_addr = conf->mac_addr;
bcm->interface.type = conf->type;
}
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
bcm43xx_select_opmode(bcm);
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP))
+ bcm43xx_refresh_templates(bcm);
+ }
err = 0;
dprintk(KERN_INFO PFX "Virtual interface added "
@@ -4343,6 +4600,11 @@
if (conf->type != IEEE80211_IF_TYPE_MNTR) {
assert(bcm->interface.if_id == if_id);
bcm->interface.bssid = conf->bssid;
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP)) {
+ assert(conf->type == IEEE80211_IF_TYPE_AP);
+ bcm43xx_set_ssid(bcm, conf->ssid, conf->ssid_len);
+ bcm43xx_refresh_templates(bcm);
+ }
}
bcm43xx_unlock_irqsafe(bcm, flags);
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c 2006-06-13 21:06:01.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c 2006-06-18 18:43:12.000000000 +0200
@@ -112,14 +112,13 @@
return 0;
}
-static void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
- const u16 octets, const u8 bitrate,
- const int ofdm_modulation)
+void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
+ const u16 octets, const u8 bitrate)
{
__le32 *data = &(plcp->data);
__u8 *raw = plcp->raw;
- if (ofdm_modulation) {
+ if (bcm43xx_is_ofdm_rate(bitrate)) {
*data = bcm43xx_plcp_get_ratecode_ofdm(bitrate);
assert(!(octets & 0xF000));
*data |= (octets << 5);
@@ -224,11 +223,9 @@
flen = sizeof(u16) + sizeof(u16) + ETH_ALEN + ETH_ALEN + FCS_LEN,
bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_plcp),
- flen, bitrate,
- !bcm43xx_is_cck_rate(bitrate));
+ flen, bitrate);
bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_fallback_plcp),
- flen, fallback_bitrate,
- !bcm43xx_is_cck_rate(fallback_bitrate));
+ flen, fallback_bitrate);
fctl = WLAN_FC_TYPE_CTRL << 2;
fctl |= WLAN_FC_STYPE_RTS << 4;
dur = le16_to_cpu(wlhdr->duration_id);
@@ -332,10 +329,9 @@
}
/* Generate the PLCP header and the fallback PLCP header. */
bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->plcp),
- plcp_fragment_len,
- bitrate, ofdm_modulation);
+ plcp_fragment_len, bitrate);
bcm43xx_generate_plcp_hdr(&txhdr->fallback_plcp, plcp_fragment_len,
- fallback_bitrate, fallback_ofdm_modulation);
+ fallback_bitrate);
/* Set the CONTROL field */
if (ofdm_modulation)
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.h
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.h 2006-06-13 14:43:08.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.h 2006-06-18 18:41:27.000000000 +0200
@@ -154,4 +154,7 @@
struct sk_buff *skb,
struct bcm43xx_rxhdr *rxhdr);
+void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
+ const u16 octets, const u8 bitrate);
+
#endif /* BCM43xx_XMIT_H_ */
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.h
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.h 2006-06-13 14:43:08.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.h 2006-06-18 18:41:03.000000000 +0200
@@ -33,24 +33,6 @@
#include "bcm43xx.h"
-#ifdef CONFIG_BCM947XX
-#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
-
-static inline void e_aton(char *str, char *dest)
-{
- int i = 0;
- u16 *d = (u16 *) dest;
-
- for (;;) {
- dest[i++] = (char) simple_strtoul(str, NULL, 16);
- str += 2;
- if (!*str++ || i == 6)
- break;
- }
- for (i = 0; i < 3; i++)
- d[i] = cpu_to_be16(d[i]);
-}
-#endif
#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes]
#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes)
@@ -143,6 +125,12 @@
rate == BCM43xx_CCK_RATE_11MB);
}
+static inline
+int bcm43xx_is_ofdm_rate(int rate)
+{
+ return !bcm43xx_is_cck_rate(rate);
+}
+
void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf);
void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf);
--
Greetings Michael.
[-- Attachment #2: hostapd-dscape.patch --]
[-- Type: text/x-diff, Size: 1112 bytes --]
diff -urN hostapd-0.5-2006-06-10/driver_devicescape.c hostapd.new/driver_devicescape.c
--- hostapd-0.5-2006-06-10/driver_devicescape.c 2006-05-03 03:04:24.000000000 +0000
+++ hostapd.new/driver_devicescape.c 2006-06-12 21:17:10.000000000 +0000
@@ -1338,8 +1338,12 @@
return -1;
}
- memset(&ifr, 0, sizeof(ifr));
- snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->mgmt_iface);
+ /* Enable management interface */
+ hostap_ioctl_prism2param(drv, PRISM2_PARAM_MGMT_IF, 1);
+ strcpy(drv->mgmt_iface, "wmgmt0");
+
+ memset(&ifr, 0, sizeof(ifr));
+ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", drv->mgmt_iface);
if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
perror("ioctl(SIOCGIFINDEX)");
return -1;
@@ -1747,6 +1751,9 @@
/* Disable the radio. */
(void) hostap_ioctl_prism2param(drv, PRISM2_PARAM_RADIO_ENABLED, 0);
+ /* Disable management interface */
+ hostap_ioctl_prism2param(drv, PRISM2_PARAM_MGMT_IF, 0);
+
drv->hapd->driver = NULL;
(void) hostapd_set_iface_flags(drv, 0);
Files hostapd-0.5-2006-06-10/hostapd and hostapd.new/hostapd differ
[-- Attachment #3: d80211-ap-mode.patch --]
[-- Type: text/x-diff, Size: 438 bytes --]
diff -urN d80211.orig/ieee80211.c d80211/ieee80211.c
--- d80211.orig/ieee80211.c 2006-05-29 10:30:12.000000000 +0000
+++ d80211/ieee80211.c 2006-06-12 20:39:47.000000000 +0000
@@ -2534,7 +2534,7 @@
if (sdata->bss)
atomic_inc(&sdata->bss->num_sta_ps);
- sta->flags |= WLAN_STA_PS;
+ /* sta->flags |= WLAN_STA_PS; */
sta->pspoll = 0;
#ifdef IEEE80211_VERBOSE_DEBUG_PS
printk(KERN_DEBUG "%s: STA " MACSTR " aid %d enters power "
^ permalink raw reply
* Re: [PATCH] AP (master) mode fixed (resubmit)
From: Michael Buesch @ 2006-06-19 9:43 UTC (permalink / raw)
To: Francois Barre; +Cc: Alexander Tsvyashchenko, bcm43xx-dev, netdev
In-Reply-To: <fd8d0180606190237vdd4cfa8s1d4178ea1fdcf78b@mail.gmail.com>
On Monday 19 June 2006 11:37, Francois Barre wrote:
> 2006/6/18, Michael Buesch <mb@bu3sch.de>:
> > Ok, I got my Airport to generate Beacons on this BE machine.
>
> Hurray, I'm not alone running BE stuff here...
>
> > There was a bug hiding in bcm43xx_ram_write().
> [..]
> Could you provide a small patch just for this issue please ? It's not
> that I'm too lasy to re-apply your whole patches again, but... Well,
> if you have it...
It is not an issue without the AP mode patch, because all callers
of bcm43xx_ram_write() are buggy, too.
So, caller buggy, callee buggy, result OK. ;)
> > But I can not associate to the bcm43xx-AP.
> > But it seems like a dscape problem. The authentication packet
> > arrives at the machine (I can capture it with the new cool virtual
> > monitor interface), but it is not processed. So the STA does
> > not receive a response.
>
> Funny, I did have no problem associating with the AP. What happens
> exactly on the STA ? Did you manage to trace anything on ?
> What exactly is your hardware, Michael ?
I think I did something wrong while bringing the device up.
It works now.
But attached is a fixed patch, already.
We had an off-by-two bug in common template write.
> Also, Alexander, did you have the opportunity to heavily test your AP
> code ? I mean, finding the maximum bandwidth a bcm43xx could provide
> while being an AP, the way it behaves with multiple STA associated,
I was able to associate now, but could not transmit ping packets, yet.
Dunno what the problem is. Maybe the STA is broken, too. Let's see.
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c 2006-06-17 21:26:10.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c 2006-06-19 11:25:02.000000000 +0200
@@ -151,8 +151,10 @@
{
u32 status;
+ assert(offset % 4 == 0);
+
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP))
+ if (status & BCM43xx_SBF_XFER_REG_BYTESWAP)
val = swab32(val);
bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
@@ -312,7 +314,7 @@
}
}
-void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
+static void bcm43xx_time_lock(struct bcm43xx_private *bcm)
{
u32 status;
@@ -320,7 +322,19 @@
status |= BCM43xx_SBF_TIME_UPDATE;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
mmiowb();
+}
+
+static void bcm43xx_time_unlock(struct bcm43xx_private *bcm)
+{
+ u32 status;
+
+ status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
+ status &= ~BCM43xx_SBF_TIME_UPDATE;
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
+}
+static void bcm43xx_tsf_write_locked(struct bcm43xx_private *bcm, u64 tsf)
+{
/* Be careful with the in-progress timer.
* First zero out the low register, so we have a full
* register-overflow duration to complete the operation.
@@ -350,10 +364,13 @@
mmiowb();
bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
}
+}
- status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
- status &= ~BCM43xx_SBF_TIME_UPDATE;
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
+void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
+{
+ bcm43xx_time_lock(bcm);
+ bcm43xx_tsf_write_locked(bcm, tsf);
+ bcm43xx_time_unlock(bcm);
}
static void bcm43xx_measure_channel_change_time(struct bcm43xx_private *bcm)
@@ -415,10 +432,11 @@
static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
{
static const u8 zero_addr[ETH_ALEN] = { 0 };
- const u8 *mac = NULL;
- const u8 *bssid = NULL;
+ const u8 *mac;
+ const u8 *bssid;
u8 mac_bssid[ETH_ALEN * 2];
int i;
+ u32 tmp;
bssid = bcm->interface.bssid;
if (!bssid)
@@ -431,12 +449,13 @@
memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
/* Write our MAC address and BSSID to template ram */
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i)));
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i)));
- for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
- bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i)));
+ for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) {
+ tmp = (u32)(mac_bssid[i + 0]);
+ tmp |= (u32)(mac_bssid[i + 1]) << 8;
+ tmp |= (u32)(mac_bssid[i + 2]) << 16;
+ tmp |= (u32)(mac_bssid[i + 3]) << 24;
+ bcm43xx_ram_write(bcm, 0x20 + i, tmp);
+ }
}
static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time)
@@ -460,49 +479,6 @@
bcm->short_slot = 0;
}
-/* FIXME: To get the MAC-filter working, we need to implement the
- * following functions (and rename them :)
- */
-#if 0
-static void bcm43xx_disassociate(struct bcm43xx_private *bcm)
-{
- bcm43xx_mac_suspend(bcm);
- bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
-
- bcm43xx_ram_write(bcm, 0x0026, 0x0000);
- bcm43xx_ram_write(bcm, 0x0028, 0x0000);
- bcm43xx_ram_write(bcm, 0x007E, 0x0000);
- bcm43xx_ram_write(bcm, 0x0080, 0x0000);
- bcm43xx_ram_write(bcm, 0x047E, 0x0000);
- bcm43xx_ram_write(bcm, 0x0480, 0x0000);
-
- if (bcm->current_core->rev < 3) {
- bcm43xx_write16(bcm, 0x0610, 0x8000);
- bcm43xx_write16(bcm, 0x060E, 0x0000);
- } else
- bcm43xx_write32(bcm, 0x0188, 0x80000000);
-
- bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
-
-#if 0
- if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G &&
- ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate))
- bcm43xx_short_slot_timing_enable(bcm);
-#endif
-
- bcm43xx_mac_enable(bcm);
-}
-
-static void bcm43xx_associate(struct bcm43xx_private *bcm,
- const u8 *mac)
-{
- bcm43xx_mac_suspend(bcm);
- bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac);
- bcm43xx_write_mac_bssid_templates(bcm);
- bcm43xx_mac_enable(bcm);
-}
-#endif
-
/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
* Returns the _previously_ enabled IRQ mask.
*/
@@ -758,12 +734,29 @@
return -ENODEV;
}
+#ifdef CONFIG_BCM947XX
+static void bcm43xx_aton(const char *str, char *dest)
+{
+ int i = 0;
+ u16 *d = (u16 *)dest;
+
+ for (;;) {
+ dest[i++] = (char)simple_strtoul(str, NULL, 16);
+ str += 2;
+ if (!*str++ || i == 6)
+ break;
+ }
+ for (i = 0; i < 3; i++)
+ d[i] = be16_to_cpu(d[i]);
+}
+#endif
+
static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
{
u16 value;
u16 *sprom;
#ifdef CONFIG_BCM947XX
- char *c;
+ const char *c;
#endif
sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16),
@@ -772,27 +765,46 @@
printk(KERN_ERR PFX "sprom_extract OOM\n");
return -ENOMEM;
}
-#ifdef CONFIG_BCM947XX
- sprom[BCM43xx_SPROM_BOARDFLAGS2] = atoi(nvram_get("boardflags2"));
- sprom[BCM43xx_SPROM_BOARDFLAGS] = atoi(nvram_get("boardflags"));
-
- if ((c = nvram_get("il0macaddr")) != NULL)
- e_aton(c, (char *) &(sprom[BCM43xx_SPROM_IL0MACADDR]));
-
- if ((c = nvram_get("et1macaddr")) != NULL)
- e_aton(c, (char *) &(sprom[BCM43xx_SPROM_ET1MACADDR]));
-
- sprom[BCM43xx_SPROM_PA0B0] = atoi(nvram_get("pa0b0"));
- sprom[BCM43xx_SPROM_PA0B1] = atoi(nvram_get("pa0b1"));
- sprom[BCM43xx_SPROM_PA0B2] = atoi(nvram_get("pa0b2"));
- sprom[BCM43xx_SPROM_PA1B0] = atoi(nvram_get("pa1b0"));
- sprom[BCM43xx_SPROM_PA1B1] = atoi(nvram_get("pa1b1"));
- sprom[BCM43xx_SPROM_PA1B2] = atoi(nvram_get("pa1b2"));
-
- sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev"));
-#else
bcm43xx_sprom_read(bcm, sprom);
+
+#ifdef CONFIG_BCM947XX
+ /* In the case some settings are found in nvram, use them
+ * to override those read from sprom.
+ */
+ c = nvram_get("boardflags2");
+ if (c)
+ sprom[BCM43xx_SPROM_BOARDFLAGS2] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("boardflags");
+ if (c)
+ sprom[BCM43xx_SPROM_BOARDFLAGS] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("il0macaddr");
+ if (c)
+ bcm43xx_aton(c, (char *)&(sprom[BCM43xx_SPROM_IL0MACADDR]));
+ c = nvram_get("et1macaddr");
+ if (c)
+ bcm43xx_aton(c, (char *)&(sprom[BCM43xx_SPROM_ET1MACADDR]));
+ c = nvram_get("pa0b0");
+ if (c)
+ sprom[BCM43xx_SPROM_PA0B0] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa0b1");
+ if (c)
+ sprom[BCM43xx_SPROM_PA0B1] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa0b2");
+ if (c)
+ sprom[BCM43xx_SPROM_PA0B2] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa1b0");
+ if (c)
+ sprom[BCM43xx_SPROM_PA1B0] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa1b1");
+ if (c)
+ sprom[BCM43xx_SPROM_PA1B1] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("pa1b2");
+ if (c)
+ sprom[BCM43xx_SPROM_PA1B2] = simple_strtoul(c, NULL, 0);
+ c = nvram_get("boardrev");
+ if (c)
+ sprom[BCM43xx_SPROM_BOARDREV] = simple_strtoul(c, NULL, 0);
#endif
/* boardflags2 */
@@ -914,21 +926,21 @@
u16 value = 0;
u32 buffer[5] = {
0x00000000,
- 0x0000D400,
+ 0x00D40000,
0x00000000,
- 0x00000001,
+ 0x01000000,
0x00000000,
};
switch (phy->type) {
case BCM43xx_PHYTYPE_A:
max_loop = 0x1E;
- buffer[0] = 0xCC010200;
+ buffer[0] = 0x000201CC;
break;
case BCM43xx_PHYTYPE_B:
case BCM43xx_PHYTYPE_G:
max_loop = 0xFA;
- buffer[0] = 0x6E840B00;
+ buffer[0] = 0x000B846E;
break;
default:
assert(0);
@@ -1521,48 +1533,274 @@
bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002);
}
+static void bcm43xx_write_template_common(struct bcm43xx_private *bcm,
+ const u8* data, u16 size,
+ u16 ram_offset,
+ u16 shm_size_offset, u8 rate)
+{
+ u32 i, tmp;
+ struct bcm43xx_plcp_hdr4 plcp;
+
+ plcp.data = 0;
+ bcm43xx_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
+ bcm43xx_ram_write(bcm, ram_offset, le32_to_cpu(plcp.data));
+ ram_offset += sizeof(u32);
+ /* The PLCP is 6 bytes long, but we only wrote 4 bytes, yet.
+ * So leave the first two bytes of the next write blank.
+ */
+ tmp = (u32)(data[0]) << 16;
+ tmp |= (u32)(data[1]) << 24;
+ bcm43xx_ram_write(bcm, ram_offset, tmp);
+ ram_offset += sizeof(u32);
+ for (i = 2; i < size; i += sizeof(u32)) {
+ tmp = (u32)(data[i + 0]);
+ if (i + 1 < size)
+ tmp |= (u32)(data[i + 1]) << 8;
+ if (i + 2 < size)
+ tmp |= (u32)(data[i + 2]) << 16;
+ if (i + 3 < size)
+ tmp |= (u32)(data[i + 3]) << 24;
+ bcm43xx_ram_write(bcm, ram_offset + i - 2, tmp);
+ }
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset,
+ size + sizeof(struct bcm43xx_plcp_hdr6));
+}
+
static void bcm43xx_write_beacon_template(struct bcm43xx_private *bcm,
u16 ram_offset,
- u16 shm_size_offset)
+ u16 shm_size_offset, u8 rate)
{
- u32 tmp;
- u16 i, size;
+ int len;
const u8 *data;
+ assert(bcm->cached_beacon);
+ len = min((size_t)bcm->cached_beacon->len,
+ 0x200 - sizeof(struct bcm43xx_plcp_hdr6));
data = (const u8 *)(bcm->cached_beacon->data);
- size = min(bcm->cached_beacon->len, (unsigned int)17);
+ bcm43xx_write_template_common(bcm, data,
+ len, ram_offset,
+ shm_size_offset, rate);
+}
- for (i = 0; i < size; i += sizeof(u32)) {
- tmp = (u32)((data + i)[0]);
- tmp |= (u32)((data + i)[1]) << 8;
- tmp |= (u32)((data + i)[2]) << 16;
- tmp |= (u32)((data + i)[3]) << 24;
- bcm43xx_ram_write(bcm, ram_offset + i, tmp);
+static void bcm43xx_write_probe_resp_plcp(struct bcm43xx_private *bcm,
+ u16 shm_offset, u16 size, u8 rate)
+{
+ struct bcm43xx_plcp_hdr4 plcp;
+ u32 tmp;
+ u16 packet_time;
+
+ plcp.data = 0;
+ bcm43xx_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
+ /*
+ * 144 + 48 + 10 = preamble + PLCP + SIFS,
+ * taken from d80211 timings calculation.
+ *
+ * FIXME: long preamble assumed!
+ *
+ */
+ packet_time = 202 + (size + FCS_LEN) * 16 / rate;
+ if ((size + FCS_LEN) * 16 % rate >= rate / 2)
+ ++packet_time;
+
+ /* Write PLCP in two parts and timing for packet transfer */
+ tmp = le32_to_cpu(plcp.data);
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_offset,
+ tmp & 0xFFFF);
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_offset + 2,
+ tmp >> 16);
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_offset + 6,
+ packet_time);
+}
+
+/* Instead of using custom probe response template, this function
+ * just patches custom beacon template by:
+ * 1) Changing packet type
+ * 2) Patching duration field
+ * 3) Stripping TIM
+ */
+static u8 * bcm43xx_generate_probe_resp(struct bcm43xx_private *bcm,
+ u16* dest_size, u8 rate)
+{
+ const u8 *src_data;
+ u8 *dest_data;
+ u16 src_size, elem_size, src_pos, dest_pos, tmp;
+
+ assert(bcm->cached_beacon);
+ src_size = bcm->cached_beacon->len;
+ src_data = (const u8*)bcm->cached_beacon->data;
+
+ if (unlikely(src_size < 0x24)) {
+ dprintk(KERN_ERR PFX "bcm43xx_generate_probe_resp: "
+ "invalid beacon\n");
+ return NULL;
+ }
+
+ dest_data = kmalloc(src_size, GFP_ATOMIC);
+ if (unlikely(!dest_data))
+ return NULL;
+
+ /* 0x24 is offset of first variable-len Information-Element
+ * in beacon frame.
+ */
+ memcpy(dest_data, src_data, 0x24);
+ src_pos = dest_pos = 0x24;
+ for ( ; src_pos < src_size - 2; src_pos += elem_size) {
+ elem_size = src_data[src_pos + 1] + 2;
+ if (src_data[src_pos] != 0x05) { /* TIM */
+ memcpy(dest_data + dest_pos, src_data + src_pos,
+ elem_size);
+ dest_pos += elem_size;
+ }
+ }
+ *dest_size = dest_pos;
+
+ /* Set the frame control. */
+ dest_data[0] = ((WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_PROBE_RESP << 4));
+ dest_data[1] = 0;
+
+ /* Set the duration field.
+ *
+ * 144 + 48 + 10 = preamble + PLCP + SIFS,
+ * taken from d80211 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;
+
+ return dest_data;
+}
+
+static void bcm43xx_write_probe_resp_template(struct bcm43xx_private *bcm,
+ u16 ram_offset,
+ u16 shm_size_offset, u8 rate)
+{
+ u8* probe_resp_data;
+ u16 size;
+
+ assert(bcm->cached_beacon);
+ size = bcm->cached_beacon->len;
+ probe_resp_data = bcm43xx_generate_probe_resp(bcm, &size, rate);
+ if (unlikely(!probe_resp_data))
+ return;
+
+ /* Looks like PLCP headers plus packet timings are stored for
+ * all possible basic rates
+ */
+ bcm43xx_write_probe_resp_plcp(bcm, 0x31A, size,
+ BCM43xx_CCK_RATE_1MB);
+ bcm43xx_write_probe_resp_plcp(bcm, 0x32C, size,
+ BCM43xx_CCK_RATE_2MB);
+ bcm43xx_write_probe_resp_plcp(bcm, 0x33E, size,
+ BCM43xx_CCK_RATE_5MB);
+ bcm43xx_write_probe_resp_plcp(bcm, 0x350, size,
+ BCM43xx_CCK_RATE_11MB);
+
+ size = min((size_t)size,
+ 0x200 - sizeof(struct bcm43xx_plcp_hdr6));
+ bcm43xx_write_template_common(bcm, probe_resp_data,
+ size, ram_offset,
+ shm_size_offset, rate);
+ kfree(probe_resp_data);
+}
+
+static int bcm43xx_refresh_cached_beacon(struct bcm43xx_private *bcm)
+{
+ struct ieee80211_tx_control control;
+
+ if (bcm->cached_beacon)
+ kfree_skb(bcm->cached_beacon);
+ bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev,
+ bcm->interface.if_id,
+ &control);
+ if (unlikely(!bcm->cached_beacon))
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void bcm43xx_update_templates(struct bcm43xx_private *bcm)
+{
+ u32 status;
+
+ assert(bcm->cached_beacon);
+
+ bcm43xx_write_beacon_template(bcm, 0x68, 0x18,
+ BCM43xx_CCK_RATE_1MB);
+ bcm43xx_write_beacon_template(bcm, 0x468, 0x1A,
+ BCM43xx_CCK_RATE_1MB);
+ bcm43xx_write_probe_resp_template(bcm, 0x268, 0x4A,
+ BCM43xx_CCK_RATE_11MB);
+
+ status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
+ status |= 0x03;
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
+}
+
+static void bcm43xx_refresh_templates(struct bcm43xx_private *bcm)
+{
+ int err;
+
+ err = bcm43xx_refresh_cached_beacon(bcm);
+ if (unlikely(err))
+ return;
+ bcm43xx_update_templates(bcm);
+ kfree_skb(bcm->cached_beacon);
+ bcm->cached_beacon = NULL;
+}
+
+static void bcm43xx_set_ssid(struct bcm43xx_private *bcm,
+ const u8 *ssid, u8 ssid_len)
+{
+ u32 tmp;
+ u16 i, len;
+
+ len = min((u16)ssid_len, (u16)0x100);
+ for (i = 0; i < len; i += sizeof(u32)) {
+ tmp = (u32)(ssid[i + 0]);
+ if (i + 1 < len)
+ tmp |= (u32)(ssid[i + 1]) << 8;
+ if (i + 2 < len)
+ tmp |= (u32)(ssid[i + 2]) << 16;
+ if (i + 3 < len)
+ tmp |= (u32)(ssid[i + 3]) << 24;
+ bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
+ 0x380 + i, tmp);
+ }
+ bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
+ 0x48, len);
+}
+
+static void bcm43xx_set_beacon_int(struct bcm43xx_private *bcm, u16 beacon_int)
+{
+ bcm43xx_time_lock(bcm);
+ if (bcm->current_core->rev >= 3) {
+ bcm43xx_write32(bcm, 0x188, (beacon_int << 16));
+ } else {
+ bcm43xx_write16(bcm, 0x606, (beacon_int >> 6));
+ bcm43xx_write16(bcm, 0x610, beacon_int);
}
- bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size);
+ bcm43xx_time_unlock(bcm);
}
static void handle_irq_beacon(struct bcm43xx_private *bcm)
{
u32 status;
+ int err;
bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON;
status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
if (!bcm->cached_beacon) {
- struct ieee80211_tx_control control;
-
- /* No cached template available, yet.
- * Request the 80211 subsystem to generate a new beacon
- * frame and use it as template.
- */
- bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev,
- bcm->interface.if_id,
- &control);
- if (unlikely(!bcm->cached_beacon)) {
- dprintkl(KERN_WARNING PFX "Could not generate beacon template.\n");
+ err = bcm43xx_refresh_cached_beacon(bcm);
+ if (unlikely(err))
goto ack;
- }
}
if ((status & 0x1) && (status & 0x2)) {
@@ -1571,18 +1809,20 @@
bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
BCM43xx_IRQ_BEACON);
bcm->irq_savedstate |= BCM43xx_IRQ_BEACON;
- if (likely(bcm->cached_beacon))
+ if (bcm->cached_beacon)
kfree_skb(bcm->cached_beacon);
bcm->cached_beacon = NULL;
return;
}
if (!(status & 0x1)) {
- bcm43xx_write_beacon_template(bcm, 0x68, 0x18);
+ bcm43xx_write_beacon_template(bcm, 0x68, 0x18,
+ BCM43xx_CCK_RATE_1MB);
status |= 0x1;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
}
if (!(status & 0x2)) {
- bcm43xx_write_beacon_template(bcm, 0x468, 0x1A);
+ bcm43xx_write_beacon_template(bcm, 0x468, 0x1A,
+ BCM43xx_CCK_RATE_1MB);
status |= 0x2;
bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
}
@@ -4114,6 +4354,17 @@
radio->power_level = conf->power_level;
bcm43xx_phy_xmitpower(bcm);
}
+
+ if (conf->ssid_hidden) {
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+ bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
+ | BCM43xx_SBF_NO_SSID_BCAST);
+ } else {
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+ bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
+ & ~BCM43xx_SBF_NO_SSID_BCAST);
+ }
+
//FIXME: This does not seem to wake up:
#if 0
if (conf->power_level == 0) {
@@ -4128,6 +4379,11 @@
//TODO: phymode
//TODO: antennas
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP)) {
+ bcm43xx_set_beacon_int(bcm, conf->beacon_int);
+ bcm43xx_refresh_templates(bcm);
+ }
+
bcm43xx_unlock_irqonly(bcm, flags);
return 0;
@@ -4293,8 +4549,11 @@
bcm->interface.mac_addr = conf->mac_addr;
bcm->interface.type = conf->type;
}
- if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
bcm43xx_select_opmode(bcm);
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP))
+ bcm43xx_refresh_templates(bcm);
+ }
err = 0;
dprintk(KERN_INFO PFX "Virtual interface added "
@@ -4343,6 +4602,11 @@
if (conf->type != IEEE80211_IF_TYPE_MNTR) {
assert(bcm->interface.if_id == if_id);
bcm->interface.bssid = conf->bssid;
+ if (bcm43xx_is_mode(bcm, IEEE80211_IF_TYPE_AP)) {
+ assert(conf->type == IEEE80211_IF_TYPE_AP);
+ bcm43xx_set_ssid(bcm, conf->ssid, conf->ssid_len);
+ bcm43xx_refresh_templates(bcm);
+ }
}
bcm43xx_unlock_irqsafe(bcm, flags);
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c 2006-06-13 21:06:01.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.c 2006-06-18 18:43:12.000000000 +0200
@@ -112,14 +112,13 @@
return 0;
}
-static void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
- const u16 octets, const u8 bitrate,
- const int ofdm_modulation)
+void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
+ const u16 octets, const u8 bitrate)
{
__le32 *data = &(plcp->data);
__u8 *raw = plcp->raw;
- if (ofdm_modulation) {
+ if (bcm43xx_is_ofdm_rate(bitrate)) {
*data = bcm43xx_plcp_get_ratecode_ofdm(bitrate);
assert(!(octets & 0xF000));
*data |= (octets << 5);
@@ -224,11 +223,9 @@
flen = sizeof(u16) + sizeof(u16) + ETH_ALEN + ETH_ALEN + FCS_LEN,
bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_plcp),
- flen, bitrate,
- !bcm43xx_is_cck_rate(bitrate));
+ flen, bitrate);
bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_fallback_plcp),
- flen, fallback_bitrate,
- !bcm43xx_is_cck_rate(fallback_bitrate));
+ flen, fallback_bitrate);
fctl = WLAN_FC_TYPE_CTRL << 2;
fctl |= WLAN_FC_STYPE_RTS << 4;
dur = le16_to_cpu(wlhdr->duration_id);
@@ -332,10 +329,9 @@
}
/* Generate the PLCP header and the fallback PLCP header. */
bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->plcp),
- plcp_fragment_len,
- bitrate, ofdm_modulation);
+ plcp_fragment_len, bitrate);
bcm43xx_generate_plcp_hdr(&txhdr->fallback_plcp, plcp_fragment_len,
- fallback_bitrate, fallback_ofdm_modulation);
+ fallback_bitrate);
/* Set the CONTROL field */
if (ofdm_modulation)
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.h
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.h 2006-06-13 14:43:08.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_xmit.h 2006-06-18 18:41:27.000000000 +0200
@@ -154,4 +154,7 @@
struct sk_buff *skb,
struct bcm43xx_rxhdr *rxhdr);
+void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
+ const u16 octets, const u8 bitrate);
+
#endif /* BCM43xx_XMIT_H_ */
Index: wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.h
===================================================================
--- wireless-dev-dscapeports.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.h 2006-06-13 14:43:08.000000000 +0200
+++ wireless-dev-dscapeports/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.h 2006-06-18 18:41:03.000000000 +0200
@@ -33,24 +33,6 @@
#include "bcm43xx.h"
-#ifdef CONFIG_BCM947XX
-#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
-
-static inline void e_aton(char *str, char *dest)
-{
- int i = 0;
- u16 *d = (u16 *) dest;
-
- for (;;) {
- dest[i++] = (char) simple_strtoul(str, NULL, 16);
- str += 2;
- if (!*str++ || i == 6)
- break;
- }
- for (i = 0; i < 3; i++)
- d[i] = cpu_to_be16(d[i]);
-}
-#endif
#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes]
#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes)
@@ -143,6 +125,12 @@
rate == BCM43xx_CCK_RATE_11MB);
}
+static inline
+int bcm43xx_is_ofdm_rate(int rate)
+{
+ return !bcm43xx_is_cck_rate(rate);
+}
+
void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf);
void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf);
--
Greetings Michael.
^ permalink raw reply
* [NET]: Prevent multiple qdisc runs
From: Herbert Xu @ 2006-06-19 12:15 UTC (permalink / raw)
To: David S. Miller, netdev
[-- Attachment #1: Type: text/plain, Size: 1415 bytes --]
Hi Dave:
I'm nearly done with the generic segmentation offload stuff (although
only TCPv4 is implemented for now), and I encountered this problem.
[NET]: Prevent multiple qdisc runs
Having two or more qdisc_run's contend against each other is bad because
it can induce packet reordering if the packets have to be requeued. It
appears that this is an unintended consequence of relinquinshing the queue
lock while transmitting. That in turn is needed for devices that spend a
lot of time in their transmit routine.
There are no advantages to be had as devices with queues are inherently
single-threaded (the loopback device is not but then it doesn't have a
queue).
Even if you were to add a queue to a parallel virtual device (e.g., bolt
a tbf filter in front of an ipip tunnel device), you would still want to
process the queue in sequence to ensure that the packets are ordered
correctly.
The solution here is to steal a bit from net_device to prevent this.
BTW, as qdisc_restart is no longer used by anyone as a module inside the
kernel (IIRC it used to with netif_wake_queue), I have not exported the
new __qdisc_run function.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
[-- Attachment #2: qdisc-run.patch --]
[-- Type: text/plain, Size: 2082 bytes --]
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e432b74..39919c8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -233,6 +233,7 @@ enum netdev_state_t
__LINK_STATE_RX_SCHED,
__LINK_STATE_LINKWATCH_PENDING,
__LINK_STATE_DORMANT,
+ __LINK_STATE_QDISC_RUNNING,
};
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index b94d1ad..75b5b93 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -218,12 +218,13 @@ extern struct qdisc_rate_table *qdisc_ge
struct rtattr *tab);
extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
-extern int qdisc_restart(struct net_device *dev);
+extern void __qdisc_run(struct net_device *dev);
static inline void qdisc_run(struct net_device *dev)
{
- while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0)
- /* NOTHING */;
+ if (!netif_queue_stopped(dev) &&
+ !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
+ __qdisc_run(dev);
}
extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index b1e4c5e..d7aca8e 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -90,7 +90,7 @@ void qdisc_unlock_tree(struct net_device
NOTE: Called under dev->queue_lock with locally disabled BH.
*/
-int qdisc_restart(struct net_device *dev)
+static inline int qdisc_restart(struct net_device *dev)
{
struct Qdisc *q = dev->qdisc;
struct sk_buff *skb;
@@ -179,6 +179,14 @@ requeue:
return q->q.qlen;
}
+void __qdisc_run(struct net_device *dev)
+{
+ while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
+ /* NOTHING */;
+
+ clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
+}
+
static void dev_watchdog(unsigned long arg)
{
struct net_device *dev = (struct net_device *)arg;
@@ -620,6 +628,5 @@ EXPORT_SYMBOL(qdisc_create_dflt);
EXPORT_SYMBOL(qdisc_alloc);
EXPORT_SYMBOL(qdisc_destroy);
EXPORT_SYMBOL(qdisc_reset);
-EXPORT_SYMBOL(qdisc_restart);
EXPORT_SYMBOL(qdisc_lock_tree);
EXPORT_SYMBOL(qdisc_unlock_tree);
^ permalink raw reply related
* Re: [NET]: Prevent multiple qdisc runs
From: jamal @ 2006-06-19 13:33 UTC (permalink / raw)
To: Herbert Xu; +Cc: netdev, David S. Miller
In-Reply-To: <20060619121519.GA16031@gondor.apana.org.au>
Herbert,
I take it you saw a lot of requeues happening that prompted this? What
were the circumstances? The _only_ times i have seen it happen is when
the (PCI) bus couldnt handle the incoming rate or there was a bug in the
driver.
Also: what happens to the packet that comes in from either local or is
being forwarded and finds the qdisc_is_running flag is set? I couldnt
tell if the intent was to drop it or not. The answer for TCP is probably
simpler than for packets being forwarded.
cheers,
jamal
On Mon, 2006-19-06 at 22:15 +1000, Herbert Xu wrote:
> Hi Dave:
>
> I'm nearly done with the generic segmentation offload stuff (although
> only TCPv4 is implemented for now), and I encountered this problem.
>
> [NET]: Prevent multiple qdisc runs
>
^ permalink raw reply
* [DOC]: generic netlink
From: jamal @ 2006-06-19 13:41 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Thomas Graf, Jay Lan, Shailabh Nagar, Per Liden
[-- Attachment #1: Type: text/plain, Size: 447 bytes --]
Folks,
Attached is a document that should help people wishing to use generic
netlink interface. It is a WIP so a lot more to go if i see interest.
The doc has been around for a while, i spent part of yesterday and this
morning cleaning it up. If you have sent me comments before, please
forgive me for having misplaced them - just send again.
cheers,
jamal
PS:- I dont have a good place to put this doc and point to, hence the
17K attachment
[-- Attachment #2: gnl.txt --]
[-- Type: text/plain, Size: 17825 bytes --]
1.0 Problem Statement
-----------------------
Netlink is a robust wire-format IPC typically used for kernel-user
communication although could also be used to be a communication
carrier between user-user and kernel-kernel.
A typical netlink connection setup is of the form:
netlink_socket = socket(PF_NETLINK, socket_type, netlink_family);
where netlink_family selects the netlink "bus" to communicate
on. Example of a family would be NETLINK_ROUTE which is 0x0 or
NETLINK_XFRM which is 0x6. [Refer to RFC 3549 for a high level view
and look at include/linux/netlink.h for some of the allocated families].
Over the years, due to its robust design, netlink has become very popular.
This has resulted in the danger of running out of family numbers to issue.
In netconf 2005 in Montreal it was decided to find ways to work around
the allocation challenge and as a result NETLINK_GENERIC "bus" was born.
This document gives a mid-level view if NETLINK_GENERIC and how to use it.
The reader does not necessarily have to know what netlink is, but needs
to know at least the encapsulation used - which is described in the next
section. There are some implicit assumptions about what netlink is
or what structures like TLVs are etc. I apologize i dont have much
time to give a tutorial - invite me to some odd conference and i will
be forced to do better than this doc. Better send patches to this doc.
2.0 High Level view
--------------------
In order to illustrate the way different components talk to each
other, the diagram below is used to provide an abstraction on
how the operations happen. There are two (three depending on your
perspective) components:
1) The generic netlink connection which for illustration is refered
to as a "bus". The generic netlink bus is shown as split between user
and kernel domains: This means programs can connect to the bus from either
kernel or user space.
2) components that talk to each other after attaching to the bus.
a) Two users are shown in user spaces
b)3 in the kernel.
All boxes have kernel-wide unique identifiers that can be used to
address them.
Typicaly, user space boxes exist to control one or more kernel level
boxen i.e they update some attributes that exist in a kernel level
box.
Any of these "boxes" can communicate to each other by first
connecting to the bus and then sending messages addressed to any
box.
+----------+ +----------+
| user1 | ...... | user-n |
+--+-------+ +-------+--+
| |
/ |
| | User
+---------+------------------------+---------+ Space/domain
user | |
--------+ Generic Netlink Bus +-----------
kernel | | Kernel
+------------------+------------------+------+ Space/domain
| | |
| | |
| | |
| | |
+--+-------+ +---+-----+ +------+-+
|controller| | foobar | | googah |
+----------+ +---------+ +--------+
The controller is a speacial built-in user of the bus. It is the repository
of info on kernel components that have attached to the bus. It has
a reserved address identifier of 0x10. By querying the controller,
one could find out that both foobar and googah are registered and
what their IDs are etc. Essentially its a namespace translator
not unlike DNS is for IP addresses. More later on this.
To get to the point of the most common usage of netlink
(user space control of a kernel component), the diagram below breaks
things down for a single user program that controls a kernel module
called foobar. The example is simple for illustration purposes; as an
example, user space could control a lot more kernel modules.
+----------------------+
| |
| user program |
gnl events ; ->-->| |
(2) ,-/ +--^-----+----------^--+
,' gnl | ^ foobar ^ foobar
,' discovery ^ | events | config/query
,' (1) | ^ (4) ^ (3)
+--/-------------- +>------|----------|-------------+
| / / \ \ |
+----------------+----------+<+--------\------------+
| / \ |
^ / \ Y
\ Y \ |
\ Y ^ |
++------- '-+ +|-----Y-----+
| controller| | foobar |
+-----------+ +------------+
#1: The user space could start by discovering the existence of
foobar by doing a dump of all existing modules or doing a specific
query by name. At that point it knows the ID of foobar.
#2: The user space could subscribe to listen to events of newly
appearing kernel modules or departure of existing ones.
#3: The user space could configure foobar or do queries on existing
state
#4: The user space program could subscribe to listen to events on
foobar. Note these events are upto the programmer of foobar. Typical
events could be things like modifications of attributes (example
by other user space programs), or creation, or deletion of attributes etc.
Events (#2, #4) are by definition asynchronous and unidirectional as shown
while configuration and querying (#1, #3) are synchronous query-response
operations.
2.1 Kernel < --> User space Communication.
-----------------------------------------
Essentially nothing new, Communication is as in standard netlink approach.
i.e from user space you open a netlink socket to the kernel - in this
case family NETLINK_GENERIC - and send and receive response as well
as asynchronous events.
To receive to events you subscribe to specific multicast groups.
You really should use libnetlink or libnl to simplify your life in
user space.
2.2 Kernel < --> User space encapsulation.
--------------------------------------
Between user space and the kernel, the message passed around looks
as follows:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| nlmsghdr |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Generic message header |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| optional user specific message header |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Optional user specific TLVs |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2.2.1 nlmsghdr
--------------
The nlmsghdr is the standard one as in:
struct nlmsghdr
{
__u32 nlmsg_len; /* Length including header */
__u16 nlmsg_type; /* Message content */
__u16 nlmsg_flags; /* Additional flags */
__u32 nlmsg_seq; /* Sequence number */
__u32 nlmsg_pid; /* Sending process PID */
};
The address of a specific kernel module is carried in nlmsg_type.
The rest of the parts of the netlink header are used exactly the
same as in current netlink (refer to RFC 3549)
2.2.2 Generic message header
----------------------------
The user specific header looks as follows:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| command | version | reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
command is an 8 bit field that your kernel/user code understands.
Typical commands are things that get/delete/add/dumping of attributes
or vectors of attributes.
It is defined like so in C-speak:
struct genlmsghdr {
__u8 cmd;
__u8 version;
__u16 reserved;
};
A get passed with a netlink flag NLMSG_F_DUMP is understood to be
requesting for a dumper.
2.2.3 optional user specific message header
---------------------------------------------
One could add the extra fields preferable to be multiples of 32
bits as:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~ ~
~ ~
~ ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The kernel module needs to understand the extra header.
Under typical circumstances this extension header doesnt exist.
2.2.4 Optional user specific TLVs
----------------------------------
The user specific header is followed typically by a list of
optional attributes in the form of TLV structures.
The example we have below has a few TLVs for illustration
The attributes carry all the data that needs to be exchanged.
This enforces a structured formating.
Messages can of course be batched as long as the socket
buffers allow it.
3.0 Kernel point of view
------------------------
Inside the kernel, the code wishing to commumicate using netlink
registers its presence by using the structre genl_type which looks as follows:
struct genl_family
{
unsigned int id;
unsigned int hdrsize;
char name[GENL_NAMSIZ];
unsigned int version;
unsigned int maxattr;
struct module * owner;
struct nlattr ** attrbuf; /* private */
struct list_head ops_list; /* private */
struct list_head family_list; /* private */
};
- id is the field which is used in the nlmsg_type of the netlink header.
Messages matching this id which are known to belong to you are
multiplexed to your specific registered handlers (more below).
Ids cannot be below 0x10 and cannot exceed 0xFFFF.
0x10 is reserved for the controller. IDs are unique system wide.
- hdrsize is the size in bytes of your msgheader that follows the
netlink header but before the TLVs.
If you have no specific messages header, this should be 0.
- name is a the string identifier you wish to be refered to.
names also have to be unique.
-version is whatever version for your own maintainance. The core
code doesnt interpret it.
- maxattr is the maximum number of attributes (TLVs) you expect to see.
You can own upto 2^16 bits of types, the danger is memory is allocated
to hold attributes; so use with care. Typically you shouldnt have more
than 10-30 types of messages you pass around. Keep reading on to see
the examples of what this is.
You probably shouldnt touch the other fields.
3.1 Kernel level Example of registering a component
----------------------------------------------------
First lets talk about registering a component foobar so that it
is visible at the controller.
We then talk about adding support for some simple commands which
can be sent to it via user space.
3.1.1 Adding foobar
------------------
//Your static Id
//
#define GENL_ID_FOOBAR 0x123
// all commands you want to process
// typicall 0 is reserved
enum {
FOOBAR_CMD_UNSPEC,
FOOBAR_CMD_NEWTYPE,
FOOBAR_CMD_DELTYPE,
FOOBAR_CMD_GETTYPE,
FOOBAR_CMD_NEWOPS,
FOOBAR_CMD_DELOPS,
FOOBAR_CMD_GETOPS,
/* add future commands here */
__FOOBAR_CMD_MAX,
};
#define FOOBAR_CMD_MAX (__FOOBAR_CMD_MAX - 1)
// the attributes you want to own
enum {
FOOBAR_ATTR_UNSPEC,
FOOBAR_ATTR_TYPE,
FOOBAR_ATTR_TYPEID,
FOOBAR_ATTR_TYPENAME,
FOOBAR_ATTR_OPER,
/* add future attributes here */
__FOOBAR_ATTR_MAX,
};
#define FOOBAR_ATTR_MAX (__FOOBAR_ATTR_MAX - 1)
static struct genl_type foobar = {
.id = GENL_ID_FOOBAR,
.name = "foobar",
.version = 0x1,
.hdrsize = sizeof(struct mymsghdr),
.maxattr = FOOBAR_ATTR_MAX,
};
So then you register yourself to receive these messages ..
Note: Your static id GENL_ID_FOOBAR is _not_ guaranteed to be
allocated to you. This is so because the system guarantees uniqueness.
If some other code has registered already for that ID - it will be too
late. You can however get a dynamically allocated ID by passing
GENL_ID_GENERATE(0x0) as the ID. In the dynamic case when the
registration succeeds you get a your .id set to whatever the system
allocated.
The user space part can discover this id by querying the controller
for your name.
err = genl_register_family(&foobar);
the registration could fail and return you the following:
1) -EINVAL if you do any of the following:
a) have an ID that is less than GENL_MIN_TYPE
b) pass a hdrsize that is either not a multiple of 4 bytes
or is less than the minimal mandated size of 4 bytes
2)-EEXIST if your name or id is already registered
3) -ENOMEM if:
a) you passed GENL_ID_GENERATE and there are no more IDs left
b) the core failed to allocate memory for your .attrbuf.
4) -EBUSY if there are issues loading the module.
on success of registration you get a 0 returned.
You MUST unregister if you are going to exit since some memmory is allocated.
You do this via:
genl_unregister_family(&foobar);
3.1.2 Adding foobar commands
-----------------------------
Next we need to register commands that will be processed by your ID.
There are two classes of commands:
a) A dumper that looks like:
int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
This callback is invoked when user space calls you with the
NLMSG_F_DUMP flag.
You are passed a skb which you fill in with the data you need to
dump.
There is a netlink_callback that you use to store state so you can
continue dumping afterwards.
As long as you return > 0 - the system will continue to call you with
skbs where you can stash more data.
Typically the trick is you should return skb->len. When you have
nothing left to add skb->len will be 0.
More later.
b) a callback for all other commands.
int (*doit)(struct sk_buff *skb, struct genl_info *info);
where struct genl_info is:
struct genl_info
{
u32 snd_seq;
u32 snd_pid;
struct nlmsghdr * nlhdr;
struct genlmsghdr * genlhdr;
void * userhdr;
struct nlattr ** attrs;
};
The system will call you with an skb where the message for you is
stored; the nlmsghdr pointer so right at the begining of the message.
the genlhdr is the generic message header mentioned earlier.
If you have a message header, this will passed to you pointed by userhdr.
If your messaging uses TLVs, they will be pointed to by attrs.
and you can process them by indexing by type into attrs.
More later.
You should return a 0 on success and a meaningful error code < 0 on failure.
Ok, so how do you register your command?
Use structure genl_ops which looks like:
struct genl_ops
{
unsigned int cmd;
unsigned int flags;
struct nla_policy *policy;
int (*doit)(struct sk_buff *skb,
struct genl_info *info);
int (*dumpit)(struct sk_buff *skb,
struct netlink_callback *cb);
struct list_head ops_list;
};
- command is the cmd identifier.
- flags are descriptors for the command.
- policy is used further to validate attributes.
- doit and dumpit have been discussed above.
To register for the dumper, you must pass GENL_DUMP_CMD in the flags.
Dumper Example:
static int foobar_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
return 0;
}
static struct genl_ops foobar_dump = {
.cmd = FOOBAR_CMD_GETTYPE,
.flags = GENL_DUMP_CMD,
.dump = foobar_dump,
};
err = genl_register_ops(&foobar, &foobar_dump);
err will be -EINVAL if foobar is not registered yet or if you pass a
NULL for foobar_dump. -EEXIST is returned if the command is found
to already have been registered.
and example for the standard interface:
static int foobar_do(struct sk_buff *skb, struct genl_info *info)
{
return 0;
}
Lets register for it to be invoked everytime the command
FOOBAR_CMD_GETTYPE is passed from user space.
static struct genl_ops foobar_do = {
.cmd = FOOBAR_CMD_GETTYPE,
.doit = foobar_do,
};
err = genl_register_ops(&foobar, &foobar_do);
TODO:
a) Add a more complete compiling kernel module with events.
Have Thomas put his Mashimaro example and point to it.
b) Describe some details on how user space -> kernel works
probably using libnl??
c) Describe discovery using the controller..
d) talk about policies etc
e) talk about how something coming from user space eventually
gets to you.
f) Talk about the TLV manipulation stuff from Thomas.
g) submit controller patch to iproute2
^ permalink raw reply
* Re: [NET]: Prevent multiple qdisc runs
From: Herbert Xu @ 2006-06-19 13:42 UTC (permalink / raw)
To: jamal; +Cc: netdev, David S. Miller
In-Reply-To: <1150724031.5815.39.camel@jzny2>
Hi Jamal:
On Mon, Jun 19, 2006 at 09:33:51AM -0400, jamal wrote:
>
> I take it you saw a lot of requeues happening that prompted this? What
> were the circumstances? The _only_ times i have seen it happen is when
> the (PCI) bus couldnt handle the incoming rate or there was a bug in the
> driver.
Actually I discovered the problem only because the generic segmentation
offload stuff that I'm working on needs to deal with the situation where
a super-packet is partially transmitted. Requeueing causes all sorts of
nasty problems so I chose to keep it within the net_device structure.
To do so requires qdisc_run to be serialised against each other. I then
found out that we want this anyway because otherwise the requeued packets
could be reordered.
> Also: what happens to the packet that comes in from either local or is
> being forwarded and finds the qdisc_is_running flag is set? I couldnt
> tell if the intent was to drop it or not. The answer for TCP is probably
> simpler than for packets being forwarded.
The qdisc_is_running only prevents qdisc_run from occuring (because it's
already running), it does not impact on the queueing of the packet.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: Network performance degradation from 2.6.11.12 to 2.6.16.20
From: Harry Edmon @ 2006-06-19 13:54 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Andrew Morton, linux-kernel, netdev
In-Reply-To: <4494C592.6090601@osdl.org>
Stephen Hemminger wrote:
> Does this fix it?
> # sysctl -w net.ipv4.tcp_abc=0
That did not help. I have 1 minute outputs from tcpdump under both 2.6.11.12
and 2.6.16.20. You will see a large size difference between the files. Since
the 2.6.11.12 one is 2 MBytes, I thought I would post them via the web instead
of via attachments. Look at:
http://www.atmos.washington.edu/~harry/linux/2.6.11.12.out.1min
http://www.atmos.washington.edu/~harry/linux/2.6.16.20.out.1min
And again, thank to all of you for looking into this.
--
Dr. Harry Edmon E-MAIL: harry@atmos.washington.edu
206-543-0547 harry@u.washington.edu
Dept of Atmospheric Sciences FAX: 206-543-0308
University of Washington, Box 351640, Seattle, WA 98195-1640
^ 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