#else
#define DRIVERNAPI "-NAPI"
#endif
-#define DRV_VERSION "1.0.126-k2"DRIVERNAPI
-char ixgb_driver_version[] = DRV_VERSION;
-static char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
+#define DRV_VERSION "1.0.126-k4"DRIVERNAPI
+const char ixgb_driver_version[] = DRV_VERSION;
+static const char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
/* ixgb_pci_tbl - PCI Device ID Table
*
/* Local Function Prototypes */
int ixgb_up(struct ixgb_adapter *adapter);
-void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
+void ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog);
void ixgb_reset(struct ixgb_adapter *adapter);
int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
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);
-static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
+static bool ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
#ifdef CONFIG_IXGB_NAPI
static int ixgb_clean(struct napi_struct *napi, int budget);
-static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter,
- int *work_done, int work_to_do);
+static bool ixgb_clean_rx_irq(struct ixgb_adapter *adapter,
+ int *work_done, int work_to_do);
#else
-static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
+static bool ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
#endif
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 work_struct *work);
static void ixgb_vlan_rx_register(struct net_device *netdev,
static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev);
static void ixgb_io_resume (struct pci_dev *pdev);
-/* Exported from other modules */
-extern void ixgb_check_options(struct ixgb_adapter *adapter);
-
static struct pci_error_handlers ixgb_err_handler = {
.error_detected = ixgb_io_error_detected,
.slot_reset = ixgb_io_slot_reset,
static void
ixgb_irq_disable(struct ixgb_adapter *adapter)
{
- atomic_inc(&adapter->irq_sem);
IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
IXGB_WRITE_FLUSH(&adapter->hw);
synchronize_irq(adapter->pdev->irq);
static void
ixgb_irq_enable(struct ixgb_adapter *adapter)
{
- if(atomic_dec_and_test(&adapter->irq_sem)) {
- IXGB_WRITE_REG(&adapter->hw, IMS,
- IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
- IXGB_INT_LSC);
- IXGB_WRITE_FLUSH(&adapter->hw);
- }
+ u32 val = IXGB_INT_RXT0 | IXGB_INT_RXDMT0 |
+ IXGB_INT_TXDW | IXGB_INT_LSC;
+ if (adapter->hw.subsystem_vendor_id == SUN_SUBVENDOR_ID)
+ val |= IXGB_INT_GPI0;
+ IXGB_WRITE_REG(&adapter->hw, IMS, val);
+ IXGB_WRITE_FLUSH(&adapter->hw);
}
int
}
}
- mod_timer(&adapter->watchdog_timer, jiffies);
+ clear_bit(__IXGB_DOWN, &adapter->flags);
#ifdef CONFIG_IXGB_NAPI
napi_enable(&adapter->napi);
#endif
ixgb_irq_enable(adapter);
+ mod_timer(&adapter->watchdog_timer, jiffies);
+
return 0;
}
void
-ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
+ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog)
{
struct net_device *netdev = adapter->netdev;
+ /* prevent the interrupt handler from restarting watchdog */
+ set_bit(__IXGB_DOWN, &adapter->flags);
+
+#ifdef CONFIG_IXGB_NAPI
+ napi_disable(&adapter->napi);
+#endif
+ /* waiting for NAPI to complete can re-enable interrupts */
ixgb_irq_disable(adapter);
free_irq(adapter->pdev->irq, netdev);
if(kill_watchdog)
del_timer_sync(&adapter->watchdog_timer);
-#ifdef CONFIG_IXGB_NAPI
- napi_disable(&adapter->napi);
-#endif
+
adapter->link_speed = 0;
adapter->link_duplex = 0;
netif_carrier_off(netdev);
void
ixgb_reset(struct ixgb_adapter *adapter)
{
+ struct ixgb_hw *hw = &adapter->hw;
- ixgb_adapter_stop(&adapter->hw);
- if(!ixgb_init_hw(&adapter->hw))
+ ixgb_adapter_stop(hw);
+ if (!ixgb_init_hw(hw))
DPRINTK(PROBE, ERR, "ixgb_init_hw failed.\n");
+
+ /* restore frame size information */
+ IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT);
+ if (hw->max_frame_size >
+ IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
+ u32 ctrl0 = IXGB_READ_REG(hw, CTRL0);
+ if (!(ctrl0 & IXGB_CTRL0_JFE)) {
+ ctrl0 |= IXGB_CTRL0_JFE;
+ IXGB_WRITE_REG(hw, CTRL0, ctrl0);
+ }
+ }
}
/**
/* enable flow control to be programmed */
hw->fc.send_xon = 1;
- atomic_set(&adapter->irq_sem, 1);
spin_lock_init(&adapter->tx_lock);
+ set_bit(__IXGB_DOWN, &adapter->flags);
return 0;
}
{
struct ixgb_adapter *adapter = netdev_priv(netdev);
- ixgb_down(adapter, TRUE);
+ ixgb_down(adapter, true);
ixgb_free_tx_resources(adapter);
ixgb_free_rx_resources(adapter);
IXGB_WRITE_REG(hw, RXDCTL, rxdctl);
/* Enable Receive Checksum Offload for TCP and UDP */
- if(adapter->rx_csum == TRUE) {
+ if (adapter->rx_csum) {
rxcsum = IXGB_READ_REG(hw, RXCSUM);
rxcsum |= IXGB_RXCSUM_TUOFL;
IXGB_WRITE_REG(hw, RXCSUM, rxcsum);
rctl |= IXGB_RCTL_MPE;
IXGB_WRITE_REG(hw, RCTL, rctl);
} else {
- uint8_t mta[netdev->mc_count * IXGB_ETH_LENGTH_OF_ADDRESS];
+ uint8_t mta[IXGB_MAX_NUM_MULTICAST_ADDRESSES *
+ IXGB_ETH_LENGTH_OF_ADDRESS];
IXGB_WRITE_REG(hw, RCTL, rctl);
}
/* Force detection of hung controller every watchdog period */
- adapter->detect_tx_hung = TRUE;
+ adapter->detect_tx_hung = true;
/* generate an interrupt to force clean up of any stragglers */
IXGB_WRITE_REG(&adapter->hw, ICS, IXGB_INT_TXDW);
return 0;
}
-static boolean_t
+static bool
ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb)
{
struct ixgb_context_desc *context_desc;
if(++i == adapter->tx_ring.count) i = 0;
adapter->tx_ring.next_to_use = i;
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
#define IXGB_MAX_TXD_PWR 14
/* Workaround for premature desc write-backs
* in TSO mode. Append 4-byte sentinel desc */
- if (unlikely(mss && !nr_frags && size == len
- && size > 8))
+ if (unlikely(mss && (f == (nr_frags - 1))
+ && size == len && size > 8))
size -= 4;
buffer_info->length = size;
int vlan_id = 0;
int tso;
+ if (test_bit(__IXGB_DOWN, &adapter->flags)) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
if(skb->len <= 0) {
dev_kfree_skb_any(skb);
return 0;
}
#ifdef NETIF_F_LLTX
- local_irq_save(flags);
- if (!spin_trylock(&adapter->tx_lock)) {
+ if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
/* Collision - tell upper layer to requeue */
local_irq_restore(flags);
return NETDEV_TX_LOCKED;
container_of(work, struct ixgb_adapter, tx_timeout_task);
adapter->tx_timeout_count++;
- ixgb_down(adapter, TRUE);
+ ixgb_down(adapter, true);
ixgb_up(adapter);
}
netdev->mtu = new_mtu;
if ((old_max_frame != max_frame) && netif_running(netdev)) {
- ixgb_down(adapter, TRUE);
+ ixgb_down(adapter, true);
ixgb_up(adapter);
}
if(unlikely(!icr))
return IRQ_NONE; /* Not our interrupt */
- if(unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
- mod_timer(&adapter->watchdog_timer, jiffies);
- }
+ if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)))
+ if (!test_bit(__IXGB_DOWN, &adapter->flags))
+ mod_timer(&adapter->watchdog_timer, jiffies);
#ifdef CONFIG_IXGB_NAPI
if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
of the posted write is intentionally left out.
*/
- atomic_inc(&adapter->irq_sem);
IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
__netif_rx_schedule(netdev, &adapter->napi);
}
{
struct ixgb_adapter *adapter = container_of(napi, struct ixgb_adapter, napi);
struct net_device *netdev = adapter->netdev;
- int tx_cleaned;
int work_done = 0;
- tx_cleaned = ixgb_clean_tx_irq(adapter);
+ ixgb_clean_tx_irq(adapter);
ixgb_clean_rx_irq(adapter, &work_done, budget);
- /* if no Tx and not enough Rx work done, exit the polling mode */
- if((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
+ /* If budget not fully consumed, exit the polling mode */
+ if (work_done < budget) {
netif_rx_complete(netdev, napi);
ixgb_irq_enable(adapter);
}
* @adapter: board private structure
**/
-static boolean_t
+static bool
ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
{
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
struct ixgb_tx_desc *tx_desc, *eop_desc;
struct ixgb_buffer *buffer_info;
unsigned int i, eop;
- boolean_t cleaned = FALSE;
+ bool cleaned = false;
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
while(eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
- for(cleaned = FALSE; !cleaned; ) {
+ for (cleaned = false; !cleaned; ) {
tx_desc = IXGB_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
if(adapter->detect_tx_hung) {
/* detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */
- adapter->detect_tx_hung = FALSE;
+ adapter->detect_tx_hung = false;
if (tx_ring->buffer_info[eop].dma &&
time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + HZ)
&& !(IXGB_READ_REG(&adapter->hw, STATUS) &
* @adapter: board private structure
**/
-static boolean_t
+static bool
#ifdef CONFIG_IXGB_NAPI
ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do)
#else
struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer;
uint32_t length;
unsigned int i, j;
- boolean_t cleaned = FALSE;
+ bool cleaned = false;
i = rx_ring->next_to_clean;
rx_desc = IXGB_RX_DESC(*rx_ring, i);
next_skb = next_buffer->skb;
prefetch(next_skb);
- cleaned = TRUE;
+ cleaned = true;
pci_unmap_single(pdev,
buffer_info->dma,
struct ixgb_buffer *buffer_info;
struct sk_buff *skb;
unsigned int i;
- int num_group_tail_writes;
long cleancount;
i = rx_ring->next_to_use;
buffer_info = &rx_ring->buffer_info[i];
cleancount = IXGB_DESC_UNUSED(rx_ring);
- num_group_tail_writes = IXGB_RX_BUFFER_WRITE;
/* leave three descriptors unused */
while(--cleancount > 2) {
IXGB_WRITE_REG(&adapter->hw, RCTL, rctl);
}
- ixgb_irq_enable(adapter);
+ /* don't enable interrupts unless we are UP */
+ if (adapter->netdev->flags & IFF_UP)
+ ixgb_irq_enable(adapter);
}
static void
vlan_group_set_device(adapter->vlgrp, vid, NULL);
- ixgb_irq_enable(adapter);
+ /* don't enable interrupts unless we are UP */
+ if (adapter->netdev->flags & IFF_UP)
+ ixgb_irq_enable(adapter);
- /* remove VID from filter table*/
+ /* remove VID from filter table */
index = (vid >> 5) & 0x7F;
vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index);
struct ixgb_adapter *adapter = netdev_priv(netdev);
if(netif_running(netdev))
- ixgb_down(adapter, TRUE);
+ ixgb_down(adapter, true);
pci_disable_device(pdev);