Netdev List
 help / color / mirror / Atom feed
* wireless softmac origin (net/ieee80211/softmac)
From: Ian Brown @ 2006-05-01 14:19 UTC (permalink / raw)
  To: netdev

Hello,
I am looking at 2.6.17-rc3 kernel.
 I wonder: what is the origin of softmac in
2.6.17-rc3 kernel ?
I see in the *.c files under that folder:
Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
 *                          Joseph Jezak <josejx@gentoo.org>
 *                          Larry Finger <Larry.Finger@lwfinger.net>
 *                          Danny van Dyk <kugelfang@gentoo.org>
 *                          Michael Buesch <mbuesch@freenet.de>

Is this softmac layer was written from scratch ? or was it
taken (fully/partially) from softmac in the devicescape linux kernel stack ?
http://devicescape.com/

Best,
IB

^ permalink raw reply

* Re: wireless softmac origin (net/ieee80211/softmac)
From: Joseph Jezak @ 2006-05-01 14:30 UTC (permalink / raw)
  To: NetDev; +Cc: Ian Brown
In-Reply-To: <d0383f90605010719p616243d0l8da568c02815f504@mail.gmail.com>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ian Brown wrote:
> Hello,
> I am looking at 2.6.17-rc3 kernel.
> I wonder: what is the origin of softmac in
> 2.6.17-rc3 kernel ?
> I see in the *.c files under that folder:
> Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
> *                          Joseph Jezak <josejx@gentoo.org>
> *                          Larry Finger <Larry.Finger@lwfinger.net>
> *                          Danny van Dyk <kugelfang@gentoo.org>
> *                          Michael Buesch <mbuesch@freenet.de>
> 
> Is this softmac layer was written from scratch ? or was it
> taken (fully/partially) from softmac in the devicescape linux kernel
> stack ?
> http://devicescape.com/
> 
> Best,
> IB
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

It was written from scratch.

- -Joe
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEVht7wGq7BLLARfoRAspnAJ9vQC8EUnzN9efWpJZijVNDnsSUIwCfUiVZ
1nsWLEQr+iA0BG18tUKoY8c=
=GRht
-----END PGP SIGNATURE-----

^ permalink raw reply

* Re: VLAN subinterfaces, bridges and udev
From: Ben Greear @ 2006-05-01 16:02 UTC (permalink / raw)
  To: netdev, md
In-Reply-To: <20060430142929.GA8901@wonderland.linux.it>

Marco d'Itri wrote:
> [Please Cc me, I am not subscribed to netdev.]
> 
> Can I rely on the presence of the $DEVPATH/driver symlink (e.g.
> /sys/class/net/eth0/driver) to check if a network interface is a "real"
> device insteaf of a VLAN or a bridge?

To distinguish I use a VLAN specific IOCTL (GET_VLAN_REALDEV_NAME_CMD).
If that IOCTL has no error, then it is a VLAN.

I don't know if there is a similar trick for bridges.

Thanks,
Ben


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply

* [1/1] AIO sendfile() implementation.
From: Evgeniy Polyakov @ 2006-05-01 16:09 UTC (permalink / raw)
  To: netdev; +Cc: David Miller

Kevent [1] based AIO sendfile() implementation.

Patch can be found in archive [2] and is attached. 
It is called /tmp/aio_sendfile.1 and depends on full kevent patchset
kevent_full.diff.2, which was recenly sent to netdev@ [3].

Patch is fairly trivial - just use file->f_op->sendpage() for page
sending, all asynchronous mechanism lives in page propagation into VFS
cache.

1. kevent system
http://tservice.net.ru/~s0mbre/old/?section=projects&item=kevent

2. kevent archive
http://tservice.net.ru/~s0mbre/archive/kevent/

3. full kevent patchset
http://marc.theaimsgroup.com/?l=linux-netdev&m=114631895701710&w=2

Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>

diff --git a/kernel/kevent/kevent_aio.c b/kernel/kevent/kevent_aio.c
index f72107a..249fbc2 100644
--- a/kernel/kevent/kevent_aio.c
+++ b/kernel/kevent/kevent_aio.c
@@ -31,6 +31,8 @@
 #include <linux/buffer_head.h>
 #include <linux/kevent.h>
 
+#include <net/sock.h>
+
 #define KEVENT_AIO_DEBUG
 
 #ifdef KEVENT_AIO_DEBUG
@@ -47,7 +49,7 @@ struct kevent_aio_private
 	loff_t			processed;
 	atomic_t		bio_page_num;
 	struct completion	bio_complete;
-	struct file		*file;
+	struct file		*file, *sock;
 	struct work_struct	work;
 };
 
@@ -320,15 +322,15 @@ static int kevent_mpage_readpages(struct
 
 static size_t kevent_aio_vfs_read_actor(struct kevent *k, struct page *kpage, size_t len)
 {
-#if 0
 	struct kevent_aio_private *priv = k->priv;
-	struct kevent *n;
+	size_t ret;
+	
+	ret = priv->sock->f_op->sendpage(priv->sock, kpage, 0, len, &priv->sock->f_pos, 1);
 
-	n = kevent_alloc(GFP_KERNEL);
-	if (!n)
-		return -ENOMEM;
-#endif	
-	return len;
+	dprintk("%s: k=%p, page=%p, len=%zu, ret=%zd.\n", 
+			__func__, k, kpage, len, ret);
+
+	return ret;
 }
 
 static int kevent_aio_vfs_read(struct kevent *k, 
@@ -444,21 +446,28 @@ static void kevent_aio_work(void *data)
 static int kevent_aio_enqueue(struct kevent *k)
 {
 	int err;
-	struct file *file;
+	struct file *file, *sock;
 	struct inode *inode;
 	struct kevent_aio_private *priv;
 	int fd = k->event.id.raw[0];
 	int num = k->event.id.raw[1];
+	int s = k->event.ret_data[0];
 	size_t size;
 
 	err = -ENODEV;
 	file = fget(fd);
 	if (!file)
 		goto err_out_exit;
+	
+	sock = fget(s);
+	if (!sock)
+		goto err_out_fput_file;
 
 	err = -EINVAL;
 	if (!file->f_dentry || !file->f_dentry->d_inode)
 		goto err_out_fput;
+	if (!sock->f_dentry || !sock->f_dentry->d_inode)
+		goto err_out_fput;
 
 	inode = igrab(file->f_dentry->d_inode);
 	if (!inode)
@@ -477,6 +486,7 @@ static int kevent_aio_enqueue(struct kev
 	priv->size = size;
 	priv->offset = 0;
 	priv->file = file;
+	priv->sock = sock;
 	INIT_WORK(&priv->work, kevent_aio_work, k);
 	k->priv = priv;
 
@@ -492,6 +502,8 @@ static int kevent_aio_enqueue(struct kev
 err_out_iput:
 	iput(inode);
 err_out_fput:
+	fput(sock);
+err_out_fput_file:
 	fput(file);
 err_out_exit:
 
@@ -503,6 +515,7 @@ static int kevent_aio_dequeue(struct kev
 	struct kevent_aio_private *priv = k->priv;
 	struct inode *inode = k->st->origin;
 	struct file *file = priv->file;
+	struct file *sock = priv->sock;
 
 	kevent_storage_dequeue(k->st, k);
 	flush_scheduled_work();
@@ -512,6 +525,7 @@ static int kevent_aio_dequeue(struct kev
 	k->priv = NULL;
 	iput(inode);
 	fput(file);
+	fput(sock);
 
 	return 0;
 }
@@ -533,6 +547,9 @@ asmlinkage long sys_aio_sendfile(int ctl
 
 	ukread.id.raw[0] = fd;
 	ukread.id.raw[1] = num;
+	ukread.ret_data[0] = s;
+
+	dprintk("%s: fd=%d, s=%d, num=%d.\n", __func__, fd, s, num);
 
 	file = fget_light(ctl_fd, &fput_needed);
 	if (!file)

-- 
	Evgeniy Polyakov

^ permalink raw reply related

* Re: tw32_f() in tg3_write_mem()
From: Michael Chan @ 2006-05-01 14:53 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <20060430.230719.90327967.davem@davemloft.net>

On Sun, 2006-04-30 at 23:07 -0700, David S. Miller wrote:
> From: "Michael Chan" <mchan@broadcom.com>
> Date: Sun, 30 Apr 2006 22:05:40 -0700
> 
> > Reading back the data register is a safe thing to do. This
> > guarantees that the data is written before we change the address
> > register to the zero value. Without the read, there is a danger of
> > the value being written to SRAM address 0 instead of the desired
> > address.
> 
> Writes can be posted, but they cannot be reordered can they?
> 

Right, reordering is not allowed unless the relaxed ordering attribute
is set. The read back here is not to guarantee ordering. Those SRAM
address and data registers require "set-up" times for the SRAM writes
and reads to work correctly. The "set-up" times are met either with
config. cycles or with a read when using MMIO cycles. No udelays are
needed, just a read will do.


^ permalink raw reply

* Fw: [Bugme-new] [Bug 6471] New: sky2 problem with Marvell 88E8055
From: Andrew Morton @ 2006-05-01 16:35 UTC (permalink / raw)
  To: netdev; +Cc: bugme-daemon@kernel-bugs.osdl.org, prb



Begin forwarded message:

Date: Mon, 1 May 2006 05:20:30 -0700
From: bugme-daemon@bugzilla.kernel.org
To: bugme-new@lists.osdl.org
Subject: [Bugme-new] [Bug 6471] New: sky2 problem with Marvell 88E8055


http://bugzilla.kernel.org/show_bug.cgi?id=6471

           Summary: sky2 problem with Marvell 88E8055
    Kernel Version: 2.6.17-rc3
            Status: NEW
          Severity: high
             Owner: jgarzik@pobox.com
         Submitter: prb@du.se


Most recent kernel where this bug did not occur: 2.6.17-rc3
Distribution: Gentoo
Hardware Environment: Fujitsu-Siemens E8110, ethernet Card Marvell 88E8055
Software Environment:
Problem Description:
Unable to connect, sometimes kernel hangs

Steps to reproduce:
boot, modprobe sky2, dhclient -d eth1

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.

^ permalink raw reply

* Re: [PATCH 4/6] tg3: Add reset_phy parameter to chip reset functions
From: Michael Chan @ 2006-05-01 15:19 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev
In-Reply-To: <20060429.185952.101410162.davem@davemloft.net>

On Sat, 2006-04-29 at 18:59 -0700, David S. Miller wrote:
> From: "Michael Chan" <mchan@broadcom.com>
> Date: Fri, 28 Apr 2006 16:36:08 -0700
> 
> > Add a reset_phy parameter to tg3_reset_hw() and tg3_init_hw(). With
> > the full chip reset during MAC address change, the automatic PHY reset
> > during chip reset will cause a link down and bonding will not work
> > properly as a result. With this reset_phy parameter, we can do a chip
> > reset without link down when changing MAC address or MTU.
> > 
> > Signed-off-by: Gary Zambrano <zambrano@broadcom.com>
> > Signed-off-by: Michael Chan <mchan@broadcom.com>
> 
> Applied.
> 
> Doesn't the signalling interface between the MAC and the
> PHY get reset during a chip reset and couldn't that cause
> problems if we bypass the PHY reset?

The PHY reset is needed if the PHY was previously put into low power
mode. In the cases where we reset the chip due to MTU or MAC address
changes, the power settings are not changed and therefore PHY reset is
not needed.


^ permalink raw reply

* Re: RtNetlink in wireless.c and netlink_broadcast(uevent_sock,...) - newbie
From: Jean Tourrilhes @ 2006-05-01 17:50 UTC (permalink / raw)
  To: netdev

Xu Nakajima wrote :
> 
> Hello,
> 
> I saw that in the wireless linux stack, there is usage
> 
> of sending messages to user space via the RtNetlink
> event channel : 
> in net/core/wireless.c,  wireless_send_event() method
> calls rtmsg_iwinfo() which calls
> netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK,
> GFP_ATOMIC); (it fills a struct with 
> rtnetlink_fill_iwinfo before).
> 
> On the other hand, I see that for example, in the case
> of 
> sending messeges to userspace udev socket, the
> netlink_broadcast() call is with a different
> mecahinsm;  
> In lib/kobject_uevent.c, there is the following call
> netlink_broadcast(uevent_sock, skb, 0, 1, GFP_KERNEL);
> 
> Is there something special about RtNetlink event
> channel
> which makes it needed fot wireless.c (for example)? 
> While udev can use some other mechanism ?
> What is special about RtNetlink event channel
> in comaprison to non RtNetlink channels?

	Netlink is a generic socket mechanism. On top of Netlink, you
can have multiple types of sockets, the same way that on top of TCP
sockets you can implement various protocols, such as HTTP, NFS, SSH...
	RtNetlink was the first Netlink protocol implemented and is
the Netlink protocol used to configure network interfaces. In the file
net/core/rtnetlink.c, you will find that there are many actions that
generates RtNetlink events. Together with wireless events, they give
you a very detailed view of what's happening with network interfaces.
	The udev-netlink protocol is quite recent and a completely
different Netlink ptotocol that uses a different packet format. As far
as exporting network information, it is very crude, because the goal
of udev is not managing network interfaces. Yes, udev does duplicate
some RtNetlink events, but the overlap is not so much, so that's ok.

	Good luck...

	Jean

^ permalink raw reply

* Re: [PATCH] Add some new card IDs to hostap_cs
From: Jean Tourrilhes @ 2006-05-01 18:04 UTC (permalink / raw)
  To: Marcin Juszkiewicz, netdev; +Cc: Pavel Roskin

Marcin Juszkiewicz wrote :
> 
> When I use pcmcia-cs then my Pretec WiFi card is handled by hostap
> driver and everything is working fine. Recently I switched to
> pcmciautils and after card insert orinoco modules are loaded. I prefer
> to use hostap modules because they work the same under 2.4 and 2.6
> kernels (with orinoco I have to use 0.13e ones because never ones does
> not work under 2.4/arm).

	I'm sorry, but I have to veto part of your patch because it's
clear you don't know what you are doing.
	Some of those cards are Orinoco or Symbol cards. The HostAP
driver do *NOT* properly support them (try to scan or to use ad-hoc
mode). Only the Orinoco driver do support those cards.
	Therefore, the HostAP driver should never bind to those cards.

	My howto do explain those things in details. Please don't do
those kind of patches as it will break support for those of use using
those cards.

> + PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001), /* "Intel PRO/Wireless
2011" */

	That's a Symbol card. I know, I have one.

> +	/*card "3Com AirConnect"*/
> +	PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card",
> +			0x90952d33, 0xfa4f2ce9),

	That's a Symbol card. I know, I have two.

> +	/*card "MELCO WLI-PCM-L11"*/
> +	PCMCIA_DEVICE_PROD_ID12( "MELCO", "WLI-PCM-L11",
> +			0xc549cac9, 0xc2f6de9b),
> +
> +	/*card "MELCO WLI-PCM-L11G"*/
> +	PCMCIA_DEVICE_PROD_ID12( "MELCO", "WLI-PCM-L11G",
> +			0xfebebb55, 0x6db62357),
> +
> +	/*card "MELCO WLI-PCM-L11G"*/
> +	PCMCIA_DEVICE_PROD_ID12( "BUFFALO", "WLI-PCM-L11G",
> +			0x6cdab6ea, 0xc364d25d),
> +
> +	/*card "Buffalo WLI2-CF-S11"*/
> +	PCMCIA_DEVICE_PROD_ID12( "BUFFALO", "WLI2-CF-S11",
> +			0x798caeca, 0xe38746ab),
> +

	I believe, from the report I got, that those are Orinoco cards.

> +	/*card "NCR WaveLAN/IEEE Adapter"*/
> +	PCMCIA_DEVICE_PROD_ID12( "NCR", "WaveLAN/IEEE",
> +			0x7b03a1a1, 0x1e9b31cf),

	That's an Orinoco card. I know, I have zillion of them.

	Regards,

	Jean

^ permalink raw reply

* Re: IP1000 gigabit nic driver
From: Pekka Enberg @ 2006-05-01 18:08 UTC (permalink / raw)
  To: David Vrabel; +Cc: romieu, linux-kernel, netdev, david
In-Reply-To: <4455F1D8.5030102@cantab.net>

Hi David,

On Mon, 2006-05-01 at 12:32 +0100, David Vrabel wrote:
> It was clocking the MII management interface (MDC) at 500 Hz so each PHY
> register access took some 130 ms, and many registers accesses were being
> done on initialization. According to the datasheet, the maximum
> frequency for MDC is 2.5 MHz.  Delays have been adjusted accordingly.

Thanks. Merged your patch.

				Pekka

[PATCH] IP1000 Gigabit Ethernet device driver

This is a cleaned up fork of the IP1000A device driver:

  http://www.icplus.com.tw/driver-pp-IP1000A.html

Open issues:

  - ipg_probe() looks really fishy and doesn't handle all errors
    (e.g. ioremap failing).
  - ipg_nic_do_ioctl() is playing games with user-space pointer
    and lets userspace do PCI access. I think we should nuke the
    ioctl. Arjan suggested ethtool ioctl instead, but we don't
    seem to have that kind of functionality now anyway.

Changelog:

  - Kill 2.2 and 2.4 compatability macros (Pekka)
  - Use proper module API (Pekka)
  - Use proper PCI API (Pekka)
  - Use netdev_priv (Pekka)
  - Consolidate headers to one file (Pekka)
  - Use __iomem annotations (Pekka)
  - Use iomap instead of read/out for I/O (Pekka)
  - Remove obfuscating register access macros (Pekka)
  - Remove changelogs (David)
  - Remove ether_crc_le() and use crc32_le() instead (David)
  - No more nonsense with root_dev. ipg_remove() now works (David)
  - Move PHY and MAC address initialization into the ipg_probe().  It was
    previously filling in the MAC address on open which breaks some user
    space. (David)
  - Folded ipg_nic_init into ipg_probe since it was broke otherwise (David)
  - Reduce delays when reading/writing the PHY registers so we clock the
    MII management interface at 2.5 MHz (the maximum according to the
    datasheet) instead of 500 Hz. (David)

The patch is 128 KB in size, so I am not including it in this
mail. You can find the patch here:

  http://www.cs.helsinki.fi/u/penberg/linux/ip1000-driver.patch

Signed-off-by: David Vrabel <dvrabel@cantab.net>
Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>


^ permalink raw reply

* Re: [PATCH] Add some new card IDs to hostap_cs
From: Pavel Roskin @ 2006-05-01 18:36 UTC (permalink / raw)
  To: jt, netdev; +Cc: Marcin Juszkiewicz
In-Reply-To: <20060501180425.GB32508@bougret.hpl.hp.com>

On Mon, 2006-05-01 at 11:04 -0700, Jean Tourrilhes wrote:
> Marcin Juszkiewicz wrote :
> > 
> > When I use pcmcia-cs then my Pretec WiFi card is handled by hostap
> > driver and everything is working fine. Recently I switched to
> > pcmciautils and after card insert orinoco modules are loaded. I prefer
> > to use hostap modules because they work the same under 2.4 and 2.6
> > kernels (with orinoco I have to use 0.13e ones because never ones does
> > not work under 2.4/arm).
> 
> 	I'm sorry, but I have to veto part of your patch because it's
> clear you don't know what you are doing.
> 	Some of those cards are Orinoco or Symbol cards.

I agree.  Please don't apply this patch.

-- 
Regards,
Pavel Roskin


^ permalink raw reply

* [PATCH] bcm43xx-d80211: proper implementation of virtual interface support
From: Michael Buesch @ 2006-05-01 19:35 UTC (permalink / raw)
  To: Jiri Benc; +Cc: John W. Linville, bcm43xx-dev, netdev

[-- Attachment #1: Type: text/plain, Size: 15995 bytes --]

Hi,

Jiri, please review this patch for things that might look
strange to you. :)

--

This replaces the bcm43xx-d80211 virtual interfaces hack by
a correct implementation with support for monitor during oper.

Index: wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h
===================================================================
--- wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h	2006-04-28 16:13:40.000000000 +0200
+++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx.h	2006-05-01 20:25:31.000000000 +0200
@@ -626,10 +626,34 @@
 	u8 algorithm;
 };
 
+struct bcm43xx_interface {
+	struct list_head list;
+	/* Interface type (IEEE80211_IF_TYPE_XXX). */
+	int type;
+	/* Opaque ID from the ieee80211 subsystem. Do not modify. */
+	int if_id;
+	/* MAC address for this interface. */
+	u8 *mac_addr;
+	/* BSSID (if any). */
+	u8 *bssid;
+};
+
+struct bcm43xx_interface_list {
+	/* Linked list of active interfaces. */
+	struct list_head list;
+	/* Shortcut pointer to the AP interface (if any). */
+	struct bcm43xx_interface *ap_if;
+
+	/* Usage counters of the internal operation modes. */
+	u16 opmode_ap;
+	u16 opmode_adhoc;
+	u16 opmode_monitor;
+	u16 opmode_promisc;
+};
+
 struct bcm43xx_private {
 	struct ieee80211_hw *ieee;
 	struct ieee80211_low_level_stats ieee_stats;
-	int iw_mode;
 
 	struct net_device *net_dev;
 	struct pci_dev *pci_dev;
@@ -653,6 +677,11 @@
 	    short_slot:1,		/* TRUE, if short slot timing is enabled. */
 	    firmware_norelease:1;	/* Do not release the firmware. Used on suspend. */
 
+	/* One physical device can have one or more virtual
+	 * interfaces. This stores and manages the virtual interfaces.
+	 */
+	struct bcm43xx_interface_list interfaces;
+	/* Various statistics about the physical device. */
 	struct bcm43xx_stats stats;
 
 	/* Bus type we are connected to.
@@ -716,8 +745,6 @@
 
 	/* Informational stuff. */
 	char nick[IW_ESSID_MAX_SIZE + 1];
-	u8 bssid[ETH_ALEN];
-	int interfaces;
 
 	/* encryption/decryption */
 	u16 security_offset;
Index: wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c	2006-04-28 16:13:40.000000000 +0200
+++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_leds.c	2006-05-01 18:57:26.000000000 +0200
@@ -217,7 +217,7 @@
 				bcm43xx_led_blink_stop(led, 0);
 			continue;
 		case BCM43xx_LED_APTRANSFER:
-			if (bcm->iw_mode == IW_MODE_MASTER) {
+			if (bcm->interfaces.opmode_ap) {
 				if (transferring) {
 					interval = BCM43xx_LEDBLINK_FAST;
 					turn_on = 1;
Index: wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c	2006-04-28 16:13:40.000000000 +0200
+++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_main.c	2006-05-01 20:25:24.000000000 +0200
@@ -378,18 +378,30 @@
 static void bcm43xx_macfilter_clear(struct bcm43xx_private *bcm,
 				    u16 offset)
 {
-	const u8 zero_addr[ETH_ALEN] = { 0 };
+	static const u8 zero_addr[ETH_ALEN] = { 0 };
 
 	bcm43xx_macfilter_set(bcm, offset, zero_addr);
 }
 
 static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
 {
+	static const u8 zero_addr[ETH_ALEN] = { 0 };
+	struct bcm43xx_interface *iface;
 	const u8 *mac = (const u8 *)(bcm->net_dev->dev_addr);
-	const u8 *bssid = bcm->bssid;
+	const u8 *bssid = NULL;
 	u8 mac_bssid[ETH_ALEN * 2];
 	int i;
 
+	list_for_each_entry(iface, &bcm->interfaces.list, list) {
+		if (iface->type != IEEE80211_IF_TYPE_MNTR &&
+		    iface->bssid) {
+			bssid = iface->bssid;
+			break;
+		}
+	}
+	if (!bssid)
+		bssid = zero_addr;
+
 	memcpy(mac_bssid, mac, ETH_ALEN);
 	memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
 
@@ -1438,15 +1450,15 @@
 
 static void handle_irq_ps(struct bcm43xx_private *bcm)
 {
-	if (bcm->iw_mode == IW_MODE_MASTER) {
+	if (bcm->interfaces.opmode_ap) {
 		///TODO: PS TBTT
 	} else {
 		if (1/*FIXME: the last PSpoll frame was sent successfully */)
 			bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
 	}
-	if (bcm->iw_mode == IW_MODE_ADHOC)
+	bcm->reg124_set_0x4 = 0;
+	if (bcm->interfaces.opmode_adhoc)
 		bcm->reg124_set_0x4 = 1;
-	//FIXME else set to false?
 }
 
 static void handle_irq_reg124(struct bcm43xx_private *bcm)
@@ -1456,7 +1468,6 @@
 	bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
 			bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD)
 			| 0x4);
-	//FIXME: reset reg124_set_0x4 to false?
 }
 
 static void handle_irq_pmq(struct bcm43xx_private *bcm)
@@ -1509,7 +1520,10 @@
 		 * Request the 80211 subsystem to generate a new beacon
 		 * frame and use it as template.
 		 */
-		bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev, 0, &control);
+		assert(bcm->interfaces.ap_if);
+		bcm->cached_beacon = ieee80211_beacon_get(bcm->net_dev,
+							  bcm->interfaces.ap_if->if_id,
+							  &control);
 		if (unlikely(!bcm->cached_beacon)) {
 			dprintkl(KERN_WARNING PFX "Could not generate beacon template.\n");
 			goto ack;
@@ -1603,7 +1617,7 @@
 	}
 
 	if (reason & BCM43xx_IRQ_BEACON) {
-		if (bcm->iw_mode == IW_MODE_MASTER)
+		if (bcm->interfaces.opmode_ap)
 			handle_irq_beacon(bcm);
 		bcmirq_handled(BCM43xx_IRQ_BEACON);
 	}
@@ -2147,55 +2161,35 @@
 	printkl(KERN_ERR PFX "MAC suspend failed\n");
 }
 
-void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
-			int iw_mode)
+static void bcm43xx_select_opmodes(struct bcm43xx_private *bcm)
 {
-	struct net_device *net_dev = bcm->net_dev;
 	u32 status;
 	u16 value;
 
-	bcm->iw_mode = iw_mode;
-	if (iw_mode == IW_MODE_MONITOR)
-		net_dev->type = ARPHRD_IEEE80211;
-	else
-		net_dev->type = ARPHRD_ETHER;
-
 	status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
-	/* Reset status to infrastructured mode */
-	status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR);
+	/* Reset status to default STA mode */
+	status &= ~BCM43xx_SBF_MODE_AP;
+	status &= ~BCM43xx_SBF_MODE_MONITOR;
 	status &= ~BCM43xx_SBF_MODE_PROMISC;
 	status |= BCM43xx_SBF_MODE_NOTADHOC;
 
+	if (bcm->interfaces.opmode_ap)
+		status |= BCM43xx_SBF_MODE_AP;
+	if (bcm->interfaces.opmode_adhoc)
+		status &= ~BCM43xx_SBF_MODE_NOTADHOC;
+	if (bcm->interfaces.opmode_monitor)
+		status |= BCM43xx_SBF_MODE_MONITOR;
+	if (bcm->interfaces.opmode_promisc)
+		status |= BCM43xx_SBF_MODE_PROMISC;
+
 /* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */
 status |= BCM43xx_SBF_MODE_PROMISC;
 
-	switch (iw_mode) {
-	case IW_MODE_MONITOR:
-		status |= BCM43xx_SBF_MODE_MONITOR;
-		status |= BCM43xx_SBF_MODE_PROMISC;
-		break;
-	case IW_MODE_ADHOC:
-		status &= ~BCM43xx_SBF_MODE_NOTADHOC;
-		break;
-	case IW_MODE_MASTER:
-		status |= BCM43xx_SBF_MODE_AP;
-		break;
-	case IW_MODE_SECOND:
-	case IW_MODE_REPEAT:
-		TODO(); /* TODO */
-		break;
-	case IW_MODE_INFRA:
-		/* nothing to be done here... */
-		break;
-	default:
-		dprintk(KERN_ERR PFX "Unknown mode in set_iwmode: %d\n", iw_mode);
-	}
-	if (net_dev->flags & IFF_PROMISC)
-		status |= BCM43xx_SBF_MODE_PROMISC;
 	bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
 
 	value = 0x0002;
-	if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
+	if (bcm->interfaces.opmode_adhoc == 0 &&
+	    bcm->interfaces.opmode_ap == 0) {
 		if (bcm->chip_id == 0x4306 && bcm->chip_rev == 3)
 			value = 0x0064;
 		else
@@ -2291,7 +2285,7 @@
 	bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000);
 
 	/* Initially set the wireless operation mode. */
-	bcm43xx_set_iwmode(bcm, bcm->iw_mode);
+	bcm43xx_select_opmodes(bcm);
 
 	if (bcm->current_core->rev < 3) {
 		bcm43xx_write16(bcm, 0x060E, 0x0000);
@@ -2599,27 +2593,6 @@
 	return err;
 }
 
-static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm)
-{
-	const u8 *mac = (const u8*)(bcm->net_dev->dev_addr);
-	u8 *bssid = bcm->bssid;
-
-	switch (bcm->iw_mode) {
-	case IW_MODE_ADHOC:
-		random_ether_addr(bssid);
-		break;
-	case IW_MODE_MASTER:
-	case IW_MODE_INFRA:
-	case IW_MODE_REPEAT:
-	case IW_MODE_SECOND:
-	case IW_MODE_MONITOR:
-		memcpy(bssid, mac, ETH_ALEN);
-		break;
-	default:
-		assert(0);
-	}
-}
-
 static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm,
 				      u16 rate,
 				      int is_ofdm)
@@ -2746,7 +2719,6 @@
 	/* Maximum Contention Window */
 	bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
 
-	bcm43xx_gen_bssid(bcm);
 	bcm43xx_write_mac_bssid_templates(bcm);
 
 	if (bcm->current_core->rev >= 5)
@@ -4169,13 +4141,8 @@
 static int bcm43xx_net_open(struct net_device *net_dev)
 {
 	struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
-	int res;
 
-	res = bcm43xx_init_board(bcm);
-	if (!res)
-		return res;
-	bcm43xx_set_iwmode(bcm, bcm->iw_mode);
-	return 0;
+	return bcm43xx_init_board(bcm);
 }
 
 static int bcm43xx_net_stop(struct net_device *net_dev)
@@ -4194,33 +4161,170 @@
 				 struct ieee80211_if_init_conf *conf)
 {
 	struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+	unsigned long flags;
+	int err = -ENOBUFS;
+	struct bcm43xx_interface *iface;
 
-	if (bcm->interfaces > 0)
-		return -ENOBUFS;
-	if (conf->type == IEEE80211_IF_TYPE_MNTR) {
-		bcm->iw_mode = IW_MODE_MONITOR;
-	} else {
-		if (memcmp(bcm->net_dev->dev_addr, conf->mac_addr, ETH_ALEN) != 0)
-			return -EADDRNOTAVAIL;
-		if (conf->type == IEEE80211_IF_TYPE_STA)
-			bcm->iw_mode = IW_MODE_INFRA;
-		else if (conf->type == IEEE80211_IF_TYPE_IBSS)
-			bcm->iw_mode = IW_MODE_ADHOC;
-		else if (conf->type == IEEE80211_IF_TYPE_AP)
-			bcm->iw_mode = IW_MODE_MASTER;
-		else
-			return -EOPNOTSUPP;
+	iface = kzalloc(sizeof(*iface), GFP_KERNEL);
+	if (!iface)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&iface->list);
+	iface->type = conf->type;
+	iface->if_id = conf->if_id;
+	iface->mac_addr = conf->mac_addr;
+
+	bcm43xx_lock_mmio(bcm, flags);
+	switch (conf->type) {
+	case IEEE80211_IF_TYPE_AP:
+		/* Cannot run more than one AP or concurrently
+		 * with IBSS mode.
+		 */
+		if (bcm->interfaces.opmode_ap)
+			break;
+		if (bcm->interfaces.opmode_adhoc)
+			break;
+		bcm->interfaces.opmode_ap++;
+		bcm->interfaces.ap_if = iface;
+		err = 0;
+		break;
+	case IEEE80211_IF_TYPE_STA:
+		/* Cannot run STA and AP or IBSS mode concurrently. */
+		if (bcm->interfaces.opmode_ap)
+			break;
+		if (bcm->interfaces.opmode_adhoc)
+			break;
+		err = 0;
+		break;
+	case IEEE80211_IF_TYPE_IBSS:
+		/* Cannot run more than one IBSS or concurrently
+		 * with AP mode.
+		 */
+		if (bcm->interfaces.opmode_ap)
+			break;
+		if (bcm->interfaces.opmode_adhoc)
+			break;
+		bcm->interfaces.opmode_adhoc++;
+		err = 0;
+		break;
+	case IEEE80211_IF_TYPE_MNTR:
+		bcm->interfaces.opmode_monitor++;
+		err = 0;
+		break;
+	case IEEE80211_IF_TYPE_WDS:
+		//TODO: Uhm..., well.
+		break;
+	default:
+		assert(0);
 	}
-	bcm->interfaces++;
-	return 0;
+	if (!err) {
+		list_add_tail(&iface->list, &bcm->interfaces.list);
+		if (bcm->initialized)
+			bcm43xx_select_opmodes(bcm);
+
+		dprintk(KERN_INFO PFX "Virtual interface added "
+				      "(type: 0x%08X, ID: %d, MAC: "
+				      BCM43xx_MACFMT ")\n",
+			conf->type, conf->if_id,
+			BCM43xx_MACARG(conf->mac_addr));
+	}
+
+	bcm43xx_unlock_mmio(bcm, flags);
+
+	if (err)
+		kfree(iface);
+
+	return err;
 }
 
 static void bcm43xx_remove_interface(struct net_device *net_dev,
 				     struct ieee80211_if_init_conf *conf)
 {
 	struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+	unsigned long flags;
+	struct bcm43xx_interface *iface, *tmp_iface;
+
+	bcm43xx_lock_mmio(bcm, flags);
+	list_for_each_entry_safe(iface, tmp_iface, &bcm->interfaces.list, list) {
+		if (iface->if_id != conf->if_id)
+			continue;
+		assert(conf->type == iface->type);
+
+		switch (iface->type) {
+		case IEEE80211_IF_TYPE_AP:
+			bcm->interfaces.opmode_ap--;
+			assert(bcm->interfaces.opmode_ap == 0);
+			bcm->interfaces.ap_if = NULL;
+			break;
+		case IEEE80211_IF_TYPE_STA:
+			break;
+		case IEEE80211_IF_TYPE_IBSS:
+			bcm->interfaces.opmode_adhoc--;
+			assert(bcm->interfaces.opmode_adhoc == 0);
+			break;
+		case IEEE80211_IF_TYPE_MNTR:
+			assert(bcm->interfaces.opmode_monitor > 0);
+			bcm->interfaces.opmode_monitor--;
+			break;
+		case IEEE80211_IF_TYPE_WDS:
+			//TODO: Uhm..., well.
+			break;
+		default:
+			assert(0);
+		}
+		list_del(&iface->list);
+		kfree(iface);
+		if (bcm->initialized)
+			bcm43xx_select_opmodes(bcm);
+
+		dprintk(KERN_INFO PFX "Virtual interface removed "
+				      "(type: 0x%08X, ID: %d, MAC: "
+				      BCM43xx_MACFMT ")\n",
+			conf->type, conf->if_id,
+			BCM43xx_MACARG(conf->mac_addr));
+		break;
+	}
+	bcm43xx_unlock_mmio(bcm, flags);
+}
+
+static int bcm43xx_config_interface(struct net_device *net_dev,
+				    int if_id,
+				    struct ieee80211_if_conf *conf)
+{
+	struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+	unsigned long flags;
+	struct bcm43xx_interface *iface;
+
+	bcm43xx_lock_mmio(bcm, flags);
+	list_for_each_entry(iface, &bcm->interfaces.list, list) {
+		if (iface->if_id == if_id)
+			goto found;
+	}
+	bcm43xx_unlock_mmio(bcm, flags);
+
+	return -ENODEV;
+found:
+	iface->bssid = conf->bssid;
+	//TODO
+
+	return 0;
+}
+
+static void bcm43xx_set_multicast_list(struct net_device *net_dev,
+				       unsigned short netflags,
+				       int mc_count)
+{
+	struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
+	unsigned long flags;
+	u16 old_promisc;
 
-	bcm->interfaces--;
+	bcm43xx_lock_mmio(bcm, flags);
+	old_promisc = bcm->interfaces.opmode_promisc;
+	bcm->interfaces.opmode_promisc = !!(netflags & IFF_PROMISC);
+	if (bcm->interfaces.opmode_promisc != old_promisc) {
+		if (bcm->initialized)
+			bcm43xx_select_opmodes(bcm);
+	}
+	bcm43xx_unlock_mmio(bcm, flags);
 }
 
 /* Initialization of struct net_device, just after allocation. */
@@ -4240,6 +4344,7 @@
 	int err;
 
 	bcm->ieee = ieee;
+	INIT_LIST_HEAD(&bcm->interfaces.list);
 	bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
 	bcm->pci_dev = pci_dev;
 	bcm->net_dev = net_dev;
@@ -4294,6 +4399,8 @@
 	ieee->name = KBUILD_MODNAME;
 	ieee->host_gen_beacon = 1;
 	ieee->rx_includes_fcs = 1;
+	ieee->monitor_during_oper = 1;
+	ieee->channel_change_time = 20000;
 	ieee->tx = bcm43xx_net_hard_start_xmit;
 	ieee->open = bcm43xx_net_open;
 	ieee->stop = bcm43xx_net_stop;
@@ -4301,6 +4408,8 @@
 	ieee->remove_interface = bcm43xx_remove_interface;
 	ieee->reset = bcm43xx_net_reset;
 	ieee->config = bcm43xx_net_config;
+	ieee->config_interface = bcm43xx_config_interface;
+	ieee->set_multicast_list = bcm43xx_set_multicast_list;
 //TODO	ieee->set_key = bcm43xx_net_set_key;
 	ieee->get_stats = bcm43xx_net_get_stats;
 	ieee->queues = 1;
Index: wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c
===================================================================
--- wireless-dev.orig/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c	2006-04-28 16:13:40.000000000 +0200
+++ wireless-dev/drivers/net/wireless/d80211/bcm43xx/bcm43xx_phy.c	2006-05-01 18:56:17.000000000 +0200
@@ -94,7 +94,7 @@
 		bcm43xx_mac_suspend(bcm);
 		spin_lock(&phy->lock);
 	} else {
-		if (bcm->iw_mode != IW_MODE_MASTER)
+		if (bcm->interfaces.opmode_ap == 0)
 			bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
 	}
 	phy->is_locked = 1;
@@ -111,7 +111,7 @@
 			bcm43xx_mac_enable(bcm);
 		}
 	} else {
-		if (bcm->iw_mode != IW_MODE_MASTER)
+		if (bcm->interfaces.opmode_ap == 0)
 			bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
 	}
 	phy->is_locked = 0;


-- 
Greetings Michael.

[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply

* Re: IP1000 gigabit nic driver
From: David Gómez @ 2006-05-01 19:39 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: David Vrabel, Francois Romieu, Linux-kernel, netdev
In-Reply-To: <1146342905.11271.3.camel@localhost>

Hi Pekka,

On Apr 29 at 11:35:04, Pekka Enberg wrote:
> No, I haven't. I don't have the hardware, so I can't test the driver.
> Furthermore, there's plenty of stuff to fix before it's in any shape for
> submission. If someone wants to give this patch a spin, I would love to
> hear the results.

The latest version of the driver including David's improvements works
here. Nice work ;)

-- 
David Gómez                                      Jabber ID: davidge@jabber.org

^ permalink raw reply

* Re: VLAN subinterfaces, bridges and udev
From: Marco d'Itri @ 2006-05-01 19:43 UTC (permalink / raw)
  To: Ben Greear; +Cc: netdev
In-Reply-To: <445630FC.3030300@candelatech.com>

On May 01, Ben Greear <greearb@candelatech.com> wrote:

> >Can I rely on the presence of the $DEVPATH/driver symlink (e.g.
> >/sys/class/net/eth0/driver) to check if a network interface is a "real"
> >device insteaf of a VLAN or a bridge?
> To distinguish I use a VLAN specific IOCTL (GET_VLAN_REALDEV_NAME_CMD).
> If that IOCTL has no error, then it is a VLAN.
This is not useful for udev, it needs something available in sysfs.

-- 
ciao,
Marco

^ permalink raw reply

* [PATCH] bcm43xx: fix iwmode crash when down
From: Michael Buesch @ 2006-05-01 20:29 UTC (permalink / raw)
  To: John W. Linville, Andrew Morton; +Cc: Johannes Berg, bcm43xx-dev, netdev

[-- Attachment #1: Type: text/plain, Size: 895 bytes --]

This should go into 2.6.17, as it fixes a user exploitable crash.

--

This fixes a crash when
iwconfig ethX mode foo
is done before
ifconfig ethX up
or after
ifconfig ethX down

Index: linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
===================================================================
--- linux-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_wx.c	2006-04-22 17:47:03.000000000 +0200
+++ linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c	2006-05-01 22:10:18.000000000 +0200
@@ -182,8 +182,11 @@
 		mode = BCM43xx_INITIAL_IWMODE;
 
 	bcm43xx_lock_mmio(bcm, flags);
-	if (bcm->ieee->iw_mode != mode)
-		bcm43xx_set_iwmode(bcm, mode);
+	if (bcm->initialized) {
+		if (bcm->ieee->iw_mode != mode)
+			bcm43xx_set_iwmode(bcm, mode);
+	} else
+		bcm->ieee->iw_mode = mode;
 	bcm43xx_unlock_mmio(bcm, flags);
 
 	return 0;


-- 
Greetings Michael.

[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]

^ permalink raw reply

* [PATCH] bcm43xx: fix iwmode crash when down
From: Michael Buesch @ 2006-05-01 20:43 UTC (permalink / raw)
  To: John W. Linville, Andrew Morton; +Cc: Johannes Berg, bcm43xx-dev, netdev

(Second attempt, now unmangled and with signed-off-by line, uh...)
This should go into 2.6.17, as it fixes a user exploitable crash.

--

This fixes a crash when
iwconfig ethX mode foo
is done before
ifconfig ethX up
or after
ifconfig ethX down

Signed-off-by: Michael Buesch <mb@bu3sch.de>

Index: linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
===================================================================
--- linux-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_wx.c	2006-04-22 17:47:03.000000000 +0200
+++ linux-2.6/drivers/net/wireless/bcm43xx/bcm43xx_wx.c	2006-05-01 22:10:18.000000000 +0200
@@ -182,8 +182,11 @@
 		mode = BCM43xx_INITIAL_IWMODE;
 
 	bcm43xx_lock_mmio(bcm, flags);
-	if (bcm->ieee->iw_mode != mode)
-		bcm43xx_set_iwmode(bcm, mode);
+	if (bcm->initialized) {
+		if (bcm->ieee->iw_mode != mode)
+			bcm43xx_set_iwmode(bcm, mode);
+	} else
+		bcm->ieee->iw_mode = mode;
 	bcm43xx_unlock_mmio(bcm, flags);
 
 	return 0;


-- 
Greetings Michael.

^ permalink raw reply

* Re: IP1000 gigabit nic driver
From: Francois Romieu @ 2006-05-01 20:38 UTC (permalink / raw)
  To: David Vrabel; +Cc: Pekka Enberg, linux-kernel, netdev, david
In-Reply-To: <4455F1D8.5030102@cantab.net>

David Vrabel <dvrabel@cantab.net> :
[...]
> It was clocking the MII management interface (MDC) at 500 Hz so each PHY
> register access took some 130 ms, and many registers accesses were being
> done on initialization. According to the datasheet, the maximum
> frequency for MDC is 2.5 MHz.  Delays have been adjusted accordingly.

[...]
> Index: linux-source-2.6.16/drivers/net/ipg.h
> ===================================================================
> --- linux-source-2.6.16.orig/drivers/net/ipg.h	2006-05-01 12:08:58.343035854 +0100
> +++ linux-source-2.6.16/drivers/net/ipg.h	2006-05-01 12:09:37.282602113 +0100
> @@ -672,10 +672,10 @@
>  /* Number of IPG_AC_RESETWAIT timeperiods before declaring timeout. */
>  #define         IPG_AC_RESET_TIMEOUT         0x0A
>  
> -/* Minimum number of miliseconds used to toggle MDC clock during
> +/* Minimum number of nanoseconds used to toggle MDC clock during
>   * MII/GMII register access.
>   */
> -#define         IPG_PC_PHYCTRLWAIT           0x01
> +#define		IPG_PC_PHYCTRLWAIT_NS		200

I would have expected a cycle of 400 ns (p.72/77 of the datasheet)
for a 2.5 MHz clock. Why is it cut by a two factor ?

-- 
Ueimor

^ permalink raw reply

* Re: IP1000 gigabit nic driver
From: Lennert Buytenhek @ 2006-05-01 20:41 UTC (permalink / raw)
  To: Francois Romieu; +Cc: David Vrabel, Pekka Enberg, linux-kernel, netdev, david
In-Reply-To: <20060501203847.GA7419@electric-eye.fr.zoreil.com>

On Mon, May 01, 2006 at 10:38:47PM +0200, Francois Romieu wrote:

> > -/* Minimum number of miliseconds used to toggle MDC clock during
> > +/* Minimum number of nanoseconds used to toggle MDC clock during
> >   * MII/GMII register access.
> >   */
> > -#define         IPG_PC_PHYCTRLWAIT           0x01
> > +#define		IPG_PC_PHYCTRLWAIT_NS		200
> 
> I would have expected a cycle of 400 ns (p.72/77 of the datasheet)
> for a 2.5 MHz clock. Why is it cut by a two factor ?

200 ns high + 200 ns low = 400 ns clock period?

^ permalink raw reply

* [PATCH] softmac: deauthentication implies deassociation
From: Daniel Drake @ 2006-05-01 21:00 UTC (permalink / raw)
  To: linville; +Cc: netdev, johannes, softmac-dev

The 802.11 specs state that deauthenticating also implies disassociating. This
patch implements that, which improve the behaviour of SIOCSIWMLME.

Signed-off-by: Daniel Drake <dsd@gentoo.org>
Acked-by: Johannes Berg <johannes@sipsolutions.net>

Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_assoc.c
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -82,28 +82,37 @@ ieee80211softmac_assoc_timeout(void *d)
 	ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL);
 }
 
-/* Sends out a disassociation request to the desired AP */
 void
-ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason)
+ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
 {
 	unsigned long flags;
+
+	spin_lock_irqsave(&mac->lock, flags);
+	if (mac->associnfo.associating)
+		cancel_delayed_work(&mac->associnfo.timeout);
+
+	netif_carrier_off(mac->dev);
+
+	mac->associated = 0;
+	mac->associnfo.bssvalid = 0;
+	mac->associnfo.associating = 0;
+	ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
+	spin_unlock_irqrestore(&mac->lock, flags);
+}
+
+/* Sends out a disassociation request to the desired AP */
+void
+ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason)
+{
 	struct ieee80211softmac_network *found;
 
 	if (mac->associnfo.bssvalid && mac->associated) {
 		found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
 		if (found)
 			ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
-	} else if (mac->associnfo.associating) {
-		cancel_delayed_work(&mac->associnfo.timeout);
 	}
 
-	/* Change our state */
-	spin_lock_irqsave(&mac->lock, flags);
-	/* Do NOT clear bssvalid as that will break ieee80211softmac_assoc_work! */
-	mac->associated = 0;
-	mac->associnfo.associating = 0;
-	ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
-	spin_unlock_irqrestore(&mac->lock, flags);
+	ieee80211softmac_disassoc(mac);
 }
 
 static inline int
@@ -176,14 +185,18 @@ ieee80211softmac_assoc_work(void *d)
 	struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
 	struct ieee80211softmac_network *found = NULL;
 	struct ieee80211_network *net = NULL, *best = NULL;
+	int bssvalid;
 	unsigned long flags;
-	
+
+	/* ieee80211_disassoc might clear this */
+	bssvalid = mac->associnfo.bssvalid;
+
 	/* meh */
 	if (mac->associated)
-		ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
+		ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
 
 	/* try to find the requested network in our list, if we found one already */
-	if (mac->associnfo.bssvalid || mac->associnfo.bssfixed)
+	if (bssvalid || mac->associnfo.bssfixed)
 		found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);	
 	
 	/* Search the ieee80211 networks for this network if we didn't find it by bssid,
@@ -380,7 +393,6 @@ ieee80211softmac_handle_disassoc(struct 
 				 struct ieee80211_disassoc *disassoc)
 {
 	struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-	unsigned long flags;
 
 	if (unlikely(!mac->running))
 		return -ENODEV;
@@ -392,14 +404,11 @@ ieee80211softmac_handle_disassoc(struct 
 		return 0;
 
 	dprintk(KERN_INFO PFX "got disassoc frame\n");
-	netif_carrier_off(dev);
-	spin_lock_irqsave(&mac->lock, flags);
-	mac->associnfo.bssvalid = 0;
-	mac->associated = 0;
-	ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
+	ieee80211softmac_disassoc(mac);
+
+	/* try to reassociate */
 	schedule_work(&mac->associnfo.work);
-	spin_unlock_irqrestore(&mac->lock, flags);
-	
+
 	return 0;
 }
 
Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_auth.c
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_auth.c
@@ -279,6 +279,9 @@ ieee80211softmac_deauth_from_net(struct 
 	struct list_head *list_ptr;
 	unsigned long flags;
 
+	/* deauthentication implies disassociation */
+	ieee80211softmac_disassoc(mac);
+
 	/* Lock and reset status flags */
 	spin_lock_irqsave(&mac->lock, flags);
 	net->authenticating = 0;
Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_wx.c
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -456,7 +456,7 @@ ieee80211softmac_wx_set_mlme(struct net_
 		}
 		return ieee80211softmac_deauth_req(mac, net, reason);
 	case IW_MLME_DISASSOC:
-		ieee80211softmac_disassoc(mac, reason);
+		ieee80211softmac_send_disassoc_req(mac, reason);
 		return 0;
 	default:
 		return -EOPNOTSUPP;

^ permalink raw reply

* [PATCH] bcm43xx-d80211: remove sta_up script
From: Michael Buesch @ 2006-05-01 21:10 UTC (permalink / raw)
  To: John W. Linville; +Cc: netdev, bcm43xx-dev

Hi John,

This is not really a patch, because it is easier for you
to do it manually. :)

Please remove the file
scripts/bcm43xx-d80211-sta_up.sh
from the wireless-dev tree, as the d80211 user interface has
been fixed and it is not really needed anymore.

While you are at it, please also remove
Documentation/networking/bcm43xx-d80211-HOWTO.txt
Documentation/networking/bcm43xx-d80211.txt
as they are completely outdated and useless these days.

Thanks.

PS: If someone wants to update
Documentation/networking/bcm43xx.txt
please feel free to submit a patch.

-- 
Greetings Michael.

^ permalink raw reply

* [RFC] vlan: add sysfs support
From: Stephen Hemminger @ 2006-05-01 21:08 UTC (permalink / raw)
  To: Ben Greear, David S. Miller; +Cc: netdev, vlan

Add basic sysfs support for vlan device. It creates an entry in the
vlan pseudo-device to display tag.  
	/sys/class/net/eth0.5/vlan_id

It would be nice at some future to have something like:
	/sys/class/net/eth0/tags/5  -> ../../eth0.5
as well.

There is a race with udev though. The sysfs entry can't be created
until after the the class_device is registered but the registration
doesn't happen until  rtnl_unlock after register_netdevice. The class_device
registration causes the hotplug event, so the hotplug user program
might get there before vlan_id is created.


--- vlan.orig/net/8021q/Makefile	2006-05-01 12:50:58.000000000 -0700
+++ vlan/net/8021q/Makefile	2006-05-01 14:04:56.000000000 -0700
@@ -6,7 +6,5 @@
 
 8021q-objs := vlan.o vlan_dev.o
 
-ifeq ($(CONFIG_PROC_FS),y)
-8021q-objs += vlanproc.o
-endif
-
+8021q-$(CONFIG_PROC_FS) += vlanproc.o
+8021q-$(CONFIG_SYSFS) += vlan_sysfs.o
--- vlan.orig/net/8021q/vlan.c	2006-05-01 12:50:58.000000000 -0700
+++ vlan/net/8021q/vlan.c	2006-05-01 13:48:35.000000000 -0700
@@ -232,6 +232,8 @@
 			/* Remove proc entry */
 			vlan_proc_rem_dev(dev);
 
+			vlan_sysfs_remove(dev);
+
 			/* Take it out of our own structures, but be sure to
 			 * interlock with HW accelerating devices or SW vlan
 			 * input packet processing.
@@ -557,6 +559,9 @@
 
 	rtnl_unlock();
 
+	if (vlan_sysfs_add(new_dev))
+		printk(KERN_WARNING "VLAN: failed to create sysfs entry for %s\n",
+		       new_dev->name);
 
 #ifdef VLAN_DEBUG
 	printk(VLAN_DBG "Allocated new device successfully, returning.\n");
--- vlan.orig/net/8021q/vlan.h	2006-05-01 12:50:58.000000000 -0700
+++ vlan/net/8021q/vlan.h	2006-05-01 13:17:16.000000000 -0700
@@ -69,4 +69,13 @@
 int vlan_dev_get_vid(const char* dev_name, unsigned short* result);
 void vlan_dev_set_multicast_list(struct net_device *vlan_dev);
 
+#ifdef CONFIG_SYSFS
+int vlan_sysfs_add(struct net_device *dev);
+void vlan_sysfs_remove(struct net_device *dev);
+#else
+#define vlan_sysfs_add(dev)	(0)
+#define vlan_sysfs_remove(dev)  do { } while (0)
+#endif
+
+
 #endif /* !(__BEN_VLAN_802_1Q_INC__) */
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ vlan/net/8021q/vlan_sysfs.c	2006-05-01 14:04:49.000000000 -0700
@@ -0,0 +1,38 @@
+/*
+ * VLAN sysfs interface.
+ *
+ * Basic access to vlan information via sysfs.
+ * Authors:
+ * Stephen Hemminger		<shemminger@osdl.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include "vlan.h"
+
+static ssize_t show_vlan_id(struct class_device *cd, char *buf)
+{
+	struct net_device *vlandev = container_of(cd, struct net_device, class_dev);
+
+	return sprintf(buf, "%d\n", VLAN_DEV_INFO(vlandev)->vlan_id);
+}
+
+static CLASS_DEVICE_ATTR(vlan_id, S_IRUGO, show_vlan_id, NULL);
+
+int vlan_sysfs_add(struct net_device *dev)
+{
+	return class_device_create_file(&dev->class_dev,
+					&class_device_attr_vlan_id);
+}
+
+void vlan_sysfs_remove(struct net_device *dev)
+{
+	return class_device_remove_file(&dev->class_dev,
+					&class_device_attr_vlan_id);
+
+}

^ permalink raw reply

* [PATCH resend] softmac: deauthentication implies deassociation
From: Daniel Drake @ 2006-05-01 21:23 UTC (permalink / raw)
  To: linville; +Cc: netdev, johannes, softmac-dev

The 802.11 specs state that deauthenticating also implies disassociating. This
patch implements that, which improve the behaviour of SIOCSIWMLME.

Signed-off-by: Daniel Drake <dsd@gentoo.org>
Acked-by: Johannes Berg <johannes@sipsolutions.net>

--

Sorry, missed a file (ieee80211softmac_priv.h) in the last attempt.

Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_assoc.c
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -82,28 +82,37 @@ ieee80211softmac_assoc_timeout(void *d)
 	ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL);
 }
 
-/* Sends out a disassociation request to the desired AP */
 void
-ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason)
+ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
 {
 	unsigned long flags;
+
+	spin_lock_irqsave(&mac->lock, flags);
+	if (mac->associnfo.associating)
+		cancel_delayed_work(&mac->associnfo.timeout);
+
+	netif_carrier_off(mac->dev);
+
+	mac->associated = 0;
+	mac->associnfo.bssvalid = 0;
+	mac->associnfo.associating = 0;
+	ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
+	spin_unlock_irqrestore(&mac->lock, flags);
+}
+
+/* Sends out a disassociation request to the desired AP */
+void
+ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason)
+{
 	struct ieee80211softmac_network *found;
 
 	if (mac->associnfo.bssvalid && mac->associated) {
 		found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
 		if (found)
 			ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
-	} else if (mac->associnfo.associating) {
-		cancel_delayed_work(&mac->associnfo.timeout);
 	}
 
-	/* Change our state */
-	spin_lock_irqsave(&mac->lock, flags);
-	/* Do NOT clear bssvalid as that will break ieee80211softmac_assoc_work! */
-	mac->associated = 0;
-	mac->associnfo.associating = 0;
-	ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
-	spin_unlock_irqrestore(&mac->lock, flags);
+	ieee80211softmac_disassoc(mac);
 }
 
 static inline int
@@ -176,14 +185,18 @@ ieee80211softmac_assoc_work(void *d)
 	struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
 	struct ieee80211softmac_network *found = NULL;
 	struct ieee80211_network *net = NULL, *best = NULL;
+	int bssvalid;
 	unsigned long flags;
-	
+
+	/* ieee80211_disassoc might clear this */
+	bssvalid = mac->associnfo.bssvalid;
+
 	/* meh */
 	if (mac->associated)
-		ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
+		ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
 
 	/* try to find the requested network in our list, if we found one already */
-	if (mac->associnfo.bssvalid || mac->associnfo.bssfixed)
+	if (bssvalid || mac->associnfo.bssfixed)
 		found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);	
 	
 	/* Search the ieee80211 networks for this network if we didn't find it by bssid,
@@ -380,7 +393,6 @@ ieee80211softmac_handle_disassoc(struct 
 				 struct ieee80211_disassoc *disassoc)
 {
 	struct ieee80211softmac_device *mac = ieee80211_priv(dev);
-	unsigned long flags;
 
 	if (unlikely(!mac->running))
 		return -ENODEV;
@@ -392,14 +404,11 @@ ieee80211softmac_handle_disassoc(struct 
 		return 0;
 
 	dprintk(KERN_INFO PFX "got disassoc frame\n");
-	netif_carrier_off(dev);
-	spin_lock_irqsave(&mac->lock, flags);
-	mac->associnfo.bssvalid = 0;
-	mac->associated = 0;
-	ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
+	ieee80211softmac_disassoc(mac);
+
+	/* try to reassociate */
 	schedule_work(&mac->associnfo.work);
-	spin_unlock_irqrestore(&mac->lock, flags);
-	
+
 	return 0;
 }
 
Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_auth.c
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_auth.c
@@ -279,6 +279,9 @@ ieee80211softmac_deauth_from_net(struct 
 	struct list_head *list_ptr;
 	unsigned long flags;
 
+	/* deauthentication implies disassociation */
+	ieee80211softmac_disassoc(mac);
+
 	/* Lock and reset status flags */
 	spin_lock_irqsave(&mac->lock, flags);
 	net->authenticating = 0;
Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_wx.c
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -456,7 +456,7 @@ ieee80211softmac_wx_set_mlme(struct net_
 		}
 		return ieee80211softmac_deauth_req(mac, net, reason);
 	case IW_MLME_DISASSOC:
-		ieee80211softmac_disassoc(mac, reason);
+		ieee80211softmac_send_disassoc_req(mac, reason);
 		return 0;
 	default:
 		return -EOPNOTSUPP;
Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_priv.h
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_priv.h
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_priv.h
@@ -150,7 +150,8 @@ int ieee80211softmac_handle_disassoc(str
 int ieee80211softmac_handle_reassoc_req(struct net_device * dev,
 				        struct ieee80211_reassoc_request * reassoc);
 void ieee80211softmac_assoc_timeout(void *d);
-void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason);
+void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason);
+void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac);
 
 /* some helper functions */
 static inline int ieee80211softmac_scan_handlers_check_self(struct ieee80211softmac_device *sm)

^ permalink raw reply

* Re: [RFC] vlan: add sysfs support
From: Sam Ravnborg @ 2006-05-01 21:31 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Ben Greear, David S. Miller, netdev, vlan
In-Reply-To: <20060501140834.43a006fd@localhost.localdomain>

On Mon, May 01, 2006 at 02:08:34PM -0700, Stephen Hemminger wrote:
> Add basic sysfs support for vlan device. It creates an entry in the
> vlan pseudo-device to display tag.  
> 	/sys/class/net/eth0.5/vlan_id
> 
> It would be nice at some future to have something like:
> 	/sys/class/net/eth0/tags/5  -> ../../eth0.5
> as well.
> 
> There is a race with udev though. The sysfs entry can't be created
> until after the the class_device is registered but the registration
> doesn't happen until  rtnl_unlock after register_netdevice. The class_device
> registration causes the hotplug event, so the hotplug user program
> might get there before vlan_id is created.
> 
> 
> --- vlan.orig/net/8021q/Makefile	2006-05-01 12:50:58.000000000 -0700
> +++ vlan/net/8021q/Makefile	2006-05-01 14:04:56.000000000 -0700
> @@ -6,7 +6,5 @@
>  
>  8021q-objs := vlan.o vlan_dev.o
Please make this
>  8021q-y := vlan.o vlan_dev.o

To avoid confusion.


>  
> -ifeq ($(CONFIG_PROC_FS),y)
> -8021q-objs += vlanproc.o
> -endif
> -
> +8021q-$(CONFIG_PROC_FS) += vlanproc.o
> +8021q-$(CONFIG_SYSFS) += vlan_sysfs.o

	Sam

^ permalink raw reply

* Re: [PATCH 1/3] Rough VJ Channel Implementation - vj_core.patch
From: David S. Miller @ 2006-05-01 21:32 UTC (permalink / raw)
  To: johnpol; +Cc: shemminger, caitlinb, kelly, rusty, netdev
In-Reply-To: <20060429124451.GA19810@2ka.mipt.ru>

From: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Date: Sat, 29 Apr 2006 16:44:51 +0400

> Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>

I understand how in some ways this is work in progress,
but direct calls into ext3 from the kevent code?  I'd
like stuff like that cleaned up before reviewing :-)

^ permalink raw reply

* [PATCH resend] softmac: suggest per-frame-type TX rate
From: Daniel Drake @ 2006-05-01 21:45 UTC (permalink / raw)
  To: linville; +Cc: netdev, johannes, softmac-dev

This patch is the first step towards rate control inside softmac.

The txrates substructure has been extended to provide different fields for
different types of packets (management/data, unicast/multicast). These fields
are updated on association to values compatible with the access point we are
associating to.

Drivers can then use the new ieee80211softmac_suggest_txrate() function call
when deciding which rate to transmit each frame at. This is immensely useful
for ZD1211, and bcm can use it too.

The user can still specify a rate through iwconfig, which is matched for all
transmissions (assuming the rate they have specified is in the rate set
required by the AP).

At a later date, we can incorporate automatic rate management into the 
ieee80211softmac_recalc_txrates() function.

This patch also removes the mcast_fallback field. Sam Leffler pointed out that
this field is meaningless, because no driver will ever be retransmitting mcast
frames (they are not acked).

Signed-off-by: Daniel Drake <dsd@gentoo.org>
Acked-by: Johannes Berg <johannes@sipsolutions.net>

--

Rediffed against my other recent patches.
Also, even though this patch modifies the softmac API
(ieee80211softmac_txrates), this should not cause any breakage because nobody
uses that yet.

Index: linux-2.6.17-rc3/include/net/ieee80211softmac.h
===================================================================
--- linux-2.6.17-rc3.orig/include/net/ieee80211softmac.h
+++ linux-2.6.17-rc3/include/net/ieee80211softmac.h
@@ -86,6 +86,9 @@ struct ieee80211softmac_assoc_info {
 	
 	/* BSSID we're trying to associate to */
 	char bssid[ETH_ALEN];
+
+	/* Rates supported by the network */
+	struct ieee80211softmac_ratesinfo supported_rates;
 	
 	/* some flags.
 	 * static_essid is valid if the essid is constant,
@@ -132,23 +135,26 @@ enum {
 struct ieee80211softmac_txrates {
 	/* The Bit-Rate to be used for multicast frames. */
 	u8 mcast_rate;
-	/* The Bit-Rate to be used for multicast fallback
-	 * (If the device supports fallback and hardware-retry)
-	 */
-	u8 mcast_fallback;
+
+	/* The Bit-Rate to be used for multicast management frames. */
+	u8 mgt_mcast_rate;
+
 	/* The Bit-Rate to be used for any other (normal) data packet. */
 	u8 default_rate;
 	/* The Bit-Rate to be used for default fallback
 	 * (If the device supports fallback and hardware-retry)
 	 */
 	u8 default_fallback;
+
+	/* This is the rate that the user asked for */
+	u8 user_rate;
 };
 
 /* Bits for txrates_change callback. */
 #define IEEE80211SOFTMAC_TXRATECHG_DEFAULT		(1 << 0) /* default_rate */
 #define IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK	(1 << 1) /* default_fallback */
 #define IEEE80211SOFTMAC_TXRATECHG_MCAST		(1 << 2) /* mcast_rate */
-#define IEEE80211SOFTMAC_TXRATECHG_MCAST_FBACK		(1 << 3) /* mcast_fallback */
+#define IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST		(1 << 3) /* mgt_mcast_rate */
 
 struct ieee80211softmac_device {
 	/* 802.11 structure for data stuff */
@@ -250,6 +256,28 @@ extern void ieee80211softmac_fragment_lo
  * Note that the rates need to be sorted. */
 extern void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates);
 
+/* Helper function which advises you the rate at which a frame should be
+ * transmitted at. */
+static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device *mac,
+						 int is_multicast,
+						 int is_mgt)
+{
+	struct ieee80211softmac_txrates *txrates = &mac->txrates;
+
+	if (!mac->associated)
+		return txrates->mgt_mcast_rate;
+
+	/* We are associated, sending unicast frame */
+	if (!is_multicast)
+		return txrates->default_rate;
+
+	/* We are associated, sending multicast frame */
+	if (is_mgt)
+		return txrates->mgt_mcast_rate;
+	else
+		return txrates->mcast_rate;
+}
+
 /* Start the SoftMAC. Call this after you initialized the device
  * and it is ready to run.
  */
Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_assoc.c
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -96,6 +96,7 @@ ieee80211softmac_disassoc(struct ieee802
 	mac->associated = 0;
 	mac->associnfo.bssvalid = 0;
 	mac->associnfo.associating = 0;
+	ieee80211softmac_init_txrates(mac);
 	ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
 	spin_unlock_irqrestore(&mac->lock, flags);
 }
@@ -118,24 +119,15 @@ ieee80211softmac_send_disassoc_req(struc
 static inline int
 we_support_all_basic_rates(struct ieee80211softmac_device *mac, u8 *from, u8 from_len)
 {
-	int idx, search, found;
-	u8 rate, search_rate;
+	int idx;
+	u8 rate;
 
 	for (idx = 0; idx < (from_len); idx++) {
 		rate = (from)[idx];
 		if (!(rate & IEEE80211_BASIC_RATE_MASK))
 			continue;
-		found = 0;
 		rate &= ~IEEE80211_BASIC_RATE_MASK;
-		for (search = 0; search < mac->ratesinfo.count; search++) {
-			search_rate = mac->ratesinfo.rates[search];
-			search_rate &= ~IEEE80211_BASIC_RATE_MASK;
-			if (rate == search_rate) {
-				found = 1;
-				break;
-			}
-		}
-		if (!found)
+		if (!ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))
 			return 0;
 	}
 	return 1;
@@ -310,6 +302,9 @@ ieee80211softmac_associated(struct ieee8
 	struct ieee80211softmac_network *net)
 {
 	mac->associnfo.associating = 0;
+	mac->associnfo.supported_rates = net->supported_rates;
+	ieee80211softmac_recalc_txrates(mac);
+
 	mac->associated = 1;
 	if (mac->set_bssid_filter)
 		mac->set_bssid_filter(mac->dev, net->bssid);
Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_module.c
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_module.c
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -26,6 +26,7 @@
 
 #include "ieee80211softmac_priv.h"
 #include <linux/sort.h>
+#include <linux/etherdevice.h>
 
 struct net_device *alloc_ieee80211softmac(int sizeof_priv)
 {
@@ -61,14 +62,6 @@ struct net_device *alloc_ieee80211softma
 	softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation;
 	softmac->stop_scan = ieee80211softmac_stop_scan_implementation;
 
-	//TODO: The mcast rate has to be assigned dynamically somewhere (in scanning, association. Not sure...)
-	//      It has to be set to the highest rate all stations in the current network can handle.
-	softmac->txrates.mcast_rate = IEEE80211_CCK_RATE_1MB;
-	softmac->txrates.mcast_fallback = IEEE80211_CCK_RATE_1MB;
-	/* This is reassigned in ieee80211softmac_start to sane values. */
-	softmac->txrates.default_rate = IEEE80211_CCK_RATE_1MB;
-	softmac->txrates.default_fallback = IEEE80211_CCK_RATE_1MB;
-
 	/* to start with, we can't send anything ... */
 	netif_carrier_off(dev);
 	
@@ -170,15 +163,82 @@ static void ieee80211softmac_start_check
 	}
 }
 
-void ieee80211softmac_start(struct net_device *dev)
+int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate)
+{
+	int search;
+	u8 search_rate;
+
+	for (search = 0; search < ri->count; search++) {
+		search_rate = ri->rates[search];
+		search_rate &= ~IEEE80211_BASIC_RATE_MASK;
+		if (rate == search_rate)
+			return 1;
+	}
+
+	return 0;
+}
+
+/* Finds the highest rate which is:
+ *  1. Present in ri (optionally a basic rate)
+ *  2. Supported by the device
+ *  3. Less than or equal to the user-defined rate
+ */
+static u8 highest_supported_rate(struct ieee80211softmac_device *mac,
+	struct ieee80211softmac_ratesinfo *ri, int basic_only)
+{
+	u8 user_rate = mac->txrates.user_rate;
+	int i;
+
+	if (ri->count == 0) {
+		dprintk(KERN_ERR PFX "empty ratesinfo?\n");
+		return IEEE80211_CCK_RATE_1MB;
+	}
+
+	for (i = ri->count - 1; i >= 0; i--) {
+		u8 rate = ri->rates[i];
+		if (basic_only && !(rate & IEEE80211_BASIC_RATE_MASK))
+			continue;
+		rate &= ~IEEE80211_BASIC_RATE_MASK;
+		if (rate > user_rate)
+			continue;
+		if (ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))
+			return rate;
+	}
+
+	/* If we haven't found a suitable rate by now, just trust the user */
+	return user_rate;
+}
+
+void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac)
+{
+	struct ieee80211softmac_txrates *txrates = &mac->txrates;
+	struct ieee80211softmac_txrates oldrates;
+	u32 change = 0;
+
+	if (mac->txrates_change)
+		oldrates = mac->txrates;
+
+	change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
+	txrates->default_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 0);
+
+	change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
+	txrates->default_fallback = lower_rate(mac, txrates->default_rate);
+
+	change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
+	txrates->mcast_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 1);
+
+	if (mac->txrates_change)
+		mac->txrates_change(mac->dev, change, &oldrates);
+
+}
+
+void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
 {
-	struct ieee80211softmac_device *mac = ieee80211_priv(dev);
 	struct ieee80211_device *ieee = mac->ieee;
 	u32 change = 0;
+	struct ieee80211softmac_txrates *txrates = &mac->txrates;
 	struct ieee80211softmac_txrates oldrates;
 
-	ieee80211softmac_start_check_rates(mac);
-
 	/* TODO: We need some kind of state machine to lower the default rates
 	 *       if we loose too many packets.
 	 */
@@ -193,22 +253,37 @@ void ieee80211softmac_start(struct net_d
 	   more reliable. Note similar logic in
 	   ieee80211softmac_wx_set_rate() */	 
 	if (ieee->modulation & IEEE80211_CCK_MODULATION) {
-		mac->txrates.default_rate = IEEE80211_CCK_RATE_11MB;
-		change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
-		mac->txrates.default_fallback = IEEE80211_CCK_RATE_5MB;
-		change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
+		txrates->user_rate = IEEE80211_CCK_RATE_11MB;
 	} else if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
-		mac->txrates.default_rate = IEEE80211_OFDM_RATE_54MB;
-		change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
-		mac->txrates.default_fallback = IEEE80211_OFDM_RATE_24MB;
-		change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
+		txrates->user_rate = IEEE80211_OFDM_RATE_54MB;
 	} else
 		assert(0);
+
+	txrates->default_rate = IEEE80211_CCK_RATE_1MB;
+	change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
+
+	txrates->default_fallback = IEEE80211_CCK_RATE_1MB;
+	change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
+
+	txrates->mcast_rate = IEEE80211_CCK_RATE_1MB;
+	change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
+
+	txrates->mgt_mcast_rate = IEEE80211_CCK_RATE_1MB;
+	change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST;
+
 	if (mac->txrates_change)
-		mac->txrates_change(dev, change, &oldrates);
+		mac->txrates_change(mac->dev, change, &oldrates);
 
 	mac->running = 1;
 }
+
+void ieee80211softmac_start(struct net_device *dev)
+{
+	struct ieee80211softmac_device *mac = ieee80211_priv(dev);
+
+	ieee80211softmac_start_check_rates(mac);
+	ieee80211softmac_init_txrates(mac);
+}
 EXPORT_SYMBOL_GPL(ieee80211softmac_start);
 
 void ieee80211softmac_stop(struct net_device *dev)
Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_wx.c
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -211,8 +211,8 @@ ieee80211softmac_wx_set_rate(struct net_
 	if (is_ofdm && !(ieee->modulation & IEEE80211_OFDM_MODULATION))
 		goto out_unlock;
 
-	mac->txrates.default_rate = rate;
-	mac->txrates.default_fallback = lower_rate(mac, rate);
+	mac->txrates.user_rate = rate;
+	ieee80211softmac_recalc_txrates(mac);
 	err = 0;
 
 out_unlock:	
Index: linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_priv.h
===================================================================
--- linux-2.6.17-rc3.orig/net/ieee80211/softmac/ieee80211softmac_priv.h
+++ linux-2.6.17-rc3/net/ieee80211/softmac/ieee80211softmac_priv.h
@@ -116,7 +116,10 @@ ieee80211softmac_get_network_by_essid(st
 	struct ieee80211softmac_essid *essid);
 
 /* Rates related */
+int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate);
 u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta);
+void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac);
+void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac);
 static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) {
 	return ieee80211softmac_lower_rate_delta(mac, rate, 1);
 }

^ 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