* Re: [2.4.32 - 2.6.15.4] e1000 - Fix mii interface
From: Paul Rolland @ 2006-02-26 11:39 UTC (permalink / raw)
To: 'Willy TARREAU'
Cc: linux-kernel, netdev, linux.nics, cramerj, john.ronciak,
Ganesh.Venkatesan
In-Reply-To: <20060226104206.GA11434@w.ods.org>
> it's mangled, tabs have been turned into whitespaces. I fixed
> it so please
> use the appended one.
Sorry about that, thanks for the fix.
Paul
^ permalink raw reply
* Re: [2.4.32 - 2.6.15.4] e1000 - Fix mii interface
From: Willy TARREAU @ 2006-02-26 10:42 UTC (permalink / raw)
To: Paul Rolland
Cc: linux-kernel, netdev, linux.nics, cramerj, john.ronciak,
Ganesh.Venkatesan
In-Reply-To: <007801c639f3$79388060$2001a8c0@cortex>
Hello Paul,
On Sat, Feb 25, 2006 at 11:08:49AM +0100, Paul Rolland wrote:
> Hello,
>
> This patch is based on Linux 2.4.32, and I've verified the same problem
> exists on 2.6.15.4.
it's mangled, tabs have been turned into whitespaces. I fixed it so please
use the appended one.
> Working on a machine with a 2.4.32 kernel, I was surprised to see the driver
> complaining when setting the speed to 100FD using mii-tool, but accepting
> the setting with ethtool.
> Digging into the code, I found that there is some confusion with :
> - DUPLEX_FULL and FULL_DUPLEX,
> - DUPLEX_HALF and HALF_DUPLEX
> in the code :
> ...
> spddplx += (mii_reg & 0x100)
> ? FULL_DUPLEX :
> HALF_DUPLEX;
> retval = e1000_set_spd_dplx(adapter,
> spddplx);
> ...
> and
> int
> e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
> {
> adapter->hw.autoneg = 0;
>
> switch(spddplx) {
> case SPEED_10 + DUPLEX_HALF:
> adapter->hw.forced_speed_duplex = e1000_10_half;
> break;
> ....
> when the constants don't have the same value.
>
> This patch is simply changing the code in the e1000_set_spd_dplx to use the
> same constants as does the caller of the function : FULL_DUPLEX and
> HALF_DUPLEX
> whose values are not 0, to make sure we have had a successfull init
> (DUPLEX_HALF value is 0, and the DUPLEX_xxx are defined in ethtool.h, thus
> are probably not meant to be used in the mii interface).
>
> Signed-off-by: Paul Rolland <rol@as2917.net>
>
> diff -urN linux-2.4.32-orig/drivers/net/e1000/e1000_main.c
> linux-2.4.32/drivers/net/e1000/e1000_main.c
> --- linux-2.4.32-orig/drivers/net/e1000/e1000_main.c Mon Apr 4 01:42:19
> 2005
> +++ linux-2.4.32/drivers/net/e1000/e1000_main.c Sat Feb 25 09:36:23 2006
> @@ -2944,23 +2944,23 @@
> adapter->hw.autoneg = 0;
>
> switch(spddplx) {
> - case SPEED_10 + DUPLEX_HALF:
> + case SPEED_10 + HALF_DUPLEX:
> adapter->hw.forced_speed_duplex = e1000_10_half;
> break;
> - case SPEED_10 + DUPLEX_FULL:
> + case SPEED_10 + FULL_DUPLEX:
> adapter->hw.forced_speed_duplex = e1000_10_full;
> break;
> - case SPEED_100 + DUPLEX_HALF:
> + case SPEED_100 + HALF_DUPLEX:
> adapter->hw.forced_speed_duplex = e1000_100_half;
> break;
> - case SPEED_100 + DUPLEX_FULL:
> + case SPEED_100 + FULL_DUPLEX:
> adapter->hw.forced_speed_duplex = e1000_100_full;
> break;
> - case SPEED_1000 + DUPLEX_FULL:
> + case SPEED_1000 + FULL_DUPLEX:
> adapter->hw.autoneg = 1;
> adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
> break;
> - case SPEED_1000 + DUPLEX_HALF: /* not supported */
> + case SPEED_1000 + HALF_DUPLEX: /* not supported */
> default:
> DPRINTK(PROBE, ERR,
> "Unsupported Speed/Duplexity configuration\n");
>
>
> Paul Rolland, rol(at)as2917.net
> ex-AS2917 Network administrator and Peering Coordinator
Regards,
Willy
diff -urN linux-2.4.32-orig/drivers/net/e1000/e1000_main.c linux-2.4.32/drivers/net/e1000/e1000_main.c
--- linux-2.4.32-orig/drivers/net/e1000/e1000_main.c Mon Apr 4 01:42:19 2005
+++ linux-2.4.32/drivers/net/e1000/e1000_main.c Sat Feb 25 09:36:23 2006
@@ -2944,23 +2944,23 @@
adapter->hw.autoneg = 0;
switch(spddplx) {
- case SPEED_10 + DUPLEX_HALF:
+ case SPEED_10 + HALF_DUPLEX:
adapter->hw.forced_speed_duplex = e1000_10_half;
break;
- case SPEED_10 + DUPLEX_FULL:
+ case SPEED_10 + FULL_DUPLEX:
adapter->hw.forced_speed_duplex = e1000_10_full;
break;
- case SPEED_100 + DUPLEX_HALF:
+ case SPEED_100 + HALF_DUPLEX:
adapter->hw.forced_speed_duplex = e1000_100_half;
break;
- case SPEED_100 + DUPLEX_FULL:
+ case SPEED_100 + FULL_DUPLEX:
adapter->hw.forced_speed_duplex = e1000_100_full;
break;
- case SPEED_1000 + DUPLEX_FULL:
+ case SPEED_1000 + FULL_DUPLEX:
adapter->hw.autoneg = 1;
adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
break;
- case SPEED_1000 + DUPLEX_HALF: /* not supported */
+ case SPEED_1000 + HALF_DUPLEX: /* not supported */
default:
DPRINTK(PROBE, ERR,
"Unsupported Speed/Duplexity configuration\n");
^ permalink raw reply
* Re: [PATCH] Revert sky2 to 0.13a
From: Wolfgang Hoffmann @ 2006-02-26 8:57 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Carl-Daniel Hailfinger, Jeff Garzik, netdev, Ian Kumlien,
Pavel Volkovitskiy, Linux Kernel Mailing List
In-Reply-To: <20060225180353.5908c955@localhost.localdomain>
On Sunday 26 February 2006 03:03, Stephen Hemminger wrote:
> Instead of whining, try this.
I tried and still see the hang.
Stephen, if you want me (as suggested off-list) to bisect the individual
patches leading from 0.13a to current head, please give me a series of
patches to incrementally apply, eighter via mail/ftp/git, and I'll test. I
don't want to hack the patches together myself, because results would be
worthless if I screw up, and given that I have no networking background
chances are high ...
It takes me between 5 - 20 GB of data transfer to reproduce the hang, so it
will take a while, but I'm willing to help. If you see vendor chip specs
arrive soon and feel it's not worth the hassle, that's fine for me, too.
In the meanwhile, I'll resort to 0.13a
Wolfgang
^ permalink raw reply
* RTL 8139 stops RX after receiving a jumbo frame
From: John Zielinski @ 2006-02-26 4:23 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev
I was testing a patch for the VIA Velocity adapter and accidentally
pinged a jumbo packet to 192.168.0.1 instead of 192.168.0.10. The
machine I pinged is my Linux firewall box with a RTL 8139 card (8139 rev
K chip). When my internet connection went down I tried pinging the
firewall with regular sized packets and it wouldn't respond. I had to
ifdown/ifup the interface to get things going again. The output from
ifconfig shows I had an overrun.
I'm replacing that card with a VIA Velocity card as I'm upgrading my
entire network to GigE but a friend of mine is only doing a partial
upgrade and will have several boxes with RTL 8139's still in them. I'm
going to move the RTL card into my test box for further testing.
I'm surprised that the switch actually let the jumbo packet through onto
a 100Mbit link. I'm going to see if I can find a non RTL 8139 card in
my parts bin and see what that one does.
What's the normal behavior for overruns on an interface?
^ permalink raw reply
* Re: VIA Velocity massive memory corruption with jumbo frames
From: John Zielinski @ 2006-02-26 3:56 UTC (permalink / raw)
To: Francois Romieu; +Cc: linux-kernel, netdev
In-Reply-To: <20060225235346.GA18558@electric-eye.fr.zoreil.com>
Francois Romieu wrote:
> Try the patch below and Cc: netdev@vger.kernel.org on further messages
> please.
>
It worked. No more memory corruption and I can ping 9000 byte packets
to my Windows box.
^ permalink raw reply
* Re: [PATCH] Revert sky2 to 0.13a
From: Ian Kumlien @ 2006-02-26 2:42 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Carl-Daniel Hailfinger, Jeff Garzik, netdev, Wolfgang Hoffmann,
Pavel Volkovitskiy, Linux Kernel Mailing List
In-Reply-To: <20060225180353.5908c955@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 213 bytes --]
On Sat, 2006-02-25 at 18:03 -0800, Stephen Hemminger wrote:
> Instead of whining, try this.
Applied and compiled, rebooting in a bit =)
--
Ian Kumlien <pomac () vapor ! com> -- http://pomac.netswarm.net
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 200 bytes --]
^ permalink raw reply
* Re: [PATCH] Revert sky2 to 0.13a
From: Ian Kumlien @ 2006-02-26 2:25 UTC (permalink / raw)
To: Carl-Daniel Hailfinger
Cc: Jeff Garzik, netdev, Wolfgang Hoffmann, Pavel Volkovitskiy,
Linux Kernel Mailing List, Stephen Hemminger
In-Reply-To: <4400FC28.1060705@gmx.net>
[-- Attachment #1: Type: text/plain, Size: 736 bytes --]
On Sun, 2006-02-26 at 01:54 +0100, Carl-Daniel Hailfinger wrote:
> Hi Jeff,
>
> you may want to push this patch into 2.6.16. The version it reverts to
> has been running stable for over four weeks for various folks (CC'ed)
> and we have had no success communicating with the maintainer.
I don't think that this is constructive, the error must be locatable on
later versions, just reverting to a older version of the driver as a cop
out solves nothing... And it also means that we don't understand WHY it
breaks at all.
It would be much better if more ppl could hack the driver source, esp if
they themselves have a system that shows the breakage.
--
Ian Kumlien <pomac () vapor ! com> -- http://pomac.netswarm.net
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 200 bytes --]
^ permalink raw reply
* Re: [PATCH] Revert sky2 to 0.13a
From: Stephen Hemminger @ 2006-02-26 2:03 UTC (permalink / raw)
To: Carl-Daniel Hailfinger
Cc: Jeff Garzik, netdev, Ian Kumlien, Wolfgang Hoffmann,
Pavel Volkovitskiy, Linux Kernel Mailing List
In-Reply-To: <4400FC28.1060705@gmx.net>
Instead of whining, try this.
--- drivers/net/sky2.c.orig 2006-02-25 18:02:10.000000000 -0800
+++ drivers/net/sky2.c 2006-02-25 18:03:13.000000000 -0800
@@ -1895,19 +1895,6 @@
u16 hwidx;
u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
- sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-
- /*
- * Kick the STAT_LEV_TIMER_CTRL timer.
- * This fixes my hangs on Yukon-EC (0xb6) rev 1.
- * The if clause is there to start the timer only if it has been
- * configured correctly and not been disabled via ethtool.
- */
- if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) {
- sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
- sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
- }
-
hwidx = sky2_read16(hw, STAT_PUT_IDX);
BUG_ON(hwidx >= STATUS_RING_SIZE);
rmb();
@@ -1995,7 +1982,20 @@
sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
}
- if (likely(work_done < to_do)) {
+ sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+
+ /*
+ * Kick the STAT_LEV_TIMER_CTRL timer.
+ * This fixes my hangs on Yukon-EC (0xb6) rev 1.
+ * The if clause is there to start the timer only if it has been
+ * configured correctly and not been disabled via ethtool.
+ */
+ if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) {
+ sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
+ sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
+ }
+
+ if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) {
spin_lock_irq(&hw->hw_lock);
__netif_rx_complete(dev0);
^ permalink raw reply
* Re: [Announce] Intel PRO/Wireless 3945ABG Network Connection
From: Stephen Evanchik @ 2006-02-26 1:09 UTC (permalink / raw)
To: gene.heskett; +Cc: Christoph Hellwig, James Ketrenos, NetDev, linux-kernel
In-Reply-To: <200602250619.04567.gene.heskett@verizon.net>
On 2/25/06, Gene Heskett <gene.heskett@verizon.net> wrote:
> that apply to all". These rules go back to about the time of when they
> outlawed any transmit tunability in CB radios in the later 70's, so its
> not a new item by any means as its just an extension of that edict to
> cover this newer technology. The fact that it effectively put a stop to
> conference call type use of single sideband because no 2 radios were on
> the same, now non-adjustable frequency was an undesirable thing, but
> thats the breaks. I might try and look it up after I've had some zz's,
> as I just came from doing transmitter maintainance overnight.
I'm not really sure what you are describing but you probably want to
reference CFR Title 47 Telecommunications [1]. Particularly
interesting is 15.202 "Certified operating frequency range." which
says in part:
"... Master devices marketed within the United States must be
limited to operation on permissible part 15 frequencies. Client devices
that can also act as master devices must meet the requirements of a
master device. ..."
Also there is a general prohibition on "harmful interference" in 15.5
which says in part:
"(b) Operation of an intentional, unintentional, or incidental
radiator is subject to the conditions that no harmful interference is
caused and that interference must be accepted that may be caused by the
operation of an authorized radio station, by another intentional or
unintentional radiator, by industrial, scientific and medical (ISM)
equipment, or by an incidental radiator. .."
I am going to guess that these two excerpts provide strong evidence
that Intel has to keep their radios from being modified accidentally
or purposefully. I also suspect that they only have to make it
difficult for an end user and not a technologist. So the well defined
interface between the closed source binary only userspace daemon and
the open source kernel driver could be reverse engineered and an
unencumbered replacement created.
I am definitely not a lawyer and this stuff is always subject to
someone making an argument in court.
Stephen
[1] http://www.access.gpo.gov/nara/cfr/waisidx_05/47cfr15_05.html
^ permalink raw reply
* Re: [Announce] Intel PRO/Wireless 3945ABG Network Connection
From: Alan Cox @ 2006-02-26 0:58 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: James Ketrenos, NetDev, linux-kernel, okir
In-Reply-To: <20060225084139.GB22109@infradead.org>
On Sad, 2006-02-25 at 08:41 +0000, Christoph Hellwig wrote:
> the regualatory problems are not true.
They are although the binary interpretation isn't AFAIK from law but
from lawyers. The same is actually true in much of the EU. The actual
requirement is that the transmitting device must be reasonably
tamperproof. Some of the lawyers have decided that for a software radio
tamperproof means "binary".
Thats pretty dumb but given the hardware variant of this is "seal
anything adjustible in plastic gunge" you can see the logic at work -
and it *will* help make the product tamperproof to end users. Remember
Christoph you are not an "end user" any more than hardware like that is
designed to proof against a person who can use a scope and solder
surface mount components.
Now a smart vendor would have put MD5 sum checking into the chip so you
can only load register sets for the transmitter as a block and that
block is loaded such that
[Data] + Secret known only to chip = MD5sum with data
or a similar cookie signing scheme. Replay attacks don't matter here so
that should be sufficient.
^ permalink raw reply
* [PATCH] Revert sky2 to 0.13a
From: Carl-Daniel Hailfinger @ 2006-02-26 0:54 UTC (permalink / raw)
To: Jeff Garzik
Cc: netdev, Ian Kumlien, Wolfgang Hoffmann, Pavel Volkovitskiy,
Linux Kernel Mailing List, Stephen Hemminger
Hi Jeff,
you may want to push this patch into 2.6.16. The version it reverts to
has been running stable for over four weeks for various folks (CC'ed)
and we have had no success communicating with the maintainer.
Regards,
Carl-Daniel
Revert sky2 to 0.13 with a four-line fix on top of it.
Later versions cause random oopses and just hang on some chips.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
diff -Nurp linux-2.6.16-rc4-git8/drivers/net/sky2.c linux-2.6.16-rc4-git8-sky2fix/drivers/net/sky2.c
--- linux-2.6.16-rc4-git8/drivers/net/sky2.c 2006-02-25 02:38:35.000000000 +0100
+++ linux-2.6.16-rc4-git8-sky2fix/drivers/net/sky2.c 2006-02-26 01:29:45.000000000 +0100
@@ -23,6 +23,12 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/*
+ * TOTEST
+ * - speed setting
+ * - suspend/resume
+ */
+
#include <linux/config.h>
#include <linux/crc32.h>
#include <linux/kernel.h>
@@ -51,7 +57,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "0.15"
+#define DRV_VERSION "0.13a"
#define PFX DRV_NAME " "
/*
@@ -96,10 +102,6 @@ static int copybreak __read_mostly = 256
module_param(copybreak, int, 0);
MODULE_PARM_DESC(copybreak, "Receive copy threshold");
-static int disable_msi = 0;
-module_param(disable_msi, int, 0);
-MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
-
static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
@@ -195,11 +197,11 @@ static int sky2_set_power_state(struct s
pr_debug("sky2_set_power_state %d\n", state);
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_PMC);
- vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
+ pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control);
+ vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
(power_control & PCI_PM_CAP_PME_D3cold);
- power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL);
+ pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control);
power_control |= PCI_PM_CTRL_PME_STATUS;
power_control &= ~(PCI_PM_CTRL_STATE_MASK);
@@ -223,7 +225,7 @@ static int sky2_set_power_state(struct s
sky2_write8(hw, B2_Y2_CLK_GATE, 0);
/* Turn off phy power saving */
- reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
+ pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®1);
reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
/* looks like this XL is back asswards .. */
@@ -232,28 +234,18 @@ static int sky2_set_power_state(struct s
if (hw->ports > 1)
reg1 |= PCI_Y2_PHY2_COMA;
}
-
- if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
- sky2_pci_write32(hw, PCI_DEV_REG3, 0);
- reg1 = sky2_pci_read32(hw, PCI_DEV_REG4);
- reg1 &= P_ASPM_CONTROL_MSK;
- sky2_pci_write32(hw, PCI_DEV_REG4, reg1);
- sky2_pci_write32(hw, PCI_DEV_REG5, 0);
- }
-
- sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-
+ pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
break;
case PCI_D3hot:
case PCI_D3cold:
/* Turn on phy power saving */
- reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
+ pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®1);
if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
else
reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
- sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
+ pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
sky2_write8(hw, B2_Y2_CLK_GATE, 0);
@@ -275,7 +267,7 @@ static int sky2_set_power_state(struct s
ret = -1;
}
- sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control);
+ pci_write_config_byte(hw->pdev, hw->pm_cap + PCI_PM_CTRL, power_control);
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
return ret;
}
@@ -473,31 +465,16 @@ static void sky2_phy_init(struct sky2_hw
ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
}
- if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) {
- /* apply fixes in PHY AFE */
- gm_phy_write(hw, port, 22, 255);
- /* increase differential signal amplitude in 10BASE-T */
- gm_phy_write(hw, port, 24, 0xaa99);
- gm_phy_write(hw, port, 23, 0x2011);
-
- /* fix for IEEE A/B Symmetry failure in 1000BASE-T */
- gm_phy_write(hw, port, 24, 0xa204);
- gm_phy_write(hw, port, 23, 0x2002);
-
- /* set page register to 0 */
- gm_phy_write(hw, port, 22, 0);
- } else {
- gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+ gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
- if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
- /* turn on 100 Mbps LED (LED_LINK100) */
- ledover |= PHY_M_LED_MO_100(MO_LED_ON);
- }
+ if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
+ /* turn on 100 Mbps LED (LED_LINK100) */
+ ledover |= PHY_M_LED_MO_100(MO_LED_ON);
+ }
- if (ledover)
- gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+ if (ledover)
+ gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
- }
/* Enable phy interrupt on auto-negotiation complete (or link up) */
if (sky2->autoneg == AUTONEG_ENABLE)
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
@@ -545,16 +522,10 @@ static void sky2_mac_init(struct sky2_hw
switch (sky2->speed) {
case SPEED_1000:
- reg &= ~GM_GPCR_SPEED_100;
reg |= GM_GPCR_SPEED_1000;
- break;
+ /* fallthru */
case SPEED_100:
- reg &= ~GM_GPCR_SPEED_1000;
reg |= GM_GPCR_SPEED_100;
- break;
- case SPEED_10:
- reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100);
- break;
}
if (sky2->duplex == DUPLEX_FULL)
@@ -978,12 +949,6 @@ static int sky2_rx_start(struct sky2_por
sky2->rx_put = sky2->rx_next = 0;
sky2_qset(hw, rxq);
-
- if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) {
- /* MAC Rx RAM Read is controlled by hardware */
- sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS);
- }
-
sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
rx_set_checksum(sky2);
@@ -1066,11 +1031,10 @@ static int sky2_up(struct net_device *de
RB_RST_SET);
sky2_qset(hw, txqaddr[port]);
-
- /* Set almost empty threshold */
- if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == 1)
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U)
sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
+
sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
TX_RING_SIZE - 1);
@@ -1079,10 +1043,8 @@ static int sky2_up(struct net_device *de
goto err_out;
/* Enable interrupts from phy/mac for port */
- spin_lock_irq(&hw->hw_lock);
hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
sky2_write32(hw, B0_IMSK, hw->intr_mask);
- spin_unlock_irq(&hw->hw_lock);
return 0;
err_out:
@@ -1382,10 +1344,10 @@ static int sky2_down(struct net_device *
netif_stop_queue(dev);
/* Disable port IRQ */
- spin_lock_irq(&hw->hw_lock);
+ local_irq_disable();
hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
sky2_write32(hw, B0_IMSK, hw->intr_mask);
- spin_unlock_irq(&hw->hw_lock);
+ local_irq_enable();
flush_scheduled_work();
@@ -1486,29 +1448,6 @@ static void sky2_link_up(struct sky2_por
sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
reg = gma_read16(hw, port, GM_GP_CTRL);
- if (sky2->autoneg == AUTONEG_DISABLE) {
- reg |= GM_GPCR_AU_ALL_DIS;
-
- /* Is write/read necessary? Copied from sky2_mac_init */
- gma_write16(hw, port, GM_GP_CTRL, reg);
- gma_read16(hw, port, GM_GP_CTRL);
-
- switch (sky2->speed) {
- case SPEED_1000:
- reg &= ~GM_GPCR_SPEED_100;
- reg |= GM_GPCR_SPEED_1000;
- break;
- case SPEED_100:
- reg &= ~GM_GPCR_SPEED_1000;
- reg |= GM_GPCR_SPEED_100;
- break;
- case SPEED_10:
- reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100);
- break;
- }
- } else
- reg &= ~GM_GPCR_AU_ALL_DIS;
-
if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE)
reg |= GM_GPCR_DUP_FULL;
@@ -1667,10 +1606,10 @@ static void sky2_phy_task(void *arg)
out:
up(&sky2->phy_sema);
- spin_lock_irq(&hw->hw_lock);
+ local_irq_disable();
hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2;
sky2_write32(hw, B0_IMSK, hw->intr_mask);
- spin_unlock_irq(&hw->hw_lock);
+ local_irq_enable();
}
@@ -1895,19 +1834,6 @@ static int sky2_poll(struct net_device *
u16 hwidx;
u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
- sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-
- /*
- * Kick the STAT_LEV_TIMER_CTRL timer.
- * This fixes my hangs on Yukon-EC (0xb6) rev 1.
- * The if clause is there to start the timer only if it has been
- * configured correctly and not been disabled via ethtool.
- */
- if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) {
- sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
- sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
- }
-
hwidx = sky2_read16(hw, STAT_PUT_IDX);
BUG_ON(hwidx >= STATUS_RING_SIZE);
rmb();
@@ -1987,22 +1913,32 @@ static int sky2_poll(struct net_device *
}
exit_loop:
- sky2_tx_check(hw, 0, tx_done[0]);
- sky2_tx_check(hw, 1, tx_done[1]);
+ sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
- if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
- sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
- sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+ /*
+ * Kick the STAT_LEV_TIMER_CTRL timer.
+ * This fixes the hangs on Yukon-EC (0xb6) rev 1.
+ * The if clause is there to start the timer only if it has been
+ * configured correctly and not been disabled via ethtool.
+ */
+ if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) {
+ sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
+ sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
}
- if (likely(work_done < to_do)) {
- spin_lock_irq(&hw->hw_lock);
- __netif_rx_complete(dev0);
+ sky2_tx_check(hw, 0, tx_done[0]);
+ sky2_tx_check(hw, 1, tx_done[1]);
+ if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) {
+ /* need to restart TX timer */
+ if (is_ec_a1(hw)) {
+ sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+ sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+ }
+
+ netif_rx_complete(dev0);
hw->intr_mask |= Y2_IS_STAT_BMU;
sky2_write32(hw, B0_IMSK, hw->intr_mask);
- spin_unlock_irq(&hw->hw_lock);
-
return 0;
} else {
*budget -= work_done;
@@ -2065,13 +2001,13 @@ static void sky2_hw_intr(struct sky2_hw
if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
u16 pci_err;
- pci_err = sky2_pci_read16(hw, PCI_STATUS);
+ pci_read_config_word(hw->pdev, PCI_STATUS, &pci_err);
if (net_ratelimit())
printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n",
pci_name(hw->pdev), pci_err);
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- sky2_pci_write16(hw, PCI_STATUS,
+ pci_write_config_word(hw->pdev, PCI_STATUS,
pci_err | PCI_STATUS_ERROR_BITS);
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
}
@@ -2080,7 +2016,7 @@ static void sky2_hw_intr(struct sky2_hw
/* PCI-Express uncorrectable Error occurred */
u32 pex_err;
- pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
+ pci_read_config_dword(hw->pdev, PEX_UNC_ERR_STAT, &pex_err);
if (net_ratelimit())
printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
@@ -2088,7 +2024,7 @@ static void sky2_hw_intr(struct sky2_hw
/* clear the interrupt */
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
+ pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
0xffffffffUL);
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
@@ -2134,7 +2070,6 @@ static void sky2_phy_intr(struct sky2_hw
hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
sky2_write32(hw, B0_IMSK, hw->intr_mask);
-
schedule_work(&sky2->phy_task);
}
@@ -2148,7 +2083,6 @@ static irqreturn_t sky2_intr(int irq, vo
if (status == 0 || status == ~0)
return IRQ_NONE;
- spin_lock(&hw->hw_lock);
if (status & Y2_IS_HW_ERR)
sky2_hw_intr(hw);
@@ -2177,7 +2111,7 @@ static irqreturn_t sky2_intr(int irq, vo
sky2_write32(hw, B0_Y2_SP_ICR, 2);
- spin_unlock(&hw->hw_lock);
+ sky2_read32(hw, B0_IMSK);
return IRQ_HANDLED;
}
@@ -2218,12 +2152,14 @@ static inline u32 sky2_clk2us(const stru
static int sky2_reset(struct sky2_hw *hw)
{
+ u32 ctst;
u16 status;
u8 t8, pmd_type;
int i;
- sky2_write8(hw, B0_CTST, CS_RST_CLR);
+ ctst = sky2_read32(hw, B0_CTST);
+ sky2_write8(hw, B0_CTST, CS_RST_CLR);
hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) {
printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n",
@@ -2231,6 +2167,12 @@ static int sky2_reset(struct sky2_hw *hw
return -EOPNOTSUPP;
}
+ /* ring for status responses */
+ hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
+ &hw->st_dma);
+ if (!hw->st_le)
+ return -ENOMEM;
+
/* disable ASF */
if (hw->chip_id <= CHIP_ID_YUKON_EC) {
sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
@@ -2242,18 +2184,20 @@ static int sky2_reset(struct sky2_hw *hw
sky2_write8(hw, B0_CTST, CS_RST_CLR);
/* clear PCI errors, if any */
- status = sky2_pci_read16(hw, PCI_STATUS);
-
+ pci_read_config_word(hw->pdev, PCI_STATUS, &status);
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
- sky2_pci_write16(hw, PCI_STATUS, status | PCI_STATUS_ERROR_BITS);
-
+ pci_write_config_word(hw->pdev, PCI_STATUS,
+ status | PCI_STATUS_ERROR_BITS);
sky2_write8(hw, B0_CTST, CS_MRST_CLR);
/* clear any PEX errors */
- if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
- sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
-
+ if (is_pciex(hw)) {
+ u16 lstat;
+ pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
+ 0xffffffffUL);
+ pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat);
+ }
pmd_type = sky2_read8(hw, B2_PMD_TYP);
hw->copper = !(pmd_type == 'L' || pmd_type == 'S');
@@ -2352,7 +2296,8 @@ static int sky2_reset(struct sky2_hw *hw
sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
- sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7));
+ sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100));
+ sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20));
}
/* enable status unit */
@@ -2617,24 +2562,19 @@ static struct net_device_stats *sky2_get
static int sky2_set_mac_address(struct net_device *dev, void *p)
{
struct sky2_port *sky2 = netdev_priv(dev);
- struct sky2_hw *hw = sky2->hw;
- unsigned port = sky2->port;
- const struct sockaddr *addr = p;
+ struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
- memcpy_toio(hw->regs + B2_MAC_1 + port * 8,
+ memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8,
dev->dev_addr, ETH_ALEN);
- memcpy_toio(hw->regs + B2_MAC_2 + port * 8,
+ memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8,
dev->dev_addr, ETH_ALEN);
- /* virtual address for data */
- gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr);
-
- /* physical address: used for pause frames */
- gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr);
+ if (netif_running(dev))
+ sky2_phy_reinit(sky2);
return 0;
}
@@ -2886,11 +2826,11 @@ static int sky2_set_coalesce(struct net_
(ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax))
return -EINVAL;
- if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1)
+ if (ecmd->tx_max_coalesced_frames > 0xffff)
return -EINVAL;
- if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING)
+ if (ecmd->rx_max_coalesced_frames > 0xff)
return -EINVAL;
- if (ecmd->rx_max_coalesced_frames_irq >RX_MAX_PENDING)
+ if (ecmd->rx_max_coalesced_frames_irq > 0xff)
return -EINVAL;
if (ecmd->tx_coalesce_usecs == 0)
@@ -3126,61 +3066,6 @@ static void __devinit sky2_show_addr(str
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
}
-/* Handle software interrupt used during MSI test */
-static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id,
- struct pt_regs *regs)
-{
- struct sky2_hw *hw = dev_id;
- u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2);
-
- if (status == 0)
- return IRQ_NONE;
-
- if (status & Y2_IS_IRQ_SW) {
- sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
- hw->msi = 1;
- }
- sky2_write32(hw, B0_Y2_SP_ICR, 2);
-
- sky2_read32(hw, B0_IMSK);
- return IRQ_HANDLED;
-}
-
-/* Test interrupt path by forcing a a software IRQ */
-static int __devinit sky2_test_msi(struct sky2_hw *hw)
-{
- struct pci_dev *pdev = hw->pdev;
- int i, err;
-
- sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
-
- err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw);
- if (err) {
- printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
- pci_name(pdev), pdev->irq);
- return err;
- }
-
- sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
- wmb();
-
- for (i = 0; i < 10; i++) {
- barrier();
- if (hw->msi)
- goto found;
- mdelay(1);
- }
-
- err = -EOPNOTSUPP;
- sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
- found:
- sky2_write32(hw, B0_IMSK, 0);
-
- free_irq(pdev->irq, hw);
-
- return err;
-}
-
static int __devinit sky2_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -3232,6 +3117,17 @@ static int __devinit sky2_probe(struct p
}
}
+#ifdef __BIG_ENDIAN
+ /* byte swap descriptors in hardware */
+ {
+ u32 reg;
+
+ pci_read_config_dword(pdev, PCI_DEV_REG2, ®);
+ reg |= PCI_REV_DESC;
+ pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
+ }
+#endif
+
err = -ENOMEM;
hw = kzalloc(sizeof(*hw), GFP_KERNEL);
if (!hw) {
@@ -3249,24 +3145,6 @@ static int __devinit sky2_probe(struct p
goto err_out_free_hw;
}
hw->pm_cap = pm_cap;
- spin_lock_init(&hw->hw_lock);
-
-#ifdef __BIG_ENDIAN
- /* byte swap descriptors in hardware */
- {
- u32 reg;
-
- reg = sky2_pci_read32(hw, PCI_DEV_REG2);
- reg |= PCI_REV_DESC;
- sky2_pci_write32(hw, PCI_DEV_REG2, reg);
- }
-#endif
-
- /* ring for status responses */
- hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
- &hw->st_dma);
- if (!hw->st_le)
- goto err_out_iounmap;
err = sky2_reset(hw);
if (err)
@@ -3302,22 +3180,7 @@ static int __devinit sky2_probe(struct p
}
}
- if (!disable_msi && pci_enable_msi(pdev) == 0) {
- err = sky2_test_msi(hw);
- if (err == -EOPNOTSUPP) {
- /* MSI test failed, go back to INTx mode */
- printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, "
- "switching to INTx mode. Please report this failure to "
- "the PCI maintainer and include system chipset information.\n",
- pci_name(pdev));
- pci_disable_msi(pdev);
- }
- else if (err)
- goto err_out_unregister;
- }
-
- err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
- DRV_NAME, hw);
+ err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
if (err) {
printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
pci_name(pdev), pdev->irq);
@@ -3332,8 +3195,6 @@ static int __devinit sky2_probe(struct p
return 0;
err_out_unregister:
- if (hw->msi)
- pci_disable_msi(pdev);
if (dev1) {
unregister_netdev(dev1);
free_netdev(dev1);
@@ -3376,8 +3237,6 @@ static void __devexit sky2_remove(struct
sky2_read8(hw, B0_CTST);
free_irq(pdev->irq, hw);
- if (hw->msi)
- pci_disable_msi(pdev);
pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -3415,33 +3274,25 @@ static int sky2_suspend(struct pci_dev *
static int sky2_resume(struct pci_dev *pdev)
{
struct sky2_hw *hw = pci_get_drvdata(pdev);
- int i, err;
+ int i;
pci_restore_state(pdev);
pci_enable_wake(pdev, PCI_D0, 0);
- err = sky2_set_power_state(hw, PCI_D0);
- if (err)
- goto out;
+ sky2_set_power_state(hw, PCI_D0);
- err = sky2_reset(hw);
- if (err)
- goto out;
+ sky2_reset(hw);
for (i = 0; i < 2; i++) {
struct net_device *dev = hw->dev[i];
- if (dev && netif_running(dev)) {
- netif_device_attach(dev);
- err = sky2_up(dev);
- if (err) {
- printk(KERN_ERR PFX "%s: could not up: %d\n",
- dev->name, err);
- dev_close(dev);
- break;
+ if (dev) {
+ if (netif_running(dev)) {
+ netif_device_attach(dev);
+ if (sky2_up(dev))
+ dev_close(dev);
}
}
}
-out:
- return err;
+ return 0;
}
#endif
diff -Nurp linux-2.6.16-rc4-git8/drivers/net/sky2.h linux-2.6.16-rc4-git8-sky2fix/drivers/net/sky2.h
--- linux-2.6.16-rc4-git8/drivers/net/sky2.h 2006-02-25 02:38:35.000000000 +0100
+++ linux-2.6.16-rc4-git8-sky2fix/drivers/net/sky2.h 2006-02-04 15:43:58.000000000 +0100
@@ -5,22 +5,14 @@
#define _SKY2_H
/* PCI config registers */
-enum {
- PCI_DEV_REG1 = 0x40,
- PCI_DEV_REG2 = 0x44,
- PCI_DEV_STATUS = 0x7c,
- PCI_DEV_REG3 = 0x80,
- PCI_DEV_REG4 = 0x84,
- PCI_DEV_REG5 = 0x88,
-};
-
-enum {
- PEX_DEV_CAP = 0xe4,
- PEX_DEV_CTRL = 0xe8,
- PEX_DEV_STA = 0xea,
- PEX_LNK_STAT = 0xf2,
- PEX_UNC_ERR_STAT= 0x104,
-};
+#define PCI_DEV_REG1 0x40
+#define PCI_DEV_REG2 0x44
+#define PCI_DEV_STATUS 0x7c
+#define PCI_OS_PCI_X (1<<26)
+
+#define PEX_LNK_STAT 0xf2
+#define PEX_UNC_ERR_STAT 0x104
+#define PEX_DEV_CTRL 0xe8
/* Yukon-2 */
enum pci_dev_reg_1 {
@@ -45,25 +37,6 @@ enum pci_dev_reg_2 {
PCI_USEDATA64 = 1<<0, /* Use 64Bit Data bus ext */
};
-/* PCI_OUR_REG_4 32 bit Our Register 4 (Yukon-ECU only) */
-enum pci_dev_reg_4 {
- /* (Link Training & Status State Machine) */
- P_TIMER_VALUE_MSK = 0xffL<<16, /* Bit 23..16: Timer Value Mask */
- /* (Active State Power Management) */
- P_FORCE_ASPM_REQUEST = 1<<15, /* Force ASPM Request (A1 only) */
- P_ASPM_GPHY_LINK_DOWN = 1<<14, /* GPHY Link Down (A1 only) */
- P_ASPM_INT_FIFO_EMPTY = 1<<13, /* Internal FIFO Empty (A1 only) */
- P_ASPM_CLKRUN_REQUEST = 1<<12, /* CLKRUN Request (A1 only) */
-
- P_ASPM_FORCE_CLKREQ_ENA = 1<<4, /* Force CLKREQ Enable (A1b only) */
- P_ASPM_CLKREQ_PAD_CTL = 1<<3, /* CLKREQ PAD Control (A1 only) */
- P_ASPM_A1_MODE_SELECT = 1<<2, /* A1 Mode Select (A1 only) */
- P_CLK_GATE_PEX_UNIT_ENA = 1<<1, /* Enable Gate PEX Unit Clock */
- P_CLK_GATE_ROOT_COR_ENA = 1<<0, /* Enable Gate Root Core Clock */
- P_ASPM_CONTROL_MSK = P_FORCE_ASPM_REQUEST | P_ASPM_GPHY_LINK_DOWN
- | P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY,
-};
-
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
@@ -534,16 +507,6 @@ enum {
};
#define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
-/* Q_F 32 bit Flag Register */
-enum {
- F_ALM_FULL = 1<<27, /* Rx FIFO: almost full */
- F_EMPTY = 1<<27, /* Tx FIFO: empty flag */
- F_FIFO_EOF = 1<<26, /* Tag (EOF Flag) bit in FIFO */
- F_WM_REACHED = 1<<25, /* Watermark reached */
- F_M_RX_RAM_DIS = 1<<24, /* MAC Rx RAM Read Port disable */
- F_FIFO_LEVEL = 0x1fL<<16, /* Bit 23..16: # of Qwords in FIFO */
- F_WATER_MARK = 0x0007ffL, /* Bit 10.. 0: Watermark */
-};
/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
enum {
@@ -946,12 +909,10 @@ enum {
PHY_BCOM_ID1_C0 = 0x6044,
PHY_BCOM_ID1_C5 = 0x6047,
- PHY_MARV_ID1_B0 = 0x0C23, /* Yukon (PHY 88E1011) */
+ PHY_MARV_ID1_B0 = 0x0C23, /* Yukon (PHY 88E1011) */
PHY_MARV_ID1_B2 = 0x0C25, /* Yukon-Plus (PHY 88E1011) */
- PHY_MARV_ID1_C2 = 0x0CC2, /* Yukon-EC (PHY 88E1111) */
- PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */
- PHY_MARV_ID1_FE = 0x0C83, /* Yukon-FE (PHY 88E3082 Rev.A1) */
- PHY_MARV_ID1_ECU= 0x0CB0, /* Yukon-ECU (PHY 88E1149 Rev.B2?) */
+ PHY_MARV_ID1_C2 = 0x0CC2, /* Yukon-EC (PHY 88E1111) */
+ PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */
};
/* Advertisement register bits */
@@ -1876,12 +1837,10 @@ struct sky2_port {
struct sky2_hw {
void __iomem *regs;
struct pci_dev *pdev;
- struct net_device *dev[2];
- spinlock_t hw_lock;
u32 intr_mask;
+ struct net_device *dev[2];
int pm_cap;
- int msi;
u8 chip_id;
u8 chip_rev;
u8 copper;
@@ -1908,6 +1867,14 @@ static inline u8 sky2_read8(const struct
return readb(hw->regs + reg);
}
+/* This should probably go away, bus based tweeks suck */
+static inline int is_pciex(const struct sky2_hw *hw)
+{
+ u32 status;
+ pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status);
+ return (status & PCI_OS_PCI_X) == 0;
+}
+
static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val)
{
writel(val, hw->regs + reg);
@@ -1952,25 +1919,4 @@ static inline void gma_set_addr(struct s
gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
}
-
-/* PCI config space access */
-static inline u32 sky2_pci_read32(const struct sky2_hw *hw, unsigned reg)
-{
- return sky2_read32(hw, Y2_CFG_SPC + reg);
-}
-
-static inline u16 sky2_pci_read16(const struct sky2_hw *hw, unsigned reg)
-{
- return sky2_read16(hw, Y2_CFG_SPC + reg);
-}
-
-static inline void sky2_pci_write32(struct sky2_hw *hw, unsigned reg, u32 val)
-{
- sky2_write32(hw, Y2_CFG_SPC + reg, val);
-}
-
-static inline void sky2_pci_write16(struct sky2_hw *hw, unsigned reg, u16 val)
-{
- sky2_write16(hw, Y2_CFG_SPC + reg, val);
-}
#endif
--
http://www.hailfinger.org/
^ permalink raw reply
* Re: [Announce] Intel PRO/Wireless 3945ABG Network Connection
From: Larry Finger @ 2006-02-25 22:47 UTC (permalink / raw)
To: matthieu castet; +Cc: John Stoffel, linux-kernel, netdev
In-Reply-To: <4400DA0B.1060502@free.fr>
matthieu castet wrote:
> And what happen with the userspace binary blob ?
>
> How it will know in which country you are ?
> Does it access to a secret GPS on your computer ?
>
> So there are 2 solutions :
> - make the card work only for a country with a flag in a RO eeprom or in
> another place in the hardware (firmware, ....).
> - make the card works on all the possible channels.
>
> Also if the firmware need to be load each time you reset the card (this
> is the case with the current ipw2xxx implementation), you won't notice
> if you switch for a firmware for a country X to a firmware for a country Y.
I haven't looked at the driver code, but I would expect it to be like the ipw2200 where the
"country" code is in eeprom, which sets a code specifying the region where it will work. If you take
a given piece of hardware somewhere else in the world, it will likely not be in complience.
Larry
^ permalink raw reply
* Re: [2.6 patch] make UNIX a bool
From: Olaf Hering @ 2006-02-25 22:46 UTC (permalink / raw)
To: Adrian Bunk; +Cc: Andrew Morton, netdev, linux-kernel
In-Reply-To: <20060225160150.GX3674@stusta.de>
On Sat, Feb 25, Adrian Bunk wrote:
> CONFIG_UNIX=m doesn't make much sense.
There is likely more code to support a modular unix.ko, this has to go
as well.
^ permalink raw reply
* Re: [Announce] Intel PRO/Wireless 3945ABG Network Connection
From: matthieu castet @ 2006-02-25 22:28 UTC (permalink / raw)
To: John Stoffel; +Cc: linux-kernel, netdev
In-Reply-To: <17408.55266.948833.168988@smtp.charter.net>
Hi,
John Stoffel wrote:
>>>>>>"Matthieu" == Matthieu CASTET <castet.matthieu@free.fr> writes:
>
>
> Matthieu> I will say, why not put the restriction of the firmware
> Matthieu> binary blob ? It run on the device so it will be difficult
> Matthieu> for people to analyse it.
>
> So what do I do when I take my US laptop and fly to country X, which
> has comletely different rules for these radios? Do I have to re-flash
> my firmware to make it work properly?
>
And what happen with the userspace binary blob ?
How it will know in which country you are ?
Does it access to a secret GPS on your computer ?
So there are 2 solutions :
- make the card work only for a country with a flag in a RO eeprom or in
another place in the hardware (firmware, ....).
- make the card works on all the possible channels.
Also if the firmware need to be load each time you reset the card (this
is the case with the current ipw2xxx implementation), you won't notice
if you switch for a firmware for a country X to a firmware for a country Y.
Matthieu
^ permalink raw reply
* Re: [Announce] Intel PRO/Wireless 3945ABG Network Connection
From: John Stoffel @ 2006-02-25 22:19 UTC (permalink / raw)
To: Matthieu CASTET; +Cc: linux-kernel, netdev
In-Reply-To: <pan.2006.02.25.22.07.53.810642@free.fr>
>>>>> "Matthieu" == Matthieu CASTET <castet.matthieu@free.fr> writes:
Matthieu> I will say, why not put the restriction of the firmware
Matthieu> binary blob ? It run on the device so it will be difficult
Matthieu> for people to analyse it.
So what do I do when I take my US laptop and fly to country X, which
has comletely different rules for these radios? Do I have to re-flash
my firmware to make it work properly?
The big problem is the lack of global unity, but that will slowly get
fixes as more countries realize it's a problem. The big issue will be
military/govt radio spectrum users, they won't want to move if they
can help it.
John
^ permalink raw reply
* Re: [Announce] Intel PRO/Wireless 3945ABG Network Connection
From: Matthieu CASTET @ 2006-02-25 22:07 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev
In-Reply-To: <Pine.LNX.4.61.0602251518200.31692@yvahk01.tjqt.qr>
Hi everybody,
Le Sat, 25 Feb 2006 15:19:40 +0100, Jan Engelhardt a écrit :
>>If the modules crc changes,
>>it must do an instant disable of the transmitter functions and exit or
>>crash, thereby precluding any 'hot rodding' of the chipset.
>>
> Would not it be easiest to have the chipset enforce the acceptable bands?
> So that software can't switch the chipset to 1337 GHz no matter how hard
> you forward/reverse-engineer it.
>
I will say, why not put the restriction of the firmware binary blob ?
It run on the device so it will be difficult for people to analyse it.
Also the firmware could be on a eeprom and transparent for the user.
Matthieu
^ permalink raw reply
* [git patch] net driver fix
From: Jeff Garzik @ 2006-02-25 22:03 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel
Please pull from 'upstream-fixes' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
to receive the following updates:
drivers/net/sis900.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
Daniele Venzano:
Fix Wake on LAN support in sis900
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 3d95fa2..7a952fe 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -540,7 +540,7 @@ static int __devinit sis900_probe(struct
printk("%2.2x.\n", net_dev->dev_addr[i]);
/* Detect Wake on Lan support */
- ret = inl(CFGPMC & PMESP);
+ ret = (inl(net_dev->base_addr + CFGPMC) & PMESP) >> 27;
if (netif_msg_probe(sis_priv) && (ret & PME_D3C) == 0)
printk(KERN_INFO "%s: Wake on LAN only available from suspend to RAM.", net_dev->name);
@@ -2040,7 +2040,7 @@ static int sis900_set_wol(struct net_dev
if (wol->wolopts == 0) {
pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr);
- cfgpmcsr |= ~PME_EN;
+ cfgpmcsr &= ~PME_EN;
pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr);
outl(pmctrl_bits, pmctrl_addr);
if (netif_msg_wol(sis_priv))
^ permalink raw reply related
* [PATCH 6/6] pktgen: Updates version.
From: Luiz Fernando Capitulino @ 2006-02-25 19:08 UTC (permalink / raw)
To: davem; +Cc: lkml, netdev, robert.olsson
With all the previous changes, we're at a new version now.
Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>
---
net/core/pktgen.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
32d9b9951586e505b4b8bc587f9e170612a48a4d
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 5d13626..2221b86 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -153,7 +153,7 @@
#include <asm/div64.h> /* do_div */
#include <asm/timex.h>
-#define VERSION "pktgen v2.64: Packet Generator for packet performance testing.\n"
+#define VERSION "pktgen v2.65: Packet Generator for packet performance testing.\n"
/* #define PG_DEBUG(a) a */
#define PG_DEBUG(a)
--
1.2.1.g3397f9
--
Luiz Fernando N. Capitulino
^ permalink raw reply related
* [PATCH 5/6] pktgen: Ports if_list to the in-kernel implementation.
From: Luiz Fernando Capitulino @ 2006-02-25 19:08 UTC (permalink / raw)
To: davem; +Cc: lkml, netdev, robert.olsson
This patch ports the per-thread interface list list to the in-kernel linked
list implementation. In the general, the resulting code is a bit simpler.
Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>
---
net/core/pktgen.c | 92 +++++++++++++++++++++++++----------------------------
1 files changed, 44 insertions(+), 48 deletions(-)
31bc49027940cd679fff67215c72c82fe958ad20
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 89480e3..5d13626 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -210,7 +210,7 @@ struct pktgen_dev {
char result[512];
struct pktgen_thread *pg_thread; /* the owner */
- struct pktgen_dev *next; /* Used for chaining in the thread's run-queue */
+ struct list_head list; /* Used for chaining in the thread's run-queue */
int running; /* if this changes to false, the test will stop */
@@ -330,7 +330,7 @@ struct pktgen_hdr {
struct pktgen_thread {
spinlock_t if_lock;
- struct pktgen_dev *if_list; /* All device here */
+ struct list_head if_list; /* All device here */
struct list_head th_list;
int removed;
char name[32];
@@ -1378,7 +1378,7 @@ static struct file_operations pktgen_if_
static int pktgen_thread_show(struct seq_file *seq, void *v)
{
struct pktgen_thread *t = seq->private;
- struct pktgen_dev *pkt_dev = NULL;
+ struct pktgen_dev *pkt_dev;
BUG_ON(!t);
@@ -1388,13 +1388,13 @@ static int pktgen_thread_show(struct seq
seq_printf(seq, "Running: ");
if_lock(t);
- for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next)
+ list_for_each_entry(pkt_dev, &t->if_list, list)
if (pkt_dev->running)
seq_printf(seq, "%s ", pkt_dev->ifname);
seq_printf(seq, "\nStopped: ");
- for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next)
+ list_for_each_entry(pkt_dev, &t->if_list, list)
if (!pkt_dev->running)
seq_printf(seq, "%s ", pkt_dev->ifname);
@@ -2421,13 +2421,13 @@ static void pktgen_clear_counters(struct
static void pktgen_run(struct pktgen_thread *t)
{
- struct pktgen_dev *pkt_dev = NULL;
+ struct pktgen_dev *pkt_dev;
int started = 0;
PG_DEBUG(printk("pktgen: entering pktgen_run. %p\n", t));
if_lock(t);
- for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next) {
+ list_for_each_entry(pkt_dev, &t->if_list, list) {
/*
* setup odev and create initial packet.
@@ -2468,15 +2468,14 @@ static void pktgen_stop_all_threads_ifs(
static int thread_is_running(struct pktgen_thread *t)
{
- struct pktgen_dev *next;
+ struct pktgen_dev *pkt_dev;
int res = 0;
- for (next = t->if_list; next; next = next->next) {
- if (next->running) {
+ list_for_each_entry(pkt_dev, &t->if_list, list)
+ if (pkt_dev->running) {
res = 1;
break;
}
- }
return res;
}
@@ -2597,17 +2596,17 @@ static int pktgen_stop_device(struct pkt
static struct pktgen_dev *next_to_run(struct pktgen_thread *t)
{
- struct pktgen_dev *next, *best = NULL;
+ struct pktgen_dev *pkt_dev, *best = NULL;
if_lock(t);
- for (next = t->if_list; next; next = next->next) {
- if (!next->running)
+ list_for_each_entry(pkt_dev, &t->if_list, list) {
+ if (!pkt_dev->running)
continue;
if (best == NULL)
- best = next;
- else if (next->next_tx_us < best->next_tx_us)
- best = next;
+ best = pkt_dev;
+ else if (pkt_dev->next_tx_us < best->next_tx_us)
+ best = pkt_dev;
}
if_unlock(t);
return best;
@@ -2615,18 +2614,18 @@ static struct pktgen_dev *next_to_run(st
static void pktgen_stop(struct pktgen_thread *t)
{
- struct pktgen_dev *next = NULL;
+ struct pktgen_dev *pkt_dev;
PG_DEBUG(printk("pktgen: entering pktgen_stop\n"));
if_lock(t);
- for (next = t->if_list; next; next = next->next) {
- pktgen_stop_device(next);
- if (next->skb)
- kfree_skb(next->skb);
+ list_for_each_entry(pkt_dev, &t->if_list, list) {
+ pktgen_stop_device(pkt_dev);
+ if (pkt_dev->skb)
+ kfree_skb(pkt_dev->skb);
- next->skb = NULL;
+ pkt_dev->skb = NULL;
}
if_unlock(t);
@@ -2638,14 +2637,15 @@ static void pktgen_stop(struct pktgen_th
*/
static void pktgen_rem_one_if(struct pktgen_thread *t)
{
- struct pktgen_dev *cur, *next = NULL;
+ struct list_head *q, *n;
+ struct pktgen_dev *cur;
PG_DEBUG(printk("pktgen: entering pktgen_rem_one_if\n"));
if_lock(t);
- for (cur = t->if_list; cur; cur = next) {
- next = cur->next;
+ list_for_each_safe(q, n, &t->if_list) {
+ cur = list_entry(q, struct pktgen_dev, list);
if (!cur->removal_mark)
continue;
@@ -2664,15 +2664,16 @@ static void pktgen_rem_one_if(struct pkt
static void pktgen_rem_all_ifs(struct pktgen_thread *t)
{
- struct pktgen_dev *cur, *next = NULL;
+ struct list_head *q, *n;
+ struct pktgen_dev *cur;
/* Remove all devices, free mem */
PG_DEBUG(printk("pktgen: entering pktgen_rem_all_ifs\n"));
if_lock(t);
- for (cur = t->if_list; cur; cur = next) {
- next = cur->next;
+ list_for_each_safe(q, n, &t->if_list) {
+ cur = list_entry(q, struct pktgen_dev, list);
if (cur->skb)
kfree_skb(cur->skb);
@@ -2959,14 +2960,14 @@ static void pktgen_thread_worker(struct
static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
const char *ifname)
{
- struct pktgen_dev *pkt_dev = NULL;
+ struct pktgen_dev *p, *pkt_dev = NULL;
if_lock(t);
- for (pkt_dev = t->if_list; pkt_dev; pkt_dev = pkt_dev->next) {
- if (strncmp(pkt_dev->ifname, ifname, IFNAMSIZ) == 0) {
+ list_for_each_entry(p, &t->if_list, list)
+ if (strncmp(p->ifname, ifname, IFNAMSIZ) == 0) {
+ pkt_dev = p;
break;
}
- }
if_unlock(t);
PG_DEBUG(printk("pktgen: find_dev(%s) returning %p\n", ifname, pkt_dev));
@@ -2989,8 +2990,8 @@ static int add_dev_to_thread(struct pktg
rv = -EBUSY;
goto out;
}
- pkt_dev->next = t->if_list;
- t->if_list = pkt_dev;
+
+ list_add(&pkt_dev->list, &t->if_list);
pkt_dev->pg_thread = t;
pkt_dev->running = 0;
@@ -3117,6 +3118,8 @@ static int __init pktgen_create_thread(c
pe->proc_fops = &pktgen_thread_fops;
pe->data = t;
+ INIT_LIST_HEAD(&t->if_list);
+
list_add_tail(&t->th_list, &pktgen_threads);
t->removed = 0;
@@ -3140,20 +3143,13 @@ static int __init pktgen_create_thread(c
static void _rem_dev_from_if_list(struct pktgen_thread *t,
struct pktgen_dev *pkt_dev)
{
- struct pktgen_dev *i, *prev = NULL;
-
- i = t->if_list;
+ struct list_head *q, *n;
+ struct pktgen_dev *p;
- while (i) {
- if (i == pkt_dev) {
- if (prev)
- prev->next = i->next;
- else
- t->if_list = NULL;
- break;
- }
- prev = i;
- i = i->next;
+ list_for_each_safe(q, n, &t->if_list) {
+ p = list_entry(q, struct pktgen_dev, list);
+ if (p == pkt_dev)
+ list_del(&p->list);
}
}
--
1.2.1.g3397f9
--
Luiz Fernando N. Capitulino
^ permalink raw reply related
* [PATCH 4/6] pktgen: Fix Initialization fail leak.
From: Luiz Fernando Capitulino @ 2006-02-25 19:08 UTC (permalink / raw)
To: davem; +Cc: lkml, netdev, robert.olsson
Even if pktgen's thread initialization fails for all CPUs, the module
will be successfully loaded.
This patch changes that behaivor, by returning an error on module load time,
and also freeing all the resources allocated. It also prints a warning if a
thread initialization has failed.
Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>
---
net/core/pktgen.c | 15 ++++++++++++++-
1 files changed, 14 insertions(+), 1 deletions(-)
7084c4ee538fcac59f0d9f64c840c45f8caeab8f
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 1c565fe..89480e3 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -3216,11 +3216,24 @@ static int __init pg_init(void)
register_netdevice_notifier(&pktgen_notifier_block);
for_each_online_cpu(cpu) {
+ int err;
char buf[30];
sprintf(buf, "kpktgend_%i", cpu);
- pktgen_create_thread(buf, cpu);
+ err = pktgen_create_thread(buf, cpu);
+ if (err)
+ printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n",
+ cpu, err);
}
+
+ if (list_empty(&pktgen_threads)) {
+ printk("pktgen: ERROR: Initialization failed for all threads\n");
+ unregister_netdevice_notifier(&pktgen_notifier_block);
+ remove_proc_entry(PGCTRL, pg_proc_dir);
+ proc_net_remove(PG_PROC_DIR);
+ return -ENODEV;
+ }
+
return 0;
}
--
1.2.1.g3397f9
--
Luiz Fernando N. Capitulino
^ permalink raw reply related
* [PATCH 3/6] pktgen: Fix kernel_thread() fail leak.
From: Luiz Fernando Capitulino @ 2006-02-25 19:08 UTC (permalink / raw)
To: davem; +Cc: lkml, netdev, robert.olsson
Free all the alocated resources if kernel_thread() call fails.
Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>
---
net/core/pktgen.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
c3fd9c4bbddab18349563c0c5d90c4bf0002de99
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 2d6b147..1c565fe 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -3082,6 +3082,7 @@ static struct pktgen_thread *__init pktg
static int __init pktgen_create_thread(const char *name, int cpu)
{
+ int err;
struct pktgen_thread *t = NULL;
struct proc_dir_entry *pe;
@@ -3120,9 +3121,15 @@ static int __init pktgen_create_thread(c
t->removed = 0;
- if (kernel_thread((void *)pktgen_thread_worker, (void *)t,
- CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
+ err = kernel_thread((void *)pktgen_thread_worker, (void *)t,
+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+ if (err < 0) {
printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
+ remove_proc_entry(t->name, pg_proc_dir);
+ list_del(&t->th_list);
+ kfree(t);
+ return err;
+ }
return 0;
}
--
1.2.1.g3397f9
--
Luiz Fernando N. Capitulino
^ permalink raw reply related
* [PATCH 2/6] pktgen: Ports thread list to Kernel list implementation.
From: Luiz Fernando Capitulino @ 2006-02-25 19:07 UTC (permalink / raw)
To: davem; +Cc: lkml, netdev, robert.olsson
The final result is a simpler and smaller code.
Note that I'm adding a new member in the struct pktgen_thread called
'removed'. The reason is that I didn't find a better wait condition to be
used in the place of the replaced one.
Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br>
---
net/core/pktgen.c | 96 +++++++++++++++++++++++------------------------------
1 files changed, 41 insertions(+), 55 deletions(-)
adfe3dff7664210019900b6436e3e5a25f55726a
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 580b65e..2d6b147 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -125,6 +125,7 @@
#include <linux/capability.h>
#include <linux/delay.h>
#include <linux/timer.h>
+#include <linux/list.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
@@ -330,7 +331,8 @@ struct pktgen_hdr {
struct pktgen_thread {
spinlock_t if_lock;
struct pktgen_dev *if_list; /* All device here */
- struct pktgen_thread *next;
+ struct list_head th_list;
+ int removed;
char name[32];
char result[512];
u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
@@ -492,7 +494,7 @@ static int pg_clone_skb_d;
static int debug;
static DECLARE_MUTEX(pktgen_sem);
-static struct pktgen_thread *pktgen_threads = NULL;
+static LIST_HEAD(pktgen_threads);
static struct notifier_block pktgen_notifier_block = {
.notifier_call = pktgen_device_event,
@@ -1522,9 +1524,7 @@ static struct pktgen_dev *__pktgen_NN_th
struct pktgen_thread *t;
struct pktgen_dev *pkt_dev = NULL;
- t = pktgen_threads;
-
- while (t) {
+ list_for_each_entry(t, &pktgen_threads, th_list) {
pkt_dev = pktgen_find_dev(t, ifname);
if (pkt_dev) {
if (remove) {
@@ -1535,7 +1535,6 @@ static struct pktgen_dev *__pktgen_NN_th
}
break;
}
- t = t->next;
}
return pkt_dev;
}
@@ -2455,15 +2454,15 @@ static void pktgen_run(struct pktgen_thr
static void pktgen_stop_all_threads_ifs(void)
{
- struct pktgen_thread *t = pktgen_threads;
+ struct pktgen_thread *t;
PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads_ifs.\n"));
thread_lock();
- while (t) {
+
+ list_for_each_entry(t, &pktgen_threads, th_list)
t->control |= T_STOP;
- t = t->next;
- }
+
thread_unlock();
}
@@ -2503,40 +2502,36 @@ signal:
static int pktgen_wait_all_threads_run(void)
{
- struct pktgen_thread *t = pktgen_threads;
+ struct pktgen_thread *t;
int sig = 1;
- while (t) {
+ thread_lock();
+
+ list_for_each_entry(t, &pktgen_threads, th_list) {
sig = pktgen_wait_thread_run(t);
if (sig == 0)
break;
- thread_lock();
- t = t->next;
- thread_unlock();
}
- if (sig == 0) {
- thread_lock();
- while (t) {
+
+ if (sig == 0)
+ list_for_each_entry(t, &pktgen_threads, th_list)
t->control |= (T_STOP);
- t = t->next;
- }
- thread_unlock();
- }
+
+ thread_unlock();
return sig;
}
static void pktgen_run_all_threads(void)
{
- struct pktgen_thread *t = pktgen_threads;
+ struct pktgen_thread *t;
PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n"));
thread_lock();
- while (t) {
+ list_for_each_entry(t, &pktgen_threads, th_list)
t->control |= (T_RUN);
- t = t->next;
- }
+
thread_unlock();
schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */
@@ -2693,24 +2688,12 @@ static void pktgen_rem_thread(struct pkt
{
/* Remove from the thread list */
- struct pktgen_thread *tmp = pktgen_threads;
-
remove_proc_entry(t->name, pg_proc_dir);
thread_lock();
- if (tmp == t)
- pktgen_threads = tmp->next;
- else {
- while (tmp) {
- if (tmp->next == t) {
- tmp->next = t->next;
- t->next = NULL;
- break;
- }
- tmp = tmp->next;
- }
- }
+ list_del(&t->th_list);
+
thread_unlock();
}
@@ -2969,6 +2952,8 @@ static void pktgen_thread_worker(struct
PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name));
pktgen_rem_thread(t);
+
+ t->removed = 1;
}
static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
@@ -3081,19 +3066,18 @@ static int pktgen_add_device(struct pktg
static struct pktgen_thread *__init pktgen_find_thread(const char *name)
{
- struct pktgen_thread *t = NULL;
+ struct pktgen_thread *t;
thread_lock();
- t = pktgen_threads;
- while (t) {
- if (strcmp(t->name, name) == 0)
- break;
+ list_for_each_entry(t, &pktgen_threads, th_list)
+ if (strcmp(t->name, name) == 0) {
+ thread_unlock();
+ return t;
+ }
- t = t->next;
- }
thread_unlock();
- return t;
+ return NULL;
}
static int __init pktgen_create_thread(const char *name, int cpu)
@@ -3132,8 +3116,9 @@ static int __init pktgen_create_thread(c
pe->proc_fops = &pktgen_thread_fops;
pe->data = t;
- t->next = pktgen_threads;
- pktgen_threads = t;
+ list_add_tail(&t->th_list, &pktgen_threads);
+
+ t->removed = 0;
if (kernel_thread((void *)pktgen_thread_worker, (void *)t,
CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
@@ -3234,17 +3219,18 @@ static int __init pg_init(void)
static void __exit pg_cleanup(void)
{
+ struct pktgen_thread *t;
+ struct list_head *q, *n;
wait_queue_head_t queue;
init_waitqueue_head(&queue);
/* Stop all interfaces & threads */
- while (pktgen_threads) {
- struct pktgen_thread *t = pktgen_threads;
- pktgen_threads->control |= (T_TERMINATE);
+ list_for_each_safe(q, n, &pktgen_threads) {
+ t = list_entry(q, struct pktgen_thread, th_list);
+ t->control |= (T_TERMINATE);
- wait_event_interruptible_timeout(queue, (t != pktgen_threads),
- HZ);
+ wait_event_interruptible_timeout(queue, (t->removed == 1), HZ);
}
/* Un-register us from receiving netdevice events */
--
1.2.1.g3397f9
--
Luiz Fernando N. Capitulino
^ permalink raw reply related
* [PATCH 1/6] pktgen: Lindent run.
From: Luiz Fernando Capitulino @ 2006-02-25 19:07 UTC (permalink / raw)
To: davem; +Cc: lkml, netdev, robert.olsson
This patch is not in-lined because it's 124K bytes long, you can get it at:
http://www.cpu.eti.br/patches/0001-pktgen-Lindent-run.patch
--
Luiz Fernando N. Capitulino
^ permalink raw reply
* [PATCH 0/6] pktgen: refinements and small fixes (V3).
From: Luiz Fernando Capitulino @ 2006-02-25 19:07 UTC (permalink / raw)
To: davem; +Cc: lkml, netdev, robert.olsson
Hi David,
As you've asked, I'm sending again my patches for pktgen:
[PATCH 1/6] pktgen: Lindent run.
[PATCH 2/6] pktgen: Ports thread list to Kernel list implementation.
[PATCH 3/6] pktgen: Fix kernel_thread() fail leak.
[PATCH 4/6] pktgen: Fix Initialization fail leak.
[PATCH 5/6] pktgen: Ports if_list to the in-kernel implementation.
[PATCH 6/6] pktgen: Updates version.
The changes from V2 are:
1. Generated all the patches again agaisnt current net-2.6.17 tree
2. Added the if_list port patch to the series, because it was sent
separately last time
3. Added a patch to updates pktgen's version (forgot this one first
time).
As I did before, all the patches were tested with QEMU emulating a four
CPU machine with four NICS.
Also note that Robert have already acked patches 1 to 4.
Thanks,
--
Luiz Fernando N. Capitulino
^ permalink raw reply
* Re: [2.6 patch] make UNIX a bool
From: Arjan van de Ven @ 2006-02-25 17:28 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Adrian Bunk, Andrew Morton, netdev, linux-kernel
In-Reply-To: <44009024.5050105@osdl.org>
On Sat, 2006-02-25 at 09:13 -0800, Stephen Hemminger wrote:
> Adrian Bunk wrote:
> > CONFIG_UNIX=m doesn't make much sense.
> >
> >
> > Signed-off-by: Adrian Bunk <bunk@stusta.de>
> >
> >
> >
> Why? You can build unix domain sockets as a loadable module and
> it runs fine (or it did last I tried). Whether that makes sense from a
> distribution point of
you didn't use to when modutils used unix sockets internally :)
unix also needs a bunch of deeply internals exported that apparently
people want to play with...
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox