Netdev List
 help / color / mirror / Atom feed
* [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(&notify_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


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