Netdev List
 help / color / mirror / Atom feed
* [PATCH] SoftMAC: Prevent multiple authentication attempts on the same network
From: Joseph Jezak @ 2006-06-11 16:00 UTC (permalink / raw)
  To: NetDev; +Cc: bcm43xx-dev

This patch addresses the "No queue exists" messages commonly seen during
authentication and associating.  These appear due to scheduling multiple
authentication attempts on the same network.  To prevent this, I added a
flag to stop multiple authentication attempts by the association layer.
I also added a check to the wx handler to see if we're connecting to a
different network than the one already in progress.  This scenario was
causing multiple requests on the same network because the network BSSID
was not being updated despite the fact that the ESSID changed.

Signed-off-by: Joseph Jezak <josejx@gentoo.org>

---

diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h
index 052ed59..82a299a 100644
--- a/include/net/ieee80211softmac.h
+++ b/include/net/ieee80211softmac.h
@@ -101,6 +101,7 @@ struct ieee80211softmac_assoc_info {
 	 */
 	u8 static_essid:1,
 	   associating:1,
+	   assoc_wait:1,
 	   bssvalid:1,
 	   bssfixed:1;
 
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index 57ea9f6..aa65a7e 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -47,9 +47,7 @@ ieee80211softmac_assoc(struct ieee80211s
 	
 	dprintk(KERN_INFO PFX "sent association request!\n");
 
-	/* Change the state to associating */
 	spin_lock_irqsave(&mac->lock, flags);
-	mac->associnfo.associating = 1;
 	mac->associated = 0; /* just to make sure */
 
 	/* Set a timer for timeout */
@@ -181,6 +179,10 @@ ieee80211softmac_assoc_work(void *d)
 	/* meh */
 	if (mac->associated)
 		ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
+	
+	spin_lock_irqsave(&mac->lock, flags);
+	mac->associnfo.associating = 1;
+	spin_unlock_irqrestore(&mac->lock, flags);
 
 	/* try to find the requested network in our list, if we found one already */
 	if (mac->associnfo.bssvalid || mac->associnfo.bssfixed)
@@ -274,19 +276,32 @@ ieee80211softmac_assoc_work(void *d)
 	memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1);
 	
 	/* we found a network! authenticate (if necessary) and associate to it. */
-	if (!found->authenticated) {
+	if (found->authenticating) {
+		dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n");
+		if(!mac->associnfo.assoc_wait) {
+			mac->associnfo.assoc_wait = 1;
+			ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify, NULL, GFP_KERNEL);
+		}
+		return;
+	}
+	if (!found->authenticated && !found->authenticating) {
 		/* This relies on the fact that _auth_req only queues the work,
 		 * otherwise adding the notification would be racy. */
 		if (!ieee80211softmac_auth_req(mac, found)) {
-			dprintk(KERN_INFO PFX "cannot associate without being authenticated, requested authentication\n");
-			ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify, NULL, GFP_KERNEL);
+			if(!mac->associnfo.assoc_wait) {
+				dprintk(KERN_INFO PFX "Cannot associate without being authenticated, requested authentication\n");
+				mac->associnfo.assoc_wait = 1;
+				ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify, NULL, GFP_KERNEL);
+			}
 		} else {
 			printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
+			mac->associnfo.assoc_wait = 0;
 			ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
 		}
 		return;
 	}
 	/* finally! now we can start associating */
+	mac->associnfo.assoc_wait = 0;
 	ieee80211softmac_assoc(mac, found);
 }
 
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c
index 06e3326..23125ae 100644
--- a/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ b/net/ieee80211/softmac/ieee80211softmac_auth.c
@@ -36,8 +36,9 @@ ieee80211softmac_auth_req(struct ieee802
 	struct ieee80211softmac_auth_queue_item *auth;
 	unsigned long flags;
 	
-	if (net->authenticating)
+	if (net->authenticating || net->authenticated) 
 		return 0;
+	net->authenticating = 1;
 
 	/* Add the network if it's not already added */
 	ieee80211softmac_add_network(mac, net);
@@ -92,7 +93,6 @@ ieee80211softmac_auth_queue(void *data)
 			return;
 		}
 		net->authenticated = 0;
-		net->authenticating = 1;
 		/* add a timeout call so we eventually give up waiting for an auth reply */
 		schedule_delayed_work(&auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT);
 		auth->retry--;
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index 27edb2b..abd5f9c 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -70,12 +70,44 @@ ieee80211softmac_wx_set_essid(struct net
 			      char *extra)
 {
 	struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
+	struct ieee80211softmac_network *n;
+	struct ieee80211softmac_auth_queue_item *authptr;
 	int length = 0;
 	unsigned long flags;
-	
+
+	/* Check if we're already associating to this or another network
+	 * If it's another network, cancel and start over with our new network
+	 * If it's our network, ignore the change, we're already doing it!
+	 */
+	if((sm->associnfo.associating || sm->associated) && 
+	   (data->essid.flags && data->essid.length && extra)) {
+		/* Get the associating network */
+		n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
+		if(n && n->essid.len == (data->essid.length - 1) && 
+		   !memcmp(n->essid.data, extra, n->essid.len)) {
+			dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
+				MAC_ARG(sm->associnfo.bssid));
+			return 0;
+		} else {
+			dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
+			spin_lock_irqsave(&sm->lock,flags);
+			/* Cancel assoc work */
+			cancel_delayed_work(&sm->associnfo.work);
+			/* We don't have to do this, but it's a little cleaner */
+			list_for_each_entry(authptr, &sm->auth_queue, list)
+				cancel_delayed_work(&authptr->work);
+			sm->associnfo.bssvalid = 0;
+			sm->associnfo.bssfixed = 0;
+			spin_unlock_irqrestore(&sm->lock,flags);
+			flush_scheduled_work();
+		}
+	}
+
+
 	spin_lock_irqsave(&sm->lock, flags);
-	
+
 	sm->associnfo.static_essid = 0;
+	sm->associnfo.assoc_wait = 0;
 
 	if (data->essid.flags && data->essid.length && extra /*required?*/) {
 		length = min(data->essid.length - 1, IW_ESSID_MAX_SIZE);


^ permalink raw reply related

* [PATCH] SoftMAC: Add network to ieee80211softmac_call_events when associate times out
From: Joseph Jezak @ 2006-06-11 16:01 UTC (permalink / raw)
  To: NetDev, bcm43xx-dev

The ieee80211softmac_call_events function, when called with event type
IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT should pass the network as the
third parameter.  This patch does that.

Signed-off-by: Joseph Jezak <josejx@gentoo.org>

---

diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index aa65a7e..f9f7c8d 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -61,6 +61,7 @@ void
 ieee80211softmac_assoc_timeout(void *d)
 {
 	struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
+	struct ieee80211softmac_network *n;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mac->lock, flags);
@@ -73,11 +74,12 @@ ieee80211softmac_assoc_timeout(void *d)
 	mac->associnfo.associating = 0;
 	mac->associnfo.bssvalid = 0;
 	mac->associated = 0;
+
+	n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid);	
 	spin_unlock_irqrestore(&mac->lock, flags);
 
 	dprintk(KERN_INFO PFX "assoc request timed out!\n");
-	/* FIXME: we need to know the network here. that requires a bit of restructuring */
-	ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL);
+	ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n);
 }
 
 /* Sends out a disassociation request to the desired AP */



^ permalink raw reply related

* Re: [patch 7/8] lock validator: fix ns83820.c irq-flags bug
From: Jeff Garzik @ 2006-06-11 16:09 UTC (permalink / raw)
  To: Arjan van de Ven; +Cc: akpm, netdev, mingo, bcrl
In-Reply-To: <448C2FFE.3010002@linux.intel.com>

Arjan van de Ven wrote:
> Jeff Garzik wrote:
>> The driver's locking is definitely wrong, but I don't think this is 
>> the fix, 
> 
> it's an obvious correct fix in the correctness sense though...
> 
>>
>> Jesus, the locking here is awful.  No wonder there are bugs.
> 
> 
> ... which given that fact, is for 2.6.17 probably the right thing, pending
> a nicer fix for 2.6.18

I disagree, the patch is wrong too.

For normal PCI hardware, the in-ISR paths should all use spin_lock(), 
and the outside-ISR paths should use either spin_lock_irq() or 
spin_lock_irqsave().

	Jeff




^ permalink raw reply

* Re: [patch 7/8] lock validator: fix ns83820.c irq-flags bug
From: Arjan van de Ven @ 2006-06-11 16:12 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: akpm, netdev, mingo, bcrl
In-Reply-To: <448C4021.80102@garzik.org>

Jeff Garzik wrote:
> Arjan van de Ven wrote:
>> Jeff Garzik wrote:
>>> The driver's locking is definitely wrong, but I don't think this is 
>>> the fix, 
>>
>> it's an obvious correct fix in the correctness sense though...
>>
>>>
>>> Jesus, the locking here is awful.  No wonder there are bugs.
>>
>>
>> ... which given that fact, is for 2.6.17 probably the right thing, 
>> pending
>> a nicer fix for 2.6.18
> 
> I disagree, the patch is wrong too.

wrong as in "not quite optimal", not wrong as in "buggy".

> For normal PCI hardware, the in-ISR paths should all use spin_lock(), 

only for per hardware locks obviously, not for per driver locks ;)


you are right that it's a lot nicer to do what you describe. No argument
from me on that part. But to call it "wrong" or "incorrect" is not quite
ok.  In terms of changing/fixing the approach we did was the simplest one.
Not the "make it look nice" one. Fix it by making the bug go away in the light
of a LOT of fishy locking.

You can demand that we first fix all the fishy locking first, and I can even
in part agree with that, but for -stable and 2.6.17 that is obviously out
of scope while a simple "make the bug go away" fix is not.


^ permalink raw reply

* Re: [PATCH 1/2] PHYLIB: Add get_link ethtool helper function
From: Jeff Garzik @ 2006-06-11 16:13 UTC (permalink / raw)
  To: Nathaniel Case; +Cc: Andy Fleming, netdev, galak
In-Reply-To: <1149551292.10700.47.camel@localhost.localdomain>

Nathaniel Case wrote:
> This adds a phy_ethtool_get_link() function along the same lines as
> phy_ethtool_gset().  This provides drivers utilizing PHYLIB an
> alternative to using ethtool_op_get_link().  This is more desirable
> since the "Link detected" field in ethtool would actually reflect the
> state of the PHY register.
> 
> Patch depends on previous patch (0/2).
> 
> Signed-off-by: Nate Case <ncase@xes-inc.com>
> Signed-off-by: Andy Fleming <afleming@freescale.com>

NAK, needs an EXPORT



^ permalink raw reply

* Re: [RFC ] [1 of 4] IEEE802.11 Regulatory/Geographical Support for drivers - statement of project
From: Larry Finger @ 2006-06-11 16:46 UTC (permalink / raw)
  To: netdev
In-Reply-To: <20060611100750.GF24167@p15091797.pureserver.info>

Uli,

Ulrich Kunitz wrote:
> Larry,
> 
> I've not read your patches your detail, so I comment only on your
> description.
> 
> 
> The problem is the driver doesn't have good ideas, whether the
> device is outdoor and in which country it operates. Devices have
> some information available, but I have definitely a device
> marketed in Canada, which had an EEPROM value for ETSI as
> regulatory domain. I would expect the daemon to know, in which
> country it is and whether the device is used outdoors. Keep also
> in mind, that this information will be available from the AP at a
> later time.

I agree that once the AP is broadcasting the country code, this all gets easier. I have a problem 
similar to yours in that my interface's EEPROM supplies a code that indicates the world, which leads 
to the bcm43xx driver code setting 2.4 GHz channels 1 - 14 and then running active scans on all of 
them. Of course in the US 12, 13 and 14 are illegal and could lead to legal action if the FCC were 
monitoring outside my house.

I don't see any means for the daemon to know its country other than the driver or the user telling 
it. If such a means exists, I would like to learn of it. My current working model is to supply the 
country code from a module option when the driver is loaded.

> So there should be an explicit method to request the minimum set
> or the configuration of daemon. Later the set can be changed again
> by the AP information provided.

If the daemon is not running, if the country code is "  ", or if it doesn't match any country in the 
database, the minimum set is supplied, but the driver could call the routine again if it learned 
more about its environment.

>>   b) It then creates a new directory, '/proc/net/ieee80211_geo', and 
>>   populates it with 2 files for communication with the daemon. The first, 
>> which is read by the daemon, contains the country and outdoor codes, and 
>> the second is for the the daemon to write the 'struct ieee80211_geo' data 
>> corresponding to the country and indoor/outdoor information passed from the 
>> kernel.
> 
> Michael Buesch already commented on /proc/net. I don't think, that
> this will be popular with a lot of folks. sysfs should be
> supported and the mechanism should be comparable to firmware
> loading. Maybe this could be some kind of udev extension. And make
> it device specific, the whole approach should not break, if you
> are accessing two devices connecting to two different access
> points at the same time, where one of them is configured by the
> central networking folks, who don't bother to adapt there configs
> to specific countries and the other is a perfectly conformant
> local AP, which is used for "testing" purposes.

Based on Michael's comments, I have changed the kernel - user space communication to use sysfs 
rather than procfs. It also uses only a single mode 0666 file in /sys for communication. The deamon 
spins waiting for that file to exist, then reads it to get the country and in/out flags. It then 
writes the geo binary data to the file, closes it, delays a while and then repeats. After the geo 
data are read, the kernel routine deletes the kobjects that create the sysfs file, loads the geo 
data into the location supplied by the driver, and exits. Because the /sys file exists for only a 
short time, I don't think that having it world writable will cause any problems. In addition, the 
data supplied are thoroughly checked to make sure that it has the proper data for geo information. 
If the 0666 mode is a problem, the daemon may have to become root to write the data.

Because, the geo data is loaded into a data area that is specific to each device, I don't expect any 
problem with the situation you describe even if the same driver is operating both devices. If I have 
missed some nuance, please enlighten me.

>> 2. The user-space daemon, which need not be run as root, does the following:
> 
> It needs only to run temporarily run as root. I would definitely
> recommend that all file parsing activities should not run as root.

At present, it does everything as an unprivileged user.

>>   e) It then spins waiting for the existence of file 
>>   '/proc/net/ieee80211_geo/country', which is the indication that the kernel 
>> is requesting data.
> 
> Again the whole interface should be device specific. 

This part I don't understand. Everything in the geo data is generic to ieee802.11 devices. As I 
stated earlier, it will end up in the private data for the device, but I don't see any reason for 
the daemon to know which device is going to use the data.


Thanks for your comments,

Larry

^ permalink raw reply

* Re: [patch 7/8] lock validator: fix ns83820.c irq-flags bug
From: Jeff Garzik @ 2006-06-11 17:01 UTC (permalink / raw)
  To: akpm; +Cc: netdev, mingo, arjan, bcrl
In-Reply-To: <200606090519.k595JmDG032032@shell0.pdx.osdl.net>

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

akpm@osdl.org wrote:
> diff -puN drivers/net/ns83820.c~lock-validator-fix-ns83820c-irq-flags-bug drivers/net/ns83820.c
> --- devel/drivers/net/ns83820.c~lock-validator-fix-ns83820c-irq-flags-bug	2006-06-08 22:18:34.000000000 -0700
> +++ devel-akpm/drivers/net/ns83820.c	2006-06-08 22:18:48.000000000 -0700
> @@ -804,7 +804,7 @@ static int ns83820_setup_rx(struct net_d
>  
>  		writel(dev->IMR_cache, dev->base + IMR);
>  		writel(1, dev->base + IER);
> -		spin_unlock_irq(&dev->misc_lock);
> +		spin_unlock(&dev->misc_lock);
>  
>  		kick_rx(ndev);
>  

The above code snippet removes the nested unlock-irq, but now the code 
is unbalanced, so IMO this patch _adds_ confusion.

I think the conservative patch for 2.6.17 is the one I have attached. 
Unless there are objections, that is what I will forward...

	Jeff



[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 1156 bytes --]

diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 706aed7..cee0e74 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -776,9 +776,11 @@ static int ns83820_setup_rx(struct net_d
 
 	ret = rx_refill(ndev, GFP_KERNEL);
 	if (!ret) {
+		unsigned long flags;
+
 		dprintk("starting receiver\n");
 		/* prevent the interrupt handler from stomping on us */
-		spin_lock_irq(&dev->rx_info.lock);
+		spin_lock_irqsave(&dev->rx_info.lock, flags);
 
 		writel(0x0001, dev->base + CCSR);
 		writel(0, dev->base + RFCR);
@@ -790,7 +792,7 @@ static int ns83820_setup_rx(struct net_d
 		phy_intr(ndev);
 
 		/* Okay, let it rip */
-		spin_lock_irq(&dev->misc_lock);
+		spin_lock(&dev->misc_lock);
 		dev->IMR_cache |= ISR_PHY;
 		dev->IMR_cache |= ISR_RXRCMP;
 		//dev->IMR_cache |= ISR_RXERR;
@@ -804,11 +806,11 @@ static int ns83820_setup_rx(struct net_d
 
 		writel(dev->IMR_cache, dev->base + IMR);
 		writel(1, dev->base + IER);
-		spin_unlock_irq(&dev->misc_lock);
+		spin_unlock(&dev->misc_lock);
 
 		kick_rx(ndev);
 
-		spin_unlock_irq(&dev->rx_info.lock);
+		spin_unlock_irqrestore(&dev->rx_info.lock, flags);
 	}
 	return ret;
 }

^ permalink raw reply related

* Re: [patch 7/8] lock validator: fix ns83820.c irq-flags bug
From: Arjan van de Ven @ 2006-06-11 17:02 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: akpm, netdev, mingo, bcrl
In-Reply-To: <448C4C7A.7020301@garzik.org>


> The above code snippet removes the nested unlock-irq, but now the code 
> is unbalanced, so IMO this patch _adds_ confusion.
> 
> I think the conservative patch for 2.6.17 is the one I have attached. 
> Unless there are objections, that is what I will forward...


this looks entirely fair and reasonable

Acked-by: Arjan van de Ven <arjan@linux.intel.com>

^ permalink raw reply

* Re: [PATCH RFC] netpoll: don't spin forever sending to stopped queues
From: Matt Mackall @ 2006-06-11 20:04 UTC (permalink / raw)
  To: Jeremy Fitzhardinge; +Cc: Linux Kernel Mailing List, netdev
In-Reply-To: <4488D9D6.6070205@goop.org>

On Thu, Jun 08, 2006 at 07:15:50PM -0700, Jeremy Fitzhardinge wrote:
> Matt Mackall wrote:
> >That's odd. Netpoll holds a reference to the device, of course, but so
> >does a normal "up" interface. So that shouldn't be the problem.
> >Another possibility is that outgoing packets from printks in the
> >driver are causing difficulty. Not sure what can be done about that.
> >  
> Here's a patch.  I haven't tested it beyond compiling it, and I don't 
> know if it is actually correct.  In this case, it seems pointless to 
> spin waiting for an even which will never happen.  Should 
> netif_poll_disable() cause netpoll_send_skb() (or something) to not even 
> bother trying to send?  netif_poll_disable seems mysteriously simple to me.
> 
>    J

Did this work for you at all?

> When transmitting a skb in netpoll_send_skb(), only retry a limited
> number of times if the device queue is stopped.

Where limited = once?

> Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
> 
> diff -r aac813f54617 net/core/netpoll.c
> --- a/net/core/netpoll.c	Wed Jun 07 14:53:40 2006 -0700
> +++ b/net/core/netpoll.c	Thu Jun 08 19:00:29 2006 -0700
> @@ -280,15 +280,10 @@ static void netpoll_send_skb(struct netp
> 		 * network drivers do not expect to be called if the queue is
> 		 * stopped.
> 		 */
> -		if (netif_queue_stopped(np->dev)) {
> -			np->dev->xmit_lock_owner = -1;
> -			spin_unlock(&np->dev->xmit_lock);
> -			netpoll_poll(np);
> -			udelay(50);
> -			continue;
> -		}
> -
> -		status = np->dev->hard_start_xmit(skb, np->dev);
> +		status = NETDEV_TX_BUSY;
> +		if (!netif_queue_stopped(np->dev))
> +			status = np->dev->hard_start_xmit(skb, np->dev);
> +
> 		np->dev->xmit_lock_owner = -1;
> 		spin_unlock(&np->dev->xmit_lock);
> 
> 
> 

-- 
Mathematics is the supreme nostalgia of our time.

^ permalink raw reply

* IEEE80211 Regulatory/Geographical Support for WLAN driver
From: Ulrich Kunitz @ 2006-06-11 20:21 UTC (permalink / raw)
  To: Larry Finger; +Cc: netdev
In-Reply-To: <448C48CF.50205@lwfinger.net>

On 06-06-11 11:46 Larry Finger wrote:

> I don't see any means for the daemon to know its country other than the 
> driver or the user telling it. If such a means exists, I would like to 
> learn of it. My current working model is to supply the country code from a 
> module option when the driver is loaded.

I thought about a config option. However thinking about they whole
thing more, I believe the functionality of your daemon should be
included into WPA supplicant and should use it's user space
communication mechanisms. It will become the universal WLAN user
space daemon anyhow. The second best option would be to extend
udev and reuse the firmware loading code.

BTW creating a file with 0666 is almost always a bad idea, even if
it exists only a "short" time. 

Kind regards,

Uli

-- 
Uli Kunitz

^ permalink raw reply

* Re: [patch 7/8] lock validator: fix ns83820.c irq-flags bug
From: Benjamin LaHaise @ 2006-06-11 20:28 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: akpm, netdev, mingo, arjan
In-Reply-To: <448C4C7A.7020301@garzik.org>

> The above code snippet removes the nested unlock-irq, but now the code 
> is unbalanced, so IMO this patch _adds_ confusion.
> 
> I think the conservative patch for 2.6.17 is the one I have attached. 
> Unless there are objections, that is what I will forward...

This looks reasonable and sufficiently conservative.  Reworking locking is 
something that I'm a bit more hesitant about, although folding misc_lock 
in with the other locks perhaps makes sense.  I would like to keep the 
split between tx and tx completion, though.  Also, any rework is going to 
need real testing, which is not something that a simple release cycle is 
likely to get enough coverage on.

		-ben
-- 
"Time is of no importance, Mr. President, only life is important."
Don't Email: <dont@kvack.org>.

^ permalink raw reply

* Re: [PATCH] [2.6.17-rc6] Section mismatch in drivers/net/ne.o during modpost
From: Sam Ravnborg @ 2006-06-11 21:54 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: rdunlap, akpm, jgarzik, linux-kernel, netdev
In-Reply-To: <200606111437.k5BEbVu5021415@harpo.it.uu.se>

On Sun, Jun 11, 2006 at 04:37:31PM +0200, Mikael Pettersson wrote:
> On Sat, 10 Jun 2006 22:38:00 +0200, Sam Ravnborg wrote:
> >> --- linux-2617-rc6.orig/drivers/net/ne.c
> >> +++ linux-2617-rc6/drivers/net/ne.c
> >> @@ -829,7 +829,7 @@ that the ne2k probe is the last 8390 bas
> >>  is at boot) and so the probe will get confused by any other 8390 cards.
> >>  ISA device autoprobes on a running machine are not recommended anyway. */
> >>  
> >> -int init_module(void)
> >> +int __init init_module(void)
> >>  {
> >>  	int this_dev, found = 0;
> >
> >When you anyway touches the driver I suggest to name the function
> ><module>_init, <module>_cleanup and use module_init(), module_cleanup().
> 
> Maybe not: in the ne.c driver init_module() is inside #ifdef MODULE,
> so conversion to ne_init() + module_init(ne_init) would be a no-op
> except for making the code larger. In the non-MODULE case Space.c
> calls ne_probe() directly.
The whole purpose of marking a function __init is to place in in a
section that can be discarded after init. This has the added advantage
that it kills off some ugly #ifdef MODULE / #endif as is the case for
ne.c

Even if not discarded then the code cleaniness is preferable to #ifdef /
#endif if purpose is only to save a few bytes.

Shifting to module_init(), module_cleanup() is the only right thing to
do - and the old behaviour is not even documented in LDD3 anymore.
[At least I did not find it last time I searched].

	Sam

^ permalink raw reply

* [PATCH] zd1211rw: disable TX queue during stop
From: Daniel Drake @ 2006-06-11 22:18 UTC (permalink / raw)
  To: linville; +Cc: netdev

This avoids some potential races.

Signed-off-by: Daniel Drake <dsd@gentoo.org>

diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index bbe067e..3bdc54d 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -197,6 +197,8 @@ int zd_mac_stop(struct net_device *netde
 	struct zd_mac *mac = zd_netdev_mac(netdev);
 	struct zd_chip *chip = &mac->chip;
 
+	netif_stop_queue(netdev);
+
 	/*
 	 * The order here deliberately is a little different from the open()
 	 * method, since we need to make sure there is no opportunity for RX

^ permalink raw reply related

* Re: [PATCH 2.6.17-rc6] Remove Prism II support from Orinoco
From: Dave Jones @ 2006-06-11 22:27 UTC (permalink / raw)
  To: Faidon Liambotis; +Cc: netdev
In-Reply-To: <20060610180850.GP7420@redhat.com>

On Sat, Jun 10, 2006 at 02:08:50PM -0400, Dave Jones wrote:
 > On Sat, Jun 10, 2006 at 08:50:10PM +0300, Faidon Liambotis wrote:
 >  > Remove Prism II IDs from the orinoco driver since now we have a separate
 >  > driver for them (HostAP). Additionally, kill orinoco_{pci,plx,nortel}
 >  > completely, since they only exist to support Prism cards.
 >  > No attempt was made to clean up the rest of the driver of the actual
 >  > Prism II code, only the PCI IDs were removed.
 > 
 > I'm fairly certain I have a buffalo card that doesn't work with hostap
 > that works just fine with orinoco.  I'll dig it out and see if that
 > has been improved.

Objection rescinded, I have a WLI-PCM-L11G, which this patch doesn't affect.

One question though. People who are currently using orinoco will have
networking scripts set up by their distros autodetection mechanisms to
set up an 'ethX' interface. Switching to hostap by default will change
their interface to a wlanX interface, requiring them to either edit
their networking interface scripts, or to add dev_template parameters
to their /etc/modprobe.conf

Whichever is chosen, the upgrade process is going to blindside end-users
into broken wireless. Maybe things would just transparently keep working
if the default template was also ethX. Though that would cause breakage
for anyone with a currently working 'wlanX' interface on upgrade.

Hmm, tricky.

		Dave

-- 
http://www.codemonkey.org.uk

^ permalink raw reply

* Re: [PATCH 2.6.17-rc6] Remove Prism II support from Orinoco
From: Dave Jones @ 2006-06-11 22:40 UTC (permalink / raw)
  To: Faidon Liambotis; +Cc: netdev
In-Reply-To: <20060611222719.GA13139@redhat.com>

On Sun, Jun 11, 2006 at 06:27:19PM -0400, Dave Jones wrote:
 > On Sat, Jun 10, 2006 at 02:08:50PM -0400, Dave Jones wrote:
 >  > On Sat, Jun 10, 2006 at 08:50:10PM +0300, Faidon Liambotis wrote:
 >  >  > Remove Prism II IDs from the orinoco driver since now we have a separate
 >  >  > driver for them (HostAP). Additionally, kill orinoco_{pci,plx,nortel}
 >  >  > completely, since they only exist to support Prism cards.
 >  >  > No attempt was made to clean up the rest of the driver of the actual
 >  >  > Prism II code, only the PCI IDs were removed.
 >  > 
 >  > I'm fairly certain I have a buffalo card that doesn't work with hostap
 >  > that works just fine with orinoco.  I'll dig it out and see if that
 >  > has been improved.
 > 
 > Objection rescinded, I have a WLI-PCM-L11G, which this patch doesn't affect.

Ah-ha, I had tested the wrong card.
I also have a Sitecom card, which matches this ident you remove in your patch..

PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */


pccardctl ident shows it as:

Socket 0:
  product info: " ", "IEEE 802.11 Wireless LAN/PC Card", "", ""
  manfid: 0xd601, 0x0002
  function: 6 (network)



Under hostap, it's a brick, it won't even report any scanning results.

pccard: PCMCIA card inserted into slot 0
pcmcia: registering new device pcmcia0.0
ieee80211_crypt: registered algorithm 'NULL'
hostap_cs: 0.4.4-kernel (Jouni Malinen <jkmaline@cc.hut.fi>)
hostap_cs: setting Vcc=33 (constant)
Checking CFTABLE_ENTRY 0x01 (default 0x01)
IO window settings: cfg->io.nwin=1 dflt.io.nwin=1
io->flags = 0x0046, io.base=0x0000, len=64
hostap_cs: Registered netdevice wifi0
hostap_cs: index 0x01: , irq 4, io 0x0100-0x013f
prism2_hw_init: initialized in 108 ms
wifi0: NIC: id=0x8002 v1.0.0
wifi0: PRI: id=0x15 v0.3.0
wifi0: STA: id=0x1f v1.3.4
wifi0: defaulting to host-based encryption as a workaround for firmware bug in Host AP mode WEP
wifi0: defaulting to bogus WDS frame as a workaround for firmware bug in Host AP mode WDS
wifi0: registered netdevice wlan0
Scan result translation succeeded (length=0)


With orinoco however, it works just fine..
(Asides from the irritating feature of orinoco that the interface has to be 'up'
 before an iwlist scanning works)


pccard: PCMCIA card inserted into slot 0
pcmcia: registering new device pcmcia0.0
eth1: Hardware identity 8002:0000:0001:0000
eth1: Station identity  001f:0004:0001:0003
eth1: Firmware determined as Intersil 1.3.4
eth1: Ad-hoc demo mode supported
eth1: IEEE standard IBSS ad-hoc mode supported
eth1: WEP supported, 104-bit key
eth1: MAC address 00:60:B3:68:AE:9B
eth1: Station name "Prism  I"
eth1: ready
eth1: index 0x01: , irq 4, io 0x0100-0x013f
ADDRCONF(NETDEV_UP): eth1: link is not ready
eth1: New link status: Connected (0001)
ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready


So with your patch, this card will become totally useless to me.

		Dave

-- 
http://www.codemonkey.org.uk

^ permalink raw reply

* Re: [PATCH 2.6.17-rc6] Remove Prism II support from Orinoco
From: Kyle McMartin @ 2006-06-11 22:31 UTC (permalink / raw)
  To: Dave Jones; +Cc: Faidon Liambotis, netdev
In-Reply-To: <20060611224054.GB13139@redhat.com>

On Sun, Jun 11, 2006 at 06:40:54PM -0400, Dave Jones wrote:
> Under hostap, it's a brick, it won't even report any scanning results.
> 

Did you switch it into managed mode? The hostap driver, iirc, defaults
to running in master (AP) mode.

Cheers,
	Kyle

^ permalink raw reply

* [PATCH] [IrDA] irda-usb.c: STIR421x cleanups
From: Samuel Ortiz @ 2006-06-12  6:12 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, irda-users, Nick Fedchik

This patch is for the net-2.6.18 tree.
It cleans the STIR421x part of the irda-usb code. We also no longer try to
load all existing firmwares but only the matching one (according to the USB
id we get from the dongle).

Signed-off-by: Nick Fedchik <nfedchik@atlantic-link.com.ua>
Signed-off-by: Samuel Ortiz <samuel@sortiz.org>


---

 drivers/net/irda/irda-usb.c |  327 +++++++++++++++++++------------------------
 drivers/net/irda/irda-usb.h |   10 +
 2 files changed, 145 insertions(+), 192 deletions(-)

946837ac4e7bb301a1fcef0046b2a72e8e81b57c
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index cd87593..844fa74 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -83,9 +83,9 @@ static struct usb_device_id dongles[] = 
 	/* Extended Systems, Inc.,  XTNDAccess IrDA USB (ESI-9685) */
 	{ USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW },
 	/* SigmaTel STIR4210/4220/4116 USB IrDA (VFIR) Bridge */
-	{ USB_DEVICE(0x66f, 0x4210), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG },
-	{ USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG },
-	{ USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG },
+	{ USB_DEVICE(0x66f, 0x4210), .driver_info = IUC_STIR421X | IUC_SPEED_BUG },
+	{ USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR421X | IUC_SPEED_BUG },
+	{ USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR421X | IUC_SPEED_BUG },
 	{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
 	  USB_DEVICE_ID_MATCH_INT_SUBCLASS,
 	  .bInterfaceClass = USB_CLASS_APP_SPEC,
@@ -154,7 +154,7 @@ static void irda_usb_build_header(struct
 	 * and if either speed or xbofs (or both) needs
 	 * to be changed.
 	 */
-	if (self->capability & IUC_STIR_4210 &&
+	if (self->capability & IUC_STIR421X &&
 	    ((self->new_speed != -1) || (self->new_xbofs != -1))) {
 
 		/* With STIR421x, speed and xBOFs must be set at the same
@@ -318,7 +318,7 @@ static void irda_usb_change_speed_xbofs(
 	/* Set the new speed and xbofs in this fake frame */
 	irda_usb_build_header(self, frame, 1);
 
-	if ( self->capability & IUC_STIR_4210 ) {
+	if (self->capability & IUC_STIR421X) {
 		if (frame[0] == 0) return ; // do nothing if no change
 		frame[1] = 0; // other parameters don't change here
 		frame[2] = 0;
@@ -455,7 +455,7 @@ static int irda_usb_hard_xmit(struct sk_
 
 	/* Change setting for next frame */
 
-	if ( self->capability & IUC_STIR_4210 ) {
+	if (self->capability & IUC_STIR421X) {
 		__u8 turnaround_time;
 		__u8* frame;
 		turnaround_time = get_turnaround_time( skb );
@@ -897,10 +897,13 @@ static void irda_usb_receive(struct urb 
 	docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD);
 
 	/* Allocate a new skb */
-	if ( self->capability & IUC_STIR_4210 )
-		newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU + USB_IRDA_SIGMATEL_HEADER);
+	if (self->capability & IUC_STIR421X)
+		newskb = dev_alloc_skb(docopy ? urb->actual_length :
+				       IRDA_SKB_MAX_MTU +
+				       USB_IRDA_STIR421X_HEADER);
 	else
-		newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU);
+		newskb = dev_alloc_skb(docopy ? urb->actual_length :
+				       IRDA_SKB_MAX_MTU);
 
 	if (!newskb)  {
 		self->stats.rx_dropped++;
@@ -1022,188 +1025,140 @@ static int irda_usb_is_receiving(struct 
 	return 0; /* For now */
 }
 
-
-#define STIR421X_PATCH_PRODUCT_VERSION_STR       "Product Version: "
-#define STIR421X_PATCH_COMPONENT_VERSION_STR     "Component Version: "
-#define STIR421X_PATCH_DATA_TAG_STR              "STMP"
-#define STIR421X_PATCH_FILE_VERSION_MAX_OFFSET   512     /* version info is before here */
-#define STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET     512     /* patch image starts before here */
-#define STIR421X_PATCH_FILE_END_OF_HEADER_TAG    0x1A    /* marks end of patch file header (PC DOS text file EOF character) */
+#define STIR421X_PATCH_PRODUCT_VER     "Product Version: "
+#define STIR421X_PATCH_STMP_TAG        "STMP"
+#define STIR421X_PATCH_CODE_OFFSET     512 /* patch image starts before here */
+/* marks end of patch file header (PC DOS text file EOF character) */
+#define STIR421X_PATCH_END_OF_HDR_TAG  0x1A
+#define STIR421X_PATCH_BLOCK_SIZE      1023
 
 /*
- * Known firmware patches for STIR421x dongles
+ * Function stir421x_fwupload (struct irda_usb_cb *self,
+ *                             unsigned char *patch,
+ *                             const unsigned int patch_len)
+ *
+ *   Upload firmware code to SigmaTel 421X IRDA-USB dongle
  */
-static char * stir421x_patches[] = {
-	"42101001.sb",
-	"42101002.sb",
-};
-
-static int stir421x_get_patch_version(unsigned char * patch, const unsigned long patch_len)
+static int stir421x_fw_upload(struct irda_usb_cb *self,
+			     unsigned char *patch,
+			     const unsigned int patch_len)
 {
-	unsigned int version_offset;
-	unsigned long version_major, version_minor, version_build;
-	unsigned char * version_start;
-	int version_found = 0;
-
-	for (version_offset = 0;
-	     version_offset < STIR421X_PATCH_FILE_END_OF_HEADER_TAG;
-	     version_offset++) {
-		if (!memcmp(patch + version_offset,
-			    STIR421X_PATCH_PRODUCT_VERSION_STR,
-			    sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1)) {
-				    version_found = 1;
-				    version_start = patch +
-					    version_offset +
-					    sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1;
-				    break;
-		}
+        int ret = -ENOMEM;
+        int actual_len = 0;
+        unsigned int i;
+        unsigned int block_size = 0;
+        unsigned char *patch_block;
+
+        patch_block = kzalloc(STIR421X_PATCH_BLOCK_SIZE, GFP_KERNEL);
+	if (patch_block == NULL)
+		return -ENOMEM;
+
+	/* break up patch into 1023-byte sections */
+	for (i = 0; i < patch_len; i += block_size) {
+		block_size = patch_len - i;
+
+		if (block_size > STIR421X_PATCH_BLOCK_SIZE)
+			block_size = STIR421X_PATCH_BLOCK_SIZE;
+
+		/* upload the patch section */
+		memcpy(patch_block, patch + i, block_size);
+
+		ret = usb_bulk_msg(self->usbdev,
+				   usb_sndbulkpipe(self->usbdev,
+						   self->bulk_out_ep),
+				   patch_block, block_size,
+				   &actual_len, msecs_to_jiffies(500));
+		IRDA_DEBUG(3,"%s(): Bulk send %u bytes, ret=%d\n",
+			   __FUNCTION__, actual_len, ret);
+
+		if (ret < 0)
+			break;
 	}
 
-	/* We couldn't find a product version on this patch */
-	if (!version_found)
-		return -EINVAL;
-
-	/* Let's check if the product version is dotted */
-	if (version_start[3] != '.' ||
-	    version_start[7] != '.')
-		return -EINVAL;
-
-	version_major = simple_strtoul(version_start, NULL, 10);
-	version_minor = simple_strtoul(version_start + 4, NULL, 10);
-	version_build = simple_strtoul(version_start + 8, NULL, 10);
-
-	IRDA_DEBUG(2, "%s(), Major: %ld Minor: %ld Build: %ld\n",
-		   __FUNCTION__,
-		   version_major, version_minor, version_build);
-
-	return (((version_major) << 12) +
-		((version_minor) << 8) +
-		((version_build / 10) << 4) +
-		(version_build % 10));
-
-}
-
-
-static int stir421x_upload_patch (struct irda_usb_cb *self,
-				  unsigned char * patch,
-				  const unsigned int patch_len)
-{
-    int retval = 0;
-    int actual_len;
-    unsigned int i = 0, download_amount = 0;
-    unsigned char * patch_chunk;
-
-    IRDA_DEBUG (2, "%s(), Uploading STIR421x Patch\n", __FUNCTION__);
-
-    patch_chunk = kzalloc(STIR421X_MAX_PATCH_DOWNLOAD_SIZE, GFP_KERNEL);
-    if (patch_chunk == NULL)
-	    return -ENOMEM;
-
-    /* break up patch into 1023-byte sections */
-    for (i = 0; retval >= 0 && i < patch_len; i += download_amount) {
-	    download_amount = patch_len - i;
-	    if (download_amount > STIR421X_MAX_PATCH_DOWNLOAD_SIZE)
-		    download_amount = STIR421X_MAX_PATCH_DOWNLOAD_SIZE;
-
-	    /* download the patch section */
-	    memcpy(patch_chunk, patch + i, download_amount);
-
-	    retval = usb_bulk_msg (self->usbdev,
-				   usb_sndbulkpipe (self->usbdev,
-						    self->bulk_out_ep),
-				   patch_chunk, download_amount,
-				   &actual_len, msecs_to_jiffies (500));
-	    IRDA_DEBUG (2, "%s(), Sent %u bytes\n", __FUNCTION__,
-			actual_len);
-	    if (retval == 0)
-		    mdelay(10);
-    }
-
-    kfree(patch_chunk);
-
-    if (i != patch_len) {
-	    IRDA_ERROR ("%s(), Pushed %d bytes (!= patch_len (%d))\n",
-		       __FUNCTION__, i, patch_len);
-	    retval = -EIO;
-    }
-
-    if (retval < 0)
-	    /* todo - mark device as not ready */
-	    IRDA_ERROR ("%s(), STIR421x patch upload failed (%d)\n",
-			__FUNCTION__, retval);
-
-    return retval;
-}
+	kfree(patch_block);
 
+        return ret;
+ }
 
+/*
+ * Function stir421x_patch_device(struct irda_usb_cb *self)
+ *
+ * Get a firmware code from userspase using hotplug request_firmware() call
+  */
 static int stir421x_patch_device(struct irda_usb_cb *self)
 {
-	unsigned int i, patch_found = 0, data_found = 0, data_offset;
-	int patch_version, ret = 0;
-	const struct firmware *fw_entry;
-
-	for (i = 0; i < ARRAY_SIZE(stir421x_patches); i++) {
-		if(request_firmware(&fw_entry, stir421x_patches[i], &self->usbdev->dev) != 0) {
-			IRDA_ERROR( "%s(), Patch %s is not available\n", __FUNCTION__, stir421x_patches[i]);
-			continue;
-		}
-
-                /* We found a patch from userspace */
-		patch_version = stir421x_get_patch_version (fw_entry->data, fw_entry->size);
-
-		if (patch_version < 0) {
-			/* Couldn't fetch a version, let's move on to the next file */
-			IRDA_ERROR("%s(), version parsing failed\n", __FUNCTION__);
-			ret = patch_version;
-			release_firmware(fw_entry);
-			continue;
-		}
-
-		if (patch_version != self->usbdev->descriptor.bcdDevice) {
-			/* Patch version and device don't match */
-			IRDA_ERROR ("%s(), wrong patch version (%d <-> %d)\n",
-				    __FUNCTION__,
-				    patch_version, self->usbdev->descriptor.bcdDevice);
-			ret = -EINVAL;
-			release_firmware(fw_entry);
-			continue;
-		}
-
-		/* If we're here, we've found a correct patch */
-		patch_found = 1;
-		break;
-
-	}
-
-	/* We couldn't find a valid firmware, let's leave */
-	if (!patch_found)
-		return ret;
-
-	/* The actual image starts after the "STMP" keyword */
-	for (data_offset = 0; data_offset < STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET; data_offset++) {
-		if (!memcmp(fw_entry->data + data_offset,
-			    STIR421X_PATCH_DATA_TAG_STR,
-			    sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))) {
-			IRDA_DEBUG(2, "%s(), found patch data for STIR421x at offset %d\n",
-				   __FUNCTION__, data_offset);
-			data_found = 1;
-			break;
-		}
-	}
-
-	/* We couldn't find "STMP" from the header */
-	if (!data_found)
-		return -EINVAL;
-
-	/* Let's upload the patch to the target */
-	ret = stir421x_upload_patch(self,
-				    &fw_entry->data[data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET)],
-				    fw_entry->size - (data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET)));
-
-	release_firmware(fw_entry);
-
-	return ret;
-
+        unsigned int i;
+        int ret;
+        char stir421x_fw_name[11];
+        const struct firmware *fw;
+        unsigned char *fw_version_ptr; /* pointer to version string */
+	unsigned long fw_version = 0;
+
+        /*
+         * Known firmware patch file names for STIR421x dongles
+         * are "42101001.sb" or "42101002.sb"
+         */
+        sprintf(stir421x_fw_name, "4210%4X.sb",
+                self->usbdev->descriptor.bcdDevice);
+        ret = request_firmware(&fw, stir421x_fw_name, &self->usbdev->dev);
+        if (ret < 0)
+                return ret;
+
+        /* We get a patch from userspace */
+        IRDA_MESSAGE("%s(): Received firmware %s (%u bytes)\n",
+                     __FUNCTION__, stir421x_fw_name, fw->size);
+
+        ret = -EINVAL;
+
+	/* Get the bcd product version */
+        if (!memcmp(fw->data, STIR421X_PATCH_PRODUCT_VER,
+                    sizeof(STIR421X_PATCH_PRODUCT_VER) - 1)) {
+                fw_version_ptr = fw->data +
+			sizeof(STIR421X_PATCH_PRODUCT_VER) - 1;
+
+                /* Let's check if the product version is dotted */
+                if (fw_version_ptr[3] == '.' &&
+		    fw_version_ptr[7] == '.') {
+			unsigned long major, minor, build;
+			major = simple_strtoul(fw_version_ptr, NULL, 10);
+			minor = simple_strtoul(fw_version_ptr + 4, NULL, 10);
+			build = simple_strtoul(fw_version_ptr + 8, NULL, 10);
+
+			fw_version = (major << 12)
+				+ (minor << 8)
+				+ ((build / 10) << 4)
+				+ (build % 10);
+
+			IRDA_DEBUG(3, "%s(): Firmware Product version %ld\n",
+                                   __FUNCTION__, fw_version);
+                }
+        }
+
+        if (self->usbdev->descriptor.bcdDevice == fw_version) {
+                /*
+		 * If we're here, we've found a correct patch
+                 * The actual image starts after the "STMP" keyword
+                 * so forward to the firmware header tag
+                 */
+                for (i = 0; (fw->data[i] != STIR421X_PATCH_END_OF_HDR_TAG)
+			     && (i < fw->size); i++) ;
+                /* here we check for the out of buffer case */
+                if ((STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i])
+                    && (i < STIR421X_PATCH_CODE_OFFSET)) {
+                        if (!memcmp(fw->data + i + 1, STIR421X_PATCH_STMP_TAG,
+                                    sizeof(STIR421X_PATCH_STMP_TAG) - 1)) {
+
+				/* We can upload the patch to the target */
+				i += sizeof(STIR421X_PATCH_STMP_TAG);
+                                ret = stir421x_fw_upload(self, &fw->data[i],
+							 fw->size - i);
+                        }
+                }
+        }
+
+        release_firmware(fw);
+
+        return ret;
 }
 
 
@@ -1702,12 +1657,12 @@ static int irda_usb_probe(struct usb_int
 	init_timer(&self->rx_defer_timer);
 
 	self->capability = id->driver_info;
-	self->needspatch = ((self->capability & IUC_STIR_4210) != 0) ;
+	self->needspatch = ((self->capability & IUC_STIR421X) != 0);
 
 	/* Create all of the needed urbs */
-	if (self->capability & IUC_STIR_4210) {
+	if (self->capability & IUC_STIR421X) {
 		self->max_rx_urb = IU_SIGMATEL_MAX_RX_URBS;
-		self->header_length = USB_IRDA_SIGMATEL_HEADER;
+		self->header_length = USB_IRDA_STIR421X_HEADER;
 	} else {
 		self->max_rx_urb = IU_MAX_RX_URBS;
 		self->header_length = USB_IRDA_HEADER;
@@ -1813,8 +1768,8 @@ static int irda_usb_probe(struct usb_int
 		/* Now we fetch and upload the firmware patch */
 		ret = stir421x_patch_device(self);
 		self->needspatch = (ret < 0);
-		if (ret < 0) {
-			printk("patch_device failed\n");
+		if (self->needspatch) {
+			IRDA_ERROR("STIR421X: Couldn't upload patch\n");
 			goto err_out_5;
 		}
 
diff --git a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h
index d833db5..6b2271f 100644
--- a/drivers/net/irda/irda-usb.h
+++ b/drivers/net/irda/irda-usb.h
@@ -34,9 +34,6 @@ #include <linux/time.h>
 #include <net/irda/irda.h>
 #include <net/irda/irda_device.h>      /* struct irlap_cb */
 
-#define PATCH_FILE_SIZE_MAX     65536
-#define PATCH_FILE_SIZE_MIN     80
-
 #define RX_COPY_THRESHOLD 200
 #define IRDA_USB_MAX_MTU 2051
 #define IRDA_USB_SPEED_MTU 64		/* Weird, but work like this */
@@ -107,14 +104,15 @@ #define IUC_SIR_ONLY	0x08	/* Device does
 #define IUC_SMALL_PKT	0x10	/* Device doesn't behave with big Rx packets */
 #define IUC_MAX_WINDOW	0x20	/* Device underestimate the Rx window */
 #define IUC_MAX_XBOFS	0x40	/* Device need more xbofs than advertised */
-#define IUC_STIR_4210	0x80	/* SigmaTel 4210/4220/4116 VFIR */
+#define IUC_STIR421X	0x80	/* SigmaTel 4210/4220/4116 VFIR */
 
 /* USB class definitions */
 #define USB_IRDA_HEADER            0x01
 #define USB_CLASS_IRDA             0x02 /* USB_CLASS_APP_SPEC subclass */
 #define USB_DT_IRDA                0x21
-#define USB_IRDA_SIGMATEL_HEADER   0x03
-#define IU_SIGMATEL_MAX_RX_URBS    (IU_MAX_ACTIVE_RX_URBS + USB_IRDA_SIGMATEL_HEADER)
+#define USB_IRDA_STIR421X_HEADER   0x03
+#define IU_SIGMATEL_MAX_RX_URBS    (IU_MAX_ACTIVE_RX_URBS + \
+                                    USB_IRDA_STIR421X_HEADER)
 
 struct irda_class_desc {
 	__u8  bLength;
-- 
1.3.3

^ permalink raw reply related

* Re: [PATCH 2.6.17-rc6] Remove Prism II support from Orinoco
From: Dave Jones @ 2006-06-11 23:08 UTC (permalink / raw)
  To: Kyle McMartin; +Cc: Faidon Liambotis, netdev
In-Reply-To: <20060611223140.GB1163@skunkworks.cabal.ca>

On Sun, Jun 11, 2006 at 06:31:40PM -0400, Kyle McMartin wrote:
 > On Sun, Jun 11, 2006 at 06:40:54PM -0400, Dave Jones wrote:
 > > Under hostap, it's a brick, it won't even report any scanning results.
 > > 
 > 
 > Did you switch it into managed mode? The hostap driver, iirc, defaults
 > to running in master (AP) mode.

Ah, yes, that gets it able to scan again, thanks.
This is another gotcha that is going to prevent a smooth transition
from orinoco->hostap for end users though.

		Dave

-- 
http://www.codemonkey.org.uk

^ permalink raw reply

* Re: [RFT] Realtek 8168 ethernet support
From: Francois Romieu @ 2006-06-11 23:30 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Randy.Dunlap, Daniel Drake, netdev
In-Reply-To: <20060610224811.GA3256@electric-eye.fr.zoreil.com>

The patch below agaisnt 2.6.17-rc6 includes the following changes:

commit 3072cc0aba3ac0c944e196a63c4154ca5746ec0b

    r8169: sync with vendor's driver
    
    - add several PCI ID for the PCI-E adapters ;
    - new identification strings ;
    - the RTL_GIGA_MAC_VER_ defines have been renamed to closely match the
      out-of-tree driver. It makes the comparison less hairy ;
    - various magic ;
    - the PCI region for the device with PCI ID 0x8136 is guessed.
      Explanation: the in-kernel Linux driver is written to allow MM register
      accesses and avoid the IO tax. The relevant BAR register was found at
      base address 1 for the plain-old PCI 8169. User reported lspci show that
      it is found at base address 2 for the new Gigabit PCI-E 816{8/9}.
      Typically:
      01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.: Unknown device 8168 (rev 01)
              Subsystem: Unknown device 1631:e015
              Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
              Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
              Latency: 0, cache line size 20
              Interrupt: pin A routed to IRQ 16
              Region 0: I/O ports at b800 [size=256]
              Region 2: Memory at ff7ff000 (64-bit, non-prefetchable) [size=4K]
              ^^^^^^^^
      So far I have not received any lspci report for the 0x8136 and
      Realtek's driver do not help: be it under BSD or Linux, their r1000 driver
      include a USE_IO_SPACE #define but the bar address is always hardcoded
      to 1 in the MM case. :o/
    
    Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit 33857396c4f7d171f4ccaca86356df5fe2fdd304

    r8169: remove rtl8169_init_board
    
    Rationale:
    - its signature is not exactly pretty;
    - it has no knowledge of pci_device_id;
    - kiss 23 lines good bye.
    
    Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit af50f4372644c3c18c2af697a933c90f2a96be77

    r8169: hardware flow control
    
    The datasheet suggests that the device handles the hardware flow
    control almost automagically. User report a different story, so
    let's try to twiddle the mii registers.
    
    Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit d1e6ebbea2297df970e52823e1d8c9af62b0548d

    r8169: RX fifo overflow recovery
    
    Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

commit 17fb3bf33149eb2cb1a37ff94ab236ab01f91a40

    r8169: mac address change support
    
    Fix for http://bugzilla.kernel.org/show_bug.cgi?id=6032.
    
    Cc: Tim Mattox <tmattox@gmail.com>
    Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

The patch is for review only: mac address change apart, I need to
test it and it will surely conflict with jeff#netdev because of a
recently added PCI ID.

The patches are available at:
http://www.fr.zoreil.com/linux/kernel/2.6.x/2.6.17-rc6/r8169

or:

git://electric-eye.fr.zoreil.com/home/romieu/linux-2.6.git r8169

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 0ad3310..53a33c5 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -150,11 +150,16 @@ #define RTL_R16(reg)		readw (ioaddr + (r
 #define RTL_R32(reg)		((unsigned long) readl (ioaddr + (reg)))
 
 enum mac_version {
-	RTL_GIGA_MAC_VER_B = 0x00,
-	/* RTL_GIGA_MAC_VER_C = 0x03, */
-	RTL_GIGA_MAC_VER_D = 0x01,
-	RTL_GIGA_MAC_VER_E = 0x02,
-	RTL_GIGA_MAC_VER_X = 0x04	/* Greater than RTL_GIGA_MAC_VER_E */
+	RTL_GIGA_MAC_VER_01 = 0x00,
+	RTL_GIGA_MAC_VER_02 = 0x01,
+	RTL_GIGA_MAC_VER_03 = 0x02,
+	RTL_GIGA_MAC_VER_04 = 0x03,
+	RTL_GIGA_MAC_VER_05 = 0x04,
+	RTL_GIGA_MAC_VER_11 = 0x0b,
+	RTL_GIGA_MAC_VER_12 = 0x0c,
+	RTL_GIGA_MAC_VER_13 = 0x0d,
+	RTL_GIGA_MAC_VER_14 = 0x0e,
+	RTL_GIGA_MAC_VER_15 = 0x0f
 };
 
 enum phy_version {
@@ -166,7 +171,6 @@ enum phy_version {
 	RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */
 };
 
-
 #define _R(NAME,MAC,MASK) \
 	{ .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
 
@@ -175,18 +179,28 @@ static const struct {
 	u8 mac_version;
 	u32 RxConfigMask;	/* Clears the bits supported by this chip */
 } rtl_chip_info[] = {
-	_R("RTL8169",		RTL_GIGA_MAC_VER_B, 0xff7e1880),
-	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_D, 0xff7e1880),
-	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_E, 0xff7e1880),
-	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_X, 0xff7e1880),
+	_R("RTL8169",		RTL_GIGA_MAC_VER_01, 0xff7e1880),
+	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_02, 0xff7e1880),
+	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_03, 0xff7e1880),
+	_R("RTL8169sb/8110sb",	RTL_GIGA_MAC_VER_04, 0xff7e1880),
+	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880),
+	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
+	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
+	_R("RTL8101e",		RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
+	_R("RTL8100e",		RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139
+	_R("RTL8100e",		RTL_GIGA_MAC_VER_15, 0xff7e1880)  // PCI-E 8139
 };
 #undef _R
 
 static struct pci_device_id rtl8169_pci_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), },
-	{ PCI_DEVICE(0x16ec,			0x0116), },
-	{ PCI_VENDOR_ID_LINKSYS,		0x1032, PCI_ANY_ID, 0x0024, },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8136), 0, 0, 2 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8167), 0, 0, 2 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, 2 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), 0, 0, 1 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), 0, 0, 1 },
+	{ PCI_DEVICE(0x16ec,			0x0116), 0, 0, 1 },
+	{ PCI_VENDOR_ID_LINKSYS,		0x1032,
+		PCI_ANY_ID, 0x0024, 0, 0, 1 },
 	{0,},
 };
 
@@ -256,10 +270,11 @@ enum RTL8169_register_content {
 	RxOK = 0x01,
 
 	/* RxStatusDesc */
-	RxRES = 0x00200000,
-	RxCRC = 0x00080000,
-	RxRUNT = 0x00100000,
-	RxRWT = 0x00400000,
+	RxFOVF	= (1 << 23),
+	RxRWT	= (1 << 22),
+	RxRES	= (1 << 21),
+	RxRUNT	= (1 << 20),
+	RxCRC	= (1 << 19),
 
 	/* ChipCmdBits */
 	CmdReset = 0x10,
@@ -345,6 +360,7 @@ enum RTL8169_register_content {
 	PHY_Cap_100_Full = 0x0100,
 
 	/* PHY_1000_CTRL_REG = 9 */
+	PHY_Cap_1000_Half = 0x0100,
 	PHY_Cap_1000_Full = 0x0200,
 
 	PHY_Cap_Null = 0x0,
@@ -748,27 +764,47 @@ static int rtl8169_set_speed_xmii(struct
 	auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_10_Full |
 		       PHY_Cap_100_Half | PHY_Cap_100_Full);
 	giga_ctrl = mdio_read(ioaddr, PHY_1000_CTRL_REG);
-	giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_Null);
+	giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_1000_Half | PHY_Cap_Null);
 
 	if (autoneg == AUTONEG_ENABLE) {
 		auto_nego |= (PHY_Cap_10_Half | PHY_Cap_10_Full |
 			      PHY_Cap_100_Half | PHY_Cap_100_Full);
-		giga_ctrl |= PHY_Cap_1000_Full;
+		giga_ctrl |= PHY_Cap_1000_Full | PHY_Cap_1000_Half;
 	} else {
 		if (speed == SPEED_10)
 			auto_nego |= PHY_Cap_10_Half | PHY_Cap_10_Full;
 		else if (speed == SPEED_100)
 			auto_nego |= PHY_Cap_100_Half | PHY_Cap_100_Full;
 		else if (speed == SPEED_1000)
-			giga_ctrl |= PHY_Cap_1000_Full;
+			giga_ctrl |= PHY_Cap_1000_Full | PHY_Cap_1000_Half;
 
 		if (duplex == DUPLEX_HALF)
 			auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
 
 		if (duplex == DUPLEX_FULL)
 			auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
+
+		/* This tweak comes straight from Realtek's driver. */
+		if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
+		    (tp->mac_version == RTL_GIGA_MAC_VER_13)) {
+			auto_nego = PHY_Cap_100_Half | 0x01;
+		}
 	}
 
+	/* The 8100e/8101e do Fast Ethernet only. */
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
+		if ((giga_ctrl & (PHY_Cap_1000_Full | PHY_Cap_1000_Half)) &&
+		    netif_msg_link(tp)) {
+			printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
+			       dev->name);
+		}
+		giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_1000_Half);
+	}
+
+	auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+
 	tp->phy_auto_nego_reg = auto_nego;
 	tp->phy_1000_ctrl_reg = giga_ctrl;
 
@@ -960,6 +996,11 @@ static void rtl8169_gset_xmii(struct net
 	else if (status & _10bps)
 		cmd->speed = SPEED_10;
 
+	if (status & TxFlowCtrl)
+		cmd->advertising |= ADVERTISED_Asym_Pause;
+	if (status & RxFlowCtrl)
+		cmd->advertising |= ADVERTISED_Pause;
+
 	cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
 		      DUPLEX_FULL : DUPLEX_HALF;
 }
@@ -1139,10 +1180,16 @@ static void rtl8169_get_mac_version(stru
 		u32 mask;
 		int mac_version;
 	} mac_info[] = {
-		{ 0x1 << 28,	RTL_GIGA_MAC_VER_X },
-		{ 0x1 << 26,	RTL_GIGA_MAC_VER_E },
-		{ 0x1 << 23,	RTL_GIGA_MAC_VER_D }, 
-		{ 0x00000000,	RTL_GIGA_MAC_VER_B } /* Catch-all */
+		{ 0x38800000,	RTL_GIGA_MAC_VER_15 },
+		{ 0x38000000,	RTL_GIGA_MAC_VER_12 },
+		{ 0x34000000,	RTL_GIGA_MAC_VER_13 },
+		{ 0x30800000,	RTL_GIGA_MAC_VER_14 },
+		{ 0x30000000,   RTL_GIGA_MAC_VER_11 },
+		{ 0x18000000,	RTL_GIGA_MAC_VER_05 },
+		{ 0x10000000,	RTL_GIGA_MAC_VER_04 },
+		{ 0x04000000,	RTL_GIGA_MAC_VER_03 },
+		{ 0x00800000,	RTL_GIGA_MAC_VER_02 },
+		{ 0x00000000,	RTL_GIGA_MAC_VER_01 }	/* Catch-all */
 	}, *p = mac_info;
 	u32 reg;
 
@@ -1154,24 +1201,7 @@ static void rtl8169_get_mac_version(stru
 
 static void rtl8169_print_mac_version(struct rtl8169_private *tp)
 {
-	struct {
-		int version;
-		char *msg;
-	} mac_print[] = {
-		{ RTL_GIGA_MAC_VER_E, "RTL_GIGA_MAC_VER_E" },
-		{ RTL_GIGA_MAC_VER_D, "RTL_GIGA_MAC_VER_D" },
-		{ RTL_GIGA_MAC_VER_B, "RTL_GIGA_MAC_VER_B" },
-		{ 0, NULL }
-	}, *p;
-
-	for (p = mac_print; p->msg; p++) {
-		if (tp->mac_version == p->version) {
-			dprintk("mac_version == %s (%04d)\n", p->msg,
-				  p->version);
-			return;
-		}
-	}
-	dprintk("mac_version == Unknown\n");
+	dprintk("mac_version = 0x%02x\n", tp->mac_version);
 }
 
 static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr)
@@ -1256,7 +1286,7 @@ static void rtl8169_hw_phy_config(struct
 	rtl8169_print_mac_version(tp);
 	rtl8169_print_phy_version(tp);
 
-	if (tp->mac_version <= RTL_GIGA_MAC_VER_B)
+	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
 		return;
 	if (tp->phy_version >= RTL_GIGA_PHY_VER_H)
 		return;
@@ -1266,7 +1296,7 @@ static void rtl8169_hw_phy_config(struct
 
 	/* Shazam ! */
 
-	if (tp->mac_version == RTL_GIGA_MAC_VER_X) {
+	if (tp->mac_version == RTL_GIGA_MAC_VER_04) {
 		mdio_write(ioaddr, 31, 0x0001);
 		mdio_write(ioaddr,  9, 0x273a);
 		mdio_write(ioaddr, 14, 0x7bfb);
@@ -1305,7 +1335,7 @@ static void rtl8169_phy_timer(unsigned l
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long timeout = RTL8169_PHY_TIMEOUT;
 
-	assert(tp->mac_version > RTL_GIGA_MAC_VER_B);
+	assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
 	assert(tp->phy_version < RTL_GIGA_PHY_VER_H);
 
 	if (!(tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full))
@@ -1341,7 +1371,7 @@ static inline void rtl8169_delete_timer(
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct timer_list *timer = &tp->timer;
 
-	if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
+	if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
 	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
 		return;
 
@@ -1353,7 +1383,7 @@ static inline void rtl8169_request_timer
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct timer_list *timer = &tp->timer;
 
-	if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
+	if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
 	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
 		return;
 
@@ -1381,6 +1411,41 @@ static void rtl8169_netpoll(struct net_d
 }
 #endif
 
+static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr)
+{
+	unsigned int i, j;
+
+	RTL_W8(Cfg9346, Cfg9346_Unlock);
+	for (i = 0; i < 2; i++) {
+		__le32 l = 0;
+
+		for (j = 0; j < 4; j++) {
+			l <<= 8;
+			l |= dev->dev_addr[4*i + j];
+		}
+		RTL_W32(MAC0 + 4*i, cpu_to_be32(l));
+	}
+	RTL_W8(Cfg9346, Cfg9346_Lock);
+}
+
+static int rtl8169_set_mac_addr(struct net_device *dev, void *p)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EINVAL;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	if (netif_running(dev)) {
+		spin_lock_irq(&tp->lock);
+		__rtl8169_set_mac_addr(dev, tp->mmio_addr);
+		spin_unlock_irq(&tp->lock);
+	}
+	return 0;
+}
+
 static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
 				  void __iomem *ioaddr)
 {
@@ -1390,23 +1455,61 @@ static void rtl8169_release_board(struct
 	free_netdev(dev);
 }
 
+static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	static int board_idx = -1;
+	u8 autoneg, duplex;
+	u16 speed;
+
+	board_idx++;
+
+	rtl8169_hw_phy_config(dev);
+
+	dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+	RTL_W8(0x82, 0x01);
+
+	if (tp->mac_version < RTL_GIGA_MAC_VER_03) {
+		dprintk("Set PCI Latency=0x40\n");
+		pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
+	}
+
+	if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
+		dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+		RTL_W8(0x82, 0x01);
+		dprintk("Set PHY Reg 0x0bh = 0x00h\n");
+		mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
+	}
+
+	rtl8169_link_option(board_idx, &autoneg, &speed, &duplex);
+
+	rtl8169_set_speed(dev, autoneg, speed, duplex);
+
+	if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
+		printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
+}
+
 static int __devinit
-rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
-		   void __iomem **ioaddr_out)
+rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	void __iomem *ioaddr;
-	struct net_device *dev;
+	const unsigned int region = ent->driver_data;
 	struct rtl8169_private *tp;
-	int rc = -ENOMEM, i, acpi_idle_state = 0, pm_cap;
+	struct net_device *dev;
+	void __iomem *ioaddr;
+	unsigned int i, pm_cap;
+	int rc;
 
-	assert(ioaddr_out != NULL);
+	if (netif_msg_drv(&debug)) {
+		printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
+		       MODULENAME, RTL8169_VERSION);
+	}
 
-	/* dev zeroed in alloc_etherdev */
 	dev = alloc_etherdev(sizeof (*tp));
-	if (dev == NULL) {
+	if (!dev) {
 		if (netif_msg_drv(&debug))
 			printk(KERN_ERR PFX "unable to alloc new ethernet\n");
-		goto err_out;
+		rc = -ENOMEM;
+		goto out;
 	}
 
 	SET_MODULE_OWNER(dev);
@@ -1421,17 +1524,17 @@ rtl8169_init_board(struct pci_dev *pdev,
 			printk(KERN_ERR PFX "%s: enable failure\n",
 			       pci_name(pdev));
 		}
-		goto err_out_free_dev;
+		goto err_out_free_dev_1;
 	}
 
 	rc = pci_set_mwi(pdev);
 	if (rc < 0)
-		goto err_out_disable;
+		goto err_out_disable_2;
 
 	/* save power state before pci_enable_device overwrites it */
 	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
 	if (pm_cap) {
-		u16 pwr_command;
+		u16 pwr_command, acpi_idle_state;
 
 		pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
 		acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
@@ -1443,22 +1546,24 @@ rtl8169_init_board(struct pci_dev *pdev,
 	}
 
 	/* make sure PCI base addr 1 is MMIO */
-	if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
+	if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
 		if (netif_msg_probe(tp)) {
 			printk(KERN_ERR PFX
-			       "region #1 not an MMIO resource, aborting\n");
+			       "region #%d not an MMIO resource, aborting\n",
+			       region);
 		}
 		rc = -ENODEV;
-		goto err_out_mwi;
+		goto err_out_mwi_3;
 	}
+
 	/* check for weird/broken PCI region reporting */
-	if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
+	if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) {
 		if (netif_msg_probe(tp)) {
 			printk(KERN_ERR PFX
 			       "Invalid PCI region size(s), aborting\n");
 		}
 		rc = -ENODEV;
-		goto err_out_mwi;
+		goto err_out_mwi_3;
 	}
 
 	rc = pci_request_regions(pdev, MODULENAME);
@@ -1467,7 +1572,7 @@ rtl8169_init_board(struct pci_dev *pdev,
 			printk(KERN_ERR PFX "%s: could not request regions.\n",
 			       pci_name(pdev));
 		}
-		goto err_out_mwi;
+		goto err_out_mwi_3;
 	}
 
 	tp->cp_cmd = PCIMulRW | RxChkSum;
@@ -1483,19 +1588,19 @@ rtl8169_init_board(struct pci_dev *pdev,
 				printk(KERN_ERR PFX
 				       "DMA configuration failed.\n");
 			}
-			goto err_out_free_res;
+			goto err_out_free_res_4;
 		}
 	}
 
 	pci_set_master(pdev);
 
 	/* ioremap MMIO region */
-	ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
-	if (ioaddr == NULL) {
+	ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE);
+	if (!ioaddr) {
 		if (netif_msg_probe(tp))
 			printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
 		rc = -EIO;
-		goto err_out_free_res;
+		goto err_out_free_res_4;
 	}
 
 	/* Unneeded ? Don't mess with Mrs. Murphy. */
@@ -1538,56 +1643,6 @@ rtl8169_init_board(struct pci_dev *pdev,
 	RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
-	*ioaddr_out = ioaddr;
-	*dev_out = dev;
-out:
-	return rc;
-
-err_out_free_res:
-	pci_release_regions(pdev);
-
-err_out_mwi:
-	pci_clear_mwi(pdev);
-
-err_out_disable:
-	pci_disable_device(pdev);
-
-err_out_free_dev:
-	free_netdev(dev);
-err_out:
-	*ioaddr_out = NULL;
-	*dev_out = NULL;
-	goto out;
-}
-
-static int __devinit
-rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	struct net_device *dev = NULL;
-	struct rtl8169_private *tp;
-	void __iomem *ioaddr = NULL;
-	static int board_idx = -1;
-	u8 autoneg, duplex;
-	u16 speed;
-	int i, rc;
-
-	assert(pdev != NULL);
-	assert(ent != NULL);
-
-	board_idx++;
-
-	if (netif_msg_drv(&debug)) {
-		printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
-		       MODULENAME, RTL8169_VERSION);
-	}
-
-	rc = rtl8169_init_board(pdev, &dev, &ioaddr);
-	if (rc)
-		return rc;
-
-	tp = netdev_priv(dev);
-	assert(ioaddr != NULL);
-
 	if (RTL_R8(PHYstatus) & TBI_Enable) {
 		tp->set_speed = rtl8169_set_speed_tbi;
 		tp->get_settings = rtl8169_gset_tbi;
@@ -1616,6 +1671,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	dev->stop = rtl8169_close;
 	dev->tx_timeout = rtl8169_tx_timeout;
 	dev->set_multicast_list = rtl8169_set_rx_mode;
+	dev->set_mac_address = rtl8169_set_mac_addr;
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long) ioaddr;
@@ -1643,15 +1699,8 @@ #endif
 	spin_lock_init(&tp->lock);
 
 	rc = register_netdev(dev);
-	if (rc) {
-		rtl8169_release_board(pdev, dev, ioaddr);
-		return rc;
-	}
-
-	if (netif_msg_probe(tp)) {
-		printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n",
-		       dev->name, rtl_chip_info[tp->chipset].name);
-	}
+	if (rc < 0)
+		goto err_out_unmap_5;
 
 	pci_set_drvdata(pdev, dev);
 
@@ -1660,38 +1709,29 @@ #endif
 		       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
 		       "IRQ %d\n",
 		       dev->name,
-		       rtl_chip_info[ent->driver_data].name,
+		       rtl_chip_info[tp->chipset].name,
 		       dev->base_addr,
 		       dev->dev_addr[0], dev->dev_addr[1],
 		       dev->dev_addr[2], dev->dev_addr[3],
 		       dev->dev_addr[4], dev->dev_addr[5], dev->irq);
 	}
 
-	rtl8169_hw_phy_config(dev);
-
-	dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
-	RTL_W8(0x82, 0x01);
-
-	if (tp->mac_version < RTL_GIGA_MAC_VER_E) {
-		dprintk("Set PCI Latency=0x40\n");
-		pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
-	}
+	rtl8169_init_phy(dev, tp);
 
-	if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
-		dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
-		RTL_W8(0x82, 0x01);
-		dprintk("Set PHY Reg 0x0bh = 0x00h\n");
-		mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
-	}
-
-	rtl8169_link_option(board_idx, &autoneg, &speed, &duplex);
-
-	rtl8169_set_speed(dev, autoneg, speed, duplex);
-	
-	if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
-		printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
+out:
+	return rc;
 
-	return 0;
+err_out_unmap_5:
+	iounmap(ioaddr);
+err_out_free_res_4:
+	pci_release_regions(pdev);
+err_out_mwi_3:
+	pci_clear_mwi(pdev);
+err_out_disable_2:
+	pci_disable_device(pdev);
+err_out_free_dev_1:
+	free_netdev(dev);
+	goto out;
 }
 
 static void __devexit
@@ -1787,6 +1827,7 @@ rtl8169_hw_start(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
+	struct pci_dev *pdev = tp->pci_dev;
 	u32 i;
 
 	/* Soft reset the chip. */
@@ -1799,8 +1840,28 @@ rtl8169_hw_start(struct net_device *dev)
 		udelay(10);
 	}
 
+	if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
+		pci_write_config_word(pdev, 0x68, 0x00);
+		pci_write_config_word(pdev, 0x69, 0x08);
+	}
+
+	/* Undocumented stuff. */
+	if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
+		u16 cmd;
+
+		/* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
+		if ((RTL_R8(Config2) & 0x07) & 0x01)
+			RTL_W32(0x7c, 0x0007ffff);
+
+		RTL_W32(0x7c, 0x0007ff00);
+
+		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+		cmd = cmd & 0xef;
+		pci_write_config_word(pdev, PCI_COMMAND, cmd);
+	}
+
+
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
-	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 	RTL_W8(EarlyTxThres, EarlyTxThld);
 
 	/* Low hurts. Let's disable the filtering. */
@@ -1815,17 +1876,18 @@ rtl8169_hw_start(struct net_device *dev)
 	RTL_W32(TxConfig,
 		(TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
 						TxInterFrameGapShift));
-	tp->cp_cmd |= RTL_R16(CPlusCmd);
-	RTL_W16(CPlusCmd, tp->cp_cmd);
 
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_D) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_E)) {
+	tp->cp_cmd |= RTL_R16(CPlusCmd) | PCIMulRW;
+
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
 		dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. "
 			"Bit-3 and bit-14 MUST be 1\n");
-		tp->cp_cmd |= (1 << 14) | PCIMulRW;
-		RTL_W16(CPlusCmd, tp->cp_cmd);
+		tp->cp_cmd |= (1 << 14);
 	}
 
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+
 	/*
 	 * Undocumented corner. Supposedly:
 	 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
@@ -1836,6 +1898,7 @@ rtl8169_hw_start(struct net_device *dev)
 	RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
 	RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
 	RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
+	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 	udelay(10);
 
@@ -1849,6 +1912,8 @@ rtl8169_hw_start(struct net_device *dev)
 	/* Enable all known interrupts by setting the interrupt mask. */
 	RTL_W16(IntrMask, rtl8169_intr_mask);
 
+	__rtl8169_set_mac_addr(dev, ioaddr);
+
 	netif_start_queue(dev);
 }
 
@@ -2435,6 +2500,10 @@ rtl8169_rx_interrupt(struct net_device *
 				tp->stats.rx_length_errors++;
 			if (status & RxCRC)
 				tp->stats.rx_crc_errors++;
+			if (status & RxFOVF) {
+				rtl8169_schedule_work(dev, rtl8169_reset_task);
+				tp->stats.rx_fifo_errors++;
+			}
 			rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
 		} else {
 			struct sk_buff *skb = tp->Rx_skbuff[entry];
@@ -2724,6 +2793,15 @@ rtl8169_set_rx_mode(struct net_device *d
 	tmp = rtl8169_rx_config | rx_mode |
 	      (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
 
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
+		mc_filter[0] = 0xffffffff;
+		mc_filter[1] = 0xffffffff;
+	}
+
 	RTL_W32(RxConfig, tmp);
 	RTL_W32(MAR0 + 0, mc_filter[0]);
 	RTL_W32(MAR0 + 4, mc_filter[1]);

^ permalink raw reply related

* Re: [PATCH 1/2] e1000: fix netpoll with NAPI
From: Neil Horman @ 2006-06-12  0:13 UTC (permalink / raw)
  To: Jeff Moyer
  Cc: Mitch Williams, Kok, Auke-jan H, Matt Mackall, Garzik, Jeff,
	netdev, Brandeburg, Jesse, Kok, Auke
In-Reply-To: <x49ac8nwo83.fsf@redhat.com>

On Thu, Jun 08, 2006 at 01:29:00PM -0400, Jeff Moyer wrote:
> ==> Regarding Re: [PATCH 1/2] e1000: fix netpoll with NAPI; Mitch Williams <mitch.a.williams@intel.com> adds:
> 
> mitch.a.williams> On Wed, 2006-06-07 at 11:44 -0700, Jeff Moyer wrote:
> >> That patch locks around the tx clean routine.  As such, it doesn't
> >> prevent the problem.
> 
> mitch.a.williams> The call to netif_rx_schedule_prep provides locking
> mitch.a.williams> because it sets the __LINK_STATE_RX_SCHED bit atomically.
> mitch.a.williams> The spinlock around e1000_clean_tx_irq is to protect it
> mitch.a.williams> from other calls to the transmit routine, not NAPI.
> 
> Yes, but what prevents recursion in the poll routine?  Consider that the
> poll routine could end up triggerring a printk (think iptables, here).  In
> that case, you end up calling into netpoll, and if the tx ring is full, we
> call the poll_controller routine.  We've now recursed.
> 
> The poll lock was originally introduced to prevent recursion, not
> concurrent access.
> 
Any further thoughts on this guys?  I still think my last solution solves all of
the netpoll problems, and isn't going to have any noticable impact on
performance.

Regards
Neil

> -Jeff
> -
> 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

^ permalink raw reply

* Remove useless check for null dev from uli526x_interrupt()
From: Dave Jones @ 2006-06-12  0:27 UTC (permalink / raw)
  To: netdev

As we're already dereferencing dev a few lines above, if this
check could ever trigger, we'd have already oopsed.

Signed-off-by: Dave Jones <davej@redhat.com>

--- linux-2.6/drivers/net/tulip/uli526x.c~	2006-06-11 20:24:41.000000000 -0400
+++ linux-2.6/drivers/net/tulip/uli526x.c	2006-06-11 20:25:14.000000000 -0400
@@ -666,11 +666,6 @@ static irqreturn_t uli526x_interrupt(int
 	unsigned long ioaddr = dev->base_addr;
 	unsigned long flags;
 
-	if (!dev) {
-		ULI526X_DBUG(1, "uli526x_interrupt() without DEVICE arg", 0);
-		return IRQ_NONE;
-	}
-
 	spin_lock_irqsave(&db->lock, flags);
 	outl(0, ioaddr + DCR7);
 

^ permalink raw reply

* Re: Problem authenticating using WPA with bcm43xx-softmac
From: Larry Finger @ 2006-06-12  1:11 UTC (permalink / raw)
  To: Johannes Berg; +Cc: netdev
In-Reply-To: <1149867292.3864.30.camel@johannes.berg>

Johannes Berg wrote:
> On Fri, 2006-06-09 at 10:31 -0500, Larry Finger wrote:
> 
>> Do you mean a special dump, or is the kernel debug output and wpa_supplicant debug output sufficient?
> 
> I was thinking of packet dumps but earlier you said you couldn't create
> any so I'm out of ideas for now.

I was finally able to get my second laptop running with bcm43xx so I could get packet dumps. When I 
analyzed them, the Association Response packet contained the following information:

"Association denied due to requesting station not supporting short preamble operation (0x0013)"

I think this is a bug in the code on my WRT54G V5 and I will report it to Linksys; however, in the 
meantime, I am able to connect using the following _ugly_ hack to softmac_assoc_req and 
softmac_reassoc_req:

diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
index cc6cd56..a1d0c10 100644
--- a/net/ieee80211/softmac/ieee80211softmac_io.c
+++ b/net/ieee80211/softmac/ieee80211softmac_io.c
@@ -199,6 +199,8 @@ ieee80211softmac_assoc_req(struct ieee80
         (*pkt)->capability |= mac->ieee->short_slot ?
                         cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
          */
+       /* add short preamble operation capability */
+       (*pkt)->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
         (*pkt)->capability |= mac->ieee->sec.level ? cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
         /* Fill in Listen Interval (?) */
         (*pkt)->listen_interval = cpu_to_le16(10);
@@ -247,6 +249,8 @@ ieee80211softmac_reassoc_req(struct ieee
         (*pkt)->capability |= mac->ieee->short_slot ?
                         cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
          */
+       /* add short preamble operation capability */
+       (*pkt)->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
         (*pkt)->capability |= mac->ieee->sec.level ?
                         cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;


I expect that softmac should be listening to the driver as to whether this capability is available; 
however, I'm now up and running once again.

Larry

^ permalink raw reply related

* Re: [PATCH netdev-2.6#upstream] net: au1000_eth: PHY framework conversion
From: Jeff Garzik @ 2006-06-12  3:19 UTC (permalink / raw)
  To: Herbert Valerio Riedel; +Cc: netdev, linux-mips, ppopov, sshtylyov, ralf
In-Reply-To: <E1Fli0i-0006o2-Tb@fencepost.gnu.org>

Herbert Valerio Riedel wrote:
> convert au1000_eth driver to use PHY framework and garbage collected
> functions and identifiers that became unused/obsolete in the process
> 
> Signed-off-by: Herbert Valerio Riedel <hvr@gnu.org>

applied



^ permalink raw reply

* Re: [PATCH] [IrDA] irda-usb.c: STIR421x cleanups
From: David Miller @ 2006-06-12  3:56 UTC (permalink / raw)
  To: samuel; +Cc: netdev, irda-users, nfedchik
In-Reply-To: <20060612061235.GB3736@sortiz.org>

From: Samuel Ortiz <samuel@sortiz.org>
Date: Mon, 12 Jun 2006 09:12:35 +0300

> This patch is for the net-2.6.18 tree.
> It cleans the STIR421x part of the irda-usb code. We also no longer try to
> load all existing firmwares but only the matching one (according to the USB
> id we get from the dongle).
> 
> Signed-off-by: Nick Fedchik <nfedchik@atlantic-link.com.ua>
> Signed-off-by: Samuel Ortiz <samuel@sortiz.org>

Applied, thanks a lot.

^ permalink raw reply

* Re: [PATCH] bnx2: endian fixes
From: David Miller @ 2006-06-12  3:57 UTC (permalink / raw)
  To: adobriyan; +Cc: netdev, mchan
In-Reply-To: <20060610115250.GA7268@martell.zuzino.mipt.ru>

From: Alexey Dobriyan <adobriyan@gmail.com>
Date: Sat, 10 Jun 2006 15:52:51 +0400

> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>

Applied, thanks Alexey.


^ 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