Commit 5bbc1722 authored by David S. Miller's avatar David S. Miller
Browse files

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

parents 30902dc3 ae7b6487
......@@ -376,7 +376,8 @@ max_bonds
Specifies the number of bonding devices to create for this
instance of the bonding driver. E.g., if max_bonds is 3, and
the bonding driver is not already loaded, then bond0, bond1
and bond2 will be created. The default value is 1.
and bond2 will be created. The default value is 1. Specifying
a value of 0 will load bonding, but will not create any devices.
miimon
......@@ -539,6 +540,17 @@ mode
swapped with the new curr_active_slave that was
chosen.
num_grat_arp
Specifies the number of gratuitous ARPs to be issued after a
failover event. One gratuitous ARP is issued immediately after
the failover, subsequent ARPs are sent at a rate of one per link
monitor interval (arp_interval or miimon, whichever is active).
The valid range is 0 - 255; the default value is 1. This option
affects only the active-backup mode. This option was added for
bonding version 3.3.0.
primary
A string (eth0, eth2, etc) specifying which slave is the
......
......@@ -2147,6 +2147,8 @@ P: Jesse Brandeburg
M: jesse.brandeburg@intel.com
P: Bruce Allan
M: bruce.w.allan@intel.com
P: PJ Waskiewicz
M: peter.p.waskiewicz.jr@intel.com
P: John Ronciak
M: john.ronciak@intel.com
L: e1000-devel@lists.sourceforge.net
......@@ -2690,12 +2692,10 @@ L: libertas-dev@lists.infradead.org
S: Maintained
MARVELL MV643XX ETHERNET DRIVER
P: Dale Farnsworth
M: dale@farnsworth.org
P: Manish Lachwani
M: mlachwani@mvista.com
P: Lennert Buytenhek
M: buytenh@marvell.com
L: netdev@vger.kernel.org
S: Odd Fixes for 2.4; Maintained for 2.6.
S: Supported
MATROX FRAMEBUFFER DRIVER
P: Petr Vandrovec
......@@ -3233,14 +3233,6 @@ L: linux-kernel@vger.kernel.org
T: git git.infradead.org/battery-2.6.git
S: Maintained
POWERPC 4xx EMAC DRIVER
P: Eugene Surovegin
M: ebs@ebshome.net
W: http://kernel.ebshome.net/emac/
L: linuxppc-dev@ozlabs.org
L: netdev@vger.kernel.org
S: Maintained
PNP SUPPORT
P: Adam Belay
M: ambx1@neo.rr.com
......
......@@ -1255,7 +1255,6 @@ config IBMVETH
To compile this driver as a module, choose M here. The module will
be called ibmveth.
source "drivers/net/ibm_emac/Kconfig"
source "drivers/net/ibm_newemac/Kconfig"
config NET_PCI
......
......@@ -4,7 +4,6 @@
obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_E1000E) += e1000e/
obj-$(CONFIG_IBM_EMAC) += ibm_emac/
obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
obj-$(CONFIG_IGB) += igb/
obj-$(CONFIG_IXGBE) += ixgbe/
......
......@@ -1189,22 +1189,21 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (new_active) {
bond_set_slave_active_flags(new_active);
}
if (new_active && bond->params.fail_over_mac)
bond_do_fail_over_mac(bond, new_active, old_active);
if (bond->params.fail_over_mac)
bond_do_fail_over_mac(bond, new_active,
old_active);
bond->send_grat_arp = bond->params.num_grat_arp;
if (bond->curr_active_slave &&
test_bit(__LINK_STATE_LINKWATCH_PENDING,
&bond->curr_active_slave->dev->state)) {
dprintk("delaying gratuitous arp on %s\n",
bond->curr_active_slave->dev->name);
} else {
if (bond->send_grat_arp > 0) {
bond_send_gratuitous_arp(bond);
bond->send_grat_arp--;
}
bond->send_grat_arp = bond->params.num_grat_arp;
bond_send_gratuitous_arp(bond);
write_unlock_bh(&bond->curr_slave_lock);
read_unlock(&bond->lock);
netdev_bonding_change(bond->dev);
read_lock(&bond->lock);
write_lock_bh(&bond->curr_slave_lock);
}
}
}
......@@ -2235,17 +2234,6 @@ static int __bond_mii_monitor(struct bonding *bond, int have_locks)
* program could monitor the link itself if needed.
*/
if (bond->send_grat_arp) {
if (bond->curr_active_slave && test_bit(__LINK_STATE_LINKWATCH_PENDING,
&bond->curr_active_slave->dev->state))
dprintk("Needs to send gratuitous arp but not yet\n");
else {
dprintk("sending delayed gratuitous arp on on %s\n",
bond->curr_active_slave->dev->name);
bond_send_gratuitous_arp(bond);
bond->send_grat_arp--;
}
}
read_lock(&bond->curr_slave_lock);
oldcurrent = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
......@@ -2486,6 +2474,13 @@ void bond_mii_monitor(struct work_struct *work)
read_unlock(&bond->lock);
return;
}
if (bond->send_grat_arp) {
read_lock(&bond->curr_slave_lock);
bond_send_gratuitous_arp(bond);
read_unlock(&bond->curr_slave_lock);
}
if (__bond_mii_monitor(bond, 0)) {
read_unlock(&bond->lock);
rtnl_lock();
......@@ -2651,6 +2646,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
/*
* Kick out a gratuitous ARP for an IP on the bonding master plus one
* for each VLAN above us.
*
* Caller must hold curr_slave_lock for read or better
*/
static void bond_send_gratuitous_arp(struct bonding *bond)
{
......@@ -2660,9 +2657,13 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name,
slave ? slave->dev->name : "NULL");
if (!slave)
if (!slave || !bond->send_grat_arp ||
test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
return;
bond->send_grat_arp--;
if (bond->master_ip) {
bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
bond->master_ip, 0);
......@@ -3166,6 +3167,12 @@ void bond_activebackup_arp_mon(struct work_struct *work)
if (bond->slave_cnt == 0)
goto re_arm;
if (bond->send_grat_arp) {
read_lock(&bond->curr_slave_lock);
bond_send_gratuitous_arp(bond);
read_unlock(&bond->curr_slave_lock);
}
if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
read_unlock(&bond->lock);
rtnl_lock();
......@@ -3840,6 +3847,7 @@ static int bond_close(struct net_device *bond_dev)
write_lock_bh(&bond->lock);
bond->send_grat_arp = 0;
/* signal timers not to re-arm */
bond->kill_timers = 1;
......@@ -4742,11 +4750,11 @@ static int bond_check_params(struct bond_params *params)
}
}
if (max_bonds < 1 || max_bonds > INT_MAX) {
if (max_bonds < 0 || max_bonds > INT_MAX) {
printk(KERN_WARNING DRV_NAME
": Warning: max_bonds (%d) not in range %d-%d, so it "
"was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
max_bonds = BOND_DEFAULT_MAX_BONDS;
}
......@@ -4945,7 +4953,7 @@ static int bond_check_params(struct bond_params *params)
printk("\n");
} else {
} else if (max_bonds) {
/* miimon and arp_interval not set, we need one so things
* work as expected, see bonding.txt for details
*/
......
......@@ -53,7 +53,6 @@ extern struct bond_parm_tbl arp_validate_tbl[];
extern struct bond_parm_tbl fail_over_mac_tbl[];
static int expected_refcount = -1;
static struct class *netdev_class;
/*--------------------------- Data Structures -----------------------------*/
/* Bonding sysfs lock. Why can't we just use the subsystem lock?
......@@ -1447,19 +1446,9 @@ static struct attribute_group bonding_group = {
*/
int bond_create_sysfs(void)
{
int ret = 0;
struct bonding *firstbond;
/* get the netdev class pointer */
firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
if (!firstbond)
return -ENODEV;
netdev_class = firstbond->dev->dev.class;
if (!netdev_class)
return -ENODEV;
int ret;
ret = class_create_file(netdev_class, &class_attr_bonding_masters);
ret = netdev_class_create_file(&class_attr_bonding_masters);
/*
* Permit multiple loads of the module by ignoring failures to
* create the bonding_masters sysfs file. Bonding devices
......@@ -1478,10 +1467,6 @@ int bond_create_sysfs(void)
printk(KERN_ERR
"network device named %s already exists in sysfs",
class_attr_bonding_masters.attr.name);
else {
netdev_class = NULL;
return 0;
}
}
return ret;
......@@ -1493,8 +1478,7 @@ int bond_create_sysfs(void)
*/
void bond_destroy_sysfs(void)
{
if (netdev_class)
class_remove_file(netdev_class, &class_attr_bonding_masters);
netdev_class_remove_file(&class_attr_bonding_masters);
}
/*
......
......@@ -22,8 +22,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
#define DRV_VERSION "3.2.5"
#define DRV_RELDATE "March 21, 2008"
#define DRV_VERSION "3.3.0"
#define DRV_RELDATE "June 10, 2008"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
......
config IBM_EMAC
tristate "PowerPC 4xx on-chip Ethernet support"
depends on 4xx && !PPC_MERGE
help
This driver supports the PowerPC 4xx EMAC family of on-chip
Ethernet controllers.
config IBM_EMAC_RXB
int "Number of receive buffers"
depends on IBM_EMAC
default "128"
config IBM_EMAC_TXB
int "Number of transmit buffers"
depends on IBM_EMAC
default "64"
config IBM_EMAC_POLL_WEIGHT
int "MAL NAPI polling weight"
depends on IBM_EMAC
default "32"
config IBM_EMAC_RX_COPY_THRESHOLD
int "RX skb copy threshold (bytes)"
depends on IBM_EMAC
default "256"
config IBM_EMAC_RX_SKB_HEADROOM
int "Additional RX skb headroom (bytes)"
depends on IBM_EMAC
default "0"
help
Additional receive skb headroom. Note, that driver
will always reserve at least 2 bytes to make IP header
aligned, so usually there is no need to add any additional
headroom.
If unsure, set to 0.
config IBM_EMAC_PHY_RX_CLK_FIX
bool "PHY Rx clock workaround"
depends on IBM_EMAC && (405EP || 440GX || 440EP || 440GR)
help
Enable this if EMAC attached to a PHY which doesn't generate
RX clock if there is no link, if this is the case, you will
see "TX disable timeout" or "RX disable timeout" in the system
log.
If unsure, say N.
config IBM_EMAC_DEBUG
bool "Debugging"
depends on IBM_EMAC
default n
config IBM_EMAC_ZMII
bool
depends on IBM_EMAC && (NP405H || NP405L || 44x)
default y
config IBM_EMAC_RGMII
bool
depends on IBM_EMAC && 440GX
default y
config IBM_EMAC_TAH
bool
depends on IBM_EMAC && 440GX
default y
#
# Makefile for the PowerPC 4xx on-chip ethernet driver
#
obj-$(CONFIG_IBM_EMAC) += ibm_emac.o
ibm_emac-objs := ibm_emac_mal.o ibm_emac_core.o ibm_emac_phy.o
ibm_emac-$(CONFIG_IBM_EMAC_ZMII) += ibm_emac_zmii.o
ibm_emac-$(CONFIG_IBM_EMAC_RGMII) += ibm_emac_rgmii.o
ibm_emac-$(CONFIG_IBM_EMAC_TAH) += ibm_emac_tah.o
ibm_emac-$(CONFIG_IBM_EMAC_DEBUG) += ibm_emac_debug.o
/*
* drivers/net/ibm_emac/ibm_emac.h
*
* Register definitions for PowerPC 4xx on-chip ethernet contoller
*
* Copyright (c) 2004, 2005 Zultys Technologies.
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
*
* Based on original work by
* Matt Porter <mporter@kernel.crashing.org>
* Armin Kuster <akuster@mvista.com>
* Copyright 2002-2004 MontaVista Software Inc.
*
* 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.
*
*/
#ifndef __IBM_EMAC_H_
#define __IBM_EMAC_H_
#include <linux/types.h>
/* This is a simple check to prevent use of this driver on non-tested SoCs */
#if !defined(CONFIG_405GP) && !defined(CONFIG_405GPR) && !defined(CONFIG_405EP) && \
!defined(CONFIG_440GP) && !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && \
!defined(CONFIG_440EP) && !defined(CONFIG_NP405H) && !defined(CONFIG_440SPE) && \
!defined(CONFIG_440GR)
#error "Unknown SoC. Please, check chip user manual and make sure EMAC defines are OK"
#endif
/* EMAC registers Write Access rules */
struct emac_regs {
u32 mr0; /* special */
u32 mr1; /* Reset */
u32 tmr0; /* special */
u32 tmr1; /* special */
u32 rmr; /* Reset */
u32 isr; /* Always */
u32 iser; /* Reset */
u32 iahr; /* Reset, R, T */
u32 ialr; /* Reset, R, T */
u32 vtpid; /* Reset, R, T */
u32 vtci; /* Reset, R, T */
u32 ptr; /* Reset, T */
u32 iaht1; /* Reset, R */
u32 iaht2; /* Reset, R */
u32 iaht3; /* Reset, R */
u32 iaht4; /* Reset, R */
u32 gaht1; /* Reset, R */
u32 gaht2; /* Reset, R */
u32 gaht3; /* Reset, R */
u32 gaht4; /* Reset, R */
u32 lsah;
u32 lsal;
u32 ipgvr; /* Reset, T */
u32 stacr; /* special */
u32 trtr; /* special */
u32 rwmr; /* Reset */
u32 octx;
u32 ocrx;
u32 ipcr;
};
#if !defined(CONFIG_IBM_EMAC4)
#define EMAC_ETHTOOL_REGS_VER 0
#define EMAC_ETHTOOL_REGS_SIZE (sizeof(struct emac_regs) - sizeof(u32))
#else
#define EMAC_ETHTOOL_REGS_VER 1
#define EMAC_ETHTOOL_REGS_SIZE sizeof(struct emac_regs)
#endif
/* EMACx_MR0 */
#define EMAC_MR0_RXI 0x80000000
#define EMAC_MR0_TXI 0x40000000
#define EMAC_MR0_SRST 0x20000000
#define EMAC_MR0_TXE 0x10000000
#define EMAC_MR0_RXE 0x08000000
#define EMAC_MR0_WKE 0x04000000
/* EMACx_MR1 */
#define EMAC_MR1_FDE 0x80000000
#define EMAC_MR1_ILE 0x40000000
#define EMAC_MR1_VLE 0x20000000
#define EMAC_MR1_EIFC 0x10000000
#define EMAC_MR1_APP 0x08000000
#define EMAC_MR1_IST 0x01000000
#define EMAC_MR1_MF_MASK 0x00c00000
#define EMAC_MR1_MF_10 0x00000000
#define EMAC_MR1_MF_100 0x00400000
#if !defined(CONFIG_IBM_EMAC4)
#define EMAC_MR1_MF_1000 0x00000000
#define EMAC_MR1_MF_1000GPCS 0x00000000
#define EMAC_MR1_MF_IPPA(id) 0x00000000
#else
#define EMAC_MR1_MF_1000 0x00800000
#define EMAC_MR1_MF_1000GPCS 0x00c00000
#define EMAC_MR1_MF_IPPA(id) (((id) & 0x1f) << 6)
#endif
#define EMAC_TX_FIFO_SIZE 2048
#if !defined(CONFIG_IBM_EMAC4)
#define EMAC_MR1_RFS_4K 0x00300000
#define EMAC_MR1_RFS_16K 0x00000000
#define EMAC_RX_FIFO_SIZE(gige) 4096
#define EMAC_MR1_TFS_2K 0x00080000
#define EMAC_MR1_TR0_MULT 0x00008000
#define EMAC_MR1_JPSM 0x00000000
#define EMAC_MR1_MWSW_001 0x00000000
#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT)
#else
#define EMAC_MR1_RFS_4K 0x00180000
#define EMAC_MR1_RFS_16K 0x00280000
#define EMAC_RX_FIFO_SIZE(gige) ((gige) ? 16384 : 4096)
#define EMAC_MR1_TFS_2K 0x00020000
#define EMAC_MR1_TR 0x00008000
#define EMAC_MR1_MWSW_001 0x00001000
#define EMAC_MR1_JPSM 0x00000800
#define EMAC_MR1_OBCI_MASK 0x00000038
#define EMAC_MR1_OBCI_50 0x00000000
#define EMAC_MR1_OBCI_66 0x00000008
#define EMAC_MR1_OBCI_83 0x00000010
#define EMAC_MR1_OBCI_100 0x00000018
#define EMAC_MR1_OBCI_100P 0x00000020
#define EMAC_MR1_OBCI(freq) ((freq) <= 50 ? EMAC_MR1_OBCI_50 : \
(freq) <= 66 ? EMAC_MR1_OBCI_66 : \
(freq) <= 83 ? EMAC_MR1_OBCI_83 : \
(freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P)
#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR | \
EMAC_MR1_OBCI(opb))
#endif
/* EMACx_TMR0 */
#define EMAC_TMR0_GNP 0x80000000
#if !defined(CONFIG_IBM_EMAC4)
#define EMAC_TMR0_DEFAULT 0x00000000
#else
#define EMAC_TMR0_TFAE_2_32 0x00000001
#define EMAC_TMR0_TFAE_4_64 0x00000002
#define EMAC_TMR0_TFAE_8_128 0x00000003
#define EMAC_TMR0_TFAE_16_256 0x00000004
#define EMAC_TMR0_TFAE_32_512 0x00000005
#define EMAC_TMR0_TFAE_64_1024 0x00000006
#define EMAC_TMR0_TFAE_128_2048 0x00000007
#define EMAC_TMR0_DEFAULT EMAC_TMR0_TFAE_2_32
#endif
#define EMAC_TMR0_XMIT (EMAC_TMR0_GNP | EMAC_TMR0_DEFAULT)
/* EMACx_TMR1 */
/* IBM manuals are not very clear here.
* This is my interpretation of how things are. --ebs
*/
#if defined(CONFIG_40x)
#define EMAC_FIFO_ENTRY_SIZE 8
#define EMAC_MAL_BURST_SIZE (16 * 4)
#else
#define EMAC_FIFO_ENTRY_SIZE 16
#define EMAC_MAL_BURST_SIZE (64 * 4)
#endif
#if !defined(CONFIG_IBM_EMAC4)
#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0xff) << 16))
#else
#define EMAC_TMR1(l,h) (((l) << 27) | (((h) & 0x3ff) << 14))
#endif
/* EMACx_RMR */
#define EMAC_RMR_SP 0x80000000
#define EMAC_RMR_SFCS 0x40000000
#define EMAC_RMR_RRP 0x20000000
#define EMAC_RMR_RFP 0x10000000
#define EMAC_RMR_ROP 0x08000000
#define EMAC_RMR_RPIR 0x04000000
#define EMAC_RMR_PPP 0x02000000
#define EMAC_RMR_PME 0x01000000
#define EMAC_RMR_PMME 0x00800000
#define EMAC_RMR_IAE 0x00400000
#define EMAC_RMR_MIAE 0x00200000
#define EMAC_RMR_BAE 0x00100000
#define EMAC_RMR_MAE 0x00080000
#if !defined(CONFIG_IBM_EMAC4)
#define EMAC_RMR_BASE 0x00000000
#else
#define EMAC_RMR_RFAF_2_32 0x00000001
#define EMAC_RMR_RFAF_4_64 0x00000002
#define EMAC_RMR_RFAF_8_128 0x00000003
#define EMAC_RMR_RFAF_16_256 0x00000004
#define EMAC_RMR_RFAF_32_512 0x00000005
#define EMAC_RMR_RFAF_64_1024 0x00000006
#define EMAC_RMR_RFAF_128_2048 0x00000007
#define EMAC_RMR_BASE EMAC_RMR_RFAF_128_2048
#endif
/* EMACx_ISR & EMACx_ISER */
#if !defined(CONFIG_IBM_EMAC4)
#define EMAC_ISR_TXPE 0x00000000
#define EMAC_ISR_RXPE 0x00000000
#define EMAC_ISR_TXUE 0x00000000
#define EMAC_ISR_RXOE 0x00000000
#else
#define EMAC_ISR_TXPE 0x20000000
#define EMAC_ISR_RXPE 0x10000000
#define EMAC_ISR_TXUE 0x08000000
#define EMAC_ISR_RXOE 0x04000000
#endif
#define EMAC_ISR_OVR 0x02000000
#define EMAC_ISR_PP 0x01000000
#define EMAC_ISR_BP 0x00800000
#define EMAC_ISR_RP 0x00400000
#define EMAC_ISR_SE 0x00200000
#define EMAC_ISR_ALE 0x00100000
#define EMAC_ISR_BFCS 0x00080000
#define EMAC_ISR_PTLE 0x00040000
#define EMAC_ISR_ORE 0x00020000
#define EMAC_ISR_IRE 0x00010000
#define EMAC_ISR_SQE 0x00000080
#define EMAC_ISR_TE 0x00000040
#define EMAC_ISR_MOS 0x00000002
#define EMAC_ISR_MOF 0x00000001
/* EMACx_STACR */
#define EMAC_STACR_PHYD_MASK 0xffff
#define EMAC_STACR_PHYD_SHIFT 16
#define EMAC_STACR_OC 0x00008000
#define EMAC_STACR_PHYE 0x00004000
#define EMAC_STACR_STAC_MASK 0x00003000
#define EMAC_STACR_STAC_READ 0x00001000
#define EMAC_STACR_STAC_WRITE 0x00002000
#if !defined(CONFIG_IBM_EMAC4)
#define EMAC_STACR_OPBC_MASK 0x00000C00
#define EMAC_STACR_OPBC_50 0x00000000
#define EMAC_STACR_OPBC_66 0x00000400
#define EMAC_STACR_OPBC_83 0x00000800
#define EMAC_STACR_OPBC_100 0x00000C00
#define EMAC_STACR_OPBC(freq) ((freq) <= 50 ? EMAC_STACR_OPBC_50 : \
(freq) <= 66 ? EMAC_STACR_OPBC_66 : \
(freq) <= 83 ? EMAC_STACR_OPBC_83 : EMAC_STACR_OPBC_100)
#define EMAC_STACR_BASE(opb) EMAC_STACR_OPBC(opb)
#else
#define EMAC_STACR_BASE(opb) 0x00000000
#endif
#define EMAC_STACR_PCDA_MASK 0x1f
#define EMAC_STACR_PCDA_SHIFT 5
#define EMAC_STACR_PRA_MASK 0x1f
/*
* For the 440SPe, AMCC inexplicably changed the polarity of
* the "operation complete" bit in the MII control register.
*/
#if defined(CONFIG_440SPE)
static inline int emac_phy_done(u32 stacr)
{
return !(stacr & EMAC_STACR_OC);
};
#define EMAC_STACR_START EMAC_STACR_OC
#else /* CONFIG_440SPE */
static inline int emac_phy_done(u32 stacr)
{
return stacr & EMAC_STACR_OC;
};
#define EMAC_STACR_START 0
#endif /* !CONFIG_440SPE */