aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/e1000e
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-20 17:43:29 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-20 17:43:29 -0700
commitdb6d8c7a4027b48d797b369a53f8470aaeed7063 (patch)
treee140c104a89abc2154e1f41a7db8ebecbb6fa0b4 /drivers/net/e1000e
parent3a533374283aea50eab3976d8a6d30532175f009 (diff)
parentfb65a7c091529bfffb1262515252c0d0f6241c5c (diff)
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: (1232 commits) iucv: Fix bad merging. net_sched: Add size table for qdiscs net_sched: Add accessor function for packet length for qdiscs net_sched: Add qdisc_enqueue wrapper highmem: Export totalhigh_pages. ipv6 mcast: Omit redundant address family checks in ip6_mc_source(). net: Use standard structures for generic socket address structures. ipv6 netns: Make several "global" sysctl variables namespace aware. netns: Use net_eq() to compare net-namespaces for optimization. ipv6: remove unused macros from net/ipv6.h ipv6: remove unused parameter from ip6_ra_control tcp: fix kernel panic with listening_get_next tcp: Remove redundant checks when setting eff_sacks tcp: options clean up tcp: Fix MD5 signatures for non-linear skbs sctp: Update sctp global memory limit allocations. sctp: remove unnecessary byteshifting, calculate directly in big-endian sctp: Allow only 1 listening socket with SO_REUSEADDR sctp: Do not leak memory on multiple listen() calls sctp: Support ipv6only AF_INET6 sockets. ...
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r--drivers/net/e1000e/e1000.h4
-rw-r--r--drivers/net/e1000e/netdev.c84
2 files changed, 67 insertions, 21 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index d3bc6f8101f..4a4f62e002b 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -283,6 +283,10 @@ struct e1000_adapter {
unsigned long led_status;
unsigned int flags;
+
+ /* for ioport free */
+ int bars;
+ int need_ioport;
};
struct e1000_info {
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 648a87bbf46..869544b8c05 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -98,8 +98,7 @@ static void e1000_receive_skb(struct e1000_adapter *adapter,
if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(vlan) &
- E1000_RXD_SPC_VLAN_MASK);
+ le16_to_cpu(vlan));
else
netif_receive_skb(skb);
@@ -1793,7 +1792,6 @@ static void e1000_vlan_rx_register(struct net_device *netdev,
if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
/* enable VLAN receive filtering */
rctl = er32(RCTL);
- rctl |= E1000_RCTL_VFE;
rctl &= ~E1000_RCTL_CFIEN;
ew32(RCTL, rctl);
e1000_update_mng_vlan(adapter);
@@ -1805,10 +1803,6 @@ static void e1000_vlan_rx_register(struct net_device *netdev,
ew32(CTRL, ctrl);
if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
- /* disable VLAN filtering */
- rctl = er32(RCTL);
- rctl &= ~E1000_RCTL_VFE;
- ew32(RCTL, rctl);
if (adapter->mng_vlan_id !=
(u16)E1000_MNG_VLAN_NONE) {
e1000_vlan_rx_kill_vid(netdev,
@@ -2231,11 +2225,16 @@ static void e1000_set_multi(struct net_device *netdev)
if (netdev->flags & IFF_PROMISC) {
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
- } else if (netdev->flags & IFF_ALLMULTI) {
- rctl |= E1000_RCTL_MPE;
- rctl &= ~E1000_RCTL_UPE;
+ rctl &= ~E1000_RCTL_VFE;
} else {
- rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+ if (netdev->flags & IFF_ALLMULTI) {
+ rctl |= E1000_RCTL_MPE;
+ rctl &= ~E1000_RCTL_UPE;
+ } else {
+ rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+ }
+ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
+ rctl |= E1000_RCTL_VFE;
}
ew32(RCTL, rctl);
@@ -2514,7 +2513,7 @@ void e1000e_down(struct e1000_adapter *adapter)
ew32(RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
/* disable transmits in the hardware */
tctl = er32(TCTL);
@@ -2664,6 +2663,8 @@ static int e1000_open(struct net_device *netdev)
e1000_irq_enable(adapter);
+ netif_tx_start_all_queues(netdev);
+
/* fire a link status change interrupt to start the watchdog */
ew32(ICS, E1000_ICS_LSC);
@@ -3119,7 +3120,7 @@ static void e1000_watchdog_task(struct work_struct *work)
ew32(TCTL, tctl);
netif_carrier_on(netdev);
- netif_wake_queue(netdev);
+ netif_tx_wake_all_queues(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
@@ -3131,7 +3132,7 @@ static void e1000_watchdog_task(struct work_struct *work)
adapter->link_duplex = 0;
ndev_info(netdev, "Link is Down\n");
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
if (!test_bit(__E1000_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
@@ -4003,7 +4004,11 @@ static int e1000_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
e1000e_disable_l1aspm(pdev);
- err = pci_enable_device(pdev);
+
+ if (adapter->need_ioport)
+ err = pci_enable_device(pdev);
+ else
+ err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
"Cannot enable PCI device from suspend\n");
@@ -4104,9 +4109,14 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ int err;
e1000e_disable_l1aspm(pdev);
- if (pci_enable_device(pdev)) {
+ if (adapter->need_ioport)
+ err = pci_enable_device(pdev);
+ else
+ err = pci_enable_device_mem(pdev);
+ if (err) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
@@ -4185,6 +4195,21 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
}
/**
+ * e1000e_is_need_ioport - determine if an adapter needs ioport resources or not
+ * @pdev: PCI device information struct
+ *
+ * Returns true if an adapters needs ioport resources
+ **/
+static int e1000e_is_need_ioport(struct pci_dev *pdev)
+{
+ switch (pdev->device) {
+ /* Currently there are no adapters that need ioport resources */
+ default:
+ return false;
+ }
+}
+
+/**
* e1000_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in e1000_pci_tbl
@@ -4209,9 +4234,19 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
int i, err, pci_using_dac;
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
+ int bars, need_ioport;
e1000e_disable_l1aspm(pdev);
- err = pci_enable_device(pdev);
+
+ /* do not allocate ioport bars when not needed */
+ need_ioport = e1000e_is_need_ioport(pdev);
+ if (need_ioport) {
+ bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
+ err = pci_enable_device(pdev);
+ } else {
+ bars = pci_select_bars(pdev, IORESOURCE_MEM);
+ err = pci_enable_device_mem(pdev);
+ }
if (err)
return err;
@@ -4234,7 +4269,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
}
}
- err = pci_request_regions(pdev, e1000e_driver_name);
+ err = pci_request_selected_regions(pdev, bars, e1000e_driver_name);
if (err)
goto err_pci_reg;
@@ -4259,6 +4294,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
adapter->hw.adapter = adapter;
adapter->hw.mac.type = ei->mac;
adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
+ adapter->bars = bars;
+ adapter->need_ioport = need_ioport;
mmio_start = pci_resource_start(pdev, 0);
mmio_len = pci_resource_len(pdev, 0);
@@ -4344,6 +4381,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
+ netdev->vlan_features |= NETIF_F_TSO;
+ netdev->vlan_features |= NETIF_F_TSO6;
+ netdev->vlan_features |= NETIF_F_HW_CSUM;
+ netdev->vlan_features |= NETIF_F_SG;
+
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
@@ -4464,7 +4506,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
/* tell the stack to leave us alone until e1000_open() is called */
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
@@ -4493,7 +4535,7 @@ err_sw_init:
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, bars);
err_pci_reg:
err_dma:
pci_disable_device(pdev);
@@ -4541,7 +4583,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
iounmap(adapter->hw.hw_addr);
if (adapter->hw.flash_address)
iounmap(adapter->hw.flash_address);
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, adapter->bars);
free_netdev(netdev);