/*******************************************************************************
-
- Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ Intel PRO/10GbE Linux driver
+ Copyright(c) 1999 - 2006 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
-
+
You should have received a copy of the GNU General Public License along with
- this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
Contact Information:
Linux NICS <linux.nics@intel.com>
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#else
#define DRIVERNAPI "-NAPI"
#endif
-#define DRV_VERSION "1.0.112-k2"DRIVERNAPI
+#define DRV_VERSION "1.0.126-k2"DRIVERNAPI
char ixgb_driver_version[] = DRV_VERSION;
static char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
static struct net_device_stats *ixgb_get_stats(struct net_device *netdev);
static int ixgb_change_mtu(struct net_device *netdev, int new_mtu);
static int ixgb_set_mac(struct net_device *netdev, void *p);
-static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs);
+static irqreturn_t ixgb_intr(int irq, void *data);
static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
#ifdef CONFIG_IXGB_NAPI
static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);
void ixgb_set_ethtool_ops(struct net_device *netdev);
static void ixgb_tx_timeout(struct net_device *dev);
-static void ixgb_tx_timeout_task(struct net_device *dev);
+static void ixgb_tx_timeout_task(struct work_struct *work);
static void ixgb_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
netdev->poll_controller = ixgb_netpoll;
#endif
- strcpy(netdev->name, pci_name(pdev));
+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len;
netdev->base_addr = adapter->hw.io_base;
NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
-#ifdef NETIF_F_TSO
netdev->features |= NETIF_F_TSO;
-#endif
#ifdef NETIF_F_LLTX
netdev->features |= NETIF_F_LLTX;
#endif
adapter->watchdog_timer.function = &ixgb_watchdog;
adapter->watchdog_timer.data = (unsigned long)adapter;
- INIT_WORK(&adapter->tx_timeout_task,
- (void (*)(void *))ixgb_tx_timeout_task, netdev);
+ INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task);
strcpy(netdev->name, "eth%d");
if((err = register_netdev(netdev)))
static int
ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
{
-#ifdef NETIF_F_TSO
struct ixgb_context_desc *context_desc;
unsigned int i;
uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
return 1;
}
-#endif
return 0;
}
unsigned int i;
uint8_t css, cso;
- if(likely(skb->ip_summed == CHECKSUM_HW)) {
+ if(likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
struct ixgb_buffer *buffer_info;
css = skb->h.raw - skb->data;
- cso = (skb->h.raw + skb->csum) - skb->data;
+ cso = css + skb->csum_offset;
i = adapter->tx_ring.next_to_use;
context_desc = IXGB_CONTEXT_DESC(adapter->tx_ring, i);
struct ixgb_buffer *buffer_info;
int len = skb->len;
unsigned int offset = 0, size, count = 0, i;
+ unsigned int mss = skb_shinfo(skb)->gso_size;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
while(len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);
+ /* Workaround for premature desc write-backs
+ * in TSO mode. Append 4-byte sentinel desc */
+ if (unlikely(mss && !nr_frags && size == len && size > 8))
+ size -= 4;
+
buffer_info->length = size;
WARN_ON(buffer_info->dma != 0);
buffer_info->dma =
while(len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);
+
+ /* Workaround for premature desc write-backs
+ * in TSO mode. Append 4-byte sentinel desc */
+ if (unlikely(mss && !nr_frags && size == len
+ && size > 8))
+ size -= 4;
+
buffer_info->length = size;
buffer_info->dma =
pci_map_page(adapter->pdev,
IXGB_WRITE_REG(&adapter->hw, TDT, i);
}
+static int __ixgb_maybe_stop_tx(struct net_device *netdev, int size)
+{
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
+ struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
+
+ netif_stop_queue(netdev);
+ /* Herbert's original patch had:
+ * smp_mb__after_netif_stop_queue();
+ * but since that doesn't exist yet, just open code it. */
+ smp_mb();
+
+ /* We need to check again in a case another CPU has just
+ * made room available. */
+ if (likely(IXGB_DESC_UNUSED(tx_ring) < size))
+ return -EBUSY;
+
+ /* A reprieve! */
+ netif_start_queue(netdev);
+ ++adapter->restart_queue;
+ return 0;
+}
+
+static int ixgb_maybe_stop_tx(struct net_device *netdev,
+ struct ixgb_desc_ring *tx_ring, int size)
+{
+ if (likely(IXGB_DESC_UNUSED(tx_ring) >= size))
+ return 0;
+ return __ixgb_maybe_stop_tx(netdev, size);
+}
+
+
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) (((S) >> IXGB_MAX_TXD_PWR) + \
(((S) & (IXGB_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
-#define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) + \
- MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
+#define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) /* skb->date */ + \
+ MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1 /* for context */ \
+ + 1 /* one more needed for sentinel TSO workaround */
static int
ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
spin_lock_irqsave(&adapter->tx_lock, flags);
#endif
- if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
+ if (unlikely(ixgb_maybe_stop_tx(netdev, &adapter->tx_ring,
+ DESC_NEEDED))) {
netif_stop_queue(netdev);
spin_unlock_irqrestore(&adapter->tx_lock, flags);
return NETDEV_TX_BUSY;
#ifdef NETIF_F_LLTX
/* Make sure there is space in the ring for the next send. */
- if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED))
- netif_stop_queue(netdev);
+ ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
spin_unlock_irqrestore(&adapter->tx_lock, flags);
}
static void
-ixgb_tx_timeout_task(struct net_device *netdev)
+ixgb_tx_timeout_task(struct work_struct *work)
{
- struct ixgb_adapter *adapter = netdev_priv(netdev);
+ struct ixgb_adapter *adapter =
+ container_of(work, struct ixgb_adapter, tx_timeout_task);
adapter->tx_timeout_count++;
ixgb_down(adapter, TRUE);
struct pci_dev *pdev = adapter->pdev;
/* Prevent stats update while adapter is being reset */
- if (pdev->error_state && pdev->error_state != pci_channel_io_normal)
+ if (pci_channel_offline(pdev))
return;
if((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) ||
* ixgb_intr - Interrupt Handler
* @irq: interrupt number
* @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
**/
static irqreturn_t
-ixgb_intr(int irq, void *data, struct pt_regs *regs)
+ixgb_intr(int irq, void *data)
{
struct net_device *netdev = data;
struct ixgb_adapter *adapter = netdev_priv(netdev);
ixgb_irq_disable(adapter);
- if(adapter->vlgrp)
- adapter->vlgrp->vlan_devices[vid] = NULL;
+ vlan_group_set_device(adapter->vlgrp, vid, NULL);
ixgb_irq_enable(adapter);
if(adapter->vlgrp) {
uint16_t vid;
for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
- if(!adapter->vlgrp->vlan_devices[vid])
+ if(!vlan_group_get_device(adapter->vlgrp, vid))
continue;
ixgb_vlan_rx_add_vid(adapter->netdev, vid);
}
struct ixgb_adapter *adapter = netdev_priv(dev);
disable_irq(adapter->pdev->irq);
- ixgb_intr(adapter->pdev->irq, dev, NULL);
+ ixgb_intr(adapter->pdev->irq, dev);
enable_irq(adapter->pdev->irq);
}
#endif
enum pci_channel_state state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgb_adapter *adapter = netdev->priv;
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
if(netif_running(netdev))
ixgb_down(adapter, TRUE);
static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgb_adapter *adapter = netdev->priv;
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
if(pci_enable_device(pdev)) {
DPRINTK(PROBE, ERR, "Cannot re-enable PCI device after reset.\n");
static void ixgb_io_resume (struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
- struct ixgb_adapter *adapter = netdev->priv;
+ struct ixgb_adapter *adapter = netdev_priv(netdev);
pci_set_master(pdev);