提交 9028780a 编写于 作者: L Linus Torvalds

Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (40 commits)
  [netdrvr] atl1: fix build
  pasemi_mac: Use local-mac-address instead of mac-address if available
  pasemi_mac: PHY support
  pasemi_mac: Add msglevel support and "debug" module param
  pasemi_mac: Logic cleanup / rx performance improvements
  pasemi_mac: Minor cleanup / define fixes
  pasemi_mac: Add SKB reuse / copy-break
  pasemi_mac: Timer and interrupt fixes
  pasemi_mac: Abstract and fix up interrupt restart routines
  pasemi_mac: Move the IRQ mapping from the PCI layer to the driver
  tc35815: Remove unnecessary skb->dev assignment
  drivers/net/dm9000: Convert to generic boolean
  AT91RM9200 Ethernet: Fix multicast addressing
  AT91RM9200 Ethernet: Support additional PHYs
  PCMCIA-NETDEV : xirc2ps_cs: bugfix of multicast code
  sky2: re-enable 88E8056 for most motherboards
  MIPS: Drop unnecessary CONFIG_ISA from RBTX49XX
  ne: MIPS: Use platform_driver for ne on RBTX49XX
  ne: Add NEEDS_PORTLIST to control ISA auto-probe
  ne: Misc fixes for platform driver.
  ...

Fix conflict in drivers/net/pasemi_mac.c (get_property() got renamed to
of_get_property()) manually.
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
......@@ -784,7 +784,6 @@ config TOSHIBA_RBTX4927
select HAS_TXX9_SERIAL
select HW_HAS_PCI
select I8259
select ISA
select SWAP_IO_SPACE
select SYS_HAS_CPU_TX49XX
select SYS_SUPPORTS_32BIT_KERNEL
......@@ -806,7 +805,6 @@ config TOSHIBA_RBTX4938
select HAS_TXX9_SERIAL
select HW_HAS_PCI
select I8259
select ISA
select SWAP_IO_SPACE
select SYS_HAS_CPU_TX49XX
select SYS_SUPPORTS_32BIT_KERNEL
......
......@@ -245,7 +245,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
#
CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_ISA=y
CONFIG_MMU=y
#
......@@ -573,7 +572,6 @@ CONFIG_MTD_CFI_UTIL=y
#
# Plug and Play support
#
# CONFIG_PNP is not set
# CONFIG_PNPACPI is not set
#
......@@ -658,7 +656,6 @@ CONFIG_BLK_DEV_IT8213=m
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_TC86C001=m
# CONFIG_IDE_ARM is not set
# CONFIG_IDE_CHIPSETS is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
# CONFIG_IDEDMA_AUTO is not set
......@@ -676,11 +673,6 @@ CONFIG_RAID_ATTRS=m
#
# CONFIG_ATA is not set
#
# Old CD-ROM drivers (not SCSI, not IDE)
#
# CONFIG_CD_NO_IDESCSI is not set
#
# Multi-device support (RAID and LVM)
#
......@@ -742,37 +734,20 @@ CONFIG_NET_ETHERNET=y
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_DM9000 is not set
# CONFIG_NET_VENDOR_RACAL is not set
#
# Tulip family network device support
#
# CONFIG_NET_TULIP is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
CONFIG_NET_ISA=y
# CONFIG_E2100 is not set
# CONFIG_EWRK3 is not set
# CONFIG_EEXPRESS is not set
# CONFIG_EEXPRESS_PRO is not set
# CONFIG_HPLAN_PLUS is not set
# CONFIG_HPLAN is not set
# CONFIG_LP486E is not set
# CONFIG_ETH16I is not set
CONFIG_NE2000=y
# CONFIG_SEEQ8005 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
# CONFIG_CS89x0 is not set
# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
......@@ -833,8 +808,6 @@ CONFIG_NET_RADIO=y
# Obsolete Wireless cards support (pre-802.11)
#
# CONFIG_STRIP is not set
# CONFIG_ARLAN is not set
# CONFIG_WAVELAN is not set
#
# Wireless 802.11b ISA/PCI cards support
......@@ -920,9 +893,6 @@ CONFIG_KEYBOARD_ATKBD=y
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_LOGIBM is not set
# CONFIG_MOUSE_PC110PAD is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
......@@ -1072,7 +1042,6 @@ CONFIG_FB_ATY_CT=y
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
# CONFIG_FRAMEBUFFER_CONSOLE is not set
......
......@@ -1049,3 +1049,22 @@ static int __init toshiba_rbtx4927_rtc_init(void)
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
device_initcall(toshiba_rbtx4927_rtc_init);
static int __init rbtx4927_ne_init(void)
{
static struct resource __initdata res[] = {
{
.start = RBTX4927_RTL_8019_BASE,
.end = RBTX4927_RTL_8019_BASE + 0x20 - 1,
.flags = IORESOURCE_IO,
}, {
.start = RBTX4927_RTL_8019_IRQ,
.flags = IORESOURCE_IRQ,
}
};
struct platform_device *dev =
platform_device_register_simple("ne", -1,
res, ARRAY_SIZE(res));
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
device_initcall(rbtx4927_ne_init);
......@@ -20,6 +20,7 @@
#include <linux/console.h>
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <asm/wbflush.h>
#include <asm/reboot.h>
......@@ -1037,3 +1038,22 @@ static int __init tx4938_spi_proc_setup(void)
__initcall(tx4938_spi_proc_setup);
#endif
static int __init rbtx4938_ne_init(void)
{
struct resource res[] = {
{
.start = RBTX4938_RTL_8019_BASE,
.end = RBTX4938_RTL_8019_BASE + 0x20 - 1,
.flags = IORESOURCE_IO,
}, {
.start = RBTX4938_RTL_8019_IRQ,
.flags = IORESOURCE_IRQ,
}
};
struct platform_device *dev =
platform_device_register_simple("ne", -1,
res, ARRAY_SIZE(res));
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
device_initcall(rbtx4938_ne_init);
......@@ -173,19 +173,6 @@ static void __init pas_fixup_phb_resources(void)
}
void __devinit pas_pci_irq_fixup(struct pci_dev *dev)
{
/* DMA is special, 84 interrupts (128 -> 211), all but 128
* need to be mapped by hand here.
*/
if (dev->vendor == 0x1959 && dev->device == 0xa007) {
int i;
for (i = 129; i < 212; i++)
irq_create_mapping(NULL, i);
}
}
void __init pas_pci_init(void)
{
struct device_node *np, *root;
......
......@@ -251,5 +251,4 @@ define_machine(pas) {
.calibrate_decr = generic_calibrate_decr,
.progress = pas_progress,
.machine_check_exception = pas_machine_check_handler,
.pci_irq_fixup = pas_pci_irq_fixup,
};
......@@ -1104,7 +1104,7 @@ config ETH16I
config NE2000
tristate "NE2000/NE1000 support"
depends on NET_ISA || (Q40 && m) || M32R
depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938
select CRC32
---help---
If you have a network (Ethernet) card of this type, say Y and read
......@@ -2488,6 +2488,7 @@ config NETXEN_NIC
config PASEMI_MAC
tristate "PA Semi 1/10Gbit MAC"
depends on PPC64 && PCI
select PHYLIB
help
This driver supports the on-chip 1/10Gbit Ethernet controller on
PA Semi's PWRficient line of chips.
......
......@@ -225,6 +225,16 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id)
if (!(phy & ((1 << 2) | 1)))
goto done;
}
else if (lp->phy_type == MII_T78Q21x3_ID) { /* ack interrupt in Teridian PHY */
read_phy(lp->phy_address, MII_T78Q21INT_REG, &phy);
if (!(phy & ((1 << 2) | 1)))
goto done;
}
else if (lp->phy_type == MII_DP83848_ID) {
read_phy(lp->phy_address, MII_DPPHYSTS_REG, &phy); /* ack interrupt in DP83848 PHY */
if (!(phy & (1 << 7)))
goto done;
}
update_linkspeed(dev, 0);
......@@ -280,6 +290,19 @@ static void enable_phyirq(struct net_device *dev)
dsintr = (1 << 10) | ( 1 << 8);
write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
}
else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */
read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
dsintr = dsintr | 0x500; /* set bits 8, 10 */
write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
}
else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */
read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
dsintr = dsintr | 0x3c; /* set bits 2..5 */
write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
dsintr = dsintr | 0x3; /* set bits 0,1 */
write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
}
disable_mdi();
spin_unlock_irq(&lp->lock);
......@@ -323,6 +346,19 @@ static void disable_phyirq(struct net_device *dev)
dsintr = ~((1 << 10) | (1 << 8));
write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
}
else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */
read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
dsintr = dsintr & ~0x500; /* clear bits 8, 10 */
write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
}
else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */
read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
dsintr = dsintr & ~0x3; /* clear bits 0, 1 */
write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
dsintr = dsintr & ~0x3c; /* clear bits 2..5 */
write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
}
disable_mdi();
spin_unlock_irq(&lp->lock);
......@@ -535,8 +571,8 @@ static void at91ether_sethashtable(struct net_device *dev)
mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
}
at91_emac_write(AT91_EMAC_HSH, mc_filter[0]);
at91_emac_write(AT91_EMAC_HSL, mc_filter[1]);
at91_emac_write(AT91_EMAC_HSL, mc_filter[0]);
at91_emac_write(AT91_EMAC_HSH, mc_filter[1]);
}
/*
......@@ -1062,10 +1098,16 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name);
else if (phy_type == MII_DP83847_ID)
printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name);
else if (phy_type == MII_DP83848_ID)
printk(KERN_INFO "%s: National Semiconductor DP83848 PHY\n", dev->name);
else if (phy_type == MII_AC101L_ID)
printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name);
else if (phy_type == MII_KS8721_ID)
printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name);
else if (phy_type == MII_T78Q21x3_ID)
printk(KERN_INFO "%s: Teridian 78Q21x3 PHY\n", dev->name);
else if (phy_type == MII_LAN83C185_ID)
printk(KERN_INFO "%s: SMSC LAN83C185 PHY\n", dev->name);
return 0;
}
......@@ -1103,8 +1145,11 @@ static int __init at91ether_probe(struct platform_device *pdev)
case MII_RTL8201_ID: /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */
case MII_BCM5221_ID: /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */
case MII_DP83847_ID: /* National Semiconductor DP83847: */
case MII_DP83848_ID: /* National Semiconductor DP83848: */
case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */
case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
case MII_T78Q21x3_ID: /* Teridian 78Q21x3: PHY_ID1 = 0x0E, PHY_ID2 = 7237 */
case MII_LAN83C185_ID: /* SMSC LAN83C185: PHY_ID1 = 0x0007, PHY_ID2 = 0xC0A1 */
detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk);
break;
}
......
......@@ -17,39 +17,46 @@
/* Davicom 9161 PHY */
#define MII_DM9161_ID 0x0181b880
#define MII_DM9161A_ID 0x0181b8a0
/* Davicom specific registers */
#define MII_DSCR_REG 16
#define MII_DSCSR_REG 17
#define MII_DSINTR_REG 21
#define MII_DM9161_ID 0x0181b880
#define MII_DM9161A_ID 0x0181b8a0
#define MII_DSCR_REG 16
#define MII_DSCSR_REG 17
#define MII_DSINTR_REG 21
/* Intel LXT971A PHY */
#define MII_LXT971A_ID 0x001378E0
/* Intel specific registers */
#define MII_ISINTE_REG 18
#define MII_ISINTS_REG 19
#define MII_LEDCTRL_REG 20
#define MII_LXT971A_ID 0x001378E0
#define MII_ISINTE_REG 18
#define MII_ISINTS_REG 19
#define MII_LEDCTRL_REG 20
/* Realtek RTL8201 PHY */
#define MII_RTL8201_ID 0x00008200
#define MII_RTL8201_ID 0x00008200
/* Broadcom BCM5221 PHY */
#define MII_BCM5221_ID 0x004061e0
/* Broadcom specific registers */
#define MII_BCMINTR_REG 26
#define MII_BCM5221_ID 0x004061e0
#define MII_BCMINTR_REG 26
/* National Semiconductor DP83847 */
#define MII_DP83847_ID 0x20005c30
#define MII_DP83847_ID 0x20005c30
/* National Semiconductor DP83848 */
#define MII_DP83848_ID 0x20005c90
#define MII_DPPHYSTS_REG 16
#define MII_DPMICR_REG 17
#define MII_DPMISR_REG 18
/* Altima AC101L PHY */
#define MII_AC101L_ID 0x00225520
#define MII_AC101L_ID 0x00225520
/* Micrel KS8721 PHY */
#define MII_KS8721_ID 0x00221610
#define MII_KS8721_ID 0x00221610
/* Teridian 78Q2123/78Q2133 */
#define MII_T78Q21x3_ID 0x000e7230
#define MII_T78Q21INT_REG 17
/* SMSC LAN83C185 */
#define MII_LAN83C185_ID 0x0007C0A0
/* ........................................................................ */
......
......@@ -156,8 +156,7 @@ static int atl1_set_settings(struct net_device *netdev,
u16 old_media_type = hw->media_type;
if (netif_running(adapter->netdev)) {
printk(KERN_DEBUG "%s: ethtool shutting down adapter\n",
atl1_driver_name);
dev_dbg(&adapter->pdev->dev, "ethtool shutting down adapter\n");
atl1_down(adapter);
}
......@@ -166,9 +165,8 @@ static int atl1_set_settings(struct net_device *netdev,
else {
if (ecmd->speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
printk(KERN_WARNING
"%s: can't force to 1000M half duplex\n",
atl1_driver_name);
dev_warn(&adapter->pdev->dev,
"can't force to 1000M half duplex\n");
ret_val = -EINVAL;
goto exit_sset;
}
......@@ -206,9 +204,8 @@ static int atl1_set_settings(struct net_device *netdev,
}
if (atl1_phy_setup_autoneg_adv(hw)) {
ret_val = -EINVAL;
printk(KERN_WARNING
"%s: invalid ethtool speed/duplex setting\n",
atl1_driver_name);
dev_warn(&adapter->pdev->dev,
"invalid ethtool speed/duplex setting\n");
goto exit_sset;
}
if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
......@@ -239,12 +236,10 @@ static int atl1_set_settings(struct net_device *netdev,
hw->media_type = old_media_type;
if (netif_running(adapter->netdev)) {
printk(KERN_DEBUG "%s: ethtool starting adapter\n",
atl1_driver_name);
dev_dbg(&adapter->pdev->dev, "ethtool starting adapter\n");
atl1_up(adapter);
} else if (!ret_val) {
printk(KERN_DEBUG "%s: ethtool resetting adapter\n",
atl1_driver_name);
dev_dbg(&adapter->pdev->dev, "ethtool resetting adapter\n");
atl1_reset(adapter);
}
return ret_val;
......
......@@ -2,20 +2,20 @@
* Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
* Copyright(c) 2006 Chris Snook <csnook@redhat.com>
* Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
*
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
......@@ -38,12 +38,13 @@
*/
s32 atl1_reset_hw(struct atl1_hw *hw)
{
struct pci_dev *pdev = hw->back->pdev;
u32 icr;
int i;
/*
/*
* Clear Interrupt mask to stop board from generating
* interrupts & Clear any pending interrupt events
* interrupts & Clear any pending interrupt events
*/
/*
* iowrite32(0, hw->hw_addr + REG_IMR);
......@@ -74,7 +75,7 @@ s32 atl1_reset_hw(struct atl1_hw *hw)
}
if (icr) {
printk (KERN_DEBUG "icr = %x\n", icr);
dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr);
return icr;
}
......@@ -136,8 +137,8 @@ s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
int i;
val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
MDIO_CLK_SEL_SHIFT;
MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
MDIO_CLK_SEL_SHIFT;
iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
ioread32(hw->hw_addr + REG_MDIO_CTRL);
......@@ -204,7 +205,7 @@ static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
/*
* get_permanent_address
* return 0 if get valid mac address,
* return 0 if get valid mac address,
*/
static int atl1_get_permanent_address(struct atl1_hw *hw)
{
......@@ -301,7 +302,7 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
}
/*
* Reads the adapter's MAC address from the EEPROM
* Reads the adapter's MAC address from the EEPROM
* hw - Struct containing variables accessed by shared code
*/
s32 atl1_read_mac_addr(struct atl1_hw *hw)
......@@ -437,6 +438,7 @@ s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
*/
static s32 atl1_phy_reset(struct atl1_hw *hw)
{
struct pci_dev *pdev = hw->back->pdev;
s32 ret_val;
u16 phy_data;
......@@ -468,8 +470,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw)
u32 val;
int i;
/* pcie serdes link may be down! */
printk(KERN_DEBUG "%s: autoneg caused pcie phy link down\n",
atl1_driver_name);
dev_dbg(&pdev->dev, "pcie phy link down\n");
for (i = 0; i < 25; i++) {
msleep(1);
......@@ -479,9 +480,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw)
}
if ((val & (MDIO_START | MDIO_BUSY)) != 0) {
printk(KERN_WARNING
"%s: pcie link down at least for 25ms\n",
atl1_driver_name);
dev_warn(&pdev->dev, "pcie link down at least 25ms\n");
return ret_val;
}
}
......@@ -571,6 +570,7 @@ s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw)
*/
static s32 atl1_setup_link(struct atl1_hw *hw)
{
struct pci_dev *pdev = hw->back->pdev;
s32 ret_val;
/*
......@@ -581,15 +581,13 @@ static s32 atl1_setup_link(struct atl1_hw *hw)
*/
ret_val = atl1_phy_setup_autoneg_adv(hw);
if (ret_val) {
printk(KERN_DEBUG "%s: error setting up autonegotiation\n",
atl1_driver_name);
dev_dbg(&pdev->dev, "error setting up autonegotiation\n");
return ret_val;
}
/* SW.Reset , En-Auto-Neg if needed */
ret_val = atl1_phy_reset(hw);
if (ret_val) {
printk(KERN_DEBUG "%s: error resetting the phy\n",
atl1_driver_name);
dev_dbg(&pdev->dev, "error resetting phy\n");
return ret_val;
}
hw->phy_configured = true;
......@@ -631,7 +629,7 @@ static void atl1_init_flash_opcode(struct atl1_hw *hw)
* Performs basic configuration of the adapter.
* hw - Struct containing variables accessed by shared code
* Assumes that the controller has previously been reset and is in a
* post-reset uninitialized state. Initializes multicast table,
* post-reset uninitialized state. Initializes multicast table,
* and Calls routines to setup link
* Leaves the transmit and receive units disabled and uninitialized.
*/
......@@ -669,6 +667,7 @@ s32 atl1_init_hw(struct atl1_hw *hw)
*/
s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
{
struct pci_dev *pdev = hw->back->pdev;
s32 ret_val;
u16 phy_data;
......@@ -691,8 +690,7 @@ s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
*speed = SPEED_10;
break;
default:
printk(KERN_DEBUG "%s: error getting speed\n",
atl1_driver_name);
dev_dbg(&pdev->dev, "error getting speed\n");
return ATL1_ERR_PHY_SPEED;
break;
}
......
......@@ -188,8 +188,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count);
tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
if (unlikely(!tpd_ring->buffer_info)) {
printk(KERN_WARNING "%s: kzalloc failed , size = D%d\n",
atl1_driver_name, size);
dev_err(&pdev->dev, "kzalloc failed , size = D%d\n", size);
goto err_nomem;
}
rfd_ring->buffer_info =
......@@ -207,9 +206,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
&ring_header->dma);
if (unlikely(!ring_header->desc)) {
printk(KERN_WARNING
"%s: pci_alloc_consistent failed, size = D%d\n",
atl1_driver_name, size);
dev_err(&pdev->dev, "pci_alloc_consistent failed\n");
goto err_nomem;
}
......@@ -373,8 +370,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
ERR_FLAG_CODE | ERR_FLAG_OV)) {
adapter->hw_csum_err++;
printk(KERN_DEBUG "%s: rx checksum error\n",
atl1_driver_name);
dev_dbg(&adapter->pdev->dev, "rx checksum error\n");
return;
}
}
......@@ -393,8 +389,9 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
}
/* IPv4, but hardware thinks its checksum is wrong */
printk(KERN_DEBUG "%s: hw csum wrong pkt_flag:%x, err_flag:%x\n",
atl1_driver_name, rrd->pkt_flg, rrd->err_flg);
dev_dbg(&adapter->pdev->dev,
"hw csum wrong, pkt_flag:%x, err_flag:%x\n",
rrd->pkt_flg, rrd->err_flg);
skb->ip_summed = CHECKSUM_COMPLETE;
skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum);
adapter->hw_csum_err++;
......@@ -507,14 +504,13 @@ static void atl1_intr_rx(struct atl1_adapter *adapter)
/* rrd seems to be bad */
if (unlikely(i-- > 0)) {
/* rrd may not be DMAed completely */
printk(KERN_DEBUG
"%s: RRD may not be DMAed completely\n",
atl1_driver_name);
dev_dbg(&adapter->pdev->dev,
"incomplete RRD DMA transfer\n");
udelay(1);
goto chk_rrd;
}
/* bad rrd */
printk(KERN_DEBUG "%s: bad RRD\n", atl1_driver_name);
dev_dbg(&adapter->pdev->dev, "bad RRD\n");
/* see if update RFD index */
if (rrd->num_buf > 1) {
u16 num_buf;
......@@ -685,8 +681,8 @@ static void atl1_check_for_link(struct atl1_adapter *adapter)
/* notify upper layer link down ASAP */
if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */
if (netif_carrier_ok(netdev)) { /* old link state: Up */
printk(KERN_INFO "%s: %s link is down\n",
atl1_driver_name, netdev->name);
dev_info(&adapter->pdev->dev, "%s link is down\n",
netdev->name);
adapter->link_speed = SPEED_0;
netif_carrier_off(netdev);
netif_stop_queue(netdev);
......@@ -731,8 +727,8 @@ static irqreturn_t atl1_intr(int irq, void *data)
/* check if PCIE PHY Link down */
if (status & ISR_PHY_LINKDOWN) {
printk(KERN_DEBUG "%s: pcie phy link down %x\n",
atl1_driver_name, status);
dev_dbg(&adapter->pdev->dev, "pcie phy link down %x\n",
status);
if (netif_running(adapter->netdev)) { /* reset MAC */
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
schedule_work(&adapter->pcie_dma_to_rst_task);
......@@ -742,9 +738,9 @@ static irqreturn_t atl1_intr(int irq, void *data)
/* check if DMA read/write error ? */
if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
printk(KERN_DEBUG
"%s: pcie DMA r/w error (status = 0x%x)\n",
atl1_driver_name, status);
dev_dbg(&adapter->pdev->dev,
"pcie DMA r/w error (status = 0x%x)\n",
status);
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
schedule_work(&adapter->pcie_dma_to_rst_task);
return IRQ_HANDLED;
......@@ -762,14 +758,13 @@ static irqreturn_t atl1_intr(int irq, void *data)
/* rx exception */
if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
ISR_HOST_RRD_OV | ISR_CMB_RX))) {
if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
ISR_HOST_RRD_OV | ISR_CMB_RX))) {
if (status &
(ISR_RXF_OV | ISR_RFD_UNRUN | ISR_RRD_OV |
ISR_HOST_RFD_UNRUN | ISR_HOST_RRD_OV))
printk(KERN_INFO
"%s: rx exception: status = 0x%x\n",
atl1_driver_name, status);
ISR_HOST_RRD_OV))
dev_dbg(&adapter->pdev->dev,
"rx exception, ISR = 0x%x\n", status);
atl1_intr_rx(adapter);
}
......@@ -874,8 +869,7 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
atl1_read_phy_reg(hw, MII_BMSR, &phy_data);
if (!(phy_data & BMSR_LSTATUS)) { /* link down */
if (netif_carrier_ok(netdev)) { /* old link state: Up */
printk(KERN_INFO "%s: link is down\n",
atl1_driver_name);
dev_info(&adapter->pdev->dev, "link is down\n");
adapter->link_speed = SPEED_0;
netif_carrier_off(netdev);
netif_stop_queue(netdev);
......@@ -918,11 +912,11 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
adapter->link_speed = speed;
adapter->link_duplex = duplex;
atl1_setup_mac_ctrl(adapter);
printk(KERN_INFO "%s: %s link is up %d Mbps %s\n",
atl1_driver_name, netdev->name,
adapter->link_speed,
adapter->link_duplex ==
FULL_DUPLEX ? "full duplex" : "half duplex");
dev_info(&adapter->pdev->dev,
"%s link is up %d Mbps %s\n",
netdev->name, adapter->link_speed,
adapter->link_duplex == FULL_DUPLEX ?
"full duplex" : "half duplex");
}
if (!netif_carrier_ok(netdev)) { /* Link down -> Up */
netif_carrier_on(netdev);
......@@ -1330,8 +1324,8 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
cso = skb_transport_offset(skb);
css = cso + skb->csum_offset;
if (unlikely(cso & 0x1)) {
printk(KERN_DEBUG "%s: payload offset != even number\n",
atl1_driver_name);
dev_dbg(&adapter->pdev->dev,
"payload offset not an even number\n");
return -1;
}
csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) <<
......@@ -1579,7 +1573,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (!spin_trylock(&adapter->lock)) {
/* Can't get lock - tell upper layer to requeue */
local_irq_restore(flags);
printk(KERN_DEBUG "%s: TX locked\n", atl1_driver_name);
dev_dbg(&adapter->pdev->dev, "tx locked\n");
return NETDEV_TX_LOCKED;
}
......@@ -1587,7 +1581,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* not enough descriptors */
netif_stop_queue(netdev);
spin_unlock_irqrestore(&adapter->lock, flags);
printk(KERN_DEBUG "%s: TX busy\n", atl1_driver_name);
dev_dbg(&adapter->pdev->dev, "tx busy\n");
return NETDEV_TX_BUSY;
}
......@@ -1841,8 +1835,7 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
(max_frame > MAX_JUMBO_FRAME_SIZE)) {
printk(KERN_WARNING "%s: invalid MTU setting\n",
atl1_driver_name);
dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
return -EINVAL;
}
......@@ -2136,9 +2129,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
if (err) {
err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (err) {
printk(KERN_DEBUG
"%s: no usable DMA configuration, aborting\n",
atl1_driver_name);
dev_err(&pdev->dev, "no usable DMA configuration\n");
goto err_dma;
}
pci_using_64 = false;
......@@ -2175,7 +2166,9 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
goto err_pci_iomap;
}
/* get device revision number */
adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + (REG_MASTER_CTRL + 2));
adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr +
(REG_MASTER_CTRL + 2));
dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
/* set default ring resource counts */
adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD;
......@@ -2466,8 +2459,6 @@ static void __exit atl1_exit_module(void)
*/
static int __init atl1_init_module(void)
{
printk(KERN_INFO "%s - version %s\n", atl1_driver_string, DRIVER_VERSION);
printk(KERN_INFO "%s\n", atl1_copyright);
return pci_register_driver(&atl1_driver);
}
......
......@@ -23,6 +23,7 @@
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include "atl1.h"
/*
......@@ -93,7 +94,7 @@ struct atl1_option {
} arg;
};
static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, struct pci_dev *pdev)
{
if (*value == OPTION_UNSET) {
*value = opt->def;
......@@ -104,19 +105,17 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
case enable_option:
switch (*value) {
case OPTION_ENABLED:
printk(KERN_INFO "%s: %s Enabled\n", atl1_driver_name,
opt->name);
dev_info(&pdev->dev, "%s enabled\n", opt->name);
return 0;
case OPTION_DISABLED:
printk(KERN_INFO "%s: %s Disabled\n", atl1_driver_name,
opt->name);
dev_info(&pdev->dev, "%s disabled\n", opt->name);
return 0;
}
break;
case range_option:
if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
printk(KERN_INFO "%s: %s set to %i\n",
atl1_driver_name, opt->name, *value);
dev_info(&pdev->dev, "%s set to %i\n", opt->name,
*value);
return 0;
}
break;
......@@ -128,8 +127,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
ent = &opt->arg.l.p[i];
if (*value == ent->i) {
if (ent->str[0] != '\0')
printk(KERN_INFO "%s: %s\n",
atl1_driver_name, ent->str);
dev_info(&pdev->dev, "%s\n",
ent->str);
return 0;
}
}
......@@ -140,8 +139,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
break;
}
printk(KERN_INFO "%s: invalid %s specified (%i) %s\n",
atl1_driver_name, opt->name, *value, opt->err);
dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
opt->name, *value, opt->err);
*value = opt->def;
return -1;
}
......@@ -157,12 +156,11 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
*/
void __devinit atl1_check_options(struct atl1_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
int bd = adapter->bd_number;
if (bd >= ATL1_MAX_NIC) {
printk(KERN_NOTICE "%s: warning: no configuration for board #%i\n",
atl1_driver_name, bd);
printk(KERN_NOTICE "%s: using defaults for all values\n",
atl1_driver_name);
dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
dev_notice(&pdev->dev, "using defaults for all values\n");
}
{ /* Interrupt Moderate Timer */
struct atl1_option opt = {
......@@ -177,7 +175,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
int val;
if (num_int_mod_timer > bd) {
val = int_mod_timer[bd];
atl1_validate_option(&val, &opt);
atl1_validate_option(&val, &opt, pdev);
adapter->imt = (u16) val;
} else
adapter->imt = (u16) (opt.def);
......@@ -197,7 +195,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
int val;
if (num_flash_vendor > bd) {
val = flash_vendor[bd];
atl1_validate_option(&val, &opt);
atl1_validate_option(&val, &opt, pdev);
adapter->hw.flash_vendor = (u8) val;
} else
adapter->hw.flash_vendor = (u8) (opt.def);
......
......@@ -77,9 +77,6 @@
#define DM9000_PHY 0x40 /* PHY address 0x01 */
#define TRUE 1
#define FALSE 0
#define CARDNAME "dm9000"
#define PFX CARDNAME ": "
......@@ -601,7 +598,7 @@ dm9000_probe(struct platform_device *pdev)
printk("%s: not found (%d).\n", CARDNAME, ret);
dm9000_release_board(pdev, db);
kfree(ndev);
free_netdev(ndev);
return ret;
}
......@@ -896,7 +893,7 @@ dm9000_rx(struct net_device *dev)
struct dm9000_rxhdr rxhdr;
struct sk_buff *skb;
u8 rxbyte, *rdptr;
int GoodPacket;
bool GoodPacket;
int RxLen;
/* Check packet ready or not */
......@@ -918,7 +915,7 @@ dm9000_rx(struct net_device *dev)
return;
/* A packet ready now & Get status/length */
GoodPacket = TRUE;
GoodPacket = true;
writeb(DM9000_MRCMD, db->io_addr);
(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));
......@@ -927,7 +924,7 @@ dm9000_rx(struct net_device *dev)
/* Packet Status check */
if (RxLen < 0x40) {
GoodPacket = FALSE;
GoodPacket = false;
PRINTK1("Bad Packet received (runt)\n");
}
......@@ -936,7 +933,7 @@ dm9000_rx(struct net_device *dev)
}
if (rxhdr.RxStatus & 0xbf00) {
GoodPacket = FALSE;
GoodPacket = false;
if (rxhdr.RxStatus & 0x100) {
PRINTK1("fifo error\n");
db->stats.rx_fifo_errors++;
......@@ -1193,7 +1190,7 @@ dm9000_drv_remove(struct platform_device *pdev)
unregister_netdev(ndev);
dm9000_release_board(pdev, (board_info_t *) ndev->priv);
kfree(ndev); /* free device structure */
free_netdev(ndev); /* free device structure */
PRINTK1("clean_module() exit\n");
......
......@@ -1803,10 +1803,10 @@ static inline int ehea_hash_skb(struct sk_buff *skb, int num_qps)
u32 tmp;
if ((skb->protocol == htons(ETH_P_IP)) &&
(skb->nh.iph->protocol == IPPROTO_TCP)) {
tcp = (struct tcphdr*)(skb->nh.raw + (skb->nh.iph->ihl * 4));
(ip_hdr(skb)->protocol == IPPROTO_TCP)) {
tcp = (struct tcphdr*)(skb_network_header(skb) + (ip_hdr(skb)->ihl * 4));
tmp = (tcp->source + (tcp->dest << 16)) % 31;
tmp += skb->nh.iph->daddr % 31;
tmp += ip_hdr(skb)->daddr % 31;
return tmp % num_qps;
}
else
......
......@@ -290,6 +290,8 @@ MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
#define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
static void myri10ge_set_multicast_list(struct net_device *dev);
static inline void put_be32(__be32 val, __be32 __iomem * p)
{
__raw_writel((__force __u32) val, (__force void __iomem *)p);
......@@ -353,6 +355,8 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
return 0;
} else if (result == MXGEFW_CMD_UNKNOWN) {
return -ENOSYS;
} else if (result == MXGEFW_CMD_ERROR_UNALIGNED) {
return -E2BIG;
} else {
dev_err(&mgp->pdev->dev,
"command %d failed, result = %d\n",
......@@ -712,14 +716,78 @@ myri10ge_change_promisc(struct myri10ge_priv *mgp, int promisc, int atomic)
mgp->dev->name);
}
static int myri10ge_reset(struct myri10ge_priv *mgp)
static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type)
{
struct myri10ge_cmd cmd;
int status;
size_t bytes;
u32 len;
struct page *dmatest_page;
dma_addr_t dmatest_bus;
char *test = " ";
dmatest_page = alloc_page(GFP_KERNEL);
if (!dmatest_page)
return -ENOMEM;
dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
DMA_BIDIRECTIONAL);
/* Run a small DMA test.
* The magic multipliers to the length tell the firmware
* to do DMA read, write, or read+write tests. The
* results are returned in cmd.data0. The upper 16
* bits or the return is the number of transfers completed.
* The lower 16 bits is the time in 0.5us ticks that the
* transfers took to complete.
*/
len = mgp->tx.boundary;
cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
cmd.data2 = len * 0x10000;
status = myri10ge_send_cmd(mgp, test_type, &cmd, 0);
if (status != 0) {
test = "read";
goto abort;
}
mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff);
cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
cmd.data2 = len * 0x1;
status = myri10ge_send_cmd(mgp, test_type, &cmd, 0);
if (status != 0) {
test = "write";
goto abort;
}
mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff);
cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
cmd.data2 = len * 0x10001;
status = myri10ge_send_cmd(mgp, test_type, &cmd, 0);
if (status != 0) {
test = "read/write";
goto abort;
}
mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) /
(cmd.data0 & 0xffff);
abort:
pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
put_page(dmatest_page);
if (status != 0 && test_type != MXGEFW_CMD_UNALIGNED_TEST)
dev_warn(&mgp->pdev->dev, "DMA %s benchmark failed: %d\n",
test, status);
return status;
}
static int myri10ge_reset(struct myri10ge_priv *mgp)
{
struct myri10ge_cmd cmd;
int status;
size_t bytes;
/* try to send a reset command to the card to see if it
* is alive */
......@@ -729,11 +797,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
dev_err(&mgp->pdev->dev, "failed reset\n");
return -ENXIO;
}
dmatest_page = alloc_page(GFP_KERNEL);
if (!dmatest_page)
return -ENOMEM;
dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
DMA_BIDIRECTIONAL);
(void)myri10ge_dma_test(mgp, MXGEFW_DMA_TEST);
/* Now exchange information about interrupts */
......@@ -761,52 +826,6 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
}
put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
/* Run a small DMA test.
* The magic multipliers to the length tell the firmware
* to do DMA read, write, or read+write tests. The
* results are returned in cmd.data0. The upper 16
* bits or the return is the number of transfers completed.
* The lower 16 bits is the time in 0.5us ticks that the
* transfers took to complete.
*/
len = mgp->tx.boundary;
cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
cmd.data2 = len * 0x10000;
status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
if (status == 0)
mgp->read_dma = ((cmd.data0 >> 16) * len * 2) /
(cmd.data0 & 0xffff);
else
dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n",
status);
cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
cmd.data2 = len * 0x1;
status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
if (status == 0)
mgp->write_dma = ((cmd.data0 >> 16) * len * 2) /
(cmd.data0 & 0xffff);
else
dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n",
status);
cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
cmd.data2 = len * 0x10001;
status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
if (status == 0)
mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) /
(cmd.data0 & 0xffff);
else
dev_warn(&mgp->pdev->dev,
"DMA read/write benchmark failed: %d\n", status);
pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
put_page(dmatest_page);
memset(mgp->rx_done.entry, 0, bytes);
/* reset mcp/driver shared state back to 0 */
......@@ -820,10 +839,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
mgp->rx_done.cnt = 0;
mgp->link_changes = 0;
status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr);
myri10ge_change_promisc(mgp, 0, 0);
myri10ge_change_pause(mgp, mgp->pause);
if (mgp->adopted_rx_filter_bug)
(void)myri10ge_send_cmd(mgp, MXGEFW_ENABLE_ALLMULTI, &cmd, 1);
myri10ge_set_multicast_list(mgp->dev);
return status;
}
......@@ -1355,7 +1372,9 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
"tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt",
"wake_queue", "stop_queue", "watchdog_resets", "tx_linearized",
"link_changes", "link_up", "dropped_link_overflow",
"dropped_link_error_or_filtered", "dropped_multicast_filtered",
"dropped_link_error_or_filtered",
"dropped_pause", "dropped_bad_phy", "dropped_bad_crc32",
"dropped_unicast_filtered", "dropped_multicast_filtered",
"dropped_runt", "dropped_overrun", "dropped_no_small_buffer",
"dropped_no_big_buffer"
};
......@@ -1412,6 +1431,11 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow);
data[i++] =
(unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered);
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_pause);
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_phy);
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_crc32);
data[i++] =
(unsigned int)ntohl(mgp->fw_stats->dropped_unicast_filtered);
data[i++] =
(unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered);
data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt);
......@@ -2276,7 +2300,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1);
/* This firmware is known to not support multicast */
if (!mgp->fw_multicast_support || mgp->adopted_rx_filter_bug)
if (!mgp->fw_multicast_support)
return;
/* Disable multicast filtering */
......@@ -2288,7 +2312,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
goto abort;
}
if (dev->flags & IFF_ALLMULTI) {
if ((dev->flags & IFF_ALLMULTI) || mgp->adopted_rx_filter_bug) {
/* request to disable multicast filtering, so quit here */
return;
}
......@@ -2461,8 +2485,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
err_cap |= PCI_ERR_CAP_ECRC_GENE;
pci_write_config_dword(bridge, cap + PCI_ERR_CAP, err_cap);
dev_info(dev, "Enabled ECRC on upstream bridge %s\n", pci_name(bridge));
mgp->tx.boundary = 4096;
mgp->fw_name = myri10ge_fw_aligned;
}
/*
......@@ -2484,22 +2506,70 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
* firmware image, and set tx.boundary to 4KB.
*/
#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510
#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b
#define PCI_DEVICE_ID_INTEL_E3000_PCIE 0x2779
#define PCI_DEVICE_ID_INTEL_E3010_PCIE 0x277a
#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140
#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142
static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
{
struct pci_dev *bridge = mgp->pdev->bus->self;
struct pci_dev *pdev = mgp->pdev;
struct device *dev = &pdev->dev;
int cap, status;
u16 val;
mgp->tx.boundary = 4096;
/*
* Verify the max read request size was set to 4KB
* before trying the test with 4KB.
*/
cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (cap < 64) {
dev_err(dev, "Bad PCI_CAP_ID_EXP location %d\n", cap);
goto abort;
}
status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val);
if (status != 0) {
dev_err(dev, "Couldn't read max read req size: %d\n", status);
goto abort;
}
if ((val & (5 << 12)) != (5 << 12)) {
dev_warn(dev, "Max Read Request size != 4096 (0x%x)\n", val);
mgp->tx.boundary = 2048;
}
/*
* load the optimized firmware (which assumes aligned PCIe
* completions) in order to see if it works on this host.
*/
mgp->fw_name = myri10ge_fw_aligned;
status = myri10ge_load_firmware(mgp);
if (status != 0) {
goto abort;
}
/*
* Enable ECRC if possible
*/
myri10ge_enable_ecrc(mgp);
/*
* Run a DMA test which watches for unaligned completions and
* aborts on the first one seen.
*/
status = myri10ge_dma_test(mgp, MXGEFW_CMD_UNALIGNED_TEST);
if (status == 0)
return; /* keep the aligned firmware */
if (status != -E2BIG)
dev_warn(dev, "DMA test failed: %d\n", status);
if (status == -ENOSYS)
dev_warn(dev, "Falling back to ethp! "
"Please install up to date fw\n");
abort:
/* fall back to using the unaligned firmware */
mgp->tx.boundary = 2048;
mgp->fw_name = myri10ge_fw_unaligned;
}
static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
{
if (myri10ge_force_firmware == 0) {
int link_width, exp_cap;
u16 lnk;
......@@ -2508,8 +2578,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
link_width = (lnk >> 4) & 0x3f;
myri10ge_enable_ecrc(mgp);
/* Check to see if Link is less than 8 or if the
* upstream bridge is known to provide aligned
* completions */
......@@ -2518,46 +2586,8 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
link_width);
mgp->tx.boundary = 4096;
mgp->fw_name = myri10ge_fw_aligned;
} else if (bridge &&
/* ServerWorks HT2000/HT1000 */
((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
&& bridge->device ==
PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE)
/* ServerWorks HT2100 */
|| (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
&& bridge->device >=
PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST
&& bridge->device <=
PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST)
/* All Intel E3000/E3010 PCIE ports */
|| (bridge->vendor == PCI_VENDOR_ID_INTEL
&& (bridge->device ==
PCI_DEVICE_ID_INTEL_E3000_PCIE
|| bridge->device ==
PCI_DEVICE_ID_INTEL_E3010_PCIE))
/* All Intel 6310/6311/6321ESB PCIE ports */
|| (bridge->vendor == PCI_VENDOR_ID_INTEL
&& bridge->device >=
PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1
&& bridge->device <=
PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4)
/* All Intel E5000 PCIE ports */
|| (bridge->vendor == PCI_VENDOR_ID_INTEL
&& bridge->device >=
PCI_DEVICE_ID_INTEL_E5000_PCIE23
&& bridge->device <=
PCI_DEVICE_ID_INTEL_E5000_PCIE47))) {
dev_info(&mgp->pdev->dev,
"Assuming aligned completions (0x%x:0x%x)\n",
bridge->vendor, bridge->device);
mgp->tx.boundary = 4096;
mgp->fw_name = myri10ge_fw_aligned;
} else if (bridge &&
bridge->vendor == PCI_VENDOR_ID_SGI &&
bridge->device == 0x4002 /* TIOCE pcie-port */ ) {
/* this pcie bridge does not support 4K rdma request */
mgp->tx.boundary = 2048;
mgp->fw_name = myri10ge_fw_aligned;
} else {
myri10ge_firmware_probe(mgp);
}
} else {
if (myri10ge_force_firmware == 1) {
......@@ -2825,7 +2855,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
status = -ENODEV;
goto abort_with_netdev;
}
myri10ge_select_firmware(mgp);
/* Find the vendor-specific cap so we can check
* the reboot register later on */
......@@ -2919,6 +2948,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto abort_with_ioremap;
memset(mgp->rx_done.entry, 0, bytes);
myri10ge_select_firmware(mgp);
status = myri10ge_load_firmware(mgp);
if (status != 0) {
dev_err(&pdev->dev, "failed to load firmware\n");
......
......@@ -200,6 +200,13 @@ enum myri10ge_mcp_cmd_type {
/* data0, data1 = bus addr,
* data2 = sizeof(struct mcp_irq_data) from driver point of view, allows
* adding new stuff to mcp_irq_data without changing the ABI */
MXGEFW_CMD_UNALIGNED_TEST,
/* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned
* chipset */
MXGEFW_CMD_UNALIGNED_STATUS
/* return data = boolean, true if the chipset is known to be unaligned */
};
enum myri10ge_mcp_cmd_status {
......@@ -212,18 +219,27 @@ enum myri10ge_mcp_cmd_status {
MXGEFW_CMD_ERROR_HASH_ERROR,
MXGEFW_CMD_ERROR_BAD_PORT,
MXGEFW_CMD_ERROR_RESOURCES,
MXGEFW_CMD_ERROR_MULTICAST
MXGEFW_CMD_ERROR_MULTICAST,
MXGEFW_CMD_ERROR_UNALIGNED
};
#define MXGEFW_OLD_IRQ_DATA_LEN 40
struct mcp_irq_data {
/* add new counters at the beginning */
__be32 future_use[5];
__be32 future_use[1];
__be32 dropped_pause;
__be32 dropped_unicast_filtered;
__be32 dropped_bad_crc32;
__be32 dropped_bad_phy;
__be32 dropped_multicast_filtered;
/* 40 Bytes */
__be32 send_done_count;
#define MXGEFW_LINK_DOWN 0
#define MXGEFW_LINK_UP 1
#define MXGEFW_LINK_MYRINET 2
#define MXGEFW_LINK_UNKNOWN 3
__be32 link_up;
__be32 dropped_link_overflow;
__be32 dropped_link_error_or_filtered;
......
......@@ -81,6 +81,8 @@ static const int multicast_filter_limit = 100;
Setting to > 1518 effectively disables this feature. */
static int rx_copybreak;
static int dspcfg_workaround = 1;
/* Used to pass the media type, etc.
Both 'options[]' and 'full_duplex[]' should exist for driver
interoperability.
......@@ -139,12 +141,14 @@ MODULE_LICENSE("GPL");
module_param(mtu, int, 0);
module_param(debug, int, 0);
module_param(rx_copybreak, int, 0);
module_param(dspcfg_workaround, int, 1);
module_param_array(options, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
MODULE_PARM_DESC(debug, "DP8381x default debug level");
MODULE_PARM_DESC(rx_copybreak,
"DP8381x copy breakpoint for copy-only-tiny-frames");
MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround");
MODULE_PARM_DESC(options,
"DP8381x: Bits 0-3: media type, bit 17: full duplex");
MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)");
......@@ -590,6 +594,7 @@ struct netdev_private {
u32 srr;
/* expected DSPCFG value */
u16 dspcfg;
int dspcfg_workaround;
/* parms saved in ethtool format */
u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */
u8 duplex; /* Duplex, half or full */
......@@ -656,6 +661,56 @@ static int netdev_get_regs(struct net_device *dev, u8 *buf);
static int netdev_get_eeprom(struct net_device *dev, u8 *buf);
static const struct ethtool_ops ethtool_ops;
#define NATSEMI_ATTR(_name) \
static ssize_t natsemi_show_##_name(struct device *dev, \
struct device_attribute *attr, char *buf); \
static ssize_t natsemi_set_##_name(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count); \
static DEVICE_ATTR(_name, 0644, natsemi_show_##_name, natsemi_set_##_name)
#define NATSEMI_CREATE_FILE(_dev, _name) \
device_create_file(&_dev->dev, &dev_attr_##_name)
#define NATSEMI_REMOVE_FILE(_dev, _name) \
device_create_file(&_dev->dev, &dev_attr_##_name)
NATSEMI_ATTR(dspcfg_workaround);
static ssize_t natsemi_show_dspcfg_workaround(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct netdev_private *np = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%s\n", np->dspcfg_workaround ? "on" : "off");
}
static ssize_t natsemi_set_dspcfg_workaround(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct netdev_private *np = netdev_priv(to_net_dev(dev));
int new_setting;
u32 flags;
/* Find out the new setting */
if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
new_setting = 1;
else if (!strncmp("off", buf, count - 1)
|| !strncmp("0", buf, count - 1))
new_setting = 0;
else
return count;
spin_lock_irqsave(&np->lock, flags);
np->dspcfg_workaround = new_setting;
spin_unlock_irqrestore(&np->lock, flags);
return count;
}
static inline void __iomem *ns_ioaddr(struct net_device *dev)
{
return (void __iomem *) dev->base_addr;
......@@ -820,6 +875,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
np->ignore_phy = 1;
else
np->ignore_phy = 0;
np->dspcfg_workaround = dspcfg_workaround;
/* Initial port:
* - If configured to ignore the PHY set up for external.
......@@ -899,6 +955,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
if (i)
goto err_register_netdev;
if (NATSEMI_CREATE_FILE(pdev, dspcfg_workaround))
goto err_create_file;
if (netif_msg_drv(np)) {
printk(KERN_INFO "natsemi %s: %s at %#08lx (%s), ",
dev->name, natsemi_pci_info[chip_idx].name, iostart,
......@@ -915,6 +974,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
}
return 0;
err_create_file:
unregister_netdev(dev);
err_register_netdev:
iounmap(ioaddr);
......@@ -1727,7 +1789,8 @@ static void init_registers(struct net_device *dev)
* It seems that a reference set for this chip went out with incorrect info,
* and there exist boards that aren't quite right. An unexpected voltage
* drop can cause the PHY to get itself in a weird state (basically reset).
* NOTE: this only seems to affect revC chips.
* NOTE: this only seems to affect revC chips. The user can disable
* this check via dspcfg_workaround sysfs option.
* 3) check of death of the RX path due to OOM
*/
static void netdev_timer(unsigned long data)
......@@ -1753,10 +1816,10 @@ static void netdev_timer(unsigned long data)
writew(1, ioaddr+PGSEL);
dspcfg = readw(ioaddr+DSPCFG);
writew(0, ioaddr+PGSEL);
if (dspcfg != np->dspcfg) {
if (np->dspcfg_workaround && dspcfg != np->dspcfg) {
if (!netif_queue_stopped(dev)) {
spin_unlock_irq(&np->lock);
if (netif_msg_hw(np))
if (netif_msg_drv(np))
printk(KERN_NOTICE "%s: possible phy reset: "
"re-initializing\n", dev->name);
disable_irq(dev->irq);
......@@ -3157,6 +3220,7 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
void __iomem * ioaddr = ns_ioaddr(dev);
NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround);
unregister_netdev (dev);
pci_release_regions (pdev);
iounmap(ioaddr);
......
......@@ -51,14 +51,11 @@ static const char version2[] =
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/jiffies.h>
#include <linux/platform_device.h>
#include <asm/system.h>
#include <asm/io.h>
#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
#include <asm/tx4938/rbtx4938.h>
#endif
#include "8390.h"
#define DRV_NAME "ne"
......@@ -77,8 +74,13 @@ static const char version2[] =
/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
/* #define PACKETBUF_MEMSIZE 0x40 */
#if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R))
/* Do we need a portlist for the ISA auto-probe ? */
#define NEEDS_PORTLIST
#endif
/* A zero-terminated list of I/O addresses to be probed at boot. */
#ifndef MODULE
#ifdef NEEDS_PORTLIST
static unsigned int netcard_portlist[] __initdata = {
0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0
};
......@@ -146,7 +148,7 @@ bad_clone_list[] __initdata = {
# define DCR_VAL 0x49
#endif
static int ne_probe1(struct net_device *dev, int ioaddr);
static int ne_probe1(struct net_device *dev, unsigned long ioaddr);
static int ne_probe_isapnp(struct net_device *dev);
static int ne_open(struct net_device *dev);
......@@ -184,8 +186,8 @@ static void ne_block_output(struct net_device *dev, const int count,
static int __init do_ne_probe(struct net_device *dev)
{
unsigned int base_addr = dev->base_addr;
#ifndef MODULE
unsigned long base_addr = dev->base_addr;
#ifdef NEEDS_PORTLIST
int orig_irq = dev->irq;
#endif
......@@ -201,7 +203,7 @@ static int __init do_ne_probe(struct net_device *dev)
if (isapnp_present() && (ne_probe_isapnp(dev) == 0))
return 0;
#ifndef MODULE
#ifdef NEEDS_PORTLIST
/* Last resort. The semi-risky ISA auto-probe. */
for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) {
int ioaddr = netcard_portlist[base_addr];
......@@ -226,10 +228,6 @@ struct net_device * __init ne_probe(int unit)
sprintf(dev->name, "eth%d", unit);
netdev_boot_setup_check(dev);
#ifdef CONFIG_TOSHIBA_RBTX4938
dev->base_addr = RBTX4938_RTL_8019_BASE;
dev->irq = RBTX4938_RTL_8019_IRQ;
#endif
err = do_ne_probe(dev);
if (err)
goto out;
......@@ -285,7 +283,7 @@ static int __init ne_probe_isapnp(struct net_device *dev)
return -ENODEV;
}
static int __init ne_probe1(struct net_device *dev, int ioaddr)
static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
{
int i;
unsigned char SA_prom[32];
......@@ -324,7 +322,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
if (ei_debug && version_printed++ == 0)
printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr);
printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr);
/* A user with a poor card that fails to ack the reset, or that
does not have a valid 0x57,0x57 signature can still use this
......@@ -516,8 +514,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
}
#endif
printk("\n%s: %s found at %#x, using IRQ %d.\n",
dev->name, name, ioaddr, dev->irq);
printk("\n");
ei_status.name = name;
ei_status.tx_start_page = start_page;
......@@ -547,6 +544,8 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
ret = register_netdev(dev);
if (ret)
goto out_irq;
printk(KERN_INFO "%s: %s found at %#lx, using IRQ %d.\n",
dev->name, name, ioaddr, dev->irq);
return 0;
out_irq:
......@@ -807,6 +806,87 @@ static void ne_block_output(struct net_device *dev, int count,
return;
}
static int __init ne_drv_probe(struct platform_device *pdev)
{
struct net_device *dev;
struct resource *res;
int err, irq;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
irq = platform_get_irq(pdev, 0);
if (!res || irq < 0)
return -ENODEV;
dev = alloc_ei_netdev();
if (!dev)
return -ENOMEM;
dev->irq = irq;
dev->base_addr = res->start;
err = do_ne_probe(dev);
if (err) {
free_netdev(dev);
return err;
}
platform_set_drvdata(pdev, dev);
return 0;
}
static int __exit ne_drv_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
unregister_netdev(dev);
free_irq(dev->irq, dev);
release_region(dev->base_addr, NE_IO_EXTENT);
free_netdev(dev);
return 0;
}
#ifdef CONFIG_PM
static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state)
{
struct net_device *dev = platform_get_drvdata(pdev);
if (netif_running(dev))
netif_device_detach(dev);
return 0;
}
static int ne_drv_resume(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
if (netif_running(dev)) {
ne_reset_8390(dev);
NS8390_init(dev, 1);
netif_device_attach(dev);
}
return 0;
}
#else
#define ne_drv_suspend NULL
#define ne_drv_resume NULL
#endif
static struct platform_driver ne_driver = {
.remove = __exit_p(ne_drv_remove),
.suspend = ne_drv_suspend,
.resume = ne_drv_resume,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
},
};
static int __init ne_init(void)
{
return platform_driver_probe(&ne_driver, ne_drv_probe);
}
static void __exit ne_exit(void)
{
platform_driver_unregister(&ne_driver);
}
#ifdef MODULE
#define MAX_NE_CARDS 4 /* Max number of NE cards per module */
......@@ -832,6 +912,7 @@ ISA device autoprobes on a running machine are not recommended anyway. */
int __init init_module(void)
{
int this_dev, found = 0;
int plat_found = !ne_init();
for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
struct net_device *dev = alloc_ei_netdev();
......@@ -845,7 +926,7 @@ int __init init_module(void)
continue;
}
free_netdev(dev);
if (found)
if (found || plat_found)
break;
if (io[this_dev] != 0)
printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]);
......@@ -853,7 +934,7 @@ int __init init_module(void)
printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
return -ENXIO;
}
if (found)
if (found || plat_found)
return 0;
return -ENODEV;
}
......@@ -871,6 +952,7 @@ void __exit cleanup_module(void)
{
int this_dev;
ne_exit();
for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
struct net_device *dev = dev_ne[this_dev];
if (dev) {
......@@ -880,4 +962,7 @@ void __exit cleanup_module(void)
}
}
}
#else /* MODULE */
module_init(ne_init);
module_exit(ne_exit);
#endif /* MODULE */
......@@ -33,6 +33,8 @@
#include <linux/tcp.h>
#include <net/checksum.h>
#include <asm/irq.h>
#include "pasemi_mac.h"
......@@ -51,6 +53,16 @@
#define RX_RING_SIZE 512
#define TX_RING_SIZE 512
#define DEFAULT_MSG_ENABLE \
(NETIF_MSG_DRV | \
NETIF_MSG_PROBE | \
NETIF_MSG_LINK | \
NETIF_MSG_TIMER | \
NETIF_MSG_IFDOWN | \
NETIF_MSG_IFUP | \
NETIF_MSG_RX_ERR | \
NETIF_MSG_TX_ERR)
#define TX_DESC(mac, num) ((mac)->tx->desc[(num) & (TX_RING_SIZE-1)])
#define TX_DESC_INFO(mac, num) ((mac)->tx->desc_info[(num) & (TX_RING_SIZE-1)])
#define RX_DESC(mac, num) ((mac)->rx->desc[(num) & (RX_RING_SIZE-1)])
......@@ -59,11 +71,13 @@
#define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
/* XXXOJN these should come out of the device tree some day */
#define PAS_DMA_CAP_BASE 0xe00d0040
#define PAS_DMA_CAP_SIZE 0x100
#define PAS_DMA_COM_BASE 0xe00d0100
#define PAS_DMA_COM_SIZE 0x100
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
static int debug = -1; /* -1 == use DEFAULT_MSG_ENABLE as value */
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
static struct pasdma_status *dma_status;
......@@ -80,7 +94,12 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
return -ENOENT;
}
maddr = of_get_property(dn, "mac-address", NULL);
maddr = of_get_property(dn, "local-mac-address", NULL);
/* Fall back to mac-address for older firmware */
if (maddr == NULL)
maddr = of_get_property(dn, "mac-address", NULL);
if (maddr == NULL) {
dev_warn(&pdev->dev,
"no mac address in device tree, not configuring\n");
......@@ -277,8 +296,8 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev)
for (i = 0; i < RX_RING_SIZE; i++) {
info = &RX_DESC_INFO(mac, i);
dp = &RX_DESC(mac, i);
if (info->dma) {
if (info->skb) {
if (info->skb) {
if (info->dma) {
pci_unmap_single(mac->dma_pdev,
info->dma,
info->skb->len,
......@@ -309,82 +328,120 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int i;
int start = mac->rx->next_to_fill;
unsigned int count;
unsigned int limit, count;
count = (mac->rx->next_to_clean + RX_RING_SIZE -
limit = (mac->rx->next_to_clean + RX_RING_SIZE -
mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
/* Check to see if we're doing first-time setup */
if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
count = RX_RING_SIZE;
limit = RX_RING_SIZE;
if (count <= 0)
if (limit <= 0)
return;
for (i = start; i < start + count; i++) {
i = start;
for (count = limit; count; count--) {
struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i);
u64 *buff = &RX_BUFF(mac, i);
struct sk_buff *skb;
dma_addr_t dma;
skb = dev_alloc_skb(BUF_SIZE);
/* skb might still be in there for recycle on short receives */
if (info->skb)
skb = info->skb;
else
skb = dev_alloc_skb(BUF_SIZE);
if (!skb) {
count = i - start;
if (unlikely(!skb))
break;
}
dma = pci_map_single(mac->dma_pdev, skb->data, skb->len,
PCI_DMA_FROMDEVICE);
if (dma_mapping_error(dma)) {
if (unlikely(dma_mapping_error(dma))) {
dev_kfree_skb_irq(info->skb);
count = i - start;
break;
}
info->skb = skb;
info->dma = dma;
*buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma);
i++;
}
wmb();
pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXCHAN_INCR(mac->dma_rxch),
count);
limit - count);
pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXINT_INCR(mac->dma_if),
count);
limit - count);
mac->rx->next_to_fill += count;
mac->rx->next_to_fill += limit - count;
}
static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
{
unsigned int reg, stat;
/* Re-enable packet count interrupts: finally
* ack the packet count interrupt we got in rx_intr.
*/
pci_read_config_dword(mac->iob_pdev,
PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch),
&stat);
reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
| PAS_IOB_DMA_RXCH_RESET_PINTC;
pci_write_config_dword(mac->iob_pdev,
PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch),
reg);
}
static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
{
unsigned int reg, stat;
/* Re-enable packet count interrupts */
pci_read_config_dword(mac->iob_pdev,
PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat);
reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
| PAS_IOB_DMA_TXCH_RESET_PINTC;
pci_write_config_dword(mac->iob_pdev,
PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
}
static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
{
unsigned int i;
int start, count;
unsigned int n;
int count;
struct pas_dma_xct_descr *dp;
struct pasemi_mac_buffer *info;
struct sk_buff *skb;
unsigned int i, len;
u64 macrx;
dma_addr_t dma;
spin_lock(&mac->rx->lock);
start = mac->rx->next_to_clean;
count = 0;
n = mac->rx->next_to_clean;
for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) {
struct pas_dma_xct_descr *dp;
struct pasemi_mac_buffer *info;
struct sk_buff *skb;
unsigned int j, len;
dma_addr_t dma;
for (count = limit; count; count--) {
rmb();
dp = &RX_DESC(mac, i);
dp = &RX_DESC(mac, n);
macrx = dp->macrx;
if (!(dp->macrx & XCT_MACRX_O))
if (!(macrx & XCT_MACRX_O))
break;
count++;
info = NULL;
......@@ -396,29 +453,42 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
*/
dma = (dp->ptr & XCT_PTR_ADDR_M);
for (j = start; j < (start + RX_RING_SIZE); j++) {
info = &RX_DESC_INFO(mac, j);
for (i = n; i < (n + RX_RING_SIZE); i++) {
info = &RX_DESC_INFO(mac, i);
if (info->dma == dma)
break;
}
BUG_ON(!info);
BUG_ON(info->dma != dma);
skb = info->skb;
info->dma = 0;
pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len,
pci_unmap_single(mac->dma_pdev, dma, skb->len,
PCI_DMA_FROMDEVICE);
skb = info->skb;
len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
if (len < 256) {
struct sk_buff *new_skb =
netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
if (new_skb) {
skb_reserve(new_skb, NET_IP_ALIGN);
memcpy(new_skb->data - NET_IP_ALIGN,
skb->data - NET_IP_ALIGN,
len + NET_IP_ALIGN);
/* save the skb in buffer_info as good */
skb = new_skb;
}
/* else just continue with the old one */
} else
info->skb = NULL;
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, mac->netdev);
if ((dp->macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
skb->ip_summed = CHECKSUM_COMPLETE;
skb->csum = (dp->macrx & XCT_MACRX_CSUM_M) >>
skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
XCT_MACRX_CSUM_S;
} else
skb->ip_summed = CHECKSUM_NONE;
......@@ -428,13 +498,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
netif_receive_skb(skb);
info->dma = 0;
info->skb = NULL;
dp->ptr = 0;
dp->macrx = 0;
n++;
}
mac->rx->next_to_clean += count;
mac->rx->next_to_clean += limit - count;
pasemi_mac_replenish_rx_ring(mac->netdev);
spin_unlock(&mac->rx->lock);
......@@ -476,6 +546,8 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
mac->tx->next_to_clean += count;
spin_unlock_irqrestore(&mac->tx->lock, flags);
netif_wake_queue(mac->netdev);
return count;
}
......@@ -486,18 +558,28 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int reg;
if (!(*mac->rx_status & PAS_STATUS_INT))
if (!(*mac->rx_status & PAS_STATUS_CAUSE_M))
return IRQ_NONE;
netif_rx_schedule(dev);
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0));
if (*mac->rx_status & PAS_STATUS_ERROR)
printk("rx_status reported error\n");
/* Don't reset packet count so it won't fire again but clear
* all others.
*/
pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), &reg);
reg = PAS_IOB_DMA_RXCH_RESET_PINTC | PAS_IOB_DMA_RXCH_RESET_SINTC |
PAS_IOB_DMA_RXCH_RESET_DINTC;
reg = 0;
if (*mac->rx_status & PAS_STATUS_SOFT)
reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
if (*mac->rx_status & PAS_STATUS_ERROR)
reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
if (*mac->rx_status & PAS_STATUS_TIMER)
reg |= PAS_IOB_DMA_RXCH_RESET_TINTC;
netif_rx_schedule(dev);
pci_write_config_dword(mac->iob_pdev,
PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
......@@ -510,31 +592,137 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
struct net_device *dev = data;
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int reg;
int was_full;
was_full = mac->tx->next_to_clean - mac->tx->next_to_use == TX_RING_SIZE;
if (!(*mac->tx_status & PAS_STATUS_INT))
if (!(*mac->tx_status & PAS_STATUS_CAUSE_M))
return IRQ_NONE;
pasemi_mac_clean_tx(mac);
reg = PAS_IOB_DMA_TXCH_RESET_PINTC | PAS_IOB_DMA_TXCH_RESET_SINTC;
if (*mac->tx_status & PAS_STATUS_TIMER)
reg |= PAS_IOB_DMA_TXCH_RESET_TINTC;
reg = PAS_IOB_DMA_TXCH_RESET_PINTC;
if (*mac->tx_status & PAS_STATUS_SOFT)
reg |= PAS_IOB_DMA_TXCH_RESET_SINTC;
if (*mac->tx_status & PAS_STATUS_ERROR)
reg |= PAS_IOB_DMA_TXCH_RESET_DINTC;
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch),
reg);
if (was_full)
netif_wake_queue(dev);
return IRQ_HANDLED;
}
static void pasemi_adjust_link(struct net_device *dev)
{
struct pasemi_mac *mac = netdev_priv(dev);
int msg;
unsigned int flags;
unsigned int new_flags;
if (!mac->phydev->link) {
/* If no link, MAC speed settings don't matter. Just report
* link down and return.
*/
if (mac->link && netif_msg_link(mac))
printk(KERN_INFO "%s: Link is down.\n", dev->name);
netif_carrier_off(dev);
mac->link = 0;
return;
} else
netif_carrier_on(dev);
pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags);
new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M |
PAS_MAC_CFG_PCFG_TSR_M);
if (!mac->phydev->duplex)
new_flags |= PAS_MAC_CFG_PCFG_HD;
switch (mac->phydev->speed) {
case 1000:
new_flags |= PAS_MAC_CFG_PCFG_SPD_1G |
PAS_MAC_CFG_PCFG_TSR_1G;
break;
case 100:
new_flags |= PAS_MAC_CFG_PCFG_SPD_100M |
PAS_MAC_CFG_PCFG_TSR_100M;
break;
case 10:
new_flags |= PAS_MAC_CFG_PCFG_SPD_10M |
PAS_MAC_CFG_PCFG_TSR_10M;
break;
default:
printk("Unsupported speed %d\n", mac->phydev->speed);
}
/* Print on link or speed/duplex change */
msg = mac->link != mac->phydev->link || flags != new_flags;
mac->duplex = mac->phydev->duplex;
mac->speed = mac->phydev->speed;
mac->link = mac->phydev->link;
if (new_flags != flags)
pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, new_flags);
if (msg && netif_msg_link(mac))
printk(KERN_INFO "%s: Link is up at %d Mbps, %s duplex.\n",
dev->name, mac->speed, mac->duplex ? "full" : "half");
}
static int pasemi_mac_phy_init(struct net_device *dev)
{
struct pasemi_mac *mac = netdev_priv(dev);
struct device_node *dn, *phy_dn;
struct phy_device *phydev;
unsigned int phy_id;
const phandle *ph;
const unsigned int *prop;
struct resource r;
int ret;
dn = pci_device_to_OF_node(mac->pdev);
ph = of_get_property(dn, "phy-handle", NULL);
if (!ph)
return -ENODEV;
phy_dn = of_find_node_by_phandle(*ph);
prop = of_get_property(phy_dn, "reg", NULL);
ret = of_address_to_resource(phy_dn->parent, 0, &r);
if (ret)
goto err;
phy_id = *prop;
snprintf(mac->phy_id, BUS_ID_SIZE, PHY_ID_FMT, (int)r.start, phy_id);
of_node_put(phy_dn);
mac->link = 0;
mac->speed = 0;
mac->duplex = -1;
phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);
if (IS_ERR(phydev)) {
printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
return PTR_ERR(phydev);
}
mac->phydev = phydev;
return 0;
err:
of_node_put(phy_dn);
return -ENODEV;
}
static int pasemi_mac_open(struct net_device *dev)
{
struct pasemi_mac *mac = netdev_priv(dev);
int base_irq;
unsigned int flags;
int ret;
......@@ -558,10 +746,18 @@ static int pasemi_mac_open(struct net_device *dev)
flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
PAS_IOB_DMA_RXCH_CFG_CNTTH(30));
PAS_IOB_DMA_RXCH_CFG_CNTTH(1));
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
/* Clear out any residual packet count state from firmware */
pasemi_mac_restart_rx_intr(mac);
pasemi_mac_restart_tx_intr(mac);
/* 0xffffff is max value, about 16ms */
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000));
PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff));
pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags);
......@@ -595,31 +791,50 @@ static int pasemi_mac_open(struct net_device *dev)
pasemi_mac_replenish_rx_ring(dev);
ret = pasemi_mac_phy_init(dev);
/* Some configs don't have PHYs (XAUI etc), so don't complain about
* failed init due to -ENODEV.
*/
if (ret && ret != -ENODEV)
dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret);
netif_start_queue(dev);
netif_poll_enable(dev);
ret = request_irq(mac->dma_pdev->irq + mac->dma_txch,
&pasemi_mac_tx_intr, IRQF_DISABLED,
/* Interrupts are a bit different for our DMA controller: While
* it's got one a regular PCI device header, the interrupt there
* is really the base of the range it's using. Each tx and rx
* channel has it's own interrupt source.
*/
base_irq = virq_to_hw(mac->dma_pdev->irq);
mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch);
mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_txch);
ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED,
mac->tx->irq_name, dev);
if (ret) {
dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
mac->dma_pdev->irq + mac->dma_txch, ret);
base_irq + mac->dma_txch, ret);
goto out_tx_int;
}
ret = request_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch,
&pasemi_mac_rx_intr, IRQF_DISABLED,
ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED,
mac->rx->irq_name, dev);
if (ret) {
dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
mac->dma_pdev->irq + 20 + mac->dma_rxch, ret);
base_irq + 20 + mac->dma_rxch, ret);
goto out_rx_int;
}
if (mac->phydev)
phy_start(mac->phydev);
return 0;
out_rx_int:
free_irq(mac->dma_pdev->irq + mac->dma_txch, dev);
free_irq(mac->tx_irq, dev);
out_tx_int:
netif_poll_disable(dev);
netif_stop_queue(dev);
......@@ -639,6 +854,11 @@ static int pasemi_mac_close(struct net_device *dev)
unsigned int stat;
int retries;
if (mac->phydev) {
phy_stop(mac->phydev);
phy_disconnect(mac->phydev);
}
netif_stop_queue(dev);
/* Clean out any pending buffers */
......@@ -660,40 +880,37 @@ static int pasemi_mac_close(struct net_device *dev)
pci_read_config_dword(mac->dma_pdev,
PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
&stat);
if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
break;
cond_resched();
}
if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)) {
if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n");
}
for (retries = 0; retries < MAX_RETRIES; retries++) {
pci_read_config_dword(mac->dma_pdev,
PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
&stat);
if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)
if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT))
break;
cond_resched();
}
if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)) {
if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)
dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n");
}
for (retries = 0; retries < MAX_RETRIES; retries++) {
pci_read_config_dword(mac->dma_pdev,
PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
&stat);
if (stat & PAS_DMA_RXINT_RCMDSTA_ACT)
if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT))
break;
cond_resched();
}
if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT)) {
if (stat & PAS_DMA_RXINT_RCMDSTA_ACT)
dev_err(&mac->dma_pdev->dev, "Failed to stop rx interface\n");
}
/* Then, disable the channel. This must be done separately from
* stopping, since you can't disable when active.
......@@ -706,8 +923,8 @@ static int pasemi_mac_close(struct net_device *dev)
pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
free_irq(mac->dma_pdev->irq + mac->dma_txch, dev);
free_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, dev);
free_irq(mac->tx_irq, dev);
free_irq(mac->rx_irq, dev);
/* Free resources */
pasemi_mac_free_rx_resources(dev);
......@@ -802,6 +1019,7 @@ static struct net_device_stats *pasemi_mac_get_stats(struct net_device *dev)
return &mac->stats;
}
static void pasemi_mac_set_rx_mode(struct net_device *dev)
{
struct pasemi_mac *mac = netdev_priv(dev);
......@@ -826,18 +1044,17 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget)
pkts = pasemi_mac_clean_rx(mac, limit);
dev->quota -= pkts;
*budget -= pkts;
if (pkts < limit) {
/* all done, no more packets present */
netif_rx_complete(dev);
/* re-enable receive interrupts */
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000));
pasemi_mac_restart_rx_intr(mac);
return 0;
} else {
/* used up our quantum, so reschedule */
dev->quota -= pkts;
*budget -= pkts;
return 1;
}
}
......@@ -937,6 +1154,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
/* Enable most messages by default */
mac->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
err = register_netdev(dev);
if (err) {
......@@ -1011,9 +1233,5 @@ int pasemi_mac_init_module(void)
return pci_register_driver(&pasemi_mac_driver);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
module_init(pasemi_mac_init_module);
module_exit(pasemi_mac_cleanup_module);
......@@ -24,6 +24,7 @@
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/phy.h>
struct pasemi_mac_txring {
spinlock_t lock;
......@@ -54,6 +55,7 @@ struct pasemi_mac {
struct pci_dev *pdev;
struct pci_dev *dma_pdev;
struct pci_dev *iob_pdev;
struct phy_device *phydev;
struct net_device_stats stats;
/* Pointer to the cacheable per-channel status registers */
......@@ -73,6 +75,14 @@ struct pasemi_mac {
struct pasemi_mac_txring *tx;
struct pasemi_mac_rxring *rx;
unsigned long tx_irq;
unsigned long rx_irq;
int link;
int speed;
int duplex;
unsigned int msg_enable;
char phy_id[BUS_ID_SIZE];
};
/* Software status descriptor (desc_info) */
......@@ -193,11 +203,15 @@ enum {
#define PAS_DMA_RXINT_RCMDSTA(i) (0x200+(i)*_PAS_DMA_RXINT_STRIDE)
#define PAS_DMA_RXINT_RCMDSTA_EN 0x00000001
#define PAS_DMA_RXINT_RCMDSTA_ST 0x00000002
#define PAS_DMA_RXINT_RCMDSTA_OO 0x00000100
#define PAS_DMA_RXINT_RCMDSTA_BP 0x00000200
#define PAS_DMA_RXINT_RCMDSTA_DR 0x00000400
#define PAS_DMA_RXINT_RCMDSTA_MBT 0x00000008
#define PAS_DMA_RXINT_RCMDSTA_MDR 0x00000010
#define PAS_DMA_RXINT_RCMDSTA_MOO 0x00000020
#define PAS_DMA_RXINT_RCMDSTA_MBP 0x00000040
#define PAS_DMA_RXINT_RCMDSTA_BT 0x00000800
#define PAS_DMA_RXINT_RCMDSTA_TB 0x00001000
#define PAS_DMA_RXINT_RCMDSTA_DR 0x00001000
#define PAS_DMA_RXINT_RCMDSTA_OO 0x00002000
#define PAS_DMA_RXINT_RCMDSTA_BP 0x00004000
#define PAS_DMA_RXINT_RCMDSTA_TB 0x00008000
#define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000
#define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000
#define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17
......@@ -297,6 +311,7 @@ enum {
#define PAS_STATUS_DCNT_S 16
#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
#define PAS_STATUS_BPCNT_S 32
#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
#define PAS_STATUS_TIMER 0x1000000000000000ull
#define PAS_STATUS_ERROR 0x2000000000000000ull
#define PAS_STATUS_SOFT 0x4000000000000000ull
......
......@@ -1420,7 +1420,7 @@ set_addresses(struct net_device *dev)
kio_addr_t ioaddr = dev->base_addr;
local_info_t *lp = netdev_priv(dev);
struct dev_mc_list *dmi = dev->mc_list;
char *addr;
unsigned char *addr;
int i,j,k,n;
SelectPage(k=0x50);
......@@ -1429,6 +1429,9 @@ set_addresses(struct net_device *dev)
if (++n > 9)
break;
i = 0;
if (n > 1 && n <= dev->mc_count && dmi) {
dmi = dmi->next;
}
}
if (j > 15) {
j = 8;
......@@ -1436,10 +1439,9 @@ set_addresses(struct net_device *dev)
SelectPage(k);
}
if (n && n <= dev->mc_count && dmi) {
if (n && n <= dev->mc_count && dmi)
addr = dmi->dmi_addr;
dmi = dmi->next;
} else
else
addr = dev->dev_addr;
if (lp->mohawk)
......@@ -1465,10 +1467,10 @@ set_multicast_list(struct net_device *dev)
if (dev->flags & IFF_PROMISC) { /* snoop */
PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */
} else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) {
PutByte(XIRCREG42_SWC1, 0x06); /* set MPE */
PutByte(XIRCREG42_SWC1, 0x02); /* set MPE */
} else if (dev->mc_count) {
/* the chip can filter 9 addresses perfectly */
PutByte(XIRCREG42_SWC1, 0x00);
PutByte(XIRCREG42_SWC1, 0x01);
SelectPage(0x40);
PutByte(XIRCREG40_CMD0, Offline);
set_addresses(dev);
......
......@@ -135,10 +135,13 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
/* Wake on Lan only supported on Yukon chips with rev 1 or above */
static u32 wol_supported(const struct skge_hw *hw)
{
if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0)
return WAKE_MAGIC | WAKE_PHY;
else
if (hw->chip_id == CHIP_ID_GENESIS)
return 0;
if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
return 0;
return WAKE_MAGIC | WAKE_PHY;
}
static u32 pci_wake_enabled(struct pci_dev *dev)
......
......@@ -124,10 +124,7 @@ static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
#ifdef broken
/* This device causes data corruption problems that are not resolved */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
#endif
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
......@@ -3581,10 +3578,21 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out;
}
/* Some Gigabyte motherboards have 88e8056 but cause problems
* There is some unresolved hardware related problem that causes
* descriptor errors and receive data corruption.
*/
if (pdev->vendor == PCI_VENDOR_ID_MARVELL &&
pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) {
dev_err(&pdev->dev,
"88E8056 on Gigabyte motherboards not supported\n");
goto err_out_disable;
}
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
dev_err(&pdev->dev, "cannot obtain PCI resources\n");
goto err_out;
goto err_out_disable;
}
pci_set_master(pdev);
......@@ -3721,6 +3729,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
kfree(hw);
err_out_free_regions:
pci_release_regions(pdev);
err_out_disable:
pci_disable_device(pdev);
err_out:
return err;
......
......@@ -279,6 +279,40 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
#elif defined(CONFIG_SUPERH)
#if defined(CONFIG_SH_7780_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE)
#define SMC_CAN_USE_8BIT 0
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
#define SMC_IO_SHIFT 0
#define SMC_NOWAIT 1
#define SMC_inb(a, r) (inw((a) + ((r)&~1)) >> (8*(r%2)))&0xff
#define SMC_inw(a, r) inw((a) + (r))
#define SMC_outb(v, a, r) outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1))
#define SMC_outw(v, a, r) outw(v, (a) + (r))
#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
#else /* BOARDS */
#define SMC_CAN_USE_8BIT 1
#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 1
#define SMC_inb(a, r) inb((a) + (r))
#define SMC_inw(a, r) inw((a) + (r))
#define SMC_outb(v, a, r) outb(v, (a) + (r))
#define SMC_outw(v, a, r) outw(v, (a) + (r))
#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
#endif /* BOARDS */
#define set_irq_type(irq, type) do {} while (0)
#elif defined(CONFIG_M32R)
#define SMC_CAN_USE_8BIT 0
......
......@@ -540,7 +540,6 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev,
skb = dev_alloc_skb(RX_BUF_SIZE);
if (!skb)
return NULL;
skb->dev = dev;
*dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE,
PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(*dma_handle)) {
......
......@@ -267,7 +267,7 @@ config IPW2200_DEBUG
config LIBERTAS_USB
tristate "Marvell Libertas 8388 802.11a/b/g cards"
depends on NET_RADIO && USB
depends on USB && WLAN_80211
select FW_LOADER
---help---
A driver for Marvell Libertas 8388 USB devices.
......
......@@ -996,18 +996,25 @@ __qdio_outbound_processing(struct qdio_q *q)
if (qdio_has_outbound_q_moved(q))
qdio_kick_outbound_handler(q);
if (q->is_iqdio_q) {
if (q->queue_type == QDIO_ZFCP_QFMT) {
if ((!q->hydra_gives_outbound_pcis) &&
(!qdio_is_outbound_q_done(q)))
qdio_mark_q(q);
}
else if (((!q->is_iqdio_q) && (!q->is_pci_out)) ||
(q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) {
/*
* for asynchronous queues, we better check, if the sent
* buffer is already switched from PRIMED to EMPTY.
* make sure buffer switch from PRIMED to EMPTY is noticed
* and outbound_handler is called
*/
if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) &&
!qdio_is_outbound_q_done(q))
qdio_mark_q(q);
} else if (!q->hydra_gives_outbound_pcis)
if (!qdio_is_outbound_q_done(q))
qdio_mark_q(q);
if (qdio_is_outbound_q_done(q)) {
del_timer(&q->timer);
} else {
if (!timer_pending(&q->timer))
mod_timer(&q->timer, jiffies +
QDIO_FORCE_CHECK_TIMEOUT);
}
}
qdio_release_q(q);
}
......@@ -1826,6 +1833,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
q->queue_type = QDIO_IQDIO_QFMT_ASYNCH;
q->int_parm=int_parm;
q->is_input_q=0;
q->is_pci_out = 0;
q->schid = irq_ptr->schid;
q->cdev = cdev;
q->irq_ptr = irq_ptr;
......@@ -1838,6 +1846,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
q->tasklet.data=(unsigned long)q;
q->tasklet.func=(void(*)(unsigned long))
&qdio_outbound_processing;
q->timer.function=(void(*)(unsigned long))
&qdio_outbound_processing;
q->timer.data = (long)q;
init_timer(&q->timer);
atomic_set(&q->busy_siga_counter,0);
q->timing.busy_start=0;
......@@ -2635,6 +2647,7 @@ qdio_shutdown(struct ccw_device *cdev, int how)
for (i=0;i<irq_ptr->no_output_qs;i++) {
tasklet_kill(&irq_ptr->output_qs[i]->tasklet);
del_timer(&irq_ptr->output_qs[i]->timer);
wait_event_interruptible_timeout(cdev->private->wait_q,
!atomic_read(&irq_ptr->
output_qs[i]->
......@@ -3458,6 +3471,10 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
qdio_perf_stat_inc(&perf_stats.outbound_cnt);
return;
}
if (callflags & QDIO_FLAG_PCI_OUT)
q->is_pci_out = 1;
else
q->is_pci_out = 0;
if (q->is_iqdio_q) {
/* one siga for every sbal */
while (count--)
......
......@@ -60,6 +60,7 @@
#define QDIO_ACTIVATE_TIMEOUT ((5*HZ)>>10)
#define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ)
#define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ)
#define QDIO_FORCE_CHECK_TIMEOUT (10*HZ)
enum qdio_irq_states {
QDIO_IRQ_STATE_INACTIVE,
......@@ -511,8 +512,8 @@ struct qdio_q {
void *irq_ptr;
#ifdef QDIO_USE_TIMERS_FOR_POLLING
struct timer_list timer;
#ifdef QDIO_USE_TIMERS_FOR_POLLING
atomic_t timer_already_set;
spinlock_t timer_lock;
#else /* QDIO_USE_TIMERS_FOR_POLLING */
......@@ -558,6 +559,7 @@ struct qdio_q {
} timing;
atomic_t busy_siga_counter;
unsigned int queue_type;
unsigned int is_pci_out;
/* leave this member at the end. won't be cleared in qdio_fill_qs */
struct slib *slib; /* a page is allocated under this pointer,
......
......@@ -1862,12 +1862,14 @@ static void netiucv_remove_connection(struct iucv_connection *conn)
write_lock_bh(&iucv_connection_rwlock);
list_del_init(&conn->list);
write_unlock_bh(&iucv_connection_rwlock);
fsm_deltimer(&conn->timer);
netiucv_purge_skb_queue(&conn->collect_queue);
if (conn->path) {
iucv_path_sever(conn->path, iucvMagic);
kfree(conn->path);
conn->path = NULL;
}
fsm_deltimer(&conn->timer);
netiucv_purge_skb_queue(&conn->commit_queue);
kfree_fsm(conn->fsm);
kfree_skb(conn->rx_buff);
kfree_skb(conn->tx_buff);
......@@ -2115,7 +2117,6 @@ static void __exit netiucv_exit(void)
while (!list_empty(&iucv_connection_list)) {
cp = list_entry(iucv_connection_list.next,
struct iucv_connection, list);
list_del(&cp->list);
ndev = cp->netdev;
priv = netdev_priv(ndev);
dev = priv->dev;
......
......@@ -620,10 +620,10 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
struct qeth_eddp_context *
qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *qhdr)
struct qeth_hdr *qhdr, unsigned char sk_protocol)
{
QETH_DBF_TEXT(trace, 5, "creddpc");
switch (skb->sk->sk_protocol){
switch (sk_protocol) {
case IPPROTO_TCP:
return qeth_eddp_create_context_tcp(card, skb, qhdr);
default:
......
......@@ -34,7 +34,8 @@ struct qeth_eddp_context_reference {
};
extern struct qeth_eddp_context *
qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,struct qeth_hdr *);
qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,
struct qeth_hdr *, unsigned char);
extern void
qeth_eddp_put_context(struct qeth_eddp_context *);
......
......@@ -1682,6 +1682,21 @@ qeth_put_reply(struct qeth_reply *reply)
kfree(reply);
}
static void
qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, struct qeth_card *card)
{
int rc;
int com;
char * ipa_name;
com = cmd->hdr.command;
rc = cmd->hdr.return_code;
ipa_name = qeth_get_ipa_cmd_name(com);
PRINT_ERR("%s(x%X) for %s returned x%X \"%s\"\n", ipa_name, com,
QETH_CARD_IFNAME(card), rc, qeth_get_ipa_msg(rc));
}
static struct qeth_ipa_cmd *
qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
{
......@@ -1690,8 +1705,11 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
QETH_DBF_TEXT(trace,5,"chkipad");
if (IS_IPA(iob->data)){
cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
if (IS_IPA_REPLY(cmd))
if (IS_IPA_REPLY(cmd)) {
if (cmd->hdr.return_code)
qeth_issue_ipa_msg(cmd, card);
return cmd;
}
else {
switch (cmd->hdr.command) {
case IPA_CMD_STOPLAN:
......@@ -2816,6 +2834,7 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
struct qeth_qdio_out_buffer *buf;
int rc;
int i;
unsigned int qdio_flags;
QETH_DBF_TEXT(trace, 6, "flushbuf");
......@@ -2859,13 +2878,13 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
queue->card->perf_stats.outbound_do_qdio_start_time =
qeth_get_micros();
}
qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
if (under_int)
rc = do_QDIO(CARD_DDEV(queue->card),
QDIO_FLAG_SYNC_OUTPUT | QDIO_FLAG_UNDER_INTERRUPT,
queue->queue_no, index, count, NULL);
else
rc = do_QDIO(CARD_DDEV(queue->card), QDIO_FLAG_SYNC_OUTPUT,
queue->queue_no, index, count, NULL);
qdio_flags |= QDIO_FLAG_UNDER_INTERRUPT;
if (atomic_read(&queue->set_pci_flags_count))
qdio_flags |= QDIO_FLAG_PCI_OUT;
rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
queue->queue_no, index, count, NULL);
if (queue->card->options.performance_stats)
queue->card->perf_stats.outbound_do_qdio_time +=
qeth_get_micros() -
......@@ -4490,7 +4509,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
qeth_fill_header(card, hdr, new_skb, ipv, cast_type);
}
if (large_send == QETH_LARGE_SEND_EDDP) {
ctx = qeth_eddp_create_context(card, new_skb, hdr);
ctx = qeth_eddp_create_context(card, new_skb, hdr,
skb->sk->sk_protocol);
if (ctx == NULL) {
__qeth_free_new_skb(skb, new_skb);
PRINT_WARN("could not create eddp context\n");
......@@ -5948,9 +5968,6 @@ qeth_layer2_send_setmac_cb(struct qeth_card *card,
cmd = (struct qeth_ipa_cmd *) data;
if (cmd->hdr.return_code) {
QETH_DBF_TEXT_(trace, 2, "L2er%x", cmd->hdr.return_code);
PRINT_WARN("Error in registering MAC address on " \
"device %s: x%x\n", CARD_BUS_ID(card),
cmd->hdr.return_code);
card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
cmd->hdr.return_code = -EIO;
} else {
......@@ -5985,9 +6002,6 @@ qeth_layer2_send_delmac_cb(struct qeth_card *card,
QETH_DBF_TEXT(trace, 2, "L2Dmaccb");
cmd = (struct qeth_ipa_cmd *) data;
if (cmd->hdr.return_code) {
PRINT_WARN("Error in deregistering MAC address on " \
"device %s: x%x\n", CARD_BUS_ID(card),
cmd->hdr.return_code);
QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
cmd->hdr.return_code = -EIO;
return 0;
......@@ -6651,7 +6665,7 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
QETH_DBF_TEXT(trace,4,"chgmaccb");
cmd = (struct qeth_ipa_cmd *) data;
if (!card->options.layer2 || card->info.guestlan ||
if (!card->options.layer2 ||
!(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
memcpy(card->dev->dev_addr,
&cmd->data.setadapterparms.data.change_addr.addr,
......@@ -8497,6 +8511,7 @@ __qeth_reboot_event_card(struct device *dev, void *data)
card = (struct qeth_card *) dev->driver_data;
qeth_clear_ip_list(card, 0, 0);
qeth_qdio_clear_card(card, 0);
qeth_clear_qdio_buffers(card);
return 0;
}
......
......@@ -157,12 +157,113 @@ unsigned char READ_CCW[]={
};
struct ipa_rc_msg {
enum qeth_ipa_return_codes rc;
char *msg;
};
struct ipa_rc_msg qeth_ipa_rc_msg[] = {
{IPA_RC_SUCCESS, "success"},
{IPA_RC_NOTSUPP, "Command not supported"},
{IPA_RC_IP_TABLE_FULL, "Add Addr IP Table Full - ipv6"},
{IPA_RC_UNKNOWN_ERROR, "IPA command failed - reason unknown"},
{IPA_RC_UNSUPPORTED_COMMAND, "Command not supported"},
{IPA_RC_DUP_IPV6_REMOTE,"ipv6 address already registered remote"},
{IPA_RC_DUP_IPV6_HOME, "ipv6 address already registered"},
{IPA_RC_UNREGISTERED_ADDR, "Address not registered"},
{IPA_RC_NO_ID_AVAILABLE, "No identifiers available"},
{IPA_RC_ID_NOT_FOUND, "Identifier not found"},
{IPA_RC_INVALID_IP_VERSION, "IP version incorrect"},
{IPA_RC_LAN_FRAME_MISMATCH, "LAN and frame mismatch"},
{IPA_RC_L2_UNSUPPORTED_CMD, "Unsupported layer 2 command"},
{IPA_RC_L2_DUP_MAC, "Duplicate MAC address"},
{IPA_RC_L2_ADDR_TABLE_FULL, "Layer2 address table full"},
{IPA_RC_L2_DUP_LAYER3_MAC, "Duplicate with layer 3 MAC"},
{IPA_RC_L2_GMAC_NOT_FOUND, "GMAC not found"},
{IPA_RC_L2_MAC_NOT_FOUND, "L2 mac address not found"},
{IPA_RC_L2_INVALID_VLAN_ID, "L2 invalid vlan id"},
{IPA_RC_L2_DUP_VLAN_ID, "L2 duplicate vlan id"},
{IPA_RC_L2_VLAN_ID_NOT_FOUND, "L2 vlan id not found"},
{IPA_RC_DATA_MISMATCH, "Data field mismatch (v4/v6 mixed)"},
{IPA_RC_INVALID_MTU_SIZE, "Invalid MTU size"},
{IPA_RC_INVALID_LANTYPE, "Invalid LAN type"},
{IPA_RC_INVALID_LANNUM, "Invalid LAN num"},
{IPA_RC_DUPLICATE_IP_ADDRESS, "Address already registered"},
{IPA_RC_IP_ADDR_TABLE_FULL, "IP address table full"},
{IPA_RC_LAN_PORT_STATE_ERROR, "LAN port state error"},
{IPA_RC_SETIP_NO_STARTLAN, "Setip no startlan received"},
{IPA_RC_SETIP_ALREADY_RECEIVED, "Setip already received"},
{IPA_RC_IP_ADDR_ALREADY_USED, "IP address already in use on LAN"},
{IPA_RC_MULTICAST_FULL, "No task available, multicast full"},
{IPA_RC_SETIP_INVALID_VERSION, "SETIP invalid IP version"},
{IPA_RC_UNSUPPORTED_SUBCMD, "Unsupported assist subcommand"},
{IPA_RC_ARP_ASSIST_NO_ENABLE, "Only partial success, no enable"},
{IPA_RC_PRIMARY_ALREADY_DEFINED,"Primary already defined"},
{IPA_RC_SECOND_ALREADY_DEFINED, "Secondary already defined"},
{IPA_RC_INVALID_SETRTG_INDICATOR,"Invalid SETRTG indicator"},
{IPA_RC_MC_ADDR_ALREADY_DEFINED,"Multicast address already defined"},
{IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"},
{IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"},
{IPA_RC_FFFF, "Unknown Error"}
};
char *
qeth_get_ipa_msg(enum qeth_ipa_return_codes rc)
{
int x = 0;
qeth_ipa_rc_msg[sizeof(qeth_ipa_rc_msg) /
sizeof(struct ipa_rc_msg) - 1].rc = rc;
while(qeth_ipa_rc_msg[x].rc != rc)
x++;
return qeth_ipa_rc_msg[x].msg;
}
struct ipa_cmd_names {
enum qeth_ipa_cmds cmd;
char *name;
};
struct ipa_cmd_names qeth_ipa_cmd_names[] = {
{IPA_CMD_STARTLAN, "startlan"},
{IPA_CMD_STOPLAN, "stoplan"},
{IPA_CMD_SETVMAC, "setvmac"},
{IPA_CMD_DELVMAC, "delvmca"},
{IPA_CMD_SETGMAC, "setgmac"},
{IPA_CMD_DELGMAC, "delgmac"},
{IPA_CMD_SETVLAN, "setvlan"},
{IPA_CMD_DELVLAN, "delvlan"},
{IPA_CMD_SETCCID, "setccid"},
{IPA_CMD_DELCCID, "delccid"},
{IPA_CMD_MODCCID, "setip"},
{IPA_CMD_SETIP, "setip"},
{IPA_CMD_QIPASSIST, "qipassist"},
{IPA_CMD_SETASSPARMS, "setassparms"},
{IPA_CMD_SETIPM, "setipm"},
{IPA_CMD_DELIPM, "delipm"},
{IPA_CMD_SETRTG, "setrtg"},
{IPA_CMD_DELIP, "delip"},
{IPA_CMD_SETADAPTERPARMS, "setadapterparms"},
{IPA_CMD_SET_DIAG_ASS, "set_diag_ass"},
{IPA_CMD_CREATE_ADDR, "create_addr"},
{IPA_CMD_DESTROY_ADDR, "destroy_addr"},
{IPA_CMD_REGISTER_LOCAL_ADDR, "register_local_addr"},
{IPA_CMD_UNREGISTER_LOCAL_ADDR, "unregister_local_addr"},
{IPA_CMD_UNKNOWN, "unknown"},
};
char *
qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd)
{
int x = 0;
qeth_ipa_cmd_names[
sizeof(qeth_ipa_cmd_names)/
sizeof(struct ipa_cmd_names)-1].cmd = cmd;
while(qeth_ipa_cmd_names[x].cmd != cmd)
x++;
return qeth_ipa_cmd_names[x].name;
}
......@@ -25,14 +25,14 @@ extern unsigned char IPA_PDU_HEADER[];
#define IPA_CMD_LENGTH (IPA_PDU_HEADER_SIZE + sizeof(struct qeth_ipa_cmd))
#define QETH_SEQ_NO_LENGTH 4
#define QETH_MPC_TOKEN_LENGTH 4
#define QETH_SEQ_NO_LENGTH 4
#define QETH_MPC_TOKEN_LENGTH 4
#define QETH_MCL_LENGTH 4
#define OSA_ADDR_LEN 6
#define QETH_TIMEOUT (10 * HZ)
#define QETH_IPA_TIMEOUT (45 * HZ)
#define QETH_IDX_COMMAND_SEQNO 0xffff0000
#define QETH_TIMEOUT (10 * HZ)
#define QETH_IPA_TIMEOUT (45 * HZ)
#define QETH_IDX_COMMAND_SEQNO 0xffff0000
#define SR_INFO_LEN 16
#define QETH_CLEAR_CHANNEL_PARM -10
......@@ -93,79 +93,107 @@ enum qeth_checksum_types {
*/
#define RESET_ROUTING_FLAG 0x10 /* indicate that routing type shall be set */
enum qeth_routing_types {
NO_ROUTER = 0, /* TODO: set to bit flag used in IPA Command */
PRIMARY_ROUTER = 1,
SECONDARY_ROUTER = 2,
MULTICAST_ROUTER = 3,
PRIMARY_CONNECTOR = 4,
SECONDARY_CONNECTOR = 5,
NO_ROUTER = 0, /* TODO: set to bit flag used in IPA Command */
PRIMARY_ROUTER = 1,
SECONDARY_ROUTER = 2,
MULTICAST_ROUTER = 3,
PRIMARY_CONNECTOR = 4,
SECONDARY_CONNECTOR = 5,
};
/* IPA Commands */
enum qeth_ipa_cmds {
IPA_CMD_STARTLAN = 0x01,
IPA_CMD_STOPLAN = 0x02,
IPA_CMD_SETVMAC = 0x21,
IPA_CMD_DELVMAC = 0x22,
IPA_CMD_SETGMAC = 0x23,
IPA_CMD_DELGMAC = 0x24,
IPA_CMD_SETVLAN = 0x25,
IPA_CMD_DELVLAN = 0x26,
IPA_CMD_SETCCID = 0x41,
IPA_CMD_DELCCID = 0x42,
IPA_CMD_MODCCID = 0x43,
IPA_CMD_SETIP = 0xb1,
IPA_CMD_DELIP = 0xb7,
IPA_CMD_QIPASSIST = 0xb2,
IPA_CMD_SETASSPARMS = 0xb3,
IPA_CMD_SETIPM = 0xb4,
IPA_CMD_DELIPM = 0xb5,
IPA_CMD_SETRTG = 0xb6,
IPA_CMD_SETADAPTERPARMS = 0xb8,
IPA_CMD_IPFRAME = 0xb9,
IPA_CMD_ADD_ADDR_ENTRY = 0xc1,
IPA_CMD_DELETE_ADDR_ENTRY = 0xc2,
IPA_CMD_CREATE_ADDR = 0xc3,
IPA_CMD_DESTROY_ADDR = 0xc4,
IPA_CMD_REGISTER_LOCAL_ADDR = 0xd1,
IPA_CMD_UNREGISTER_LOCAL_ADDR = 0xd2,
IPA_CMD_STARTLAN = 0x01,
IPA_CMD_STOPLAN = 0x02,
IPA_CMD_SETVMAC = 0x21,
IPA_CMD_DELVMAC = 0x22,
IPA_CMD_SETGMAC = 0x23,
IPA_CMD_DELGMAC = 0x24,
IPA_CMD_SETVLAN = 0x25,
IPA_CMD_DELVLAN = 0x26,
IPA_CMD_SETCCID = 0x41,
IPA_CMD_DELCCID = 0x42,
IPA_CMD_MODCCID = 0x43,
IPA_CMD_SETIP = 0xb1,
IPA_CMD_QIPASSIST = 0xb2,
IPA_CMD_SETASSPARMS = 0xb3,
IPA_CMD_SETIPM = 0xb4,
IPA_CMD_DELIPM = 0xb5,
IPA_CMD_SETRTG = 0xb6,
IPA_CMD_DELIP = 0xb7,
IPA_CMD_SETADAPTERPARMS = 0xb8,
IPA_CMD_SET_DIAG_ASS = 0xb9,
IPA_CMD_CREATE_ADDR = 0xc3,
IPA_CMD_DESTROY_ADDR = 0xc4,
IPA_CMD_REGISTER_LOCAL_ADDR = 0xd1,
IPA_CMD_UNREGISTER_LOCAL_ADDR = 0xd2,
IPA_CMD_UNKNOWN = 0x00
};
enum qeth_ip_ass_cmds {
IPA_CMD_ASS_START = 0x0001,
IPA_CMD_ASS_STOP = 0x0002,
IPA_CMD_ASS_CONFIGURE = 0x0003,
IPA_CMD_ASS_ENABLE = 0x0004,
IPA_CMD_ASS_CONFIGURE = 0x0003,
IPA_CMD_ASS_ENABLE = 0x0004,
};
enum qeth_arp_process_subcmds {
IPA_CMD_ASS_ARP_SET_NO_ENTRIES = 0x0003,
IPA_CMD_ASS_ARP_QUERY_CACHE = 0x0004,
IPA_CMD_ASS_ARP_ADD_ENTRY = 0x0005,
IPA_CMD_ASS_ARP_REMOVE_ENTRY = 0x0006,
IPA_CMD_ASS_ARP_FLUSH_CACHE = 0x0007,
IPA_CMD_ASS_ARP_QUERY_INFO = 0x0104,
IPA_CMD_ASS_ARP_QUERY_STATS = 0x0204,
IPA_CMD_ASS_ARP_SET_NO_ENTRIES = 0x0003,
IPA_CMD_ASS_ARP_QUERY_CACHE = 0x0004,
IPA_CMD_ASS_ARP_ADD_ENTRY = 0x0005,
IPA_CMD_ASS_ARP_REMOVE_ENTRY = 0x0006,
IPA_CMD_ASS_ARP_FLUSH_CACHE = 0x0007,
IPA_CMD_ASS_ARP_QUERY_INFO = 0x0104,
IPA_CMD_ASS_ARP_QUERY_STATS = 0x0204,
};
/* Return Codes for IPA Commands */
/* Return Codes for IPA Commands
* according to OSA card Specs */
enum qeth_ipa_return_codes {
IPA_RC_SUCCESS = 0x0000,
IPA_RC_NOTSUPP = 0x0001,
IPA_RC_NO_ACCESS = 0x0002,
IPA_RC_FAILED = 0x0003,
IPA_RC_DATA_MISMATCH = 0xe001,
IPA_RC_INVALID_LAN_TYPE = 0xe003,
IPA_RC_INVALID_LAN_NO = 0xe004,
IPA_RC_IPADDR_ALREADY_REG = 0xe005,
IPA_RC_IPADDR_TABLE_FULL = 0xe006,
IPA_RC_IPADDR_ALREADY_USED = 0xe00a,
IPA_RC_ASSNO_NOT_SUPP = 0xe00d,
IPA_RC_ASSCMD_START_FAILED = 0xe00e,
IPA_RC_ASSCMD_PART_SUCCESS = 0xe00f,
IPA_RC_IPADDR_NOT_DEFINED = 0xe010,
IPA_RC_LAN_OFFLINE = 0xe080,
IPA_RC_SUCCESS = 0x0000,
IPA_RC_NOTSUPP = 0x0001,
IPA_RC_IP_TABLE_FULL = 0x0002,
IPA_RC_UNKNOWN_ERROR = 0x0003,
IPA_RC_UNSUPPORTED_COMMAND = 0x0004,
IPA_RC_DUP_IPV6_REMOTE = 0x0008,
IPA_RC_DUP_IPV6_HOME = 0x0010,
IPA_RC_UNREGISTERED_ADDR = 0x0011,
IPA_RC_NO_ID_AVAILABLE = 0x0012,
IPA_RC_ID_NOT_FOUND = 0x0013,
IPA_RC_INVALID_IP_VERSION = 0x0020,
IPA_RC_LAN_FRAME_MISMATCH = 0x0040,
IPA_RC_L2_UNSUPPORTED_CMD = 0x2003,
IPA_RC_L2_DUP_MAC = 0x2005,
IPA_RC_L2_ADDR_TABLE_FULL = 0x2006,
IPA_RC_L2_DUP_LAYER3_MAC = 0x200a,
IPA_RC_L2_GMAC_NOT_FOUND = 0x200b,
IPA_RC_L2_MAC_NOT_FOUND = 0x2010,
IPA_RC_L2_INVALID_VLAN_ID = 0x2015,
IPA_RC_L2_DUP_VLAN_ID = 0x2016,
IPA_RC_L2_VLAN_ID_NOT_FOUND = 0x2017,
IPA_RC_DATA_MISMATCH = 0xe001,
IPA_RC_INVALID_MTU_SIZE = 0xe002,
IPA_RC_INVALID_LANTYPE = 0xe003,
IPA_RC_INVALID_LANNUM = 0xe004,
IPA_RC_DUPLICATE_IP_ADDRESS = 0xe005,
IPA_RC_IP_ADDR_TABLE_FULL = 0xe006,
IPA_RC_LAN_PORT_STATE_ERROR = 0xe007,
IPA_RC_SETIP_NO_STARTLAN = 0xe008,
IPA_RC_SETIP_ALREADY_RECEIVED = 0xe009,
IPA_RC_IP_ADDR_ALREADY_USED = 0xe00a,
IPA_RC_MULTICAST_FULL = 0xe00b,
IPA_RC_SETIP_INVALID_VERSION = 0xe00d,
IPA_RC_UNSUPPORTED_SUBCMD = 0xe00e,
IPA_RC_ARP_ASSIST_NO_ENABLE = 0xe00f,
IPA_RC_PRIMARY_ALREADY_DEFINED = 0xe010,
IPA_RC_SECOND_ALREADY_DEFINED = 0xe011,
IPA_RC_INVALID_SETRTG_INDICATOR = 0xe012,
IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013,
IPA_RC_LAN_OFFLINE = 0xe080,
IPA_RC_INVALID_IP_VERSION2 = 0xf001,
IPA_RC_FFFF = 0xffff
};
/* IPA function flags; each flag marks availability of respective function */
......@@ -183,7 +211,9 @@ enum qeth_ipa_funcs {
IPA_SETADAPTERPARMS = 0x00000400L,
IPA_VLAN_PRIO = 0x00000800L,
IPA_PASSTHRU = 0x00001000L,
IPA_FLUSH_ARP_SUPPORT = 0x00002000L,
IPA_FULL_VLAN = 0x00004000L,
IPA_INBOUND_PASSTHRU = 0x00008000L,
IPA_SOURCE_MAC = 0x00010000L,
IPA_OSA_MC_ROUTER = 0x00020000L,
IPA_QUERY_ARP_ASSIST = 0x00040000L,
......@@ -204,31 +234,30 @@ enum qeth_ipa_setdelip_flags {
/* SETADAPTER IPA Command: ****************************************************/
enum qeth_ipa_setadp_cmd {
IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x01,
IPA_SETADP_ALTER_MAC_ADDRESS = 0x02,
IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x04,
IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x08,
IPA_SETADP_SET_ADDRESSING_MODE = 0x10,
IPA_SETADP_SET_CONFIG_PARMS = 0x20,
IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x40,
IPA_SETADP_SET_BROADCAST_MODE = 0x80,
IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
IPA_SETADP_READ_SNMP_PARMS = 0x0400,
IPA_SETADP_ALTER_MAC_ADDRESS = 0x02,
IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x04,
IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x08,
IPA_SETADP_SET_ADDRESSING_MODE = 0x10,
IPA_SETADP_SET_CONFIG_PARMS = 0x20,
IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x40,
IPA_SETADP_SET_BROADCAST_MODE = 0x80,
IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
IPA_SETADP_QUERY_CARD_INFO = 0x0400,
IPA_SETADP_SET_PROMISC_MODE = 0x0800,
IPA_SETADP_QUERY_CARD_INFO = 0x1000,
};
enum qeth_ipa_mac_ops {
CHANGE_ADDR_READ_MAC = 0,
CHANGE_ADDR_REPLACE_MAC = 1,
CHANGE_ADDR_ADD_MAC = 2,
CHANGE_ADDR_DEL_MAC = 4,
CHANGE_ADDR_RESET_MAC = 8,
CHANGE_ADDR_READ_MAC = 0,
CHANGE_ADDR_REPLACE_MAC = 1,
CHANGE_ADDR_ADD_MAC = 2,
CHANGE_ADDR_DEL_MAC = 4,
CHANGE_ADDR_RESET_MAC = 8,
};
enum qeth_ipa_addr_ops {
CHANGE_ADDR_READ_ADDR = 0,
CHANGE_ADDR_ADD_ADDR = 1,
CHANGE_ADDR_DEL_ADDR = 2,
CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
CHANGE_ADDR_READ_ADDR = 0,
CHANGE_ADDR_ADD_ADDR = 1,
CHANGE_ADDR_DEL_ADDR = 2,
CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
};
enum qeth_ipa_promisc_modes {
SET_PROMISC_MODE_OFF = 0,
......@@ -407,15 +436,15 @@ struct qeth_ipacmd_hdr {
struct qeth_ipa_cmd {
struct qeth_ipacmd_hdr hdr;
union {
struct qeth_ipacmd_setdelip4 setdelip4;
struct qeth_ipacmd_setdelip6 setdelip6;
struct qeth_ipacmd_setdelip4 setdelip4;
struct qeth_ipacmd_setdelip6 setdelip6;
struct qeth_ipacmd_setdelipm setdelipm;
struct qeth_ipacmd_setassparms setassparms;
struct qeth_ipacmd_layer2setdelmac setdelmac;
struct qeth_ipacmd_layer2setdelvlan setdelvlan;
struct qeth_create_destroy_address create_destroy_addr;
struct qeth_ipacmd_setadpparms setadapterparms;
struct qeth_set_routing setrtg;
struct qeth_ipacmd_setassparms setassparms;
struct qeth_ipacmd_layer2setdelmac setdelmac;
struct qeth_ipacmd_layer2setdelvlan setdelvlan;
struct qeth_create_destroy_address create_destroy_addr;
struct qeth_ipacmd_setadpparms setadapterparms;
struct qeth_set_routing setrtg;
} data;
} __attribute__ ((packed));
......@@ -433,6 +462,12 @@ enum qeth_ipa_arp_return_codes {
QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008,
};
extern char *
qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
extern char *
qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
#define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
sizeof(struct qeth_ipacmd_setassparms_hdr))
#define QETH_IPA_ARP_DATA_POS(buffer) (buffer + IPA_PDU_HEADER_SIZE + \
......@@ -521,7 +556,7 @@ extern unsigned char DM_ACT[];
extern unsigned char IDX_ACTIVATE_READ[];
extern unsigned char IDX_ACTIVATE_WRITE[];
#define IDX_ACTIVATE_SIZE 0x22
#define IDX_ACTIVATE_SIZE 0x22
#define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer+0x0c)
#define QETH_IDX_NO_PORTNAME_REQUIRED(buffer) ((buffer)[0x0b]&0x80)
#define QETH_IDX_ACT_FUNC_LEVEL(buffer) (buffer+0x10)
......
......@@ -384,8 +384,6 @@ qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route,
route->type = PRIMARY_CONNECTOR;
} else if (!strcmp(tmp, "secondary_connector")) {
route->type = SECONDARY_CONNECTOR;
} else if (!strcmp(tmp, "multicast_router")) {
route->type = MULTICAST_ROUTER;
} else if (!strcmp(tmp, "primary_router")) {
route->type = PRIMARY_ROUTER;
} else if (!strcmp(tmp, "secondary_router")) {
......
......@@ -120,6 +120,7 @@ extern unsigned long qdio_get_status(int irq);
#define QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT 0x08 /* no effect on
adapter interrupts */
#define QDIO_FLAG_DONT_SIGA 0x10
#define QDIO_FLAG_PCI_OUT 0x20
extern int do_QDIO(struct ccw_device*, unsigned int flags,
unsigned int queue_number,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册