diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-13 17:38:31 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-13 17:38:31 -0500 |
commit | 122ce878dc189860a380539bde19498bf93443a7 (patch) | |
tree | 8414acd7b686ad4af6b16d0952823f07a12f2522 /drivers/infiniband | |
parent | daf9fe2ee9a203c4fc555cfe5c5f3d9f660e743c (diff) | |
parent | 0636b33c5f2fac4e274464ae6867805f080fc433 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
RDMA/nes: Fix CX4 link problem in back-to-back configuration
RDMA/nes: Clear stall bit before destroying NIC QP
RDMA/nes: Set assume_aligned_header bit
RDMA/cxgb3: Wait at least one schedule cycle during device removal
IB/mad: Ignore iWARP devices on device removal
IPoIB: Include return code in trace message for ib_post_send() failures
IPoIB: Fix TX queue lockup with mixed UD/CM traffic
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/mad.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_nic.c | 30 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_cm.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 9 |
8 files changed, 55 insertions, 9 deletions
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 58463da814d1..e351b1548535 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -2953,6 +2953,9 @@ static void ib_mad_remove_device(struct ib_device *device) | |||
2953 | { | 2953 | { |
2954 | int i, num_ports, cur_port; | 2954 | int i, num_ports, cur_port; |
2955 | 2955 | ||
2956 | if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB) | ||
2957 | return; | ||
2958 | |||
2956 | if (device->node_type == RDMA_NODE_IB_SWITCH) { | 2959 | if (device->node_type == RDMA_NODE_IB_SWITCH) { |
2957 | num_ports = 1; | 2960 | num_ports = 1; |
2958 | cur_port = 0; | 2961 | cur_port = 0; |
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c index ee1d8b4d4541..63f975f3e30f 100644 --- a/drivers/infiniband/hw/cxgb3/iwch.c +++ b/drivers/infiniband/hw/cxgb3/iwch.c | |||
@@ -189,6 +189,7 @@ static void close_rnic_dev(struct t3cdev *tdev) | |||
189 | list_for_each_entry_safe(dev, tmp, &dev_list, entry) { | 189 | list_for_each_entry_safe(dev, tmp, &dev_list, entry) { |
190 | if (dev->rdev.t3cdev_p == tdev) { | 190 | if (dev->rdev.t3cdev_p == tdev) { |
191 | dev->rdev.flags = CXIO_ERROR_FATAL; | 191 | dev->rdev.flags = CXIO_ERROR_FATAL; |
192 | synchronize_net(); | ||
192 | cancel_delayed_work_sync(&dev->db_drop_task); | 193 | cancel_delayed_work_sync(&dev->db_drop_task); |
193 | list_del(&dev->entry); | 194 | list_del(&dev->entry); |
194 | iwch_unregister_device(dev); | 195 | iwch_unregister_device(dev); |
@@ -217,6 +218,7 @@ static void iwch_event_handler(struct t3cdev *tdev, u32 evt, u32 port_id) | |||
217 | switch (evt) { | 218 | switch (evt) { |
218 | case OFFLOAD_STATUS_DOWN: { | 219 | case OFFLOAD_STATUS_DOWN: { |
219 | rdev->flags = CXIO_ERROR_FATAL; | 220 | rdev->flags = CXIO_ERROR_FATAL; |
221 | synchronize_net(); | ||
220 | event.event = IB_EVENT_DEVICE_FATAL; | 222 | event.event = IB_EVENT_DEVICE_FATAL; |
221 | dispatch = 1; | 223 | dispatch = 1; |
222 | break; | 224 | break; |
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index ce7f53833577..925075557dc2 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -1899,9 +1899,14 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | |||
1899 | u16 wqe_fragment_index; | 1899 | u16 wqe_fragment_index; |
1900 | u64 wqe_frag; | 1900 | u64 wqe_frag; |
1901 | u32 cqp_head; | 1901 | u32 cqp_head; |
1902 | u32 wqm_cfg0; | ||
1902 | unsigned long flags; | 1903 | unsigned long flags; |
1903 | int ret; | 1904 | int ret; |
1904 | 1905 | ||
1906 | /* clear wqe stall before destroying NIC QP */ | ||
1907 | wqm_cfg0 = nes_read_indexed(nesdev, NES_IDX_WQM_CONFIG0); | ||
1908 | nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0 & 0xFFFF7FFF); | ||
1909 | |||
1905 | /* Free remaining NIC receive buffers */ | 1910 | /* Free remaining NIC receive buffers */ |
1906 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { | 1911 | while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { |
1907 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; | 1912 | nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; |
@@ -2020,6 +2025,9 @@ void nes_destroy_nic_qp(struct nes_vnic *nesvnic) | |||
2020 | 2025 | ||
2021 | pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase, | 2026 | pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase, |
2022 | nesvnic->nic_pbase); | 2027 | nesvnic->nic_pbase); |
2028 | |||
2029 | /* restore old wqm_cfg0 value */ | ||
2030 | nes_write_indexed(nesdev, NES_IDX_WQM_CONFIG0, wqm_cfg0); | ||
2023 | } | 2031 | } |
2024 | 2032 | ||
2025 | /** | 2033 | /** |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 9b1e7f869d83..bbbfe9fc5a5a 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -160,6 +160,7 @@ enum indexed_regs { | |||
160 | NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004, | 160 | NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004, |
161 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008, | 161 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008, |
162 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c, | 162 | NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c, |
163 | NES_IDX_WQM_CONFIG0 = 0x5000, | ||
163 | NES_IDX_WQM_CONFIG1 = 0x5004, | 164 | NES_IDX_WQM_CONFIG1 = 0x5004, |
164 | NES_IDX_CM_CONFIG = 0x5100, | 165 | NES_IDX_CM_CONFIG = 0x5100, |
165 | NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000, | 166 | NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000, |
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index a1d79b6856ac..91fdde382e82 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -1595,7 +1595,6 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1595 | struct nes_vnic *nesvnic; | 1595 | struct nes_vnic *nesvnic; |
1596 | struct net_device *netdev; | 1596 | struct net_device *netdev; |
1597 | struct nic_qp_map *curr_qp_map; | 1597 | struct nic_qp_map *curr_qp_map; |
1598 | u32 u32temp; | ||
1599 | u8 phy_type = nesdev->nesadapter->phy_type[nesdev->mac_index]; | 1598 | u8 phy_type = nesdev->nesadapter->phy_type[nesdev->mac_index]; |
1600 | 1599 | ||
1601 | netdev = alloc_etherdev(sizeof(struct nes_vnic)); | 1600 | netdev = alloc_etherdev(sizeof(struct nes_vnic)); |
@@ -1707,6 +1706,10 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1707 | ((phy_type == NES_PHY_TYPE_PUMA_1G) && | 1706 | ((phy_type == NES_PHY_TYPE_PUMA_1G) && |
1708 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || | 1707 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || |
1709 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { | 1708 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { |
1709 | u32 u32temp; | ||
1710 | u32 link_mask; | ||
1711 | u32 link_val; | ||
1712 | |||
1710 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1713 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1711 | (0x200 * (nesdev->mac_index & 1))); | 1714 | (0x200 * (nesdev->mac_index & 1))); |
1712 | if (phy_type != NES_PHY_TYPE_PUMA_1G) { | 1715 | if (phy_type != NES_PHY_TYPE_PUMA_1G) { |
@@ -1715,13 +1718,36 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1715 | (0x200 * (nesdev->mac_index & 1)), u32temp); | 1718 | (0x200 * (nesdev->mac_index & 1)), u32temp); |
1716 | } | 1719 | } |
1717 | 1720 | ||
1721 | /* Check and set linkup here. This is for back to back */ | ||
1722 | /* configuration where second port won't get link interrupt */ | ||
1723 | switch (phy_type) { | ||
1724 | case NES_PHY_TYPE_PUMA_1G: | ||
1725 | if (nesdev->mac_index < 2) { | ||
1726 | link_mask = 0x01010000; | ||
1727 | link_val = 0x01010000; | ||
1728 | } else { | ||
1729 | link_mask = 0x02020000; | ||
1730 | link_val = 0x02020000; | ||
1731 | } | ||
1732 | break; | ||
1733 | default: | ||
1734 | link_mask = 0x0f1f0000; | ||
1735 | link_val = 0x0f0f0000; | ||
1736 | break; | ||
1737 | } | ||
1738 | |||
1739 | u32temp = nes_read_indexed(nesdev, | ||
1740 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + | ||
1741 | (0x200 * (nesdev->mac_index & 1))); | ||
1742 | if ((u32temp & link_mask) == link_val) | ||
1743 | nesvnic->linkup = 1; | ||
1744 | |||
1718 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ | 1745 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ |
1719 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); | 1746 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); |
1720 | nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); | 1747 | nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); |
1721 | nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp); | 1748 | nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp); |
1722 | 1749 | ||
1723 | nes_init_phy(nesdev); | 1750 | nes_init_phy(nesdev); |
1724 | |||
1725 | } | 1751 | } |
1726 | 1752 | ||
1727 | return netdev; | 1753 | return netdev; |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 815725f886c4..69928296d74b 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -1323,6 +1323,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
1323 | nesqp->nesqp_context->aeq_token_low = cpu_to_le32((u32)((unsigned long)(nesqp))); | 1323 | nesqp->nesqp_context->aeq_token_low = cpu_to_le32((u32)((unsigned long)(nesqp))); |
1324 | nesqp->nesqp_context->aeq_token_high = cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp)))); | 1324 | nesqp->nesqp_context->aeq_token_high = cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp)))); |
1325 | nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM | | 1325 | nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM | |
1326 | NES_QPCONTEXT_ORDIRD_AAH | | ||
1326 | ((((u32)nesadapter->max_irrq_wr) << | 1327 | ((((u32)nesadapter->max_irrq_wr) << |
1327 | NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK)); | 1328 | NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK)); |
1328 | if (disable_mpa_crc) { | 1329 | if (disable_mpa_crc) { |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 83a7751c38d6..bc658373ad55 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -708,6 +708,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
708 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 708 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
709 | struct ipoib_cm_tx_buf *tx_req; | 709 | struct ipoib_cm_tx_buf *tx_req; |
710 | u64 addr; | 710 | u64 addr; |
711 | int rc; | ||
711 | 712 | ||
712 | if (unlikely(skb->len > tx->mtu)) { | 713 | if (unlikely(skb->len > tx->mtu)) { |
713 | ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", | 714 | ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", |
@@ -739,9 +740,10 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
739 | 740 | ||
740 | tx_req->mapping = addr; | 741 | tx_req->mapping = addr; |
741 | 742 | ||
742 | if (unlikely(post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), | 743 | rc = post_send(priv, tx, tx->tx_head & (ipoib_sendq_size - 1), |
743 | addr, skb->len))) { | 744 | addr, skb->len); |
744 | ipoib_warn(priv, "post_send failed\n"); | 745 | if (unlikely(rc)) { |
746 | ipoib_warn(priv, "post_send failed, error %d\n", rc); | ||
745 | ++dev->stats.tx_errors; | 747 | ++dev->stats.tx_errors; |
746 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); | 748 | ib_dma_unmap_single(priv->ca, addr, skb->len, DMA_TO_DEVICE); |
747 | dev_kfree_skb_any(skb); | 749 | dev_kfree_skb_any(skb); |
@@ -752,6 +754,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ | |||
752 | if (++priv->tx_outstanding == ipoib_sendq_size) { | 754 | if (++priv->tx_outstanding == ipoib_sendq_size) { |
753 | ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", | 755 | ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", |
754 | tx->qp->qp_num); | 756 | tx->qp->qp_num); |
757 | if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP)) | ||
758 | ipoib_warn(priv, "request notify on send CQ failed\n"); | ||
755 | netif_stop_queue(dev); | 759 | netif_stop_queue(dev); |
756 | } | 760 | } |
757 | } | 761 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 8c91d9f37ada..5df40b128f81 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -529,7 +529,7 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
529 | { | 529 | { |
530 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 530 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
531 | struct ipoib_tx_buf *tx_req; | 531 | struct ipoib_tx_buf *tx_req; |
532 | int hlen; | 532 | int hlen, rc; |
533 | void *phead; | 533 | void *phead; |
534 | 534 | ||
535 | if (skb_is_gso(skb)) { | 535 | if (skb_is_gso(skb)) { |
@@ -585,9 +585,10 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb, | |||
585 | netif_stop_queue(dev); | 585 | netif_stop_queue(dev); |
586 | } | 586 | } |
587 | 587 | ||
588 | if (unlikely(post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), | 588 | rc = post_send(priv, priv->tx_head & (ipoib_sendq_size - 1), |
589 | address->ah, qpn, tx_req, phead, hlen))) { | 589 | address->ah, qpn, tx_req, phead, hlen); |
590 | ipoib_warn(priv, "post_send failed\n"); | 590 | if (unlikely(rc)) { |
591 | ipoib_warn(priv, "post_send failed, error %d\n", rc); | ||
591 | ++dev->stats.tx_errors; | 592 | ++dev->stats.tx_errors; |
592 | --priv->tx_outstanding; | 593 | --priv->tx_outstanding; |
593 | ipoib_dma_unmap_tx(priv->ca, tx_req); | 594 | ipoib_dma_unmap_tx(priv->ca, tx_req); |