Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[pandora-kernel.git] / drivers / net / s2io.c
index 685030b..9dae40c 100644 (file)
@@ -86,7 +86,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.24"
+#define DRV_VERSION "2.0.26.25"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -545,63 +545,53 @@ static struct pci_driver s2io_driver = {
 /* netqueue manipulation helper functions */
 static inline void s2io_stop_all_tx_queue(struct s2io_nic *sp)
 {
-       int i;
-       if (sp->config.multiq) {
-               for (i = 0; i < sp->config.tx_fifo_num; i++)
-                       netif_stop_subqueue(sp->dev, i);
-       } else {
+       if (!sp->config.multiq) {
+               int i;
+
                for (i = 0; i < sp->config.tx_fifo_num; i++)
                        sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_STOP;
-               netif_stop_queue(sp->dev);
        }
+       netif_tx_stop_all_queues(sp->dev);
 }
 
 static inline void s2io_stop_tx_queue(struct s2io_nic *sp, int fifo_no)
 {
-       if (sp->config.multiq)
-               netif_stop_subqueue(sp->dev, fifo_no);
-       else {
+       if (!sp->config.multiq)
                sp->mac_control.fifos[fifo_no].queue_state =
                        FIFO_QUEUE_STOP;
-               netif_stop_queue(sp->dev);
-       }
+
+       netif_tx_stop_all_queues(sp->dev);
 }
 
 static inline void s2io_start_all_tx_queue(struct s2io_nic *sp)
 {
-       int i;
-       if (sp->config.multiq) {
-               for (i = 0; i < sp->config.tx_fifo_num; i++)
-                       netif_start_subqueue(sp->dev, i);
-       } else {
+       if (!sp->config.multiq) {
+               int i;
+
                for (i = 0; i < sp->config.tx_fifo_num; i++)
                        sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
-               netif_start_queue(sp->dev);
        }
+       netif_tx_start_all_queues(sp->dev);
 }
 
 static inline void s2io_start_tx_queue(struct s2io_nic *sp, int fifo_no)
 {
-       if (sp->config.multiq)
-               netif_start_subqueue(sp->dev, fifo_no);
-       else {
+       if (!sp->config.multiq)
                sp->mac_control.fifos[fifo_no].queue_state =
                        FIFO_QUEUE_START;
-               netif_start_queue(sp->dev);
-       }
+
+       netif_tx_start_all_queues(sp->dev);
 }
 
 static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp)
 {
-       int i;
-       if (sp->config.multiq) {
-               for (i = 0; i < sp->config.tx_fifo_num; i++)
-                       netif_wake_subqueue(sp->dev, i);
-       } else {
+       if (!sp->config.multiq) {
+               int i;
+
                for (i = 0; i < sp->config.tx_fifo_num; i++)
                        sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
-               netif_wake_queue(sp->dev);
        }
+       netif_tx_wake_all_queues(sp->dev);
 }
 
 static inline void s2io_wake_tx_queue(
@@ -1891,8 +1881,6 @@ static int init_nic(struct s2io_nic *nic)
 
 static int s2io_link_fault_indication(struct s2io_nic *nic)
 {
-       if (nic->config.intr_type != INTA)
-               return MAC_RMAC_ERR_TIMER;
        if (nic->device_type == XFRAME_II_DEVICE)
                return LINK_UP_DOWN_INTERRUPT;
        else
@@ -1925,7 +1913,9 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
 {
        struct XENA_dev_config __iomem *bar0 = nic->bar0;
        register u64 gen_int_mask = 0;
+       u64 interruptible;
 
+       writeq(DISABLE_ALL_INTRS, &bar0->general_int_mask);
        if (mask & TX_DMA_INTR) {
 
                gen_int_mask |= TXDMA_INT_M;
@@ -2015,10 +2005,12 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
                gen_int_mask |= RXMAC_INT_M;
                do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag,
                                &bar0->mac_int_mask);
-               do_s2io_write_bits(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
+               interruptible = RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
                                RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR |
-                               RMAC_DOUBLE_ECC_ERR |
-                               RMAC_LINK_STATE_CHANGE_INT,
+                               RMAC_DOUBLE_ECC_ERR;
+               if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER)
+                       interruptible |= RMAC_LINK_STATE_CHANGE_INT;
+               do_s2io_write_bits(interruptible,
                                flag, &bar0->mac_rmac_err_mask);
        }
 
@@ -4376,18 +4368,24 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
                /* Nothing much can be done. Get out */
                return IRQ_HANDLED;
 
-       writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
+       if (reason & (GEN_INTR_TXPIC | GEN_INTR_TXTRAFFIC)) {
+               writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
 
-       if (reason & GEN_INTR_TXTRAFFIC)
-               writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
+               if (reason & GEN_INTR_TXPIC)
+                       s2io_txpic_intr_handle(sp);
 
-       for (i = 0; i < config->tx_fifo_num; i++)
-               tx_intr_handler(&fifos[i]);
+               if (reason & GEN_INTR_TXTRAFFIC)
+                       writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
 
-       writeq(sp->general_int_mask, &bar0->general_int_mask);
-       readl(&bar0->general_int_status);
+               for (i = 0; i < config->tx_fifo_num; i++)
+                       tx_intr_handler(&fifos[i]);
 
-       return IRQ_HANDLED;
+               writeq(sp->general_int_mask, &bar0->general_int_mask);
+               readl(&bar0->general_int_status);
+               return IRQ_HANDLED;
+       }
+       /* The interrupt was not raised by us */
+       return IRQ_NONE;
 }
 
 static void s2io_txpic_intr_handle(struct s2io_nic *sp)
@@ -7115,6 +7113,9 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 
        s2io_rem_isr(sp);
 
+       /* stop the tx queue, indicate link down */
+       s2io_link(sp, LINK_DOWN);
+
        /* Check if the device is Quiescent and then Reset the NIC */
        while(do_io) {
                /* As per the HW requirement we need to replenish the
@@ -7247,17 +7248,19 @@ static int s2io_card_up(struct s2io_nic * sp)
 
        S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2));
 
+       set_bit(__S2IO_STATE_CARD_UP, &sp->state);
+
        /*  Enable select interrupts */
        en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
-       if (sp->config.intr_type != INTA)
-               en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS);
-       else {
+       if (sp->config.intr_type != INTA) {
+               interruptible = TX_TRAFFIC_INTR | TX_PIC_INTR;
+               en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
+       } else {
                interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
                interruptible |= TX_PIC_INTR;
                en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
        }
 
-       set_bit(__S2IO_STATE_CARD_UP, &sp->state);
        return 0;
 }
 
@@ -7953,8 +7956,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                dev->features |= NETIF_F_UFO;
                dev->features |= NETIF_F_HW_CSUM;
        }
-       if (config->multiq)
-               dev->features |= NETIF_F_MULTI_QUEUE;
        dev->tx_timeout = &s2io_tx_watchdog;
        dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
        INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
@@ -8680,5 +8681,5 @@ static void s2io_io_resume(struct pci_dev *pdev)
        }
 
        netif_device_attach(netdev);
-       netif_wake_queue(netdev);
+       netif_tx_wake_all_queues(netdev);
 }