Commit d779188d authored by Linus Torvalds's avatar Linus Torvalds

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

parents f61ea1b0 ac67c624
The Gianfar Ethernet Driver
Sysfs File description
Author: Andy Fleming <afleming@freescale.com>
Updated: 2005-07-28
SYSFS
Several of the features of the gianfar driver are controlled
through sysfs files. These are:
bd_stash:
To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
bd_stash, echo 'off' or '0' to disable
rx_stash_len:
To stash the first n bytes of the packet in L2, echo the number
of bytes to buf_stash_len. echo 0 to disable.
WARNING: You could really screw these up if you set them too low or high!
fifo_threshold:
To change the number of bytes the controller needs in the
fifo before it starts transmission, echo the number of bytes to
fifo_thresh. Range should be 0-511.
fifo_starve:
When the FIFO has less than this many bytes during a transmit, it
enters starve mode, and increases the priority of TX memory
transactions. To change, echo the number of bytes to
fifo_starve. Range should be 0-511.
fifo_starve_off:
Once in starve mode, the FIFO remains there until it has this
many bytes. To change, echo the number of bytes to
fifo_starve_off. Range should be 0-511.
CHECKSUM OFFLOADING
The eTSEC controller (first included in parts from late 2005 like
the 8548) has the ability to perform TCP, UDP, and IP checksums
in hardware. The Linux kernel only offloads the TCP and UDP
checksums (and always performs the pseudo header checksums), so
the driver only supports checksumming for TCP/IP and UDP/IP
packets. Use ethtool to enable or disable this feature for RX
and TX.
VLAN
In order to use VLAN, please consult Linux documentation on
configuring VLANs. The gianfar driver supports hardware insertion and
extraction of VLAN headers, but not filtering. Filtering will be
done by the kernel.
MULTICASTING
The gianfar driver supports using the group hash table on the
TSEC (and the extended hash table on the eTSEC) for multicast
filtering. On the eTSEC, the exact-match MAC registers are used
before the hash tables. See Linux documentation on how to join
multicast groups.
PADDING
The gianfar driver supports padding received frames with 2 bytes
to align the IP header to a 16-byte boundary, when supported by
hardware.
ETHTOOL
The gianfar driver supports the use of ethtool for many
configuration options. You must run ethtool only on currently
open interfaces. See ethtool documentation for details.
...@@ -586,16 +586,16 @@ struct rtl8139_private { ...@@ -586,16 +586,16 @@ struct rtl8139_private {
dma_addr_t tx_bufs_dma; dma_addr_t tx_bufs_dma;
signed char phys[4]; /* MII device addresses. */ signed char phys[4]; /* MII device addresses. */
char twistie, twist_row, twist_col; /* Twister tune state. */ char twistie, twist_row, twist_col; /* Twister tune state. */
unsigned int default_port:4; /* Last dev->if_port value. */ unsigned int default_port : 4; /* Last dev->if_port value. */
unsigned int have_thread : 1;
spinlock_t lock; spinlock_t lock;
spinlock_t rx_lock; spinlock_t rx_lock;
chip_t chipset; chip_t chipset;
pid_t thr_pid;
wait_queue_head_t thr_wait;
struct completion thr_exited;
u32 rx_config; u32 rx_config;
struct rtl_extra_stats xstats; struct rtl_extra_stats xstats;
int time_to_die;
struct work_struct thread;
struct mii_if_info mii; struct mii_if_info mii;
unsigned int regs_len; unsigned int regs_len;
unsigned long fifo_copy_timeout; unsigned long fifo_copy_timeout;
...@@ -620,7 +620,7 @@ static int rtl8139_open (struct net_device *dev); ...@@ -620,7 +620,7 @@ static int rtl8139_open (struct net_device *dev);
static int mdio_read (struct net_device *dev, int phy_id, int location); static int mdio_read (struct net_device *dev, int phy_id, int location);
static void mdio_write (struct net_device *dev, int phy_id, int location, static void mdio_write (struct net_device *dev, int phy_id, int location,
int val); int val);
static void rtl8139_start_thread(struct net_device *dev); static void rtl8139_start_thread(struct rtl8139_private *tp);
static void rtl8139_tx_timeout (struct net_device *dev); static void rtl8139_tx_timeout (struct net_device *dev);
static void rtl8139_init_ring (struct net_device *dev); static void rtl8139_init_ring (struct net_device *dev);
static int rtl8139_start_xmit (struct sk_buff *skb, static int rtl8139_start_xmit (struct sk_buff *skb,
...@@ -637,6 +637,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev); ...@@ -637,6 +637,7 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
static void rtl8139_set_rx_mode (struct net_device *dev); static void rtl8139_set_rx_mode (struct net_device *dev);
static void __set_rx_mode (struct net_device *dev); static void __set_rx_mode (struct net_device *dev);
static void rtl8139_hw_start (struct net_device *dev); static void rtl8139_hw_start (struct net_device *dev);
static void rtl8139_thread (void *_data);
static struct ethtool_ops rtl8139_ethtool_ops; static struct ethtool_ops rtl8139_ethtool_ops;
/* write MMIO register, with flush */ /* write MMIO register, with flush */
...@@ -1007,8 +1008,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, ...@@ -1007,8 +1008,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
(debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1)); (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
spin_lock_init (&tp->lock); spin_lock_init (&tp->lock);
spin_lock_init (&tp->rx_lock); spin_lock_init (&tp->rx_lock);
init_waitqueue_head (&tp->thr_wait); INIT_WORK(&tp->thread, rtl8139_thread, dev);
init_completion (&tp->thr_exited);
tp->mii.dev = dev; tp->mii.dev = dev;
tp->mii.mdio_read = mdio_read; tp->mii.mdio_read = mdio_read;
tp->mii.mdio_write = mdio_write; tp->mii.mdio_write = mdio_write;
...@@ -1345,7 +1345,7 @@ static int rtl8139_open (struct net_device *dev) ...@@ -1345,7 +1345,7 @@ static int rtl8139_open (struct net_device *dev)
dev->irq, RTL_R8 (MediaStatus), dev->irq, RTL_R8 (MediaStatus),
tp->mii.full_duplex ? "full" : "half"); tp->mii.full_duplex ? "full" : "half");
rtl8139_start_thread(dev); rtl8139_start_thread(tp);
return 0; return 0;
} }
...@@ -1594,55 +1594,43 @@ static inline void rtl8139_thread_iter (struct net_device *dev, ...@@ -1594,55 +1594,43 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
RTL_R8 (Config1)); RTL_R8 (Config1));
} }
static int rtl8139_thread (void *data) static void rtl8139_thread (void *_data)
{ {
struct net_device *dev = data; struct net_device *dev = _data;
struct rtl8139_private *tp = netdev_priv(dev); struct rtl8139_private *tp = netdev_priv(dev);
unsigned long timeout; unsigned long thr_delay;
daemonize("%s", dev->name);
allow_signal(SIGTERM);
while (1) {
timeout = next_tick;
do {
timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
/* make swsusp happy with our thread */
try_to_freeze();
} while (!signal_pending (current) && (timeout > 0));
if (signal_pending (current)) {
flush_signals(current);
}
if (tp->time_to_die) if (rtnl_shlock_nowait() == 0) {
break;
if (rtnl_lock_interruptible ())
break;
rtl8139_thread_iter (dev, tp, tp->mmio_addr); rtl8139_thread_iter (dev, tp, tp->mmio_addr);
rtnl_unlock (); rtnl_unlock ();
thr_delay = next_tick;
} else {
/* unlikely race. mitigate with fast poll. */
thr_delay = HZ / 2;
} }
complete_and_exit (&tp->thr_exited, 0); schedule_delayed_work(&tp->thread, thr_delay);
} }
static void rtl8139_start_thread(struct net_device *dev) static void rtl8139_start_thread(struct rtl8139_private *tp)
{ {
struct rtl8139_private *tp = netdev_priv(dev);
tp->thr_pid = -1;
tp->twistie = 0; tp->twistie = 0;
tp->time_to_die = 0;
if (tp->chipset == CH_8139_K) if (tp->chipset == CH_8139_K)
tp->twistie = 1; tp->twistie = 1;
else if (tp->drv_flags & HAS_LNK_CHNG) else if (tp->drv_flags & HAS_LNK_CHNG)
return; return;
tp->thr_pid = kernel_thread(rtl8139_thread, dev, CLONE_FS|CLONE_FILES); tp->have_thread = 1;
if (tp->thr_pid < 0) {
printk (KERN_WARNING "%s: unable to start kernel thread\n", schedule_delayed_work(&tp->thread, next_tick);
dev->name); }
static void rtl8139_stop_thread(struct rtl8139_private *tp)
{
if (tp->have_thread) {
cancel_rearming_delayed_work(&tp->thread);
tp->have_thread = 0;
} }
} }
...@@ -2224,22 +2212,12 @@ static int rtl8139_close (struct net_device *dev) ...@@ -2224,22 +2212,12 @@ static int rtl8139_close (struct net_device *dev)
{ {
struct rtl8139_private *tp = netdev_priv(dev); struct rtl8139_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
int ret = 0;
unsigned long flags; unsigned long flags;
netif_stop_queue (dev); netif_stop_queue (dev);
if (tp->thr_pid >= 0) { rtl8139_stop_thread(tp);
tp->time_to_die = 1;
wmb();
ret = kill_proc (tp->thr_pid, SIGTERM, 1);
if (ret) {
printk (KERN_ERR "%s: unable to signal thread\n", dev->name);
return ret;
}
wait_for_completion (&tp->thr_exited);
}
if (netif_msg_ifdown(tp)) if (netif_msg_ifdown(tp))
printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
dev->name, RTL_R16 (IntrStatus)); dev->name, RTL_R16 (IntrStatus));
......
...@@ -1901,6 +1901,8 @@ config E1000_NAPI ...@@ -1901,6 +1901,8 @@ config E1000_NAPI
If in doubt, say N. If in doubt, say N.
source "drivers/net/ixp2000/Kconfig"
config MYRI_SBUS config MYRI_SBUS
tristate "MyriCOM Gigabit Ethernet support" tristate "MyriCOM Gigabit Ethernet support"
depends on SBUS depends on SBUS
...@@ -2008,7 +2010,18 @@ config SKGE ...@@ -2008,7 +2010,18 @@ config SKGE
It does not support the link failover and network management It does not support the link failover and network management
features that "portable" vendor supplied sk98lin driver does. features that "portable" vendor supplied sk98lin driver does.
config SKY2
tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
depends on PCI && EXPERIMENTAL
select CRC32
---help---
This driver support the Marvell Yukon 2 Gigabit Ethernet adapter.
To compile this driver as a module, choose M here: the module
will be called sky2. This is recommended.
config SK98LIN config SK98LIN
tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support" tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
depends on PCI depends on PCI
...@@ -2120,7 +2133,7 @@ config BNX2 ...@@ -2120,7 +2133,7 @@ config BNX2
config SPIDER_NET config SPIDER_NET
tristate "Spider Gigabit Ethernet driver" tristate "Spider Gigabit Ethernet driver"
depends on PCI && PPC_BPA depends on PCI && PPC_CELL
help help
This driver supports the Gigabit Ethernet chips present on the This driver supports the Gigabit Ethernet chips present on the
Cell Processor-Based Blades from IBM. Cell Processor-Based Blades from IBM.
......
...@@ -13,7 +13,10 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/ ...@@ -13,7 +13,10 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
obj-$(CONFIG_BONDING) += bonding/ obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o obj-$(CONFIG_GIANFAR) += gianfar_driver.o
gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o \
gianfar_mii.o \
gianfar_sysfs.o
# #
# link order important here # link order important here
...@@ -59,6 +62,7 @@ spidernet-y += spider_net.o spider_net_ethtool.o sungem_phy.o ...@@ -59,6 +62,7 @@ spidernet-y += spider_net.o spider_net_ethtool.o sungem_phy.o
obj-$(CONFIG_SPIDER_NET) += spidernet.o obj-$(CONFIG_SPIDER_NET) += spidernet.o
obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_TC35815) += tc35815.o
obj-$(CONFIG_SKGE) += skge.o obj-$(CONFIG_SKGE) += skge.o
obj-$(CONFIG_SKY2) += sky2.o
obj-$(CONFIG_SK98LIN) += sk98lin/ obj-$(CONFIG_SK98LIN) += sk98lin/
obj-$(CONFIG_SKFP) += skfp/ obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o obj-$(CONFIG_VIA_RHINE) += via-rhine.o
...@@ -202,6 +206,7 @@ obj-$(CONFIG_NET_TULIP) += tulip/ ...@@ -202,6 +206,7 @@ obj-$(CONFIG_NET_TULIP) += tulip/
obj-$(CONFIG_HAMRADIO) += hamradio/ obj-$(CONFIG_HAMRADIO) += hamradio/
obj-$(CONFIG_IRDA) += irda/ obj-$(CONFIG_IRDA) += irda/
obj-$(CONFIG_ETRAX_ETHERNET) += cris/ obj-$(CONFIG_ETRAX_ETHERNET) += cris/
obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
obj-$(CONFIG_NETCONSOLE) += netconsole.o obj-$(CONFIG_NETCONSOLE) += netconsole.o
......
...@@ -4,5 +4,5 @@ ...@@ -4,5 +4,5 @@
obj-$(CONFIG_BONDING) += bonding.o obj-$(CONFIG_BONDING) += bonding.o
bonding-objs := bond_main.o bond_3ad.o bond_alb.o bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
This diff is collapsed.
...@@ -18,19 +18,6 @@ ...@@ -18,19 +18,6 @@
* The full GNU General Public License is included in this distribution in the * The full GNU General Public License is included in this distribution in the
* file called LICENSE. * file called LICENSE.
* *
*
* Changes:
*
* 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
* Amir Noam <amir.noam at intel dot com>
* - Added support for lacp_rate module param.
*
* 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Renamed bond_3ad_link_status_changed() to
* bond_3ad_handle_link_change() for compatibility with TLB.
*
* 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Code cleanup and style changes
*/ */
#ifndef __BOND_3AD_H__ #ifndef __BOND_3AD_H__
......
...@@ -18,25 +18,6 @@ ...@@ -18,25 +18,6 @@
* The full GNU General Public License is included in this distribution in the * The full GNU General Public License is included in this distribution in the
* file called LICENSE. * file called LICENSE.
* *
*
* Changes:
*
* 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
* - Fixed signed/unsigned calculation errors that caused load sharing
* to collapse to one slave under very heavy UDP Tx stress.
*
* 2003/08/06 - Amir Noam <amir.noam at intel dot com>
* - Add support for setting bond's MAC address with special
* handling required for ALB/TLB.
*
* 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Code cleanup and style changes
*
* 2003/12/30 - Amir Noam <amir.noam at intel dot com>
* - Fixed: Cannot remove and re-enslave the original active slave.
*
* 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
* - Add capability to tag self generated packets in ALB/TLB modes.
*/ */
//#define BONDING_DEBUG 1 //#define BONDING_DEBUG 1
...@@ -198,20 +179,21 @@ static int tlb_initialize(struct bonding *bond) ...@@ -198,20 +179,21 @@ static int tlb_initialize(struct bonding *bond)
{ {
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info); int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
struct tlb_client_info *new_hashtbl;
int i; int i;
spin_lock_init(&(bond_info->tx_hashtbl_lock)); spin_lock_init(&(bond_info->tx_hashtbl_lock));
_lock_tx_hashtbl(bond); new_hashtbl = kmalloc(size, GFP_KERNEL);
if (!new_hashtbl) {
bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
if (!bond_info->tx_hashtbl) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": Error: %s: Failed to allocate TLB hash table\n", ": %s: Error: Failed to allocate TLB hash table\n",
bond->dev->name); bond->dev->name);
_unlock_tx_hashtbl(bond);
return -1; return -1;
} }
_lock_tx_hashtbl(bond);
bond_info->tx_hashtbl = new_hashtbl;
memset(bond_info->tx_hashtbl, 0, size); memset(bond_info->tx_hashtbl, 0, size);
...@@ -513,7 +495,8 @@ static void rlb_update_client(struct rlb_client_info *client_info) ...@@ -513,7 +495,8 @@ static void rlb_update_client(struct rlb_client_info *client_info)
client_info->mac_dst); client_info->mac_dst);
if (!skb) { if (!skb) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": Error: failed to create an ARP packet\n"); ": %s: Error: failed to create an ARP packet\n",
client_info->slave->dev->master->name);
continue; continue;
} }
...@@ -523,7 +506,8 @@ static void rlb_update_client(struct rlb_client_info *client_info) ...@@ -523,7 +506,8 @@ static void rlb_update_client(struct rlb_client_info *client_info)
skb = vlan_put_tag(skb, client_info->vlan_id); skb = vlan_put_tag(skb, client_info->vlan_id);
if (!skb) { if (!skb) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": Error: failed to insert VLAN tag\n"); ": %s: Error: failed to insert VLAN tag\n",
client_info->slave->dev->master->name);
continue; continue;
} }
} }
...@@ -606,8 +590,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip) ...@@ -606,8 +590,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
if (!client_info->slave) { if (!client_info->slave) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": Error: found a client with no channel in " ": %s: Error: found a client with no channel in "
"the client's hash table\n"); "the client's hash table\n",
bond->dev->name);
continue; continue;
} }
/*update all clients using this src_ip, that are not assigned /*update all clients using this src_ip, that are not assigned
...@@ -797,21 +782,22 @@ static int rlb_initialize(struct bonding *bond) ...@@ -797,21 +782,22 @@ static int rlb_initialize(struct bonding *bond)
{ {
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type); struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
struct rlb_client_info *new_hashtbl;
int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info); int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
int i; int i;
spin_lock_init(&(bond_info->rx_hashtbl_lock)); spin_lock_init(&(bond_info->rx_hashtbl_lock));
_lock_rx_hashtbl(bond); new_hashtbl = kmalloc(size, GFP_KERNEL);
if (!new_hashtbl) {
bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL);
if (!bond_info->rx_hashtbl) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": Error: %s: Failed to allocate RLB hash table\n", ": %s: Error: Failed to allocate RLB hash table\n",
bond->dev->name); bond->dev->name);
_unlock_rx_hashtbl(bond);
return -1; return -1;
} }
_lock_rx_hashtbl(bond);
bond_info->rx_hashtbl = new_hashtbl;
bond_info->rx_hashtbl_head = RLB_NULL_INDEX; bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
...@@ -927,7 +913,8 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]) ...@@ -927,7 +913,8 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
skb = vlan_put_tag(skb, vlan->vlan_id); skb = vlan_put_tag(skb, vlan->vlan_id);
if (!skb) { if (!skb) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": Error: failed to insert VLAN tag\n"); ": %s: Error: failed to insert VLAN tag\n",
bond->dev->name);
continue; continue;
} }
} }
...@@ -956,11 +943,11 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw) ...@@ -956,11 +943,11 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
s_addr.sa_family = dev->type; s_addr.sa_family = dev->type;
if (dev_set_mac_address(dev, &s_addr)) { if (dev_set_mac_address(dev, &s_addr)) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": Error: dev_set_mac_address of dev %s failed! ALB " ": %s: Error: dev_set_mac_address of dev %s failed! ALB "
"mode requires that the base driver support setting " "mode requires that the base driver support setting "
"the hw address also when the network device's " "the hw address also when the network device's "
"interface is open\n", "interface is open\n",
dev->name); dev->master->name, dev->name);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
return 0; return 0;
...@@ -1153,16 +1140,16 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav ...@@ -1153,16 +1140,16 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
bond->alb_info.rlb_enabled); bond->alb_info.rlb_enabled);
printk(KERN_WARNING DRV_NAME printk(KERN_WARNING DRV_NAME
": Warning: the hw address of slave %s is in use by " ": %s: Warning: the hw address of slave %s is in use by "
"the bond; giving it the hw address of %s\n", "the bond; giving it the hw address of %s\n",
slave->dev->name, free_mac_slave->dev->name); bond->dev->name, slave->dev->name, free_mac_slave->dev->name);
} else if (has_bond_addr) { } else if (has_bond_addr) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": Error: the hw address of slave %s is in use by the " ": %s: Error: the hw address of slave %s is in use by the "
"bond; couldn't find a slave with a free hw address to " "bond; couldn't find a slave with a free hw address to "
"give it (this should not have happened)\n", "give it (this should not have happened)\n",
slave->dev->name); bond->dev->name, slave->dev->name);
return -EFAULT; return -EFAULT;
} }
...@@ -1250,6 +1237,8 @@ int bond_alb_initialize(struct bonding *bond, int rlb_enabled) ...@@ -1250,6 +1237,8 @@ int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
tlb_deinitialize(bond); tlb_deinitialize(bond);
return res; return res;
} }
} else {
bond->alb_info.rlb_enabled = 0;
} }
return 0; return 0;
...@@ -1409,7 +1398,7 @@ void bond_alb_monitor(struct bonding *bond) ...@@ -1409,7 +1398,7 @@ void bond_alb_monitor(struct bonding *bond)
read_lock(&bond->curr_slave_lock); read_lock(&bond->curr_slave_lock);
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave, i) {
alb_send_learning_packets(slave,slave->dev->dev_addr); alb_send_learning_packets(slave, slave->dev->dev_addr);
} }
read_unlock(&bond->curr_slave_lock); read_unlock(&bond->curr_slave_lock);
......
...@@ -18,15 +18,6 @@ ...@@ -18,15 +18,6 @@
* The full GNU General Public License is included in this distribution in the * The full GNU General Public License is included in this distribution in the
* file called LICENSE. * file called LICENSE.
* *
*
* Changes:
*
* 2003/08/06 - Amir Noam <amir.noam at intel dot com>
* - Add support for setting bond's MAC address with special
* handling required for ALB/TLB.
*
* 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Code cleanup and style changes
*/ */
#ifndef __BOND_ALB_H__ #ifndef __BOND_ALB_H__
......
This diff is collapsed.
This diff is collapsed.
...@@ -10,25 +10,6 @@ ...@@ -10,25 +10,6 @@
* This software may be used and distributed according to the terms * This software may be used and distributed according to the terms
* of the GNU Public License, incorporated herein by reference. * of the GNU Public License, incorporated herein by reference.
* *
*
* 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
* Tsippy Mendelson <tsippy.mendelson at intel dot com> and
* Shmulik Hen <shmulik.hen at intel dot com>
* - Added support for IEEE 802.3ad Dynamic link aggregation mode.
*
* 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
* Amir Noam <amir.noam at intel dot com>
* - Code beautification and style changes (mainly in comments).
*
* 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Added support for Transmit load balancing mode.
*
* 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
* - Code cleanup and style changes
*
* 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
* - added "xmit_policy" kernel parameter for alternate hashing policy
* support for mode 2
*/ */
#ifndef _LINUX_BONDING_H #ifndef _LINUX_BONDING_H
...@@ -37,11 +18,12 @@ ...@@ -37,11 +18,12 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/if_bonding.h> #include <linux/if_bonding.h>
#include <linux/kobject.h>
#include "bond_3ad.h" #include "bond_3ad.h"
#include "bond_alb.h" #include "bond_alb.h"
#define DRV_VERSION "2.6.5" #define DRV_VERSION "3.0.0"
#define DRV_RELDATE "November 4, 2005" #define DRV_RELDATE "November 8, 2005"
#define DRV_NAME "bonding" #define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
...@@ -152,6 +134,11 @@ struct bond_params { ...@@ -152,6 +134,11 @@ struct bond_params {
u32 arp_targets[BOND_MAX_ARP_TARGETS]; u32 arp_targets[BOND_MAX_ARP_TARGETS];
}; };
struct bond_parm_tbl {
char *modename;
int mode;
};
struct vlan_entry { struct vlan_entry {
struct list_head vlan_list; struct list_head vlan_list;
u32 vlan_ip; u32 vlan_ip;
...@@ -159,7 +146,7 @@ struct vlan_entry { ...@@ -159,7 +146,7 @@ struct vlan_entry {
}; };
struct slave { struct slave {
struct net_device *dev; /* first - usefull for panic debug */ struct net_device *dev; /* first - useful for panic debug */
struct slave *next; struct slave *next;
struct slave *prev; struct slave *prev;
s16 delay; s16 delay;
...@@ -185,7 +172,7 @@ struct slave { ...@@ -185,7 +172,7 @@ struct slave {
* beforehand. * beforehand.
*/ */
struct bonding { struct bonding {
struct net_device *dev; /* first - usefull for panic debug */ struct net_device *dev; /* first - useful for panic debug */
struct slave *first_slave; struct slave *first_slave;
struct slave *curr_active_slave; struct slave *curr_active_slave;
struct slave *current_arp_slave; struct slave *current_arp_slave;
...@@ -255,6 +242,25 @@ extern inline void bond_set_slave_active_flags(struct slave *slave) ...@@ -255,6 +242,25 @@ extern inline void bond_set_slave_active_flags(struct slave *slave)
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
void bond_deinit(struct net_device *bond_dev);
int bond_create_sysfs(void);
void bond_destroy_sysfs(void);
void bond_destroy_sysfs_entry(struct bonding *bond);
int bond_create_sysfs_entry(struct bonding *bond);
int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);
void bond_mii_monitor(struct net_device *bond_dev);
void bond_loadbalance_arp_mon(struct net_device *bond_dev);
void bond_activebackup_arp_mon(struct net_device *bond_dev);
void bond_set_mode_ops(struct bonding *bond, int mode);
int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
const char *bond_mode_name(int mode);
void bond_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
#endif /* _LINUX_BONDING_H */ #endif /* _LINUX_BONDING_H */
...@@ -1332,8 +1332,8 @@ intr_handler_t t1_select_intr_handler(adapter_t *adapter) ...@@ -1332,8 +1332,8 @@ intr_handler_t t1_select_intr_handler(adapter_t *adapter)
* *
* This runs with softirqs disabled. * This runs with softirqs disabled.
*/ */
unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
unsigned int qid, struct net_device *dev) unsigned int qid, struct net_device *dev)
{ {
struct sge *sge = adapter->sge; struct sge *sge = adapter->sge;
struct cmdQ *q = &sge->cmdQ[qid]; struct cmdQ *q = &sge->cmdQ[qid];
...@@ -1352,9 +1352,10 @@ unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, ...@@ -1352,9 +1352,10 @@ unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
set_bit(dev->if_port, &sge->stopped_tx_queues); set_bit(dev->if_port, &sge->stopped_tx_queues);
sge->stats.cmdQ_full[3]++; sge->stats.cmdQ_full[3]++;
spin_unlock(&q->lock); spin_unlock(&q->lock);
CH_ERR("%s: Tx ring full while queue awake!\n", if (!netif_queue_stopped(dev))
adapter->name); CH_ERR("%s: Tx ring full while queue awake!\n",
return 1; adapter->name);
return NETDEV_TX_BUSY;
} }
if (unlikely(credits - count < q->stop_thres)) { if (unlikely(credits - count < q->stop_thres)) {
sge->stats.cmdQ_full[3]++; sge->stats.cmdQ_full[3]++;
...@@ -1389,7 +1390,7 @@ unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, ...@@ -1389,7 +1390,7 @@ unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL); writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL);
} }
} }
return 0; return NETDEV_TX_OK;
} }
#define MK_ETH_TYPE_MSS(type, mss) (((mss) & 0x3FFF) | ((type) << 14)) #define MK_ETH_TYPE_MSS(type, mss) (((mss) & 0x3FFF) | ((type) << 14))
...@@ -1449,7 +1450,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1449,7 +1450,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (unlikely(skb->len < ETH_HLEN || if (unlikely(skb->len < ETH_HLEN ||
skb->len > dev->mtu + eth_hdr_len(skb->data))) { skb->len > dev->mtu + eth_hdr_len(skb->data))) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NET_XMIT_SUCCESS; return NETDEV_TX_OK;
} }
/* /*
...@@ -1467,7 +1468,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1467,7 +1468,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb = skb_realloc_headroom(skb, sizeof(*cpl)); skb = skb_realloc_headroom(skb, sizeof(*cpl));
dev_kfree_skb_any(orig_skb); dev_kfree_skb_any(orig_skb);
if (!skb) if (!skb)
return -ENOMEM; return NETDEV_TX_OK;
} }
if (!(adapter->flags & UDP_CSUM_CAPABLE) && if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
...@@ -1475,7 +1476,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1475,7 +1476,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb->nh.iph->protocol == IPPROTO_UDP) skb->nh.iph->protocol == IPPROTO_UDP)
if (unlikely(skb_checksum_help(skb, 0))) { if (unlikely(skb_checksum_help(skb, 0))) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return -ENOMEM; return NETDEV_TX_OK;
} }
/* Hmmm, assuming to catch the gratious arp... and we'll use /* Hmmm, assuming to catch the gratious arp... and we'll use
......
...@@ -89,8 +89,6 @@ int t1_sge_configure(struct sge *, struct sge_params *); ...@@ -89,8 +89,6 @@ int t1_sge_configure(struct sge *, struct sge_params *);
int t1_sge_set_coalesce_params(struct sge *, struct sge_params *); int t1_sge_set_coalesce_params(struct sge *, struct sge_params *);
void t1_sge_destroy(struct sge *); void t1_sge_destroy(struct sge *);
intr_handler_t t1_select_intr_handler(adapter_t *adapter); intr_handler_t t1_select_intr_handler(adapter_t *adapter);
unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
unsigned int qid, struct net_device *netdev);
int t1_start_xmit(struct sk_buff *skb, struct net_device *dev); int t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
void t1_set_vlan_accel(struct adapter *adapter, int on_off); void t1_set_vlan_accel(struct adapter *adapter, int on_off);
void t1_sge_start(struct sge *); void t1_sge_start(struct sge *);
......
...@@ -188,11 +188,13 @@ struct e1000_tx_ring { ...@@ -188,11 +188,13 @@ struct e1000_tx_ring {
/* array of buffer information structs */ /* array of buffer information structs */
struct e1000_buffer *buffer_info; struct e1000_buffer *buffer_info;
struct e1000_buffer previous_buffer_info;
spinlock_t tx_lock; spinlock_t tx_lock;
uint16_t tdh; uint16_t tdh;
uint16_t tdt; uint16_t tdt;
uint64_t pkt; uint64_t pkt;
boolean_t last_tx_tso;
}; };
struct e1000_rx_ring { struct e1000_rx_ring {
......
...@@ -562,10 +562,29 @@ e1000_get_drvinfo(struct net_device *netdev, ...@@ -562,10 +562,29 @@ e1000_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo) struct ethtool_drvinfo *drvinfo)
{ {
struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_adapter *adapter = netdev_priv(netdev);
char firmware_version[32];
uint16_t eeprom_data;
strncpy(drvinfo->driver, e1000_driver_name, 32); strncpy(drvinfo->driver, e1000_driver_name, 32);
strncpy(drvinfo->version, e1000_driver_version, 32); strncpy(drvinfo->version, e1000_driver_version, 32);
strncpy(drvinfo->fw_version, "N/A", 32);
/* EEPROM image version # is reported as firware version # for
* 8257{1|2|3} controllers */
e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data);
switch (adapter->hw.mac_type) {
case e1000_82571:
case e1000_82572:
case e1000_82573:
sprintf(firmware_version, "%d.%d-%d",
(eeprom_data & 0xF000) >> 12,
(eeprom_data & 0x0FF0) >> 4,
eeprom_data & 0x000F);
break;
default:
sprintf(firmware_version, "n/a");
}
strncpy(drvinfo->fw_version, firmware_version, 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_stats = E1000_STATS_LEN; drvinfo->n_stats = E1000_STATS_LEN;
drvinfo->testinfo_len = E1000_TEST_LEN; drvinfo->testinfo_len = E1000_TEST_LEN;
...@@ -960,13 +979,21 @@ e1000_free_desc_rings(struct e1000_adapter *adapter) ...@@ -960,13 +979,21 @@ e1000_free_desc_rings(struct e1000_adapter *adapter)
} }
} }
if(txdr->desc) if(txdr->desc) {
pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma); pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma);
if(rxdr->desc) txdr->desc = NULL;
}
if(rxdr->desc) {
pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma); pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
rxdr->desc = NULL;
}
kfree(txdr->buffer_info); kfree(txdr->buffer_info);
txdr->buffer_info = NULL;
kfree(rxdr->buffer_info); kfree(rxdr->buffer_info);
rxdr->buffer_info = NULL;
return; return;
} }
...@@ -1301,21 +1328,32 @@ static int ...@@ -1301,21 +1328,32 @@ static int
e1000_setup_loopback_test(struct e1000_adapter *adapter) e1000_setup_loopback_test(struct e1000_adapter *adapter)
{ {
uint32_t rctl; uint32_t rctl;
struct e1000_hw *hw = &adapter->hw;
if(adapter->hw.media_type == e1000_media_type_fiber || if (hw->media_type == e1000_media_type_fiber ||
adapter->hw.media_type == e1000_media_type_internal_serdes) { hw->media_type == e1000_media_type_internal_serdes) {
if(adapter->hw.mac_type == e1000_82545 || switch (hw->mac_type) {
adapter->hw.mac_type == e1000_82546 || case e1000_82545:
adapter->hw.mac_type == e1000_82545_rev_3 || case e1000_82546:
adapter->hw.mac_type == e1000_82546_rev_3) case e1000_82545_rev_3:
case e1000_82546_rev_3:
return e1000_set_phy_loopback(adapter); return e1000_set_phy_loopback(adapter);
else { break;
rctl = E1000_READ_REG(&adapter->hw, RCTL); case e1000_82571:
case e1000_82572:
#define E1000_SERDES_LB_ON 0x410
e1000_set_phy_loopback(adapter);
E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_ON);
msec_delay(10);
return 0;
break;
default:
rctl = E1000_READ_REG(hw, RCTL);
rctl |= E1000_RCTL_LBM_TCVR; rctl |= E1000_RCTL_LBM_TCVR;
E1000_WRITE_REG(&adapter->hw, RCTL, rctl); E1000_WRITE_REG(hw, RCTL, rctl);
return 0; return 0;
} }
} else if(adapter->hw.media_type == e1000_media_type_copper) } else if (hw->media_type == e1000_media_type_copper)
return e1000_set_phy_loopback(adapter); return e1000_set_phy_loopback(adapter);
return 7; return 7;
...@@ -1326,25 +1364,36 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter) ...@@ -1326,25 +1364,36 @@ e1000_loopback_cleanup(struct e1000_adapter *adapter)
{ {
uint32_t rctl; uint32_t rctl;
uint16_t phy_reg; uint16_t phy_reg;
struct e1000_hw *hw = &adapter->hw;
rctl = E1000_READ_REG(&adapter->hw, RCTL); rctl = E1000_READ_REG(&adapter->hw, RCTL);
rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
E1000_WRITE_REG(&adapter->hw, RCTL, rctl); E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
if(adapter->hw.media_type == e1000_media_type_copper || switch (hw->mac_type) {
((adapter->hw.media_type == e1000_media_type_fiber || case e1000_82571:
adapter->hw.media_type == e1000_media_type_internal_serdes) && case e1000_82572:
(adapter->hw.mac_type == e1000_82545 || if (hw->media_type == e1000_media_type_fiber ||
adapter->hw.mac_type == e1000_82546 || hw->media_type == e1000_media_type_internal_serdes){
adapter->hw.mac_type == e1000_82545_rev_3 || #define E1000_SERDES_LB_OFF 0x400
adapter->hw.mac_type == e1000_82546_rev_3))) { E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF);
adapter->hw.autoneg = TRUE; msec_delay(10);
e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg); break;
if(phy_reg & MII_CR_LOOPBACK) { }
/* fall thru for Cu adapters */
case e1000_82545:
case e1000_82546:
case e1000_82545_rev_3:
case e1000_82546_rev_3:
default:
hw->autoneg = TRUE;
e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
if (phy_reg & MII_CR_LOOPBACK) {
phy_reg &= ~MII_CR_LOOPBACK; phy_reg &= ~MII_CR_LOOPBACK;
e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg); e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
e1000_phy_reset(&adapter->hw); e1000_phy_reset(hw);
} }
break;
} }
} }
...@@ -1440,9 +1489,11 @@ static int ...@@ -1440,9 +1489,11 @@ static int
e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data) e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data)
{ {
if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback; if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback;
if((*data = e1000_setup_loopback_test(adapter))) goto err_loopback; if((*data = e1000_setup_loopback_test(adapter)))
goto err_loopback_setup;
*data = e1000_run_loopback_test(adapter); *data = e1000_run_loopback_test(adapter);
e1000_loopback_cleanup(adapter); e1000_loopback_cleanup(adapter);
err_loopback_setup:
e1000_free_desc_rings(adapter); e1000_free_desc_rings(adapter);
err_loopback: err_loopback:
return *data; return *data;
...@@ -1671,6 +1722,14 @@ e1000_phys_id(struct net_device *netdev, uint32_t data) ...@@ -1671,6 +1722,14 @@ e1000_phys_id(struct net_device *netdev, uint32_t data)
msleep_interruptible(data * 1000); msleep_interruptible(data * 1000);
del_timer_sync(&adapter->blink_timer); del_timer_sync(&adapter->blink_timer);
} }
else if(adapter->hw.mac_type < e1000_82573) {
E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK |
(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) |
(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT)));
msleep_interruptible(data * 1000);
}
else { else {
E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE | E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK |
......
...@@ -563,11 +563,13 @@ e1000_reset_hw(struct e1000_hw *hw) ...@@ -563,11 +563,13 @@ e1000_reset_hw(struct e1000_hw *hw)
msec_delay(20); msec_delay(20);
break; break;
case e1000_82573: case e1000_82573:
udelay(10); if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) {
ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); udelay(10);
ctrl_ext |= E1000_CTRL_EXT_EE_RST; ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); ctrl_ext |= E1000_CTRL_EXT_EE_RST;
E1000_WRITE_FLUSH(hw); E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
}
/* fall through */ /* fall through */
case e1000_82571: case e1000_82571:
case e1000_82572: case e1000_82572:
...@@ -844,19 +846,27 @@ e1000_setup_link(struct e1000_hw *hw) ...@@ -844,19 +846,27 @@ e1000_setup_link(struct e1000_hw *hw)
* control setting, then the variable hw->fc will * control setting, then the variable hw->fc will
* be initialized based on a value in the EEPROM. * be initialized based on a value in the EEPROM.
*/ */
if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) { if (hw->fc == e1000_fc_default) {
DEBUGOUT("EEPROM Read Error\n"); switch (hw->mac_type) {
return -E1000_ERR_EEPROM; case e1000_82573:
}
if(hw->fc == e1000_fc_default) {
if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
hw->fc = e1000_fc_none;
else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
EEPROM_WORD0F_ASM_DIR)
hw->fc = e1000_fc_tx_pause;
else
hw->fc = e1000_fc_full; hw->fc = e1000_fc_full;
break;
default:
ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
1, &eeprom_data);
if (ret_val) {
DEBUGOUT("EEPROM Read Error\n");
return -E1000_ERR_EEPROM;
}
if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
hw->fc = e1000_fc_none;
else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
EEPROM_WORD0F_ASM_DIR)
hw->fc = e1000_fc_tx_pause;
else
hw->fc = e1000_fc_full;
break;
}
} }
/* We want to save off the original Flow Control configuration just /* We want to save off the original Flow Control configuration just
...@@ -2962,13 +2972,22 @@ e1000_phy_hw_reset(struct e1000_hw *hw) ...@@ -2962,13 +2972,22 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
if(hw->mac_type > e1000_82543) { if(hw->mac_type > e1000_82543) {
/* Read the device control register and assert the E1000_CTRL_PHY_RST /* Read the device control register and assert the E1000_CTRL_PHY_RST
* bit. Then, take it out of reset. * bit. Then, take it out of reset.
* For pre-e1000_82571 hardware, we delay for 10ms between the assert
* and deassert. For e1000_82571 hardware and later, we instead delay
* for 10ms after the deassertion.
*/ */
ctrl = E1000_READ_REG(hw, CTRL); ctrl = E1000_READ_REG(hw, CTRL);
E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST); E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
msec_delay(10);
if (hw->mac_type < e1000_82571)
msec_delay(10);
E1000_WRITE_REG(hw, CTRL, ctrl); E1000_WRITE_REG(hw, CTRL, ctrl);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
if (hw->mac_type >= e1000_82571)
msec_delay(10);
} else { } else {
/* Read the Extended Device Control Register, assert the PHY_RESET_DIR /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
* bit to put the PHY into reset. Then, take it out of reset. * bit to put the PHY into reset. Then, take it out of reset.
...@@ -5278,9 +5297,13 @@ e1000_get_bus_info(struct e1000_hw *hw) ...@@ -5278,9 +5297,13 @@ e1000_get_bus_info(struct e1000_hw *hw)
hw->bus_speed = e1000_bus_speed_unknown; hw->bus_speed = e1000_bus_speed_unknown;
hw->bus_width = e1000_bus_width_unknown; hw->bus_width = e1000_bus_width_unknown;
break; break;
case e1000_82571:
case e1000_82572: case e1000_82572:
case e1000_82573: case e1000_82573:
hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500;
hw->bus_width = e1000_bus_width_pciex_1;
break;
case e1000_82571:
hw->bus_type = e1000_bus_type_pci_express; hw->bus_type = e1000_bus_type_pci_express;
hw->bus_speed = e1000_bus_speed_2500; hw->bus_speed = e1000_bus_speed_2500;
hw->bus_width = e1000_bus_width_pciex_4; hw->bus_width = e1000_bus_width_pciex_4;
...@@ -6650,6 +6673,12 @@ e1000_get_auto_rd_done(struct e1000_hw *hw) ...@@ -6650,6 +6673,12 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
break; break;
} }
/* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
* Need to wait for PHY configuration completion before accessing NVM
* and PHY. */
if (hw->mac_type == e1000_82573)
msec_delay(25);
return E1000_SUCCESS; return E1000_SUCCESS;
} }
......
...@@ -123,6 +123,7 @@ typedef enum { ...@@ -123,6 +123,7 @@ typedef enum {
e1000_bus_width_32, e1000_bus_width_32,
e1000_bus_width_64, e1000_bus_width_64,
e1000_bus_width_pciex_1, e1000_bus_width_pciex_1,
e1000_bus_width_pciex_2,
e1000_bus_width_pciex_4, e1000_bus_width_pciex_4,
e1000_bus_width_reserved e1000_bus_width_reserved
} e1000_bus_width; } e1000_bus_width;
...@@ -149,6 +150,7 @@ typedef enum { ...@@ -149,6 +150,7 @@ typedef enum {
e1000_igp_cable_length_90 = 90, e1000_igp_cable_length_90 = 90,
e1000_igp_cable_length_100 = 100, e1000_igp_cable_length_100 = 100,
e1000_igp_cable_length_110 = 110, e1000_igp_cable_length_110 = 110,
e1000_igp_cable_length_115 = 115,
e1000_igp_cable_length_120 = 120, e1000_igp_cable_length_120 = 120,
e1000_igp_cable_length_130 = 130, e1000_igp_cable_length_130 = 130,
e1000_igp_cable_length_140 = 140, e1000_igp_cable_length_140 = 140,
...@@ -1457,6 +1459,7 @@ struct e1000_hw { ...@@ -1457,6 +1459,7 @@ struct e1000_hw {
#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ #define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ #define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ #define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
#define E1000_EECD_SECVAL_SHIFT 22
#define E1000_STM_OPCODE 0xDB00 #define E1000_STM_OPCODE 0xDB00
#define E1000_HICR_FW_RESET 0xC0 #define E1000_HICR_FW_RESET 0xC0
...@@ -1951,7 +1954,6 @@ struct e1000_host_command_info { ...@@ -1951,7 +1954,6 @@ struct e1000_host_command_info {
#define E1000_MDALIGN 4096 #define E1000_MDALIGN 4096
#define E1000_GCR_BEM32 0x00400000
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
/* Function Active and Power State to MNG */ /* Function Active and Power State to MNG */
#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003 #define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003
......
...@@ -711,6 +711,7 @@ e1000_probe(struct pci_dev *pdev, ...@@ -711,6 +711,7 @@ e1000_probe(struct pci_dev *pdev,
break; break;
case e1000_82546: case e1000_82546:
case e1000_82546_rev_3: case e1000_82546_rev_3:
case e1000_82571:
if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1) if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
&& (adapter->hw.media_type == e1000_media_type_copper)) { && (adapter->hw.media_type == e1000_media_type_copper)) {
e1000_read_eeprom(&adapter->hw, e1000_read_eeprom(&adapter->hw,
...@@ -1158,7 +1159,6 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter, ...@@ -1158,7 +1159,6 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter,
return -ENOMEM; return -ENOMEM;
} }
memset(txdr->buffer_info, 0, size); memset(txdr->buffer_info, 0, size);
memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer));
/* round up to nearest 4K */ /* round up to nearest 4K */
...@@ -1813,11 +1813,6 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter, ...@@ -1813,11 +1813,6 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
/* Free all the Tx ring sk_buffs */ /* Free all the Tx ring sk_buffs */
if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
e1000_unmap_and_free_tx_resource(adapter,
&tx_ring->previous_buffer_info);
}
for(i = 0; i < tx_ring->count; i++) { for(i = 0; i < tx_ring->count; i++) {
buffer_info = &tx_ring->buffer_info[i]; buffer_info = &tx_ring->buffer_info[i];
e1000_unmap_and_free_tx_resource(adapter, buffer_info); e1000_unmap_and_free_tx_resource(adapter, buffer_info);
...@@ -1832,6 +1827,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter, ...@@ -1832,6 +1827,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter,
tx_ring->next_to_use = 0; tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0; tx_ring->next_to_clean = 0;
tx_ring->last_tx_tso = 0;
writel(0, adapter->hw.hw_addr + tx_ring->tdh); writel(0, adapter->hw.hw_addr + tx_ring->tdh);
writel(0, adapter->hw.hw_addr + tx_ring->tdt); writel(0, adapter->hw.hw_addr + tx_ring->tdt);
...@@ -2437,6 +2433,16 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, ...@@ -2437,6 +2433,16 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
buffer_info = &tx_ring->buffer_info[i]; buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd); size = min(len, max_per_txd);
#ifdef NETIF_F_TSO #ifdef NETIF_F_TSO
/* Workaround for Controller erratum --
* descriptor for non-tso packet in a linear SKB that follows a
* tso gets written back prematurely before the data is fully
* DMAd to the controller */
if (!skb->data_len && tx_ring->last_tx_tso &&
!skb_shinfo(skb)->tso_size) {
tx_ring->last_tx_tso = 0;
size -= 4;
}
/* Workaround for premature desc write-backs /* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */ * in TSO mode. Append 4-byte sentinel desc */
if(unlikely(mss && !nr_frags && size == len && size > 8)) if(unlikely(mss && !nr_frags && size == len && size > 8))
...@@ -2693,6 +2699,14 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -2693,6 +2699,14 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if(skb->ip_summed == CHECKSUM_HW) if(skb->ip_summed == CHECKSUM_HW)
count++; count++;
#endif #endif
#ifdef NETIF_F_TSO
/* Controller Erratum workaround */
if (!skb->data_len && tx_ring->last_tx_tso &&
!skb_shinfo(skb)->tso_size)
count++;
#endif
count += TXD_USE_COUNT(len, max_txd_pwr); count += TXD_USE_COUNT(len, max_txd_pwr);
if(adapter->pcix_82544) if(adapter->pcix_82544)
...@@ -2774,9 +2788,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -2774,9 +2788,10 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }
if (likely(tso)) if (likely(tso)) {
tx_ring->last_tx_tso = 1;
tx_flags |= E1000_TX_FLAGS_TSO; tx_flags |= E1000_TX_FLAGS_TSO;
else if (likely(e1000_tx_csum(adapter, tx_ring, skb))) } else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
tx_flags |= E1000_TX_FLAGS_CSUM; tx_flags |= E1000_TX_FLAGS_CSUM;
/* Old method was to assume IPv4 packet by default if TSO was enabled. /* Old method was to assume IPv4 packet by default if TSO was enabled.
...@@ -3227,37 +3242,12 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, ...@@ -3227,37 +3242,12 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
eop_desc = E1000_TX_DESC(*tx_ring, eop); eop_desc = E1000_TX_DESC(*tx_ring, eop);
while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
/* Premature writeback of Tx descriptors clear (free buffers
* and unmap pci_mapping) previous_buffer_info */
if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
e1000_unmap_and_free_tx_resource(adapter,
&tx_ring->previous_buffer_info);
}
for(cleaned = FALSE; !cleaned; ) { for(cleaned = FALSE; !cleaned; ) {
tx_desc = E1000_TX_DESC(*tx_ring, i); tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i]; buffer_info = &tx_ring->buffer_info[i];
cleaned = (i == eop); cleaned = (i == eop);
#ifdef NETIF_F_TSO e1000_unmap_and_free_tx_resource(adapter, buffer_info);
if (!(netdev->features & NETIF_F_TSO)) {
#endif
e1000_unmap_and_free_tx_resource(adapter,
buffer_info);
#ifdef NETIF_F_TSO
} else {
if (cleaned) {
memcpy(&tx_ring->previous_buffer_info,
buffer_info,
sizeof(struct e1000_buffer));
memset(buffer_info, 0,
sizeof(struct e1000_buffer));
} else {
e1000_unmap_and_free_tx_resource(
adapter, buffer_info);
}
}
#endif
tx_desc->buffer_addr = 0; tx_desc->buffer_addr = 0;
tx_desc->lower.data = 0; tx_desc->lower.data = 0;
...@@ -3318,12 +3308,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, ...@@ -3318,12 +3308,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
netif_stop_queue(netdev); netif_stop_queue(netdev);
} }
} }
#ifdef NETIF_F_TSO
if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ)))
e1000_unmap_and_free_tx_resource(
adapter, &tx_ring->previous_buffer_info);
#endif
return cleaned; return cleaned;
} }
......
This diff is collapsed.
...@@ -90,12 +90,26 @@ extern const char gfar_driver_version[]; ...@@ -90,12 +90,26 @@ extern const char gfar_driver_version[];
#define GFAR_RX_MAX_RING_SIZE 256 #define GFAR_RX_MAX_RING_SIZE 256
#define GFAR_TX_MAX_RING_SIZE 256 #define GFAR_TX_MAX_RING_SIZE 256
#define GFAR_MAX_FIFO_THRESHOLD 511
#define GFAR_MAX_FIFO_STARVE 511
#define GFAR_MAX_FIFO_STARVE_OFF 511
#define DEFAULT_RX_BUFFER_SIZE 1536 #define DEFAULT_RX_BUFFER_SIZE 1536
#define TX_RING_MOD_MASK(size) (size-1) #define TX_RING_MOD_MASK(size) (size-1)
#define RX_RING_MOD_MASK(size) (size-1) #define RX_RING_MOD_MASK(size) (size-1)
#define JUMBO_BUFFER_SIZE 9728 #define JUMBO_BUFFER_SIZE 9728
#define JUMBO_FRAME_SIZE 9600 #define JUMBO_FRAME_SIZE 9600
#define DEFAULT_FIFO_TX_THR 0x100
#define DEFAULT_FIFO_TX_STARVE 0x40
#define DEFAULT_FIFO_TX_STARVE_OFF 0x80
#define DEFAULT_BD_STASH 1
#define DEFAULT_STASH_LENGTH 64
#define DEFAULT_STASH_INDEX 0
/* The number of Exact Match registers */
#define GFAR_EM_NUM 15
/* Latency of interface clock in nanoseconds */ /* Latency of interface clock in nanoseconds */
/* Interface clock latency , in this case, means the /* Interface clock latency , in this case, means the
* time described by a value of 1 in the interrupt * time described by a value of 1 in the interrupt
...@@ -112,11 +126,11 @@ extern const char gfar_driver_version[]; ...@@ -112,11 +126,11 @@ extern const char gfar_driver_version[];
#define DEFAULT_TX_COALESCE 1 #define DEFAULT_TX_COALESCE 1
#define DEFAULT_TXCOUNT 16 #define DEFAULT_TXCOUNT 16
#define DEFAULT_TXTIME 400 #define DEFAULT_TXTIME 4
#define DEFAULT_RX_COALESCE 1 #define DEFAULT_RX_COALESCE 1
#define DEFAULT_RXCOUNT 16 #define DEFAULT_RXCOUNT 16
#define DEFAULT_RXTIME 400 #define DEFAULT_RXTIME 4
#define TBIPA_VALUE 0x1f #define TBIPA_VALUE 0x1f
#define MIIMCFG_INIT_VALUE 0x00000007 #define MIIMCFG_INIT_VALUE 0x00000007
...@@ -147,6 +161,7 @@ extern const char gfar_driver_version[]; ...@@ -147,6 +161,7 @@ extern const char gfar_driver_version[];
#define ECNTRL_INIT_SETTINGS 0x00001000 #define ECNTRL_INIT_SETTINGS 0x00001000
#define ECNTRL_TBI_MODE 0x00000020 #define ECNTRL_TBI_MODE 0x00000020
#define ECNTRL_R100 0x00000008
#define MRBLR_INIT_SETTINGS DEFAULT_RX_BUFFER_SIZE #define MRBLR_INIT_SETTINGS DEFAULT_RX_BUFFER_SIZE
...@@ -181,10 +196,12 @@ extern const char gfar_driver_version[]; ...@@ -181,10 +196,12 @@ extern const char gfar_driver_version[];
#define RCTRL_PRSDEP_MASK 0x000000c0 #define RCTRL_PRSDEP_MASK 0x000000c0
#define RCTRL_PRSDEP_INIT 0x000000c0 #define RCTRL_PRSDEP_INIT 0x000000c0
#define RCTRL_PROM 0x00000008 #define RCTRL_PROM 0x00000008
#define RCTRL_EMEN 0x00000002
#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN \ #define RCTRL_CHECKSUMMING (RCTRL_IPCSEN \
| RCTRL_TUCSEN | RCTRL_PRSDEP_INIT) | RCTRL_TUCSEN | RCTRL_PRSDEP_INIT)
#define RCTRL_EXTHASH (RCTRL_GHTX) #define RCTRL_EXTHASH (RCTRL_GHTX)
#define RCTRL_VLAN (RCTRL_PRSDEP_INIT) #define RCTRL_VLAN (RCTRL_PRSDEP_INIT)
#define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK)
#define RSTAT_CLEAR_RHALT 0x00800000 #define RSTAT_CLEAR_RHALT 0x00800000
...@@ -251,28 +268,26 @@ extern const char gfar_driver_version[]; ...@@ -251,28 +268,26 @@ extern const char gfar_driver_version[];
IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \ IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
| IMASK_PERR) | IMASK_PERR)
/* Fifo management */
#define FIFO_TX_THR_MASK 0x01ff
#define FIFO_TX_STARVE_MASK 0x01ff
#define FIFO_TX_STARVE_OFF_MASK 0x01ff
/* Attribute fields */ /* Attribute fields */
/* This enables rx snooping for buffers and descriptors */ /* This enables rx snooping for buffers and descriptors */
#ifdef CONFIG_GFAR_BDSTASH
#define ATTR_BDSTASH 0x00000800 #define ATTR_BDSTASH 0x00000800
#else
#define ATTR_BDSTASH 0x00000000
#endif
#ifdef CONFIG_GFAR_BUFSTASH
#define ATTR_BUFSTASH 0x00004000 #define ATTR_BUFSTASH 0x00004000
#define STASH_LENGTH 64
#else
#define ATTR_BUFSTASH 0x00000000
#endif
#define ATTR_SNOOPING 0x000000c0 #define ATTR_SNOOPING 0x000000c0
#define ATTR_INIT_SETTINGS (ATTR_SNOOPING \ #define ATTR_INIT_SETTINGS ATTR_SNOOPING
| ATTR_BDSTASH | ATTR_BUFSTASH)
#define ATTRELI_INIT_SETTINGS 0x0 #define ATTRELI_INIT_SETTINGS 0x0
#define ATTRELI_EL_MASK 0x3fff0000
#define ATTRELI_EL(x) (x << 16)
#define ATTRELI_EI_MASK 0x00003fff
#define ATTRELI_EI(x) (x)
/* TxBD status field bits */ /* TxBD status field bits */
...@@ -328,6 +343,7 @@ extern const char gfar_driver_version[]; ...@@ -328,6 +343,7 @@ extern const char gfar_driver_version[];
#define RXFCB_CTU 0x0400 #define RXFCB_CTU 0x0400
#define RXFCB_EIP 0x0200 #define RXFCB_EIP 0x0200
#define RXFCB_ETU 0x0100 #define RXFCB_ETU 0x0100
#define RXFCB_CSUM_MASK 0x0f00
#define RXFCB_PERR_MASK 0x000c #define RXFCB_PERR_MASK 0x000c
#define RXFCB_PERR_BADL3 0x0008 #define RXFCB_PERR_BADL3 0x0008
...@@ -339,14 +355,7 @@ struct txbd8 ...@@ -339,14 +355,7 @@ struct txbd8
}; };
struct txfcb { struct txfcb {
u8 vln:1, u8 flags;
ip:1,
ip6:1,
tup:1,
udp:1,
cip:1,
ctu:1,
nph:1;
u8 reserved; u8 reserved;
u8 l4os; /* Level 4 Header Offset */ u8 l4os; /* Level 4 Header Offset */
u8 l3os; /* Level 3 Header Offset */ u8 l3os; /* Level 3 Header Offset */
...@@ -362,14 +371,7 @@ struct rxbd8 ...@@ -362,14 +371,7 @@ struct rxbd8
}; };
struct rxfcb { struct rxfcb {
u16 vln:1, u16 flags;
ip:1,
ip6:1,
tup:1,
cip:1,
ctu:1,
eip:1,
etu:1;
u8 rq; /* Receive Queue index */ u8 rq; /* Receive Queue index */
u8 pro; /* Layer 4 Protocol */ u8 pro; /* Layer 4 Protocol */
u16 reserved; u16 reserved;
...@@ -688,12 +690,17 @@ struct gfar_private { ...@@ -688,12 +690,17 @@ struct gfar_private {
spinlock_t lock; spinlock_t lock;
unsigned int rx_buffer_size; unsigned int rx_buffer_size;
unsigned int rx_stash_size; unsigned int rx_stash_size;
unsigned int rx_stash_index;
unsigned int tx_ring_size; unsigned int tx_ring_size;
unsigned int rx_ring_size; unsigned int rx_ring_size;
unsigned int fifo_threshold;
unsigned int fifo_starve;
unsigned int fifo_starve_off;
unsigned char vlan_enable:1, unsigned char vlan_enable:1,
rx_csum_enable:1, rx_csum_enable:1,
extended_hash:1; extended_hash:1,
bd_stash_en:1;
unsigned short padding; unsigned short padding;
struct vlan_group *vlgrp; struct vlan_group *vlgrp;
/* Info structure initialized by board setup code */ /* Info structure initialized by board setup code */
...@@ -731,6 +738,6 @@ extern void stop_gfar(struct net_device *dev); ...@@ -731,6 +738,6 @@ extern void stop_gfar(struct net_device *dev);
extern void gfar_halt(struct net_device *dev); extern void gfar_halt(struct net_device *dev);
extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
int enable, u32 regnum, u32 read); int enable, u32 regnum, u32 read);
void gfar_setup_stashing(struct net_device *dev); void gfar_init_sysfs(struct net_device *dev);
#endif /* __GIANFAR_H */ #endif /* __GIANFAR_H */
...@@ -125,7 +125,7 @@ static char stat_gstrings[][ETH_GSTRING_LEN] = { ...@@ -125,7 +125,7 @@ static char stat_gstrings[][ETH_GSTRING_LEN] = {
static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf) static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
{ {
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN); memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
else else
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define MII_READ_COMMAND 0x00000001 #define MII_READ_COMMAND 0x00000001
#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \ #define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
| SUPPORTED_10baseT_Full \
| SUPPORTED_100baseT_Half \ | SUPPORTED_100baseT_Half \
| SUPPORTED_100baseT_Full \ | SUPPORTED_100baseT_Full \
| SUPPORTED_Autoneg \ | SUPPORTED_Autoneg \
......
/*
* drivers/net/gianfar_sysfs.c
*
* Gianfar Ethernet Driver
* This driver is designed for the non-CPM ethernet controllers
* on the 85xx and 83xx family of integrated processors
* Based on 8260_io/fcc_enet.c
*
* Author: Andy Fleming
* Maintainer: Kumar Gala (kumar.gala@freescale.com)
*
* Copyright (c) 2002-2005 Freescale Semiconductor, 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.
*
* Sysfs file creation and management
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/version.h>
#include "gianfar.h"
#define GFAR_ATTR(_name) \
static ssize_t gfar_show_##_name(struct class_device *cdev, char *buf); \
static ssize_t gfar_set_##_name(struct class_device *cdev, \
const char *buf, size_t count); \
static CLASS_DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
#define GFAR_CREATE_FILE(_dev, _name) \
class_device_create_file(&_dev->class_dev, &class_device_attr_##_name)
GFAR_ATTR(bd_stash);
GFAR_ATTR(rx_stash_size);
GFAR_ATTR(rx_stash_index);
GFAR_ATTR(fifo_threshold);
GFAR_ATTR(fifo_starve);
GFAR_ATTR(fifo_starve_off);
#define to_net_dev(cd) container_of(cd, struct net_device, class_dev)
static ssize_t gfar_show_bd_stash(struct class_device *cdev, char *buf)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
return sprintf(buf, "%s\n", priv->bd_stash_en? "on" : "off");
}
static ssize_t gfar_set_bd_stash(struct class_device *cdev,
const char *buf, size_t count)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
int new_setting = 0;
u32 temp;
unsigned long 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(&priv->lock, flags);
/* Set the new stashing value */
priv->bd_stash_en = new_setting;
temp = gfar_read(&priv->regs->attr);
if (new_setting)
temp |= ATTR_BDSTASH;
else
temp &= ~(ATTR_BDSTASH);
gfar_write(&priv->regs->attr, temp);
spin_unlock_irqrestore(&priv->lock, flags);
return count;
}
static ssize_t gfar_show_rx_stash_size(struct class_device *cdev, char *buf)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
return sprintf(buf, "%d\n", priv->rx_stash_size);
}
static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
const char *buf, size_t count)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
unsigned int length = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
if (length > priv->rx_buffer_size)
return count;
if (length == priv->rx_stash_size)
return count;
priv->rx_stash_size = length;
temp = gfar_read(&priv->regs->attreli);
temp &= ~ATTRELI_EL_MASK;
temp |= ATTRELI_EL(length);
gfar_write(&priv->regs->attreli, temp);
/* Turn stashing on/off as appropriate */
temp = gfar_read(&priv->regs->attr);
if (length)
temp |= ATTR_BUFSTASH;
else
temp &= ~(ATTR_BUFSTASH);
gfar_write(&priv->regs->attr, temp);
spin_unlock_irqrestore(&priv->lock, flags);
return count;
}
/* Stashing will only be enabled when rx_stash_size != 0 */
static ssize_t gfar_show_rx_stash_index(struct class_device *cdev, char *buf)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
return sprintf(buf, "%d\n", priv->rx_stash_index);
}
static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
const char *buf, size_t count)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
unsigned short index = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
if (index > priv->rx_stash_size)
return count;
if (index == priv->rx_stash_index)
return count;
priv->rx_stash_index = index;
temp = gfar_read(&priv->regs->attreli);
temp &= ~ATTRELI_EI_MASK;
temp |= ATTRELI_EI(index);
gfar_write(&priv->regs->attreli, flags);
spin_unlock_irqrestore(&priv->lock, flags);
return count;
}
static ssize_t gfar_show_fifo_threshold(struct class_device *cdev, char *buf)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
return sprintf(buf, "%d\n", priv->fifo_threshold);
}
static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
const char *buf, size_t count)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
unsigned int length = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
if (length > GFAR_MAX_FIFO_THRESHOLD)
return count;
spin_lock_irqsave(&priv->lock, flags);
priv->fifo_threshold = length;
temp = gfar_read(&priv->regs->fifo_tx_thr);
temp &= ~FIFO_TX_THR_MASK;
temp |= length;
gfar_write(&priv->regs->fifo_tx_thr, temp);
spin_unlock_irqrestore(&priv->lock, flags);
return count;
}
static ssize_t gfar_show_fifo_starve(struct class_device *cdev, char *buf)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
return sprintf(buf, "%d\n", priv->fifo_starve);
}
static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
const char *buf, size_t count)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
unsigned int num = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
if (num > GFAR_MAX_FIFO_STARVE)
return count;
spin_lock_irqsave(&priv->lock, flags);
priv->fifo_starve = num;
temp = gfar_read(&priv->regs->fifo_tx_starve);
temp &= ~FIFO_TX_STARVE_MASK;
temp |= num;
gfar_write(&priv->regs->fifo_tx_starve, temp);
spin_unlock_irqrestore(&priv->lock, flags);
return count;
}
static ssize_t gfar_show_fifo_starve_off(struct class_device *cdev, char *buf)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
return sprintf(buf, "%d\n", priv->fifo_starve_off);
}
static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
const char *buf, size_t count)
{
struct net_device *dev = to_net_dev(cdev);
struct gfar_private *priv = netdev_priv(dev);
unsigned int num = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
if (num > GFAR_MAX_FIFO_STARVE_OFF)
return count;
spin_lock_irqsave(&priv->lock, flags);
priv->fifo_starve_off = num;
temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
temp &= ~FIFO_TX_STARVE_OFF_MASK;
temp |= num;
gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);
spin_unlock_irqrestore(&priv->lock, flags);
return count;
}
void gfar_init_sysfs(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
/* Initialize the default values */
priv->rx_stash_size = DEFAULT_STASH_LENGTH;
priv->rx_stash_index = DEFAULT_STASH_INDEX;
priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
priv->bd_stash_en = DEFAULT_BD_STASH;
/* Create our sysfs files */
GFAR_CREATE_FILE(dev, bd_stash);
GFAR_CREATE_FILE(dev, rx_stash_size);
GFAR_CREATE_FILE(dev, rx_stash_index);
GFAR_CREATE_FILE(dev, fifo_threshold);
GFAR_CREATE_FILE(dev, fifo_starve);
GFAR_CREATE_FILE(dev, fifo_starve_off);
}
config ENP2611_MSF_NET
tristate "Radisys ENP2611 MSF network interface support"
depends on ARCH_ENP2611
help
This is a driver for the MSF network interface unit in
the IXP2400 on the Radisys ENP2611 platform.
obj-$(CONFIG_ENP2611_MSF_NET) += enp2611_mod.o
enp2611_mod-objs := caleb.o enp2611.o ixp2400-msf.o ixpdev.o pm3386.o
/*
* Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
* Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
* Dedicated to Marija Kulikova.
*
* 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.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <asm/io.h>
#include "caleb.h"
#define CALEB_IDLO 0x00
#define CALEB_IDHI 0x01
#define CALEB_RID 0x02
#define CALEB_RESET 0x03
#define CALEB_INTREN0 0x04
#define CALEB_INTREN1 0x05
#define CALEB_INTRSTAT0 0x06
#define CALEB_INTRSTAT1 0x07
#define CALEB_PORTEN 0x08
#define CALEB_BURST 0x09
#define CALEB_PORTPAUS 0x0A
#define CALEB_PORTPAUSD 0x0B
#define CALEB_PHY0RX 0x10
#define CALEB_PHY1RX 0x11
#define CALEB_PHY0TX 0x12
#define CALEB_PHY1TX 0x13
#define CALEB_IXPRX_HI_CNTR 0x15
#define CALEB_PHY0RX_HI_CNTR 0x16
#define CALEB_PHY1RX_HI_CNTR 0x17
#define CALEB_IXPRX_CNTR 0x18
#define CALEB_PHY0RX_CNTR 0x19
#define CALEB_PHY1RX_CNTR 0x1A
#define CALEB_IXPTX_CNTR 0x1B
#define CALEB_PHY0TX_CNTR 0x1C
#define CALEB_PHY1TX_CNTR 0x1D
#define CALEB_DEBUG0 0x1E
#define CALEB_DEBUG1 0x1F
static u8 caleb_reg_read(int reg)
{
u8 value;
value = *((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg));
// printk(KERN_INFO "caleb_reg_read(%d) = %.2x\n", reg, value);
return value;
}
static void caleb_reg_write(int reg, u8 value)
{
u8 dummy;
// printk(KERN_INFO "caleb_reg_write(%d, %.2x)\n", reg, value);
*((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg)) = value;
dummy = *((volatile u8 *)ENP2611_CALEB_VIRT_BASE);
__asm__ __volatile__("mov %0, %0" : "+r" (dummy));
}
void caleb_reset(void)
{
/*
* Perform a chip reset.
*/
caleb_reg_write(CALEB_RESET, 0x02);
udelay(1);
/*
* Enable all interrupt sources. This is needed to get
* meaningful results out of the status bits (register 6
* and 7.)
*/
caleb_reg_write(CALEB_INTREN0, 0xff);
caleb_reg_write(CALEB_INTREN1, 0x07);
/*
* Set RX and TX FIFO thresholds to 1.5kb.
*/
caleb_reg_write(CALEB_PHY0RX, 0x11);
caleb_reg_write(CALEB_PHY1RX, 0x11);
caleb_reg_write(CALEB_PHY0TX, 0x11);
caleb_reg_write(CALEB_PHY1TX, 0x11);
/*
* Program SPI-3 burst size.
*/
caleb_reg_write(CALEB_BURST, 0); // 64-byte RBUF mpackets
// caleb_reg_write(CALEB_BURST, 1); // 128-byte RBUF mpackets
// caleb_reg_write(CALEB_BURST, 2); // 256-byte RBUF mpackets
}
void caleb_enable_rx(int port)
{
u8 temp;
temp = caleb_reg_read(CALEB_PORTEN);
temp |= 1 << port;
caleb_reg_write(CALEB_PORTEN, temp);
}
void caleb_disable_rx(int port)
{
u8 temp;
temp = caleb_reg_read(CALEB_PORTEN);
temp &= ~(1 << port);
caleb_reg_write(CALEB_PORTEN, temp);
}
void caleb_enable_tx(int port)
{
u8 temp;
temp = caleb_reg_read(CALEB_PORTEN);
temp |= 1 << (port + 4);
caleb_reg_write(CALEB_PORTEN, temp);
}
void caleb_disable_tx(int port)
{
u8 temp;
temp = caleb_reg_read(CALEB_PORTEN);
temp &= ~(1 << (port + 4));
caleb_reg_write(CALEB_PORTEN, temp);
}
/*
* Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
* Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
* Dedicated to Marija Kulikova.
*
* 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 __CALEB_H
#define __CALEB_H
void caleb_reset(void);
void caleb_enable_rx(int port);
void caleb_disable_rx(int port);
void caleb_enable_tx(int port);
void caleb_disable_tx(int port);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* IXP2000 MSF network device driver
* Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
* Dedicated to Marija Kulikova.
*
* 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 __IXPDEV_H
#define __IXPDEV_H
struct ixpdev_priv
{
int channel;
int tx_queue_entries;
};
struct net_device *ixpdev_alloc(int channel, int sizeof_priv);
int ixpdev_init(int num_ports, struct net_device **nds,
void (*set_port_admin_status)(int port, int up));
void ixpdev_deinit(void);
#endif
This diff is collapsed.
This diff is collapsed.
/*
* Helper functions for the PM3386s on the Radisys ENP2611
* Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
* Dedicated to Marija Kulikova.
*
* 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 __PM3386_H
#define __PM3386_H
void pm3386_reset(void);
void pm3386_init_port(int port);
void pm3386_get_mac(int port, u8 *mac);
void pm3386_set_mac(int port, u8 *mac);
void pm3386_get_stats(int port, struct net_device_stats *stats);
void pm3386_set_carrier(int port, int state);
int pm3386_is_link_up(int port);
void pm3386_enable_rx(int port);
void pm3386_disable_rx(int port);
void pm3386_enable_tx(int port);
void pm3386_disable_tx(int port);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment