Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (29 commits)
  tcp: Restore ordering of TCP options for the sake of inter-operability
  net: Fix disjunct computation of netdev features
  sctp: Fix to handle SHUTDOWN in SHUTDOWN_RECEIVED state
  sctp: Fix to handle SHUTDOWN in SHUTDOWN-PENDING state
  sctp: Add check for the TSN field of the SHUTDOWN chunk
  sctp: Drop ICMP packet too big message with MTU larger than current PMTU
  p54: enable 2.4/5GHz spectrum by eeprom bits.
  orinoco: reduce stack usage in firmware download path
  ath5k: fix suspend-related oops on rmmod
  [netdrvr] fec_mpc52xx: Implement polling, to make netconsole work.
  qlge: Fix MSI/legacy single interrupt bug.
  smc911x: Make the driver safer on SMP
  smc911x: Add IRQ polarity configuration
  smc911x: Allow Kconfig dependency on ARM
  sis190: add identifier for Atheros AR8021 PHY
  8139x: reduce message severity on driver overlap
  igb: add IGB_DCA instead of selecting INTEL_IOATDMA
  igb: fix tx data corruption with transition to L0s on 82575
  ehea: Fix memory hotplug support
  netdev: DM9000: remove BLACKFIN hacking in DM9000 netdev driver
  ...
This commit is contained in:
Linus Torvalds
2008-10-23 19:19:54 -07:00
35 changed files with 558 additions and 292 deletions
+2 -3
View File
@@ -1836,10 +1836,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (pdev->vendor == PCI_VENDOR_ID_REALTEK && if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision < 0x20) { pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision < 0x20) {
dev_err(&pdev->dev, dev_info(&pdev->dev,
"This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n", "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip, use 8139too\n",
pdev->vendor, pdev->device, pdev->revision); pdev->vendor, pdev->device, pdev->revision);
dev_err(&pdev->dev, "Try the \"8139too\" driver instead.\n");
return -ENODEV; return -ENODEV;
} }
+2 -3
View File
@@ -946,10 +946,9 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
if (pdev->vendor == PCI_VENDOR_ID_REALTEK && if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision >= 0x20) { pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision >= 0x20) {
dev_info(&pdev->dev, dev_info(&pdev->dev,
"This (id %04x:%04x rev %02x) is an enhanced 8139C+ chip\n", "This (id %04x:%04x rev %02x) is an enhanced 8139C+ chip, use 8139cp\n",
pdev->vendor, pdev->device, pdev->revision); pdev->vendor, pdev->device, pdev->revision);
dev_info(&pdev->dev, return -ENODEV;
"Use the \"8139cp\" driver for improved performance and stability.\n");
} }
if (pdev->vendor == PCI_VENDOR_ID_REALTEK && if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
+7 -2
View File
@@ -894,7 +894,7 @@ config SMC91X
select CRC32 select CRC32
select MII select MII
depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \ depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
SOC_AU1X00 || BLACKFIN || MN10300 MIPS || BLACKFIN || MN10300
help help
This is a driver for SMC's 91x series of Ethernet chipsets, This is a driver for SMC's 91x series of Ethernet chipsets,
including the SMC91C94 and the SMC91C111. Say Y if you want it including the SMC91C94 and the SMC91C111. Say Y if you want it
@@ -966,7 +966,7 @@ config SMC911X
tristate "SMSC LAN911[5678] support" tristate "SMSC LAN911[5678] support"
select CRC32 select CRC32
select MII select MII
depends on ARCH_PXA || SUPERH depends on ARM || SUPERH
help help
This is a driver for SMSC's LAN911x series of Ethernet chipsets This is a driver for SMSC's LAN911x series of Ethernet chipsets
including the new LAN9115, LAN9116, LAN9117, and LAN9118. including the new LAN9115, LAN9116, LAN9117, and LAN9118.
@@ -2009,6 +2009,11 @@ config IGB_LRO
If in doubt, say N. If in doubt, say N.
config IGB_DCA
bool "Enable DCA"
default y
depends on IGB && DCA && !(IGB=y && DCA=m)
source "drivers/net/ixp2000/Kconfig" source "drivers/net/ixp2000/Kconfig"
config MYRI_SBUS config MYRI_SBUS
+3 -3
View File
@@ -838,12 +838,12 @@ static int ax_probe(struct platform_device *pdev)
/* find the platform resources */ /* find the platform resources */
dev->irq = platform_get_irq(pdev, 0); ret = platform_get_irq(pdev, 0);
if (dev->irq < 0) { if (ret < 0) {
dev_err(&pdev->dev, "no IRQ specified\n"); dev_err(&pdev->dev, "no IRQ specified\n");
ret = -ENXIO;
goto exit_mem; goto exit_mem;
} }
dev->irq = ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) { if (res == NULL) {
+11 -5
View File
@@ -1341,18 +1341,24 @@ static int bond_compute_features(struct bonding *bond)
int i; int i;
features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES); features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | features |= NETIF_F_GSO_MASK | NETIF_F_NO_CSUM;
NETIF_F_GSO_MASK | NETIF_F_NO_CSUM;
if (!bond->first_slave)
goto done;
features &= ~NETIF_F_ONE_FOR_ALL;
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave, i) {
features = netdev_compute_features(features, features = netdev_increment_features(features,
slave->dev->features); slave->dev->features,
NETIF_F_ONE_FOR_ALL);
if (slave->dev->hard_header_len > max_hard_header_len) if (slave->dev->hard_header_len > max_hard_header_len)
max_hard_header_len = slave->dev->hard_header_len; max_hard_header_len = slave->dev->hard_header_len;
} }
done:
features |= (bond_dev->features & BOND_VLAN_FEATURES); features |= (bond_dev->features & BOND_VLAN_FEATURES);
bond_dev->features = features; bond_dev->features = netdev_fix_features(features, NULL);
bond_dev->hard_header_len = max_hard_header_len; bond_dev->hard_header_len = max_hard_header_len;
return 0; return 0;
+1
View File
@@ -431,6 +431,7 @@ struct l2t_data *t3_init_l2t(unsigned int l2t_capacity)
for (i = 0; i < l2t_capacity; ++i) { for (i = 0; i < l2t_capacity; ++i) {
d->l2tab[i].idx = i; d->l2tab[i].idx = i;
d->l2tab[i].state = L2T_STATE_UNUSED; d->l2tab[i].state = L2T_STATE_UNUSED;
__skb_queue_head_init(&d->l2tab[i].arpq);
spin_lock_init(&d->l2tab[i].lock); spin_lock_init(&d->l2tab[i].lock);
atomic_set(&d->l2tab[i].refcnt, 0); atomic_set(&d->l2tab[i].refcnt, 0);
} }
-9
View File
@@ -47,15 +47,6 @@
#define CARDNAME "dm9000" #define CARDNAME "dm9000"
#define DRV_VERSION "1.31" #define DRV_VERSION "1.31"
#ifdef CONFIG_BLACKFIN
#define readsb insb
#define readsw insw
#define readsl insl
#define writesb outsb
#define writesw outsw
#define writesl outsl
#endif
/* /*
* Transmit timeout, default 5 seconds. * Transmit timeout, default 5 seconds.
*/ */
+1 -1
View File
@@ -40,7 +40,7 @@
#include <asm/io.h> #include <asm/io.h>
#define DRV_NAME "ehea" #define DRV_NAME "ehea"
#define DRV_VERSION "EHEA_0093" #define DRV_VERSION "EHEA_0094"
/* eHEA capability flags */ /* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1 #define DLPAR_PORT_ADD_REM 1
+15 -10
View File
@@ -2863,7 +2863,7 @@ static void ehea_rereg_mrs(struct work_struct *work)
struct ehea_adapter *adapter; struct ehea_adapter *adapter;
mutex_lock(&dlpar_mem_lock); mutex_lock(&dlpar_mem_lock);
ehea_info("LPAR memory enlarged - re-initializing driver"); ehea_info("LPAR memory changed - re-initializing driver");
list_for_each_entry(adapter, &adapter_list, list) list_for_each_entry(adapter, &adapter_list, list)
if (adapter->active_ports) { if (adapter->active_ports) {
@@ -2900,13 +2900,6 @@ static void ehea_rereg_mrs(struct work_struct *work)
} }
} }
ehea_destroy_busmap();
ret = ehea_create_busmap();
if (ret) {
ehea_error("creating ehea busmap failed");
goto out;
}
clear_bit(__EHEA_STOP_XFER, &ehea_driver_flags); clear_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
list_for_each_entry(adapter, &adapter_list, list) list_for_each_entry(adapter, &adapter_list, list)
@@ -3519,9 +3512,21 @@ void ehea_crash_handler(void)
static int ehea_mem_notifier(struct notifier_block *nb, static int ehea_mem_notifier(struct notifier_block *nb,
unsigned long action, void *data) unsigned long action, void *data)
{ {
struct memory_notify *arg = data;
switch (action) { switch (action) {
case MEM_OFFLINE: case MEM_CANCEL_OFFLINE:
ehea_info("memory has been removed"); ehea_info("memory offlining canceled");
/* Readd canceled memory block */
case MEM_ONLINE:
ehea_info("memory is going online");
if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages))
return NOTIFY_BAD;
ehea_rereg_mrs(NULL);
break;
case MEM_GOING_OFFLINE:
ehea_info("memory is going offline");
if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages))
return NOTIFY_BAD;
ehea_rereg_mrs(NULL); ehea_rereg_mrs(NULL);
break; break;
default: default:
+101 -30
View File
@@ -587,53 +587,124 @@ static inline int ehea_init_bmap(struct ehea_bmap *ehea_bmap, int top, int dir)
return ehea_init_top_bmap(ehea_bmap->top[top], dir); return ehea_init_top_bmap(ehea_bmap->top[top], dir);
} }
static int ehea_create_busmap_callback(unsigned long pfn, static DEFINE_MUTEX(ehea_busmap_mutex);
unsigned long nr_pages, void *arg) static unsigned long ehea_mr_len;
{
unsigned long i, mr_len, start_section, end_section;
start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE;
end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE);
mr_len = *(unsigned long *)arg;
if (!ehea_bmap) #define EHEA_BUSMAP_ADD_SECT 1
#define EHEA_BUSMAP_REM_SECT 0
static void ehea_rebuild_busmap(void)
{
u64 vaddr = EHEA_BUSMAP_START;
int top, dir, idx;
for (top = 0; top < EHEA_MAP_ENTRIES; top++) {
struct ehea_top_bmap *ehea_top;
int valid_dir_entries = 0;
if (!ehea_bmap->top[top])
continue;
ehea_top = ehea_bmap->top[top];
for (dir = 0; dir < EHEA_MAP_ENTRIES; dir++) {
struct ehea_dir_bmap *ehea_dir;
int valid_entries = 0;
if (!ehea_top->dir[dir])
continue;
valid_dir_entries++;
ehea_dir = ehea_top->dir[dir];
for (idx = 0; idx < EHEA_MAP_ENTRIES; idx++) {
if (!ehea_dir->ent[idx])
continue;
valid_entries++;
ehea_dir->ent[idx] = vaddr;
vaddr += EHEA_SECTSIZE;
}
if (!valid_entries) {
ehea_top->dir[dir] = NULL;
kfree(ehea_dir);
}
}
if (!valid_dir_entries) {
ehea_bmap->top[top] = NULL;
kfree(ehea_top);
}
}
}
static int ehea_update_busmap(unsigned long pfn, unsigned long pgnum, int add)
{
unsigned long i, start_section, end_section;
if (!ehea_bmap) {
ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL); ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
if (!ehea_bmap) if (!ehea_bmap)
return -ENOMEM; return -ENOMEM;
for (i = start_section; i < end_section; i++) {
int ret;
int top, dir, idx;
u64 vaddr;
top = ehea_calc_index(i, EHEA_TOP_INDEX_SHIFT);
dir = ehea_calc_index(i, EHEA_DIR_INDEX_SHIFT);
ret = ehea_init_bmap(ehea_bmap, top, dir);
if(ret)
return ret;
idx = i & EHEA_INDEX_MASK;
vaddr = EHEA_BUSMAP_START + mr_len + i * EHEA_SECTSIZE;
ehea_bmap->top[top]->dir[dir]->ent[idx] = vaddr;
} }
mr_len += nr_pages * PAGE_SIZE; start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE;
*(unsigned long *)arg = mr_len; end_section = start_section + ((pgnum * PAGE_SIZE) / EHEA_SECTSIZE);
/* Mark entries as valid or invalid only; address is assigned later */
for (i = start_section; i < end_section; i++) {
u64 flag;
int top = ehea_calc_index(i, EHEA_TOP_INDEX_SHIFT);
int dir = ehea_calc_index(i, EHEA_DIR_INDEX_SHIFT);
int idx = i & EHEA_INDEX_MASK;
if (add) {
int ret = ehea_init_bmap(ehea_bmap, top, dir);
if (ret)
return ret;
flag = 1; /* valid */
ehea_mr_len += EHEA_SECTSIZE;
} else {
if (!ehea_bmap->top[top])
continue;
if (!ehea_bmap->top[top]->dir[dir])
continue;
flag = 0; /* invalid */
ehea_mr_len -= EHEA_SECTSIZE;
}
ehea_bmap->top[top]->dir[dir]->ent[idx] = flag;
}
ehea_rebuild_busmap(); /* Assign contiguous addresses for mr */
return 0; return 0;
} }
static unsigned long ehea_mr_len; int ehea_add_sect_bmap(unsigned long pfn, unsigned long nr_pages)
{
int ret;
static DEFINE_MUTEX(ehea_busmap_mutex); mutex_lock(&ehea_busmap_mutex);
ret = ehea_update_busmap(pfn, nr_pages, EHEA_BUSMAP_ADD_SECT);
mutex_unlock(&ehea_busmap_mutex);
return ret;
}
int ehea_rem_sect_bmap(unsigned long pfn, unsigned long nr_pages)
{
int ret;
mutex_lock(&ehea_busmap_mutex);
ret = ehea_update_busmap(pfn, nr_pages, EHEA_BUSMAP_REM_SECT);
mutex_unlock(&ehea_busmap_mutex);
return ret;
}
static int ehea_create_busmap_callback(unsigned long pfn,
unsigned long nr_pages, void *arg)
{
return ehea_update_busmap(pfn, nr_pages, EHEA_BUSMAP_ADD_SECT);
}
int ehea_create_busmap(void) int ehea_create_busmap(void)
{ {
int ret; int ret;
mutex_lock(&ehea_busmap_mutex); mutex_lock(&ehea_busmap_mutex);
ehea_mr_len = 0; ehea_mr_len = 0;
ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, &ehea_mr_len, ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
ehea_create_busmap_callback); ehea_create_busmap_callback);
mutex_unlock(&ehea_busmap_mutex); mutex_unlock(&ehea_busmap_mutex);
return ret; return ret;
+2
View File
@@ -378,6 +378,8 @@ int ehea_rem_mr(struct ehea_mr *mr);
void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle); void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle);
int ehea_add_sect_bmap(unsigned long pfn, unsigned long nr_pages);
int ehea_rem_sect_bmap(unsigned long pfn, unsigned long nr_pages);
int ehea_create_busmap(void); int ehea_create_busmap(void);
void ehea_destroy_busmap(void); void ehea_destroy_busmap(void);
u64 ehea_map_vaddr(void *caddr); u64 ehea_map_vaddr(void *caddr);
+18
View File
@@ -401,6 +401,21 @@ static int mpc52xx_fec_hard_start_xmit(struct sk_buff *skb, struct net_device *d
return 0; return 0;
} }
#ifdef CONFIG_NET_POLL_CONTROLLER
static void mpc52xx_fec_poll_controller(struct net_device *dev)
{
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
disable_irq(priv->t_irq);
mpc52xx_fec_tx_interrupt(priv->t_irq, dev);
enable_irq(priv->t_irq);
disable_irq(priv->r_irq);
mpc52xx_fec_rx_interrupt(priv->r_irq, dev);
enable_irq(priv->r_irq);
}
#endif
/* This handles BestComm transmit task interrupts /* This handles BestComm transmit task interrupts
*/ */
static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id) static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id)
@@ -926,6 +941,9 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
ndev->tx_timeout = mpc52xx_fec_tx_timeout; ndev->tx_timeout = mpc52xx_fec_tx_timeout;
ndev->watchdog_timeo = FEC_WATCHDOG_TIMEOUT; ndev->watchdog_timeo = FEC_WATCHDOG_TIMEOUT;
ndev->base_addr = mem.start; ndev->base_addr = mem.start;
#ifdef CONFIG_NET_POLL_CONTROLLER
ndev->poll_controller = mpc52xx_fec_poll_controller;
#endif
priv->t_irq = priv->r_irq = ndev->irq = NO_IRQ; /* IRQ are free for now */ priv->t_irq = priv->r_irq = ndev->irq = NO_IRQ; /* IRQ are free for now */
+17 -7
View File
@@ -161,7 +161,7 @@ static int gfar_probe(struct platform_device *pdev)
struct gfar_private *priv = NULL; struct gfar_private *priv = NULL;
struct gianfar_platform_data *einfo; struct gianfar_platform_data *einfo;
struct resource *r; struct resource *r;
int err = 0; int err = 0, irq;
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
einfo = (struct gianfar_platform_data *) pdev->dev.platform_data; einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
@@ -187,15 +187,25 @@ static int gfar_probe(struct platform_device *pdev)
/* fill out IRQ fields */ /* fill out IRQ fields */
if (einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { if (einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
priv->interruptTransmit = platform_get_irq_byname(pdev, "tx"); irq = platform_get_irq_byname(pdev, "tx");
priv->interruptReceive = platform_get_irq_byname(pdev, "rx"); if (irq < 0)
priv->interruptError = platform_get_irq_byname(pdev, "error");
if (priv->interruptTransmit < 0 || priv->interruptReceive < 0 || priv->interruptError < 0)
goto regs_fail; goto regs_fail;
priv->interruptTransmit = irq;
irq = platform_get_irq_byname(pdev, "rx");
if (irq < 0)
goto regs_fail;
priv->interruptReceive = irq;
irq = platform_get_irq_byname(pdev, "error");
if (irq < 0)
goto regs_fail;
priv->interruptError = irq;
} else { } else {
priv->interruptTransmit = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (priv->interruptTransmit < 0) if (irq < 0)
goto regs_fail; goto regs_fail;
priv->interruptTransmit = irq;
} }
/* get a pointer to the register memory */ /* get a pointer to the register memory */
+42 -18
View File
@@ -38,10 +38,11 @@
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci-aspm.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
#include <linux/dca.h> #include <linux/dca.h>
#endif #endif
#include "igb.h" #include "igb.h"
@@ -106,11 +107,11 @@ static irqreturn_t igb_msix_other(int irq, void *);
static irqreturn_t igb_msix_rx(int irq, void *); static irqreturn_t igb_msix_rx(int irq, void *);
static irqreturn_t igb_msix_tx(int irq, void *); static irqreturn_t igb_msix_tx(int irq, void *);
static int igb_clean_rx_ring_msix(struct napi_struct *, int); static int igb_clean_rx_ring_msix(struct napi_struct *, int);
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
static void igb_update_rx_dca(struct igb_ring *); static void igb_update_rx_dca(struct igb_ring *);
static void igb_update_tx_dca(struct igb_ring *); static void igb_update_tx_dca(struct igb_ring *);
static void igb_setup_dca(struct igb_adapter *); static void igb_setup_dca(struct igb_adapter *);
#endif /* CONFIG_DCA */ #endif /* CONFIG_IGB_DCA */
static bool igb_clean_tx_irq(struct igb_ring *); static bool igb_clean_tx_irq(struct igb_ring *);
static int igb_poll(struct napi_struct *, int); static int igb_poll(struct napi_struct *, int);
static bool igb_clean_rx_irq_adv(struct igb_ring *, int *, int); static bool igb_clean_rx_irq_adv(struct igb_ring *, int *, int);
@@ -131,7 +132,7 @@ static int igb_suspend(struct pci_dev *, pm_message_t);
static int igb_resume(struct pci_dev *); static int igb_resume(struct pci_dev *);
#endif #endif
static void igb_shutdown(struct pci_dev *); static void igb_shutdown(struct pci_dev *);
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
static int igb_notify_dca(struct notifier_block *, unsigned long, void *); static int igb_notify_dca(struct notifier_block *, unsigned long, void *);
static struct notifier_block dca_notifier = { static struct notifier_block dca_notifier = {
.notifier_call = igb_notify_dca, .notifier_call = igb_notify_dca,
@@ -207,7 +208,7 @@ static int __init igb_init_module(void)
global_quad_port_a = 0; global_quad_port_a = 0;
ret = pci_register_driver(&igb_driver); ret = pci_register_driver(&igb_driver);
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
dca_register_notify(&dca_notifier); dca_register_notify(&dca_notifier);
#endif #endif
return ret; return ret;
@@ -223,7 +224,7 @@ module_init(igb_init_module);
**/ **/
static void __exit igb_exit_module(void) static void __exit igb_exit_module(void)
{ {
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
dca_unregister_notify(&dca_notifier); dca_unregister_notify(&dca_notifier);
#endif #endif
pci_unregister_driver(&igb_driver); pci_unregister_driver(&igb_driver);
@@ -966,10 +967,11 @@ static int __devinit igb_probe(struct pci_dev *pdev,
struct net_device *netdev; struct net_device *netdev;
struct igb_adapter *adapter; struct igb_adapter *adapter;
struct e1000_hw *hw; struct e1000_hw *hw;
struct pci_dev *us_dev;
const struct e1000_info *ei = igb_info_tbl[ent->driver_data]; const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
unsigned long mmio_start, mmio_len; unsigned long mmio_start, mmio_len;
int i, err, pci_using_dac; int i, err, pci_using_dac, pos;
u16 eeprom_data = 0; u16 eeprom_data = 0, state = 0;
u16 eeprom_apme_mask = IGB_EEPROM_APME; u16 eeprom_apme_mask = IGB_EEPROM_APME;
u32 part_num; u32 part_num;
int bars, need_ioport; int bars, need_ioport;
@@ -1004,6 +1006,28 @@ static int __devinit igb_probe(struct pci_dev *pdev,
} }
} }
/* 82575 requires that the pci-e link partner disable the L0s state */
switch (pdev->device) {
case E1000_DEV_ID_82575EB_COPPER:
case E1000_DEV_ID_82575EB_FIBER_SERDES:
case E1000_DEV_ID_82575GB_QUAD_COPPER:
us_dev = pdev->bus->self;
pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
if (pos) {
pci_read_config_word(us_dev, pos + PCI_EXP_LNKCTL,
&state);
state &= ~PCIE_LINK_STATE_L0S;
pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL,
state);
printk(KERN_INFO "Disabling ASPM L0s upstream switch "
"port %x:%x.%x\n", us_dev->bus->number,
PCI_SLOT(us_dev->devfn),
PCI_FUNC(us_dev->devfn));
}
default:
break;
}
err = pci_request_selected_regions(pdev, bars, igb_driver_name); err = pci_request_selected_regions(pdev, bars, igb_driver_name);
if (err) if (err)
goto err_pci_reg; goto err_pci_reg;
@@ -1237,7 +1261,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (err) if (err)
goto err_register; goto err_register;
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
if ((adapter->flags & IGB_FLAG_HAS_DCA) && if ((adapter->flags & IGB_FLAG_HAS_DCA) &&
(dca_add_requester(&pdev->dev) == 0)) { (dca_add_requester(&pdev->dev) == 0)) {
adapter->flags |= IGB_FLAG_DCA_ENABLED; adapter->flags |= IGB_FLAG_DCA_ENABLED;
@@ -1311,7 +1335,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev); struct igb_adapter *adapter = netdev_priv(netdev);
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
#endif #endif
@@ -1323,7 +1347,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
flush_scheduled_work(); flush_scheduled_work();
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED) { if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
dev_info(&pdev->dev, "DCA disabled\n"); dev_info(&pdev->dev, "DCA disabled\n");
dca_remove_requester(&pdev->dev); dca_remove_requester(&pdev->dev);
@@ -3271,7 +3295,7 @@ static irqreturn_t igb_msix_tx(int irq, void *data)
struct igb_adapter *adapter = tx_ring->adapter; struct igb_adapter *adapter = tx_ring->adapter;
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED) if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_tx_dca(tx_ring); igb_update_tx_dca(tx_ring);
#endif #endif
@@ -3323,14 +3347,14 @@ static irqreturn_t igb_msix_rx(int irq, void *data)
if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi)) if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi))
__netif_rx_schedule(adapter->netdev, &rx_ring->napi); __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED) if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_rx_dca(rx_ring); igb_update_rx_dca(rx_ring);
#endif #endif
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
static void igb_update_rx_dca(struct igb_ring *rx_ring) static void igb_update_rx_dca(struct igb_ring *rx_ring)
{ {
u32 dca_rxctrl; u32 dca_rxctrl;
@@ -3450,7 +3474,7 @@ static int igb_notify_dca(struct notifier_block *nb, unsigned long event,
return ret_val ? NOTIFY_BAD : NOTIFY_DONE; return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
} }
#endif /* CONFIG_DCA */ #endif /* CONFIG_IGB_DCA */
/** /**
* igb_intr_msi - Interrupt Handler * igb_intr_msi - Interrupt Handler
@@ -3529,13 +3553,13 @@ static int igb_poll(struct napi_struct *napi, int budget)
int tx_clean_complete, work_done = 0; int tx_clean_complete, work_done = 0;
/* this poll routine only supports one tx and one rx queue */ /* this poll routine only supports one tx and one rx queue */
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED) if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_tx_dca(&adapter->tx_ring[0]); igb_update_tx_dca(&adapter->tx_ring[0]);
#endif #endif
tx_clean_complete = igb_clean_tx_irq(&adapter->tx_ring[0]); tx_clean_complete = igb_clean_tx_irq(&adapter->tx_ring[0]);
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED) if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_rx_dca(&adapter->rx_ring[0]); igb_update_rx_dca(&adapter->rx_ring[0]);
#endif #endif
@@ -3563,7 +3587,7 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int work_done = 0; int work_done = 0;
#ifdef CONFIG_DCA #ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED) if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_rx_dca(rx_ring); igb_update_rx_dca(rx_ring);
#endif #endif
+5 -1
View File
@@ -75,7 +75,7 @@
#include "myri10ge_mcp.h" #include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h" #include "myri10ge_mcp_gen_header.h"
#define MYRI10GE_VERSION_STR "1.4.3-1.369" #define MYRI10GE_VERSION_STR "1.4.3-1.371"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com"); MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -2497,6 +2497,10 @@ static int myri10ge_open(struct net_device *dev)
return 0; return 0;
abort_with_rings: abort_with_rings:
while (slice) {
slice--;
napi_disable(&mgp->ss[slice].napi);
}
for (i = 0; i < mgp->num_slices; i++) for (i = 0; i < mgp->num_slices; i++)
myri10ge_free_rings(&mgp->ss[i]); myri10ge_free_rings(&mgp->ss[i]);
+1 -4
View File
@@ -1375,7 +1375,6 @@ struct ql_adapter {
spinlock_t adapter_lock; spinlock_t adapter_lock;
spinlock_t hw_lock; spinlock_t hw_lock;
spinlock_t stats_lock; spinlock_t stats_lock;
spinlock_t legacy_lock; /* used for maintaining legacy intr sync */
/* PCI Bus Relative Register Addresses */ /* PCI Bus Relative Register Addresses */
void __iomem *reg_base; void __iomem *reg_base;
@@ -1399,8 +1398,6 @@ struct ql_adapter {
struct msix_entry *msi_x_entry; struct msix_entry *msi_x_entry;
struct intr_context intr_context[MAX_RX_RINGS]; struct intr_context intr_context[MAX_RX_RINGS];
int (*legacy_check) (struct ql_adapter *);
int tx_ring_count; /* One per online CPU. */ int tx_ring_count; /* One per online CPU. */
u32 rss_ring_first_cq_id;/* index of first inbound (rss) rx_ring */ u32 rss_ring_first_cq_id;/* index of first inbound (rss) rx_ring */
u32 rss_ring_count; /* One per online CPU. */ u32 rss_ring_count; /* One per online CPU. */
@@ -1502,7 +1499,7 @@ void ql_mpi_work(struct work_struct *work);
void ql_mpi_reset_work(struct work_struct *work); void ql_mpi_reset_work(struct work_struct *work);
int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 ebit); int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 ebit);
void ql_queue_asic_error(struct ql_adapter *qdev); void ql_queue_asic_error(struct ql_adapter *qdev);
void ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr); u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
void ql_set_ethtool_ops(struct net_device *ndev); void ql_set_ethtool_ops(struct net_device *ndev);
int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data); int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data);
+44 -41
View File
@@ -577,41 +577,53 @@ static void ql_disable_interrupts(struct ql_adapter *qdev)
* incremented everytime we queue a worker and decremented everytime * incremented everytime we queue a worker and decremented everytime
* a worker finishes. Once it hits zero we enable the interrupt. * a worker finishes. Once it hits zero we enable the interrupt.
*/ */
void ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr) u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
{ {
if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) u32 var = 0;
unsigned long hw_flags = 0;
struct intr_context *ctx = qdev->intr_context + intr;
if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags) && intr)) {
/* Always enable if we're MSIX multi interrupts and
* it's not the default (zeroeth) interrupt.
*/
ql_write32(qdev, INTR_EN, ql_write32(qdev, INTR_EN,
qdev->intr_context[intr].intr_en_mask); ctx->intr_en_mask);
else { var = ql_read32(qdev, STS);
if (qdev->legacy_check) return var;
spin_lock(&qdev->legacy_lock); }
if (atomic_dec_and_test(&qdev->intr_context[intr].irq_cnt)) {
QPRINTK(qdev, INTR, ERR, "Enabling interrupt %d.\n", spin_lock_irqsave(&qdev->hw_lock, hw_flags);
intr); if (atomic_dec_and_test(&ctx->irq_cnt)) {
ql_write32(qdev, INTR_EN, ql_write32(qdev, INTR_EN,
qdev->intr_context[intr].intr_en_mask); ctx->intr_en_mask);
} else { var = ql_read32(qdev, STS);
QPRINTK(qdev, INTR, ERR,
"Skip enable, other queue(s) are active.\n");
}
if (qdev->legacy_check)
spin_unlock(&qdev->legacy_lock);
} }
spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
return var;
} }
static u32 ql_disable_completion_interrupt(struct ql_adapter *qdev, u32 intr) static u32 ql_disable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
{ {
u32 var = 0; u32 var = 0;
unsigned long hw_flags;
struct intr_context *ctx;
if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) /* HW disables for us if we're MSIX multi interrupts and
goto exit; * it's not the default (zeroeth) interrupt.
else if (!atomic_read(&qdev->intr_context[intr].irq_cnt)) { */
if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags) && intr))
return 0;
ctx = qdev->intr_context + intr;
spin_lock_irqsave(&qdev->hw_lock, hw_flags);
if (!atomic_read(&ctx->irq_cnt)) {
ql_write32(qdev, INTR_EN, ql_write32(qdev, INTR_EN,
qdev->intr_context[intr].intr_dis_mask); ctx->intr_dis_mask);
var = ql_read32(qdev, STS); var = ql_read32(qdev, STS);
} }
atomic_inc(&qdev->intr_context[intr].irq_cnt); atomic_inc(&ctx->irq_cnt);
exit: spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
return var; return var;
} }
@@ -623,6 +635,8 @@ static void ql_enable_all_completion_interrupts(struct ql_adapter *qdev)
* and enables only if the result is zero. * and enables only if the result is zero.
* So we precharge it here. * So we precharge it here.
*/ */
if (unlikely(!test_bit(QL_MSIX_ENABLED, &qdev->flags) ||
i == 0))
atomic_set(&qdev->intr_context[i].irq_cnt, 1); atomic_set(&qdev->intr_context[i].irq_cnt, 1);
ql_enable_completion_interrupt(qdev, i); ql_enable_completion_interrupt(qdev, i);
} }
@@ -1725,19 +1739,6 @@ static irqreturn_t qlge_msix_rx_isr(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/* We check here to see if we're already handling a legacy
* interrupt. If we are, then it must belong to another
* chip with which we're sharing the interrupt line.
*/
int ql_legacy_check(struct ql_adapter *qdev)
{
int err;
spin_lock(&qdev->legacy_lock);
err = atomic_read(&qdev->intr_context[0].irq_cnt);
spin_unlock(&qdev->legacy_lock);
return err;
}
/* This handles a fatal error, MPI activity, and the default /* This handles a fatal error, MPI activity, and the default
* rx_ring in an MSI-X multiple vector environment. * rx_ring in an MSI-X multiple vector environment.
* In MSI/Legacy environment it also process the rest of * In MSI/Legacy environment it also process the rest of
@@ -1752,12 +1753,15 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
int i; int i;
int work_done = 0; int work_done = 0;
if (qdev->legacy_check && qdev->legacy_check(qdev)) { spin_lock(&qdev->hw_lock);
QPRINTK(qdev, INTR, INFO, "Already busy, not our interrupt.\n"); if (atomic_read(&qdev->intr_context[0].irq_cnt)) {
return IRQ_NONE; /* Not our interrupt */ QPRINTK(qdev, INTR, DEBUG, "Shared Interrupt, Not ours!\n");
spin_unlock(&qdev->hw_lock);
return IRQ_NONE;
} }
spin_unlock(&qdev->hw_lock);
var = ql_read32(qdev, STS); var = ql_disable_completion_interrupt(qdev, intr_context->intr);
/* /*
* Check for fatal error. * Check for fatal error.
@@ -1823,6 +1827,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
} }
} }
} }
ql_enable_completion_interrupt(qdev, intr_context->intr);
return work_done ? IRQ_HANDLED : IRQ_NONE; return work_done ? IRQ_HANDLED : IRQ_NONE;
} }
@@ -2701,8 +2706,6 @@ msi:
} }
} }
irq_type = LEG_IRQ; irq_type = LEG_IRQ;
spin_lock_init(&qdev->legacy_lock);
qdev->legacy_check = ql_legacy_check;
QPRINTK(qdev, IFUP, DEBUG, "Running with legacy interrupts.\n"); QPRINTK(qdev, IFUP, DEBUG, "Running with legacy interrupts.\n");
} }
+29 -7
View File
@@ -81,6 +81,10 @@ static const int multicast_filter_limit = 32;
#define RTL8169_TX_TIMEOUT (6*HZ) #define RTL8169_TX_TIMEOUT (6*HZ)
#define RTL8169_PHY_TIMEOUT (10*HZ) #define RTL8169_PHY_TIMEOUT (10*HZ)
#define RTL_EEPROM_SIG cpu_to_le32(0x8129)
#define RTL_EEPROM_SIG_MASK cpu_to_le32(0xffff)
#define RTL_EEPROM_SIG_ADDR 0x0000
/* write/read MMIO register */ /* write/read MMIO register */
#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) #define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg))
@@ -1944,14 +1948,15 @@ static void rtl_init_mac_address(struct rtl8169_private *tp,
void __iomem *ioaddr) void __iomem *ioaddr)
{ {
struct pci_dev *pdev = tp->pci_dev; struct pci_dev *pdev = tp->pci_dev;
u8 cfg1;
int vpd_cap; int vpd_cap;
__le32 sig;
u8 mac[8]; u8 mac[8];
DECLARE_MAC_BUF(buf); u8 cfg1;
cfg1 = RTL_R8(Config1); cfg1 = RTL_R8(Config1);
if (!(cfg1 & VPD)) { if (!(cfg1 & VPD)) {
dprintk("VPD access not enabled, enabling\n"); if (netif_msg_probe(tp))
dev_info(&pdev->dev, "VPD access disabled, enabling\n");
RTL_W8(Cfg9346, Cfg9346_Unlock); RTL_W8(Cfg9346, Cfg9346_Unlock);
RTL_W8(Config1, cfg1 | VPD); RTL_W8(Config1, cfg1 | VPD);
RTL_W8(Cfg9346, Cfg9346_Lock); RTL_W8(Cfg9346, Cfg9346_Lock);
@@ -1961,7 +1966,16 @@ static void rtl_init_mac_address(struct rtl8169_private *tp,
if (!vpd_cap) if (!vpd_cap)
return; return;
/* MAC address is stored in EEPROM at offset 0x0e if (rtl_eeprom_read(pdev, vpd_cap, RTL_EEPROM_SIG_ADDR, &sig) < 0)
return;
if ((sig & RTL_EEPROM_SIG_MASK) != RTL_EEPROM_SIG) {
dev_info(&pdev->dev, "Missing EEPROM signature: %08x\n", sig);
return;
}
/*
* MAC address is stored in EEPROM at offset 0x0e
* Realtek says: "The VPD address does not have to be a DWORD-aligned * Realtek says: "The VPD address does not have to be a DWORD-aligned
* address as defined in the PCI 2.2 Specifications, but the VPD data * address as defined in the PCI 2.2 Specifications, but the VPD data
* is always consecutive 4-byte data starting from the VPD address * is always consecutive 4-byte data starting from the VPD address
@@ -1969,13 +1983,21 @@ static void rtl_init_mac_address(struct rtl8169_private *tp,
*/ */
if (rtl_eeprom_read(pdev, vpd_cap, 0x000e, (__le32*)&mac[0]) < 0 || if (rtl_eeprom_read(pdev, vpd_cap, 0x000e, (__le32*)&mac[0]) < 0 ||
rtl_eeprom_read(pdev, vpd_cap, 0x0012, (__le32*)&mac[4]) < 0) { rtl_eeprom_read(pdev, vpd_cap, 0x0012, (__le32*)&mac[4]) < 0) {
dprintk("Reading MAC address from EEPROM failed\n"); if (netif_msg_probe(tp)) {
dev_warn(&pdev->dev,
"reading MAC address from EEPROM failed\n");
}
return; return;
} }
dprintk("MAC address found in EEPROM: %s\n", print_mac(buf, mac)); if (netif_msg_probe(tp)) {
DECLARE_MAC_BUF(buf);
/* Write MAC address */ dev_info(&pdev->dev, "MAC address found in EEPROM: %s\n",
print_mac(buf, mac));
}
if (is_valid_ether_addr(mac))
rtl_rar_set(tp, mac); rtl_rar_set(tp, mac);
} }
+1
View File
@@ -317,6 +317,7 @@ static struct mii_chip_info {
unsigned int type; unsigned int type;
u32 feature; u32 feature;
} mii_chip_table[] = { } mii_chip_table[] = {
{ "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 },
{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 }, { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
{ "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 }, { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 },
{ "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 }, { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 },
+17 -21
View File
@@ -155,23 +155,17 @@ static void PRINT_PKT(u_char *buf, int length)
/* this enables an interrupt in the interrupt mask register */ /* this enables an interrupt in the interrupt mask register */
#define SMC_ENABLE_INT(lp, x) do { \ #define SMC_ENABLE_INT(lp, x) do { \
unsigned int __mask; \ unsigned int __mask; \
unsigned long __flags; \
spin_lock_irqsave(&lp->lock, __flags); \
__mask = SMC_GET_INT_EN((lp)); \ __mask = SMC_GET_INT_EN((lp)); \
__mask |= (x); \ __mask |= (x); \
SMC_SET_INT_EN((lp), __mask); \ SMC_SET_INT_EN((lp), __mask); \
spin_unlock_irqrestore(&lp->lock, __flags); \
} while (0) } while (0)
/* this disables an interrupt from the interrupt mask register */ /* this disables an interrupt from the interrupt mask register */
#define SMC_DISABLE_INT(lp, x) do { \ #define SMC_DISABLE_INT(lp, x) do { \
unsigned int __mask; \ unsigned int __mask; \
unsigned long __flags; \
spin_lock_irqsave(&lp->lock, __flags); \
__mask = SMC_GET_INT_EN((lp)); \ __mask = SMC_GET_INT_EN((lp)); \
__mask &= ~(x); \ __mask &= ~(x); \
SMC_SET_INT_EN((lp), __mask); \ SMC_SET_INT_EN((lp), __mask); \
spin_unlock_irqrestore(&lp->lock, __flags); \
} while (0) } while (0)
/* /*
@@ -180,7 +174,7 @@ static void PRINT_PKT(u_char *buf, int length)
static void smc911x_reset(struct net_device *dev) static void smc911x_reset(struct net_device *dev)
{ {
struct smc911x_local *lp = netdev_priv(dev); struct smc911x_local *lp = netdev_priv(dev);
unsigned int reg, timeout=0, resets=1; unsigned int reg, timeout=0, resets=1, irq_cfg;
unsigned long flags; unsigned long flags;
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
@@ -252,7 +246,12 @@ static void smc911x_reset(struct net_device *dev)
* Deassert IRQ for 1*10us for edge type interrupts * Deassert IRQ for 1*10us for edge type interrupts
* and drive IRQ pin push-pull * and drive IRQ pin push-pull
*/ */
SMC_SET_IRQ_CFG(lp, (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_); irq_cfg = (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_;
#ifdef SMC_DYNAMIC_BUS_CONFIG
if (lp->cfg.irq_polarity)
irq_cfg |= INT_CFG_IRQ_POL_;
#endif
SMC_SET_IRQ_CFG(lp, irq_cfg);
/* clear anything saved */ /* clear anything saved */
if (lp->pending_tx_skb != NULL) { if (lp->pending_tx_skb != NULL) {
@@ -274,6 +273,8 @@ static void smc911x_enable(struct net_device *dev)
DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
SMC_SET_MAC_ADDR(lp, dev->dev_addr); SMC_SET_MAC_ADDR(lp, dev->dev_addr);
/* Enable TX */ /* Enable TX */
@@ -286,12 +287,10 @@ static void smc911x_enable(struct net_device *dev)
SMC_SET_FIFO_TSL(lp, 64); SMC_SET_FIFO_TSL(lp, 64);
SMC_SET_GPT_CFG(lp, GPT_CFG_TIMER_EN_ | 10000); SMC_SET_GPT_CFG(lp, GPT_CFG_TIMER_EN_ | 10000);
spin_lock_irqsave(&lp->lock, flags);
SMC_GET_MAC_CR(lp, cr); SMC_GET_MAC_CR(lp, cr);
cr |= MAC_CR_TXEN_ | MAC_CR_HBDIS_; cr |= MAC_CR_TXEN_ | MAC_CR_HBDIS_;
SMC_SET_MAC_CR(lp, cr); SMC_SET_MAC_CR(lp, cr);
SMC_SET_TX_CFG(lp, TX_CFG_TX_ON_); SMC_SET_TX_CFG(lp, TX_CFG_TX_ON_);
spin_unlock_irqrestore(&lp->lock, flags);
/* Add 2 byte padding to start of packets */ /* Add 2 byte padding to start of packets */
SMC_SET_RX_CFG(lp, (2<<8) & RX_CFG_RXDOFF_); SMC_SET_RX_CFG(lp, (2<<8) & RX_CFG_RXDOFF_);
@@ -300,9 +299,7 @@ static void smc911x_enable(struct net_device *dev)
if (cr & MAC_CR_RXEN_) if (cr & MAC_CR_RXEN_)
DBG(SMC_DEBUG_RX, "%s: Receiver already enabled\n", dev->name); DBG(SMC_DEBUG_RX, "%s: Receiver already enabled\n", dev->name);
spin_lock_irqsave(&lp->lock, flags);
SMC_SET_MAC_CR(lp, cr | MAC_CR_RXEN_); SMC_SET_MAC_CR(lp, cr | MAC_CR_RXEN_);
spin_unlock_irqrestore(&lp->lock, flags);
/* Interrupt on every received packet */ /* Interrupt on every received packet */
SMC_SET_FIFO_RSA(lp, 0x01); SMC_SET_FIFO_RSA(lp, 0x01);
@@ -318,6 +315,8 @@ static void smc911x_enable(struct net_device *dev)
mask|=INT_EN_RDFO_EN_; mask|=INT_EN_RDFO_EN_;
} }
SMC_ENABLE_INT(lp, mask); SMC_ENABLE_INT(lp, mask);
spin_unlock_irqrestore(&lp->lock, flags);
} }
/* /*
@@ -458,7 +457,6 @@ static void smc911x_hardware_send_pkt(struct net_device *dev)
struct sk_buff *skb; struct sk_buff *skb;
unsigned int cmdA, cmdB, len; unsigned int cmdA, cmdB, len;
unsigned char *buf; unsigned char *buf;
unsigned long flags;
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __func__); DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __func__);
BUG_ON(lp->pending_tx_skb == NULL); BUG_ON(lp->pending_tx_skb == NULL);
@@ -503,11 +501,9 @@ static void smc911x_hardware_send_pkt(struct net_device *dev)
dev->trans_start = jiffies; dev->trans_start = jiffies;
dev_kfree_skb(skb); dev_kfree_skb(skb);
#endif #endif
spin_lock_irqsave(&lp->lock, flags);
if (!lp->tx_throttle) { if (!lp->tx_throttle) {
netif_wake_queue(dev); netif_wake_queue(dev);
} }
spin_unlock_irqrestore(&lp->lock, flags);
SMC_ENABLE_INT(lp, INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_); SMC_ENABLE_INT(lp, INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_);
} }
@@ -526,6 +522,8 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n",
dev->name, __func__); dev->name, __func__);
spin_lock_irqsave(&lp->lock, flags);
BUG_ON(lp->pending_tx_skb != NULL); BUG_ON(lp->pending_tx_skb != NULL);
free = SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TDFREE_; free = SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TDFREE_;
@@ -535,12 +533,10 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (free <= SMC911X_TX_FIFO_LOW_THRESHOLD) { if (free <= SMC911X_TX_FIFO_LOW_THRESHOLD) {
DBG(SMC_DEBUG_TX, "%s: Disabling data flow due to low FIFO space (%d)\n", DBG(SMC_DEBUG_TX, "%s: Disabling data flow due to low FIFO space (%d)\n",
dev->name, free); dev->name, free);
spin_lock_irqsave(&lp->lock, flags);
/* Reenable when at least 1 packet of size MTU present */ /* Reenable when at least 1 packet of size MTU present */
SMC_SET_FIFO_TDA(lp, (SMC911X_TX_FIFO_LOW_THRESHOLD)/64); SMC_SET_FIFO_TDA(lp, (SMC911X_TX_FIFO_LOW_THRESHOLD)/64);
lp->tx_throttle = 1; lp->tx_throttle = 1;
netif_stop_queue(dev); netif_stop_queue(dev);
spin_unlock_irqrestore(&lp->lock, flags);
} }
/* Drop packets when we run out of space in TX FIFO /* Drop packets when we run out of space in TX FIFO
@@ -556,6 +552,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
lp->pending_tx_skb = NULL; lp->pending_tx_skb = NULL;
dev->stats.tx_errors++; dev->stats.tx_errors++;
dev->stats.tx_dropped++; dev->stats.tx_dropped++;
spin_unlock_irqrestore(&lp->lock, flags);
dev_kfree_skb(skb); dev_kfree_skb(skb);
return 0; return 0;
} }
@@ -565,7 +562,6 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* If the DMA is already running then defer this packet Tx until /* If the DMA is already running then defer this packet Tx until
* the DMA IRQ starts it * the DMA IRQ starts it
*/ */
spin_lock_irqsave(&lp->lock, flags);
if (lp->txdma_active) { if (lp->txdma_active) {
DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Tx DMA running, deferring packet\n", dev->name); DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Tx DMA running, deferring packet\n", dev->name);
lp->pending_tx_skb = skb; lp->pending_tx_skb = skb;
@@ -576,11 +572,11 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Activating Tx DMA\n", dev->name); DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Activating Tx DMA\n", dev->name);
lp->txdma_active = 1; lp->txdma_active = 1;
} }
spin_unlock_irqrestore(&lp->lock, flags);
} }
#endif #endif
lp->pending_tx_skb = skb; lp->pending_tx_skb = skb;
smc911x_hardware_send_pkt(dev); smc911x_hardware_send_pkt(dev);
spin_unlock_irqrestore(&lp->lock, flags);
return 0; return 0;
} }
@@ -1242,7 +1238,7 @@ smc911x_rx_dma_irq(int dma, void *data)
netif_rx(skb); netif_rx(skb);
spin_lock_irqsave(&lp->lock, flags); spin_lock_irqsave(&lp->lock, flags);
pkts = (SMC_GET_RX_FIFO_INF() & RX_FIFO_INF_RXSUSED_) >> 16; pkts = (SMC_GET_RX_FIFO_INF(lp) & RX_FIFO_INF_RXSUSED_) >> 16;
if (pkts != 0) { if (pkts != 0) {
smc911x_rcv(dev); smc911x_rcv(dev);
}else { }else {
@@ -2054,7 +2050,7 @@ err_out:
*/ */
static int smc911x_drv_probe(struct platform_device *pdev) static int smc911x_drv_probe(struct platform_device *pdev)
{ {
struct smc91x_platdata *pd = pdev->dev.platform_data; struct smc911x_platdata *pd = pdev->dev.platform_data;
struct net_device *ndev; struct net_device *ndev;
struct resource *res; struct resource *res;
struct smc911x_local *lp; struct smc911x_local *lp;

Some files were not shown because too many files have changed in this diff Show More