public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] IBM Lanstreamer bugfixes (round 3)
@ 2002-02-04 17:16 Kent Yoder
  0 siblings, 0 replies; 15+ messages in thread
From: Kent Yoder @ 2002-02-04 17:16 UTC (permalink / raw)
  To: jgarzik; +Cc: linux-kernel, marcelo

[-- Attachment #1: Type: TEXT/PLAIN, Size: 601 bytes --]


 Sorry, in round 2 I neglected to #include version.h.  Please ignore round 
2.

  Below is the old changelog, with this now added:

 * #include linux/version.h for in-kernel support

--------------

  Changes made:

 * No more magic numbers, all come from pci.h
 * no more udelay()'s, which covered up PCI posting effects
 * got rid of a __u8/__u16 here and there for u8/u16
 * ioctl code disabled for kernel >= 2.5 (now with version.h, too!)
 * bounded the number of times we could loop inside the interrupt function
 * spin_lock_irqsave/restore in open()/close()
 * better formatting

Thanks,
Kent

[-- Attachment #2: Type: APPLICATION/x-gzip, Size: 4883 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH] IBM Lanstreamer bugfixes (round 3)
@ 2002-02-15 21:44 Kent Yoder
  2002-02-16 11:12 ` Jeff Garzik
  0 siblings, 1 reply; 15+ messages in thread
From: Kent Yoder @ 2002-02-15 21:44 UTC (permalink / raw)
  To: jgarzik; +Cc: linux-kernel, marcelo

[-- Attachment #1: Type: TEXT/PLAIN, Size: 734 bytes --]


Second try..  :-)

  When and if this passes code inspection, it should be included in 2.4 and 
2.5.  

Thanks,
Kent

-------------

 Sorry, in round 2 I neglected to #include version.h.  Please ignore round 
2.

  Below is the old changelog, with this now added:

 * #include linux/version.h for in-kernel support

--------------

  Changes made:

 * No more magic numbers, all come from pci.h
 * no more udelay()'s, which covered up PCI posting effects
 * got rid of a __u8/__u16 here and there for u8/u16
 * ioctl code disabled for kernel >= 2.5 (now with version.h, too!)
 * bounded the number of times we could loop inside the interrupt function
 * spin_lock_irqsave/restore in open()/close()
 * better formatting

Thanks,
Kent

[-- Attachment #2: Type: APPLICATION/X-GZIP, Size: 4883 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-02-15 21:44 [PATCH] IBM Lanstreamer bugfixes (round 3) Kent Yoder
@ 2002-02-16 11:12 ` Jeff Garzik
  2002-03-04 16:51   ` Kent Yoder
  0 siblings, 1 reply; 15+ messages in thread
From: Jeff Garzik @ 2002-02-16 11:12 UTC (permalink / raw)
  To: Kent Yoder; +Cc: linux-kernel, marcelo

Sorry I've been slow to respond... I'm going to apply your driver
locally, so you and I have a good baseline to work with, but there are
some small issues related to PCI initialization that I want to review
and discuss with you, before submitting officially to Marcelo...

(another message should follow during the upcoming work week)

Regards,

	Jeff


-- 
Jeff Garzik      | "Why is it that attractive girls like you
Building 1024    |  always seem to have a boyfriend?"
MandrakeSoft     | "Because I'm a nympho that owns a brewery?"
                 |             - BBC TV show "Coupling"

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-02-16 11:12 ` Jeff Garzik
@ 2002-03-04 16:51   ` Kent Yoder
  2002-03-04 17:04     ` Jeff Garzik
  0 siblings, 1 reply; 15+ messages in thread
From: Kent Yoder @ 2002-03-04 16:51 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel, marcelo


  Jeff,

	I have a feeling you're talking about this section:

>  pci_write_config_byte (pdev, PCI_CACHE_LINE_SIZE, cls);
>  pci_read_config_word (pdev, PCI_COMMAND, &pcr);
>
>  /* Turn off Fast B2B enable */
>  pcr &= ~PCI_COMMAND_FAST_BACK;
>  /* Turn on SERR# enable and others */
>  pcr |= (PCI_COMMAND_SERR | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
>          PCI_COMMAND_IO   | PCI_COMMAND_MEMORY);
>
>  pci_write_config_word (pdev, PCI_COMMAND, pcr);
>  pci_read_config_word (pdev, PCI_COMMAND, &pcr);

  Basically, this section exists from a time when I had no idea why the
card was behaving badly, so I was trying everything :-).

  So, after revisiting them, I see that setting cache line size to 0 and
then using memory write and invalidate doesn't make any sense.  I'm thinking 
both can just be dropped, since I haven't seen any change in performance on 
the machines I've made netperf runs with (a constant 14.7 Mb/s) after 
changing these.

  Any thoughts?

Kent

Thus Spake Jeff Garzik:

>Sorry I've been slow to respond... I'm going to apply your driver
>locally, so you and I have a good baseline to work with, but there are
>some small issues related to PCI initialization that I want to review
>and discuss with you, before submitting officially to Marcelo...
>
>(another message should follow during the upcoming work week)
>
>Regards,
>
>	Jeff
>
>
>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 16:51   ` Kent Yoder
@ 2002-03-04 17:04     ` Jeff Garzik
  2002-03-04 17:27       ` David Dillow
  2002-03-04 18:58       ` Kent Yoder
  0 siblings, 2 replies; 15+ messages in thread
From: Jeff Garzik @ 2002-03-04 17:04 UTC (permalink / raw)
  To: Kent Yoder; +Cc: linux-kernel, marcelo

Kent Yoder wrote:
> 
>   Jeff,
> 
>         I have a feeling you're talking about this section:
> 
> >  pci_write_config_byte (pdev, PCI_CACHE_LINE_SIZE, cls);
> >  pci_read_config_word (pdev, PCI_COMMAND, &pcr);
> >
> >  /* Turn off Fast B2B enable */
> >  pcr &= ~PCI_COMMAND_FAST_BACK;
> >  /* Turn on SERR# enable and others */
> >  pcr |= (PCI_COMMAND_SERR | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
> >          PCI_COMMAND_IO   | PCI_COMMAND_MEMORY);
> >
> >  pci_write_config_word (pdev, PCI_COMMAND, pcr);
> >  pci_read_config_word (pdev, PCI_COMMAND, &pcr);
> 
>   Basically, this section exists from a time when I had no idea why the
> card was behaving badly, so I was trying everything :-).
> 
>   So, after revisiting them, I see that setting cache line size to 0 and
> then using memory write and invalidate doesn't make any sense.  I'm thinking
> both can just be dropped, since I haven't seen any change in performance on
> the machines I've made netperf runs with (a constant 14.7 Mb/s) after
> changing these.

I agree to the first part :)

Set cache line size just like drivers/net/acenic.c does, and enable
memory-write-invalidate...

	Jeff


-- 
Jeff Garzik      |
Building 1024    |
MandrakeSoft     | Choose life.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 17:04     ` Jeff Garzik
@ 2002-03-04 17:27       ` David Dillow
  2002-03-04 17:46         ` Jeff Garzik
  2002-03-04 18:58       ` Kent Yoder
  1 sibling, 1 reply; 15+ messages in thread
From: David Dillow @ 2002-03-04 17:27 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel

Jeff Garzik wrote:
> Set cache line size just like drivers/net/acenic.c does, and enable
> memory-write-invalidate...

Does this mean the setup pci_enable_device() does on the cache line size
is not sufficient?

I ask, because I've been relying on it for a driver I'm working on;
should I be setting this as acenic does? It would seem that this is
something many drivers would need to do...

Thanks,
Dave Dillow
dillowd@y12.doe.gov

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 17:27       ` David Dillow
@ 2002-03-04 17:46         ` Jeff Garzik
  2002-03-04 18:45           ` David Dillow
  0 siblings, 1 reply; 15+ messages in thread
From: Jeff Garzik @ 2002-03-04 17:46 UTC (permalink / raw)
  To: David Dillow; +Cc: linux-kernel

David Dillow wrote:
> 
> Jeff Garzik wrote:
> > Set cache line size just like drivers/net/acenic.c does, and enable
> > memory-write-invalidate...
> 
> Does this mean the setup pci_enable_device() does on the cache line size
> is not sufficient?

pci_enable_device doesn't touch the PCI_COMMAND_INVALIDATE bit at all...

> I ask, because I've been relying on it for a driver I'm working on;
> should I be setting this as acenic does? It would seem that this is
> something many drivers would need to do...

Yes, acenic is the code to copy, for setting that up.

I need to create a pci_set_mwi() helper function.

	Jeff



-- 
Jeff Garzik      |
Building 1024    |
MandrakeSoft     | Choose life.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 17:46         ` Jeff Garzik
@ 2002-03-04 18:45           ` David Dillow
  2002-03-04 18:52             ` Jeff Garzik
  0 siblings, 1 reply; 15+ messages in thread
From: David Dillow @ 2002-03-04 18:45 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel

Jeff Garzik wrote:
> 
> David Dillow wrote:
> >
> > Jeff Garzik wrote:
> > > Set cache line size just like drivers/net/acenic.c does, and enable
> > > memory-write-invalidate...
> >
> > Does this mean the setup pci_enable_device() does on the cache line size
> > is not sufficient?
> 
> pci_enable_device doesn't touch the PCI_COMMAND_INVALIDATE bit at all...

Right, I was talking more about the cache line size... is it sufficient
for that?

As for PCI_COMMAND_INVALIDATE, what does that do for me; my PCI spec
isn't handy....

> > I ask, because I've been relying on it for a driver I'm working on;
> > should I be setting this as acenic does? It would seem that this is
> > something many drivers would need to do...
> 
> Yes, acenic is the code to copy, for setting that up.

INVALIDATE, or cache line size?

Thanks,
Dave Dillow
dillowd@y12.doe.gov

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 18:45           ` David Dillow
@ 2002-03-04 18:52             ` Jeff Garzik
  2002-03-04 19:02               ` David Dillow
  0 siblings, 1 reply; 15+ messages in thread
From: Jeff Garzik @ 2002-03-04 18:52 UTC (permalink / raw)
  To: David Dillow; +Cc: linux-kernel

David Dillow wrote:
> 
> Jeff Garzik wrote:
> >
> > David Dillow wrote:
> > >
> > > Jeff Garzik wrote:
> > > > Set cache line size just like drivers/net/acenic.c does, and enable
> > > > memory-write-invalidate...
> > >
> > > Does this mean the setup pci_enable_device() does on the cache line size
> > > is not sufficient?
> >
> > pci_enable_device doesn't touch the PCI_COMMAND_INVALIDATE bit at all...
> 
> Right, I was talking more about the cache line size... is it sufficient
> for that?

pci_enable_device doesn't touch PCI_COMMAND_INVALIDATE either, on most
platforms (particularly ia32, i.e. the popular one :))


> As for PCI_COMMAND_INVALIDATE, what does that do for me; my PCI spec
> isn't handy....

Enables Memory-Write-Invalidate (MWI).


> > > I ask, because I've been relying on it for a driver I'm working on;
> > > should I be setting this as acenic does? It would seem that this is
> > > something many drivers would need to do...
> >
> > Yes, acenic is the code to copy, for setting that up.
> 
> INVALIDATE, or cache line size?

both.

	Jeff



-- 
Jeff Garzik      |
Building 1024    |
MandrakeSoft     | Choose life.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 17:04     ` Jeff Garzik
  2002-03-04 17:27       ` David Dillow
@ 2002-03-04 18:58       ` Kent Yoder
  2002-03-04 19:10         ` Jeff Garzik
  1 sibling, 1 reply; 15+ messages in thread
From: Kent Yoder @ 2002-03-04 18:58 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel, marcelo

Thus Spake Jeff Garzik:

>I agree to the first part :)
>
>Set cache line size just like drivers/net/acenic.c does, and enable
>memory-write-invalidate...
>

  Ok, hopefully below is the section you were referring to:

-------

  pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cls);
  cls <<= 2;
  if (cls != SMP_CACHE_BYTES) {
         printk(KERN_INFO "  PCI cache line size set incorrectly "
                "(%i bytes) by BIOS/FW, ", cls);
         if (cls > SMP_CACHE_BYTES)
                printk("expecting %i\n", SMP_CACHE_BYTES);
         else {
                printk("correcting to %i\n", SMP_CACHE_BYTES);
                pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
                                      SMP_CACHE_BYTES >> 2);
         }
  }
  
  pci_read_config_word (pdev, PCI_COMMAND, &pcr);

  /* Turn off Fast B2B enable */
  pcr &= ~PCI_COMMAND_FAST_BACK;
  /* Turn on SERR# enable and others */
  pcr |= (PCI_COMMAND_SERR | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
          PCI_COMMAND_IO   | PCI_COMMAND_MEMORY);

  pci_write_config_word (pdev, PCI_COMMAND, pcr);
  pci_read_config_word (pdev, PCI_COMMAND, &pcr);

------

 Out of curiosity, does it in fact make sense to use memory write and 
invalidate and set cache line size to 0 in some cases?  This seems to go 
against the PCI spec, which, if I'm reading it correctly, says that memory 
write and invalidate is the same as a memory write, but it guarantees that
at least 1 cache line will be written.  So, setting cacheline size =0 would 
negate this effect(?)  

Kent

>
>	Jeff
>
>
>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 18:52             ` Jeff Garzik
@ 2002-03-04 19:02               ` David Dillow
  2002-03-04 19:12                 ` Jeff Garzik
  0 siblings, 1 reply; 15+ messages in thread
From: David Dillow @ 2002-03-04 19:02 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel

Jeff Garzik wrote:
> 
> David Dillow wrote:
> > Right, I was talking more about the cache line size... is it sufficient
> > for that?
> 
> pci_enable_device doesn't touch PCI_COMMAND_INVALIDATE either, on most
> platforms (particularly ia32, i.e. the popular one :))

Doh! I see my mistake; I was reading pdev_enable_device() which sets it
to L1_CACHE_BYTES. And a quick grep shows me that it is called from
pci_assign_unassigned_resources(), which is not called on ia32 as far as
I can see....

This seems to be a common thing to set; shouldn't we have a helper for
it as well, or have pci_enable_device() do it?

Thanks,
Dave Dillow
dillowd@y12.doe.gov

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 18:58       ` Kent Yoder
@ 2002-03-04 19:10         ` Jeff Garzik
  2002-03-05 14:59           ` pjd
  2002-03-05 15:37           ` Kent Yoder
  0 siblings, 2 replies; 15+ messages in thread
From: Jeff Garzik @ 2002-03-04 19:10 UTC (permalink / raw)
  To: Kent Yoder; +Cc: linux-kernel, marcelo

Kent Yoder wrote:
>   Ok, hopefully below is the section you were referring to:
> 
> -------
> 
>   pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cls);
>   cls <<= 2;
>   if (cls != SMP_CACHE_BYTES) {
>          printk(KERN_INFO "  PCI cache line size set incorrectly "
>                 "(%i bytes) by BIOS/FW, ", cls);
>          if (cls > SMP_CACHE_BYTES)
>                 printk("expecting %i\n", SMP_CACHE_BYTES);
>          else {
>                 printk("correcting to %i\n", SMP_CACHE_BYTES);
>                 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
>                                       SMP_CACHE_BYTES >> 2);
>          }
>   }

this gets cache line size correct

>   /* Turn off Fast B2B enable */
>   pcr &= ~PCI_COMMAND_FAST_BACK;
>   /* Turn on SERR# enable and others */
>   pcr |= (PCI_COMMAND_SERR | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
>           PCI_COMMAND_IO   | PCI_COMMAND_MEMORY);
> 
>   pci_write_config_word (pdev, PCI_COMMAND, pcr);
>   pci_read_config_word (pdev, PCI_COMMAND, &pcr);

You only need to worry about the PCI_COMMAND_INVALIDATE bit here, unless
your chip requires other setup, or you care to handle PCI hard errors in
the driver.

>  Out of curiosity, does it in fact make sense to use memory write and
> invalidate and set cache line size to 0 in some cases?  This seems to go
> against the PCI spec, which, if I'm reading it correctly, says that memory
> write and invalidate is the same as a memory write, but it guarantees that
> at least 1 cache line will be written.  So, setting cacheline size =0 would
> negate this effect(?)

The rule is, never ever enable MWI if cache line size is zero.

MWI -does- make a difference in performance, though you may need to
check lanstreamer docs to see if there is a chip-specific MWI bit you
need to enable, over and above the PCI_COMMAND bit.

	Jeff


-- 
Jeff Garzik      |
Building 1024    |
MandrakeSoft     | Choose life.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 19:02               ` David Dillow
@ 2002-03-04 19:12                 ` Jeff Garzik
  0 siblings, 0 replies; 15+ messages in thread
From: Jeff Garzik @ 2002-03-04 19:12 UTC (permalink / raw)
  To: David Dillow; +Cc: linux-kernel

David Dillow wrote:
> Jeff Garzik wrote:
> > pci_enable_device doesn't touch PCI_COMMAND_INVALIDATE either, on most
> > platforms (particularly ia32, i.e. the popular one :))

> This seems to be a common thing to set; shouldn't we have a helper for
> it as well, or have pci_enable_device() do it?

Quoting my message to you from a couple hours ago:
> I need to create a pci_set_mwi() helper function.

	Jeff



-- 
Jeff Garzik      |
Building 1024    |
MandrakeSoft     | Choose life.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 19:10         ` Jeff Garzik
@ 2002-03-05 14:59           ` pjd
  2002-03-05 15:37           ` Kent Yoder
  1 sibling, 0 replies; 15+ messages in thread
From: pjd @ 2002-03-05 14:59 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Kent Yoder, linux-kernel, marcelo

Jeff Garzik wrote:
> 
> MWI -does- make a difference in performance, though you may need to
> check lanstreamer docs to see if there is a chip-specific MWI bit you
> need to enable, over and above the PCI_COMMAND bit.

My experience - which is 2-3 years old now - is that many BIOSes will
enable MWI for you.  Which makes it very easy to forget to do this,
and then have it discovered by your customers who have machines that
don't set MWI...

............................................................................
 Peter Desnoyers 
 162 Pleasant St.         (617) 661-1979          pjd@fred.cambridge.ma.us
 Cambridge, Mass. 02139


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH] IBM Lanstreamer bugfixes (round 3)
  2002-03-04 19:10         ` Jeff Garzik
  2002-03-05 14:59           ` pjd
@ 2002-03-05 15:37           ` Kent Yoder
  1 sibling, 0 replies; 15+ messages in thread
From: Kent Yoder @ 2002-03-05 15:37 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel, marcelo


  Ok, below is the current patch including the MWI changes as well as adding
printk log levels (as suggested by someone).

*fingers crossed* :-)

Kent

diff -urN linux-2.4.17.vanilla/drivers/net/tokenring/lanstreamer.c linux-2.4.17/drivers/net/tokenring/lanstreamer.c
--- linux-2.4.17.vanilla/drivers/net/tokenring/lanstreamer.c	Mon Feb  4 11:09:30 2002
+++ linux-2.4.17/drivers/net/tokenring/lanstreamer.c	Mon Mar  4 17:40:16 2002
@@ -60,6 +60,11 @@
  *		malloc free checks, reviewed code. <alan@redhat.com>
  *  03/13/00 - Added spinlocks for smp
  *  03/08/01 - Added support for module_init() and module_exit()
+ *  08/15/01 - Added ioctl() functionality for debugging, changed netif_*_queue
+ *             calls and other incorrectness - Kent Yoder <yoder1@us.ibm.com>
+ *  11/05/01 - Restructured the interrupt function, added delays, reduced the 
+ *             the number of TX descriptors to 1, which together can prevent 
+ *             the card from locking up the box - <yoder1@us.ibm.com>
  *  
  *  To Do:
  *
@@ -84,6 +89,14 @@
 
 #define STREAMER_NETWORK_MONITOR 0
 
+/* #define CONFIG_PROC_FS */
+
+/*
+ *  Allow or disallow ioctl's for debugging
+ */
+
+#define STREAMER_IOCTL 0
+
 #include <linux/config.h>
 #include <linux/module.h>
 
@@ -105,6 +118,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
+#include <linux/version.h>
 #include <net/checksum.h>
 
 #include <asm/io.h>
@@ -121,7 +135,8 @@
  * Official releases will only have an a.b.c version number format.
  */
 
-static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan";
+static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan\n"
+                        "              v0.5.1 03/04/02 - Kent Yoder";
 
 static struct pci_device_id streamer_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,},
@@ -175,6 +190,10 @@
 MODULE_PARM(message_level,
 	    "1-" __MODULE_STRING(STREAMER_MAX_ADAPTERS) "i");
 
+#if STREAMER_IOCTL
+static int streamer_ioctl(struct net_device *, struct ifreq *, int);
+#endif
+
 static int streamer_reset(struct net_device *dev);
 static int streamer_open(struct net_device *dev);
 static int streamer_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -206,6 +225,8 @@
   __u32 mmio_start, mmio_end, mmio_flags, mmio_len;
   int rc=0;
   static int card_no=-1;
+  u16 pcr;
+  u8 cls = 0;
 
 #if STREAMER_DEBUG
   printk("lanstreamer::streamer_init_one, entry pdev %p\n",pdev);
@@ -281,7 +302,11 @@
 			dev->hard_start_xmit = &streamer_xmit;
 			dev->change_mtu = &streamer_change_mtu;
 			dev->stop = &streamer_close;
+#if STREAMER_IOCTL
+			dev->do_ioctl = &streamer_ioctl;
+#else
 			dev->do_ioctl = NULL;
+#endif
 			dev->set_multicast_list = &streamer_set_rx_mode;
 			dev->get_stats = &streamer_get_stats;
 			dev->set_mac_address = &streamer_set_mac_address;
@@ -303,6 +328,27 @@
 
   spin_lock_init(&streamer_priv->streamer_lock);
   
+  pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cls);
+  cls <<= 2;
+  if (cls != SMP_CACHE_BYTES) {
+         printk(KERN_INFO "  PCI cache line size set incorrectly "
+                "(%i bytes) by BIOS/FW, ", cls);
+         if (cls > SMP_CACHE_BYTES)
+                printk("expecting %i\n", SMP_CACHE_BYTES);
+         else {
+                printk("correcting to %i\n", SMP_CACHE_BYTES);
+                pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+                                      SMP_CACHE_BYTES >> 2);
+         }
+  }
+
+  pci_read_config_word (pdev, PCI_COMMAND, &pcr);
+
+  pcr |= (PCI_COMMAND_INVALIDATE | PCI_COMMAND_SERR);
+
+  pci_write_config_word (pdev, PCI_COMMAND, pcr);
+  pci_read_config_word (pdev, PCI_COMMAND, &pcr);
+
   printk("%s \n", version);
   printk("%s: %s. I/O at %hx, MMIO at %p, using irq %d\n",dev->name,
 	 streamer_priv->streamer_card_name,
@@ -403,6 +449,7 @@
 	printk("GPR: %x\n", readw(streamer_mmio + GPR));
 	printk("SISRMASK: %x\n", readw(streamer_mmio + SISR_MASK));
 #endif
+	writew(readw(streamer_mmio + BCTL) | (BCTL_RX_FIFO_8 | BCTL_TX_FIFO_8), streamer_mmio + BCTL );
 
 	if (streamer_priv->streamer_ring_speed == 0) {	/* Autosense */
 		writew(readw(streamer_mmio + GPR) | GPR_AUTOSENSE,
@@ -558,8 +605,6 @@
 	do {
 		int i;
 
-		save_flags(flags);
-		cli();
 		for (i = 0; i < SRB_COMMAND_SIZE; i += 2) {
 			writew(0, streamer_mmio + LAPDINC);
 		}
@@ -599,11 +644,12 @@
 		}
 		printk("\n");
 #endif
-
+		spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
 		streamer_priv->srb_queued = 1;
 
 		/* signal solo that SRB command has been issued */
 		writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM);
+		spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags);
 
 		while (streamer_priv->srb_queued) {
 			interruptible_sleep_on_timeout(&streamer_priv->srb_wait, 5 * HZ);
@@ -617,7 +663,6 @@
 				break;
 			}
 		}
-		restore_flags(flags);
 
 #if STREAMER_DEBUG
 		printk("SISR_MASK: %x\n", readw(streamer_mmio + SISR_MASK));
@@ -767,9 +812,12 @@
 		streamer_priv->streamer_tx_ring[i].bufcnt_framelen = 0;
 		streamer_priv->streamer_tx_ring[i].buffer = 0;
 		streamer_priv->streamer_tx_ring[i].buflen = 0;
+		streamer_priv->streamer_tx_ring[i].rsvd1 = 0;
+		streamer_priv->streamer_tx_ring[i].rsvd2 = 0;
+		streamer_priv->streamer_tx_ring[i].rsvd3 = 0;
 	}
 	streamer_priv->streamer_tx_ring[STREAMER_TX_RING_SIZE - 1].forward =
-					virt_to_bus(&streamer_priv->streamer_tx_ring[0]);;
+					virt_to_bus(&streamer_priv->streamer_tx_ring[0]);
 
 	streamer_priv->free_tx_ring_entries = STREAMER_TX_RING_SIZE;
 	streamer_priv->tx_ring_free = 0;	/* next entry in tx ring to use */
@@ -941,37 +989,30 @@
 	__u8 *streamer_mmio = streamer_priv->streamer_mmio;
 	__u16 sisr;
 	__u16 misr;
-	__u16 sisrmask;
+	u8 max_intr = MAX_INTR;
 
-	sisrmask = SISR_MI;
-	writew(~sisrmask, streamer_mmio + SISR_MASK_RUM);
+	spin_lock(&streamer_priv->streamer_lock);
 	sisr = readw(streamer_mmio + SISR);
-	writew(~sisr, streamer_mmio + SISR_RUM);
-	misr = readw(streamer_mmio + MISR_RUM);
-	writew(~misr, streamer_mmio + MISR_RUM);
 
-	if (!sisr) 
-	{		/* Interrupt isn't for us */
-  	        writew(~misr,streamer_mmio+MISR_RUM);
-		return;
-	}
+	while((sisr & (SISR_MI | SISR_SRB_REPLY | SISR_ADAPTER_CHECK | SISR_ASB_FREE | 
+		       SISR_ARB_CMD | SISR_TRB_REPLY | SISR_PAR_ERR | SISR_SERR_ERR))
+               && (max_intr > 0)) {
 
-	spin_lock(&streamer_priv->streamer_lock);
+		if(sisr & SISR_PAR_ERR) {
+			writew(~SISR_PAR_ERR, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
+		}
 
-	if ((sisr & (SISR_SRB_REPLY | SISR_ADAPTER_CHECK | SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY))
-	    || (misr & (MISR_TX2_EOF | MISR_RX_NOBUF | MISR_RX_EOF))) {
-		if (sisr & SISR_SRB_REPLY) {
-			if (streamer_priv->srb_queued == 1) {
-				wake_up_interruptible(&streamer_priv->srb_wait);
-			} else if (streamer_priv->srb_queued == 2) {
-				streamer_srb_bh(dev);
-			}
-			streamer_priv->srb_queued = 0;
+		else if(sisr & SISR_SERR_ERR) {
+			writew(~SISR_SERR_ERR, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
 		}
-		/* SISR_SRB_REPLY */
+
+		else if(sisr & SISR_MI) {
+			misr = readw(streamer_mmio + MISR_RUM);
+
 		if (misr & MISR_TX2_EOF) {
-			while (streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) 
-			{
+				while(streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) {
 				streamer_priv->tx_ring_last_status = (streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1);
 				streamer_priv->free_tx_ring_entries++;
 				streamer_priv->streamer_stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len;
@@ -981,6 +1022,9 @@
 				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].status = 0;
 				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].bufcnt_framelen = 0;
 				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buflen = 0;
+				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd1 = 0;
+				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd2 = 0;
+				streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd3 = 0;
 			}
 			netif_wake_queue(dev);
 		}
@@ -989,7 +1033,30 @@
 			streamer_rx(dev);
 		}
 		/* MISR_RX_EOF */
-		if (sisr & SISR_ADAPTER_CHECK) {
+
+			if (misr & MISR_RX_NOBUF) {
+				/* According to the documentation, we don't have to do anything,  
+                                 * but trapping it keeps it out of /var/log/messages.  
+                                 */
+			}		/* SISR_RX_NOBUF */
+
+			writew(~misr, streamer_mmio + MISR_RUM);
+			(void)readw(streamer_mmio + MISR_RUM);
+		}
+
+		else if (sisr & SISR_SRB_REPLY) {
+			if (streamer_priv->srb_queued == 1) {
+				wake_up_interruptible(&streamer_priv->srb_wait);
+			} else if (streamer_priv->srb_queued == 2) {
+				streamer_srb_bh(dev);
+			}
+			streamer_priv->srb_queued = 0;
+
+			writew(~SISR_SRB_REPLY, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
+		}
+
+		else if (sisr & SISR_ADAPTER_CHECK) {
 			printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
 			writel(readl(streamer_mmio + LAPWWO), streamer_mmio + LAPA);
 			printk(KERN_WARNING "%s: Words %x:%x:%x:%x:\n",
@@ -1001,38 +1068,37 @@
 		}
 
 		/* SISR_ADAPTER_CHECK */
-		if (sisr & SISR_ASB_FREE) {
+		else if (sisr & SISR_ASB_FREE) {
 			/* Wake up anything that is waiting for the asb response */
 			if (streamer_priv->asb_queued) {
 				streamer_asb_bh(dev);
 			}
+			writew(~SISR_ASB_FREE, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
 		}
 		/* SISR_ASB_FREE */
-		if (sisr & SISR_ARB_CMD) {
+		else if (sisr & SISR_ARB_CMD) {
 			streamer_arb_cmd(dev);
+			writew(~SISR_ARB_CMD, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
 		}
 		/* SISR_ARB_CMD */
-		if (sisr & SISR_TRB_REPLY) {
+		else if (sisr & SISR_TRB_REPLY) {
 			/* Wake up anything that is waiting for the trb response */
 			if (streamer_priv->trb_queued) {
 				wake_up_interruptible(&streamer_priv->
 						      trb_wait);
 			}
 			streamer_priv->trb_queued = 0;
+			writew(~SISR_TRB_REPLY, streamer_mmio + SISR_RUM);
+			(void)readw(streamer_mmio + SISR_RUM);
 		}
 		/* SISR_TRB_REPLY */
-		if (misr & MISR_RX_NOBUF) {
-			/* According to the documentation, we don't have to do anything, but trapping it keeps it out of
-			   /var/log/messages.  */
-		}		/* SISR_RX_NOBUF */
-	} else {
-		printk(KERN_WARNING "%s: Unexpected interrupt: %x\n",
-		       dev->name, sisr);
-		printk(KERN_WARNING "%s: SISR_MASK: %x\n", dev->name,
-		       readw(streamer_mmio + SISR_MASK));
-	}			/* One if the interrupts we want */
 
-	writew(SISR_MI, streamer_mmio + SISR_MASK_SUM);
+		sisr = readw(streamer_mmio + SISR);
+		max_intr--;
+	} /* while() */		
+
 	spin_unlock(&streamer_priv->streamer_lock) ; 
 }
 
@@ -1044,13 +1110,16 @@
 	unsigned long flags ;
 
 	spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
-	netif_stop_queue(dev);
 
 	if (streamer_priv->free_tx_ring_entries) {
 		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].status = 0;
-		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00010000 | skb->len;
+		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00020000 | skb->len;
 		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buffer = virt_to_bus(skb->data);
+		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd1 = skb->len;
+		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd2 = 0;
+		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd3 = 0;
 		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buflen = skb->len;
+
 		streamer_priv->tx_ring_skb[streamer_priv->tx_ring_free] = skb;
 		streamer_priv->free_tx_ring_entries--;
 #if STREAMER_DEBUG_PACKETS
@@ -1067,12 +1136,13 @@
 #endif
 
 		writel(virt_to_bus (&streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free]),streamer_mmio + TX2LFDA);
+		(void)readl(streamer_mmio + TX2LFDA);
 
 		streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1);
-		netif_wake_queue(dev);
 		spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
 		return 0;
 	} else {
+	        netif_stop_queue(dev);
 	        spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
 		return 1;
 	}
@@ -1092,12 +1162,13 @@
 	writew(htons(SRB_CLOSE_ADAPTER << 8),streamer_mmio+LAPDINC);
 	writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);
 
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
 
 	streamer_priv->srb_queued = 1;
 	writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM);
 
+	spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags);
+
 	while (streamer_priv->srb_queued) 
 	{
 		interruptible_sleep_on_timeout(&streamer_priv->srb_wait,
@@ -1114,7 +1185,6 @@
 		}
 	}
 
-	restore_flags(flags);
 	streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1);
 
 	for (i = 0; i < STREAMER_RX_RING_SIZE; i++) {
@@ -1808,6 +1878,64 @@
 #endif
 #endif
 
+#if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static int streamer_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+        int i;
+	struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv;
+	u8 *streamer_mmio = streamer_priv->streamer_mmio;
+
+	switch(cmd) {
+	case IOCTL_SISR_MASK:
+		writew(SISR_MI, streamer_mmio + SISR_MASK_SUM);
+		break;
+	case IOCTL_SPIN_LOCK_TEST:
+	        printk(KERN_INFO "spin_lock() called.\n");
+		spin_lock(&streamer_priv->streamer_lock);
+		spin_unlock(&streamer_priv->streamer_lock);
+		printk(KERN_INFO "spin_unlock() finished.\n");
+		break;
+	case IOCTL_PRINT_BDAS:
+	        printk(KERN_INFO "bdas: RXBDA: %x RXLBDA: %x TX2FDA: %x TX2LFDA: %x\n",
+		       readw(streamer_mmio + RXBDA),
+		       readw(streamer_mmio + RXLBDA),
+		       readw(streamer_mmio + TX2FDA),
+		       readw(streamer_mmio + TX2LFDA));
+		break;
+	case IOCTL_PRINT_REGISTERS:
+	        printk(KERN_INFO "registers:\n");
+		printk(KERN_INFO "SISR: %04x MISR: %04x LISR: %04x BCTL: %04x BMCTL: %04x\nmask  %04x mask  %04x\n", 
+		       readw(streamer_mmio + SISR),
+		       readw(streamer_mmio + MISR_RUM),
+		       readw(streamer_mmio + LISR),
+		       readw(streamer_mmio + BCTL),
+		       readw(streamer_mmio + BMCTL_SUM),
+		       readw(streamer_mmio + SISR_MASK),
+		       readw(streamer_mmio + MISR_MASK));
+		break;
+	case IOCTL_PRINT_RX_BUFS:
+	        printk(KERN_INFO "Print rx bufs:\n");
+		for(i=0; i<STREAMER_RX_RING_SIZE; i++)
+		        printk(KERN_INFO "rx_ring %d status: 0x%x\n", i, 
+			       streamer_priv->streamer_rx_ring[i].status);
+		break;
+	case IOCTL_PRINT_TX_BUFS:
+	        printk(KERN_INFO "Print tx bufs:\n");
+		for(i=0; i<STREAMER_TX_RING_SIZE; i++)
+		        printk(KERN_INFO "tx_ring %d status: 0x%x\n", i, 
+			       streamer_priv->streamer_tx_ring[i].status);
+		break;
+	case IOCTL_RX_CMD:
+	        streamer_rx(dev);
+		printk(KERN_INFO "Sent rx command.\n");
+		break;
+	default:
+	        printk(KERN_INFO "Bad ioctl!\n");
+	}
+	return 0;
+}
+#endif
+
 static struct pci_driver streamer_pci_driver = {
   name:       "lanstreamer",
   id_table:   streamer_pci_tbl,
diff -urN linux-2.4.17.vanilla/drivers/net/tokenring/lanstreamer.h linux-2.4.17/drivers/net/tokenring/lanstreamer.h
--- linux-2.4.17.vanilla/drivers/net/tokenring/lanstreamer.h	Mon Feb  4 11:09:30 2002
+++ linux-2.4.17/drivers/net/tokenring/lanstreamer.h	Mon Feb  4 10:21:42 2002
@@ -56,11 +56,36 @@
  * 
  *  12/10/99 - Alpha Release 0.1.0
  *            First release to the public
+ *  08/15/01 - Added ioctl() definitions and others - Kent Yoder <yoder1@us.ibm.com>
  *
  */
 
+#if STREAMER_IOCTL && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include <asm/ioctl.h>
+#define IOCTL_PRINT_RX_BUFS   SIOCDEVPRIVATE
+#define IOCTL_PRINT_TX_BUFS   SIOCDEVPRIVATE+1
+#define IOCTL_RX_CMD          SIOCDEVPRIVATE+2
+#define IOCTL_TX_CMD          SIOCDEVPRIVATE+3
+#define IOCTL_PRINT_REGISTERS SIOCDEVPRIVATE+4
+#define IOCTL_PRINT_BDAS      SIOCDEVPRIVATE+5
+#define IOCTL_SPIN_LOCK_TEST  SIOCDEVPRIVATE+6
+#define IOCTL_SISR_MASK       SIOCDEVPRIVATE+7
+#endif
+
+/* MAX_INTR - the maximum number of times we can loop
+ * inside the interrupt function before returning
+ * control to the OS (maximum value is 256)
+ */
+#define MAX_INTR 5
+
+#define CLS 0x0C
+#define MLR 0x86
+#define LTR 0x0D
+
 #define BCTL 0x60
 #define BCTL_SOFTRESET (1<<15)
+#define BCTL_RX_FIFO_8 (1<<1)
+#define BCTL_TX_FIFO_8 (1<<3)
 
 #define GPR 0x4a
 #define GPR_AUTOSENSE (1<<2)
@@ -89,6 +114,7 @@
 #define SISR_MASK_RUM 0x58
 
 #define SISR_MI (1<<15)
+#define SISR_SERR_ERR (1<<14)
 #define SISR_TIMER (1<<11)
 #define SISR_LAP_PAR_ERR (1<<10)
 #define SISR_LAP_ACC_ERR (1<<9)
@@ -218,7 +244,13 @@
 /* Streamer defaults for buffers */
 
 #define STREAMER_RX_RING_SIZE 16	/* should be a power of 2 */
-#define STREAMER_TX_RING_SIZE 8	/* should be a power of 2 */
+/* Setting the number of TX descriptors to 1 is a workaround for an
+ * undocumented hardware problem with the lanstreamer board. Setting
+ * this to something higher may slightly increase the throughput you
+ * can get from the card, but at the risk of locking up the box. - 
+ * <yoder1@us.ibm.com>
+ */
+#define STREAMER_TX_RING_SIZE 1	/* should be a power of 2 */
 
 #define PKT_BUF_SZ 4096		/* Default packet size */
 


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2002-03-05 15:39 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-02-15 21:44 [PATCH] IBM Lanstreamer bugfixes (round 3) Kent Yoder
2002-02-16 11:12 ` Jeff Garzik
2002-03-04 16:51   ` Kent Yoder
2002-03-04 17:04     ` Jeff Garzik
2002-03-04 17:27       ` David Dillow
2002-03-04 17:46         ` Jeff Garzik
2002-03-04 18:45           ` David Dillow
2002-03-04 18:52             ` Jeff Garzik
2002-03-04 19:02               ` David Dillow
2002-03-04 19:12                 ` Jeff Garzik
2002-03-04 18:58       ` Kent Yoder
2002-03-04 19:10         ` Jeff Garzik
2002-03-05 14:59           ` pjd
2002-03-05 15:37           ` Kent Yoder
  -- strict thread matches above, loose matches on Subject: below --
2002-02-04 17:16 Kent Yoder

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