]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/qlge/qlge_main.c
qlge: reset the chip before freeing the buffers
[net-next-2.6.git] / drivers / net / qlge / qlge_main.c
index fa4b24c49f42875bfad43015a9db6ab089b2add8..5f89e83501f4f5c1892ac15a84681a76ade08c19 100644 (file)
@@ -574,6 +574,22 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
                            (RT_IDX_ALL_ERR_SLOT << RT_IDX_IDX_SHIFT);/* index */
                        break;
                }
+       case RT_IDX_IP_CSUM_ERR: /* Pass up IP CSUM error frames. */
+               {
+                       value = RT_IDX_DST_DFLT_Q | /* dest */
+                               RT_IDX_TYPE_NICQ | /* type */
+                               (RT_IDX_IP_CSUM_ERR_SLOT <<
+                               RT_IDX_IDX_SHIFT); /* index */
+                       break;
+               }
+       case RT_IDX_TU_CSUM_ERR: /* Pass up TCP/UDP CSUM error frames. */
+               {
+                       value = RT_IDX_DST_DFLT_Q | /* dest */
+                               RT_IDX_TYPE_NICQ | /* type */
+                               (RT_IDX_TCP_UDP_CSUM_ERR_SLOT <<
+                               RT_IDX_IDX_SHIFT); /* index */
+                       break;
+               }
        case RT_IDX_BCAST:      /* Pass up Broadcast frames to default Q. */
                {
                        value = RT_IDX_DST_DFLT_Q |     /* dest */
@@ -1521,7 +1537,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
 
        /* Frame error, so drop the packet. */
        if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
-               netif_err(qdev, drv, qdev->ndev,
+               netif_info(qdev, drv, qdev->ndev,
                          "Receive error, flags2 = 0x%x\n", ib_mac_rsp->flags2);
                rx_ring->rx_errors++;
                goto err_out;
@@ -1618,7 +1634,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
 
        /* Frame error, so drop the packet. */
        if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
-               netif_err(qdev, drv, qdev->ndev,
+               netif_info(qdev, drv, qdev->ndev,
                          "Receive error, flags2 = 0x%x\n", ib_mac_rsp->flags2);
                dev_kfree_skb_any(skb);
                rx_ring->rx_errors++;
@@ -1677,7 +1693,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
                        /* Unfragmented ipv4 UDP frame. */
                        struct iphdr *iph = (struct iphdr *) skb->data;
                        if (!(iph->frag_off &
-                               cpu_to_be16(IP_MF|IP_OFFSET))) {
+                               ntohs(IP_MF|IP_OFFSET))) {
                                skb->ip_summed = CHECKSUM_UNNECESSARY;
                                netif_printk(qdev, rx_status, KERN_DEBUG,
                                             qdev->ndev,
@@ -1939,7 +1955,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
 
        /* Frame error, so drop the packet. */
        if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
-               netif_err(qdev, drv, qdev->ndev,
+               netif_info(qdev, drv, qdev->ndev,
                          "Receive error, flags2 = 0x%x\n", ib_mac_rsp->flags2);
                dev_kfree_skb_any(skb);
                rx_ring->rx_errors++;
@@ -1997,7 +2013,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev,
                /* Unfragmented ipv4 UDP frame. */
                        struct iphdr *iph = (struct iphdr *) skb->data;
                        if (!(iph->frag_off &
-                               cpu_to_be16(IP_MF|IP_OFFSET))) {
+                               ntohs(IP_MF|IP_OFFSET))) {
                                skb->ip_summed = CHECKSUM_UNNECESSARY;
                                netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
                                             "TCP checksum done!\n");
@@ -3587,10 +3603,20 @@ static int ql_route_initialize(struct ql_adapter *qdev)
        if (status)
                return status;
 
-       status = ql_set_routing_reg(qdev, RT_IDX_ALL_ERR_SLOT, RT_IDX_ERR, 1);
+       status = ql_set_routing_reg(qdev, RT_IDX_IP_CSUM_ERR_SLOT,
+                                               RT_IDX_IP_CSUM_ERR, 1);
+       if (status) {
+               netif_err(qdev, ifup, qdev->ndev,
+                       "Failed to init routing register "
+                       "for IP CSUM error packets.\n");
+               goto exit;
+       }
+       status = ql_set_routing_reg(qdev, RT_IDX_TCP_UDP_CSUM_ERR_SLOT,
+                                               RT_IDX_TU_CSUM_ERR, 1);
        if (status) {
                netif_err(qdev, ifup, qdev->ndev,
-                         "Failed to init routing register for error packets.\n");
+                       "Failed to init routing register "
+                       "for TCP/UDP CSUM error packets.\n");
                goto exit;
        }
        status = ql_set_routing_reg(qdev, RT_IDX_BCAST_SLOT, RT_IDX_BCAST, 1);
@@ -3893,12 +3919,12 @@ static int ql_adapter_down(struct ql_adapter *qdev)
        for (i = 0; i < qdev->rss_ring_count; i++)
                netif_napi_del(&qdev->rx_ring[i].napi);
 
-       ql_free_rx_buffers(qdev);
-
        status = ql_adapter_reset(qdev);
        if (status)
                netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n",
                          qdev->func);
+       ql_free_rx_buffers(qdev);
+
        return status;
 }
 
@@ -3919,6 +3945,11 @@ static int ql_adapter_up(struct ql_adapter *qdev)
        if ((ql_read32(qdev, STS) & qdev->port_init) &&
                        (ql_read32(qdev, STS) & qdev->port_link_up))
                ql_link_on(qdev);
+       /* Restore rx mode. */
+       clear_bit(QL_ALLMULTI, &qdev->flags);
+       clear_bit(QL_PROMISCUOUS, &qdev->flags);
+       qlge_set_multicast_list(qdev->ndev);
+
        ql_enable_interrupts(qdev);
        ql_enable_all_completion_interrupts(qdev);
        netif_tx_start_all_queues(qdev->ndev);
@@ -4204,7 +4235,7 @@ static struct net_device_stats *qlge_get_stats(struct net_device
        return &ndev->stats;
 }
 
-static void qlge_set_multicast_list(struct net_device *ndev)
+void qlge_set_multicast_list(struct net_device *ndev)
 {
        struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
        struct netdev_hw_addr *ha;
@@ -4611,8 +4642,7 @@ static void ql_timer(unsigned long data)
                return;
        }
 
-       qdev->timer.expires = jiffies + (5*HZ);
-       add_timer(&qdev->timer);
+       mod_timer(&qdev->timer, jiffies + (5*HZ));
 }
 
 static int __devinit qlge_probe(struct pci_dev *pdev,
@@ -4713,6 +4743,8 @@ static void ql_eeh_close(struct net_device *ndev)
                netif_stop_queue(ndev);
        }
 
+       /* Disabling the timer */
+       del_timer_sync(&qdev->timer);
        if (test_bit(QL_ADAPTER_UP, &qdev->flags))
                cancel_delayed_work_sync(&qdev->asic_reset_work);
        cancel_delayed_work_sync(&qdev->mpi_reset_work);
@@ -4808,8 +4840,7 @@ static void qlge_io_resume(struct pci_dev *pdev)
                netif_err(qdev, ifup, qdev->ndev,
                          "Device was not running prior to EEH.\n");
        }
-       qdev->timer.expires = jiffies + (5*HZ);
-       add_timer(&qdev->timer);
+       mod_timer(&qdev->timer, jiffies + (5*HZ));
        netif_device_attach(ndev);
 }
 
@@ -4871,8 +4902,7 @@ static int qlge_resume(struct pci_dev *pdev)
                        return err;
        }
 
-       qdev->timer.expires = jiffies + (5*HZ);
-       add_timer(&qdev->timer);
+       mod_timer(&qdev->timer, jiffies + (5*HZ));
        netif_device_attach(ndev);
 
        return 0;