summaryrefslogtreecommitdiff
path: root/drivers/net/qlge/qlge_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/qlge/qlge_main.c')
-rw-r--r--drivers/net/qlge/qlge_main.c79
1 files changed, 56 insertions, 23 deletions
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index d10bcefc0e45..2e0ca39713fa 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -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");
@@ -2206,10 +2222,11 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
ql_update_cq(rx_ring);
prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
}
+ if (!net_rsp)
+ return 0;
ql_write_cq_idx(rx_ring);
tx_ring = &qdev->tx_ring[net_rsp->txq_idx];
- if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id) &&
- net_rsp != NULL) {
+ if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id)) {
if (atomic_read(&tx_ring->queue_stopped) &&
(atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4)))
/*
@@ -3587,10 +3604,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);
@@ -3862,11 +3889,8 @@ int ql_wol(struct ql_adapter *qdev)
return status;
}
-static int ql_adapter_down(struct ql_adapter *qdev)
+static void ql_cancel_all_work_sync(struct ql_adapter *qdev)
{
- int i, status = 0;
-
- ql_link_off(qdev);
/* Don't kill the reset worker thread if we
* are in the process of recovery.
@@ -3878,6 +3902,15 @@ static int ql_adapter_down(struct ql_adapter *qdev)
cancel_delayed_work_sync(&qdev->mpi_idc_work);
cancel_delayed_work_sync(&qdev->mpi_core_to_log);
cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+}
+
+static int ql_adapter_down(struct ql_adapter *qdev)
+{
+ int i, status = 0;
+
+ ql_link_off(qdev);
+
+ ql_cancel_all_work_sync(qdev);
for (i = 0; i < qdev->rss_ring_count; i++)
napi_disable(&qdev->rx_ring[i].napi);
@@ -3893,12 +3926,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 +3952,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 +4242,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;
@@ -4695,6 +4733,7 @@ static void __devexit qlge_remove(struct pci_dev *pdev)
struct net_device *ndev = pci_get_drvdata(pdev);
struct ql_adapter *qdev = netdev_priv(ndev);
del_timer_sync(&qdev->timer);
+ ql_cancel_all_work_sync(qdev);
unregister_netdev(ndev);
ql_release_all(pdev);
pci_disable_device(pdev);
@@ -4714,13 +4753,7 @@ static void ql_eeh_close(struct net_device *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);
- cancel_delayed_work_sync(&qdev->mpi_work);
- cancel_delayed_work_sync(&qdev->mpi_idc_work);
- cancel_delayed_work_sync(&qdev->mpi_core_to_log);
- cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+ ql_cancel_all_work_sync(qdev);
for (i = 0; i < qdev->rss_ring_count; i++)
netif_napi_del(&qdev->rx_ring[i].napi);