aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-03-13 16:25:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-03-13 16:25:32 -0400
commitdba92d3bc49c036056a48661d2d8fefe4c78375a (patch)
treee8ef6b2f0f62477dab50fe7d0435c76460c20f49 /drivers
parentb1881fb148a67a5b694ac9701672ce6b359abfa4 (diff)
parent10313cbb92206450b450e14f2b3f6ccde42d9a34 (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: IPoIB: Allocate priv->tx_ring with vmalloc() IPoIB/cm: Set tx_wr.num_sge in connected mode post_send() IPoIB: Don't drop multicast sends when they can be queued IB/ipath: Reset the retry counter for RDMA_READ_RESPONSE_MIDDLE packets IB/ipath: Fix error completion put on send CQ instead of recv CQ IB/ipath: Fix RC QP initialization IB/ipath: Fix potentially wrong RNR retry counter returned in ipath_query_qp() IB/ipath: Fix IB compliance problems with link state vs physical state
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/ipath/ipath_common.h2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c28
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mad.c7
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c13
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_registers.h2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c9
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c9
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c2
10 files changed, 41 insertions, 36 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h
index 414621095540..591901aab6b7 100644
--- a/drivers/infiniband/hw/ipath/ipath_common.h
+++ b/drivers/infiniband/hw/ipath/ipath_common.h
@@ -75,7 +75,7 @@
75#define IPATH_IB_LINKDOWN 0 75#define IPATH_IB_LINKDOWN 0
76#define IPATH_IB_LINKARM 1 76#define IPATH_IB_LINKARM 1
77#define IPATH_IB_LINKACTIVE 2 77#define IPATH_IB_LINKACTIVE 2
78#define IPATH_IB_LINKINIT 3 78#define IPATH_IB_LINKDOWN_ONLY 3
79#define IPATH_IB_LINKDOWN_SLEEP 4 79#define IPATH_IB_LINKDOWN_SLEEP 4
80#define IPATH_IB_LINKDOWN_DISABLE 5 80#define IPATH_IB_LINKDOWN_DISABLE 5
81#define IPATH_IB_LINK_LOOPBACK 6 /* enable local loopback */ 81#define IPATH_IB_LINK_LOOPBACK 6 /* enable local loopback */
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index d5ff6ca2db30..ca4d0acc6786 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -851,8 +851,7 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first,
851 * -ETIMEDOUT state can have multiple states set, for any of several 851 * -ETIMEDOUT state can have multiple states set, for any of several
852 * transitions. 852 * transitions.
853 */ 853 */
854static int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, 854int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, int msecs)
855 int msecs)
856{ 855{
857 dd->ipath_state_wanted = state; 856 dd->ipath_state_wanted = state;
858 wait_event_interruptible_timeout(ipath_state_wait, 857 wait_event_interruptible_timeout(ipath_state_wait,
@@ -1656,8 +1655,8 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl)
1656static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) 1655static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1657{ 1656{
1658 static const char *what[4] = { 1657 static const char *what[4] = {
1659 [0] = "DOWN", 1658 [0] = "NOP",
1660 [INFINIPATH_IBCC_LINKCMD_INIT] = "INIT", 1659 [INFINIPATH_IBCC_LINKCMD_DOWN] = "DOWN",
1661 [INFINIPATH_IBCC_LINKCMD_ARMED] = "ARMED", 1660 [INFINIPATH_IBCC_LINKCMD_ARMED] = "ARMED",
1662 [INFINIPATH_IBCC_LINKCMD_ACTIVE] = "ACTIVE" 1661 [INFINIPATH_IBCC_LINKCMD_ACTIVE] = "ACTIVE"
1663 }; 1662 };
@@ -1672,9 +1671,9 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which)
1672 (dd, dd->ipath_kregs->kr_ibcstatus) >> 1671 (dd, dd->ipath_kregs->kr_ibcstatus) >>
1673 INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) & 1672 INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) &
1674 INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]); 1673 INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]);
1675 /* flush all queued sends when going to DOWN or INIT, to be sure that 1674 /* flush all queued sends when going to DOWN to be sure that
1676 * they don't block MAD packets */ 1675 * they don't block MAD packets */
1677 if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) 1676 if (linkcmd == INFINIPATH_IBCC_LINKCMD_DOWN)
1678 ipath_cancel_sends(dd, 1); 1677 ipath_cancel_sends(dd, 1);
1679 1678
1680 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, 1679 ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl,
@@ -1687,6 +1686,13 @@ int ipath_set_linkstate(struct ipath_devdata *dd, u8 newstate)
1687 int ret; 1686 int ret;
1688 1687
1689 switch (newstate) { 1688 switch (newstate) {
1689 case IPATH_IB_LINKDOWN_ONLY:
1690 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_DOWN <<
1691 INFINIPATH_IBCC_LINKCMD_SHIFT);
1692 /* don't wait */
1693 ret = 0;
1694 goto bail;
1695
1690 case IPATH_IB_LINKDOWN: 1696 case IPATH_IB_LINKDOWN:
1691 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_POLL << 1697 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_POLL <<
1692 INFINIPATH_IBCC_LINKINITCMD_SHIFT); 1698 INFINIPATH_IBCC_LINKINITCMD_SHIFT);
@@ -1709,16 +1715,6 @@ int ipath_set_linkstate(struct ipath_devdata *dd, u8 newstate)
1709 ret = 0; 1715 ret = 0;
1710 goto bail; 1716 goto bail;
1711 1717
1712 case IPATH_IB_LINKINIT:
1713 if (dd->ipath_flags & IPATH_LINKINIT) {
1714 ret = 0;
1715 goto bail;
1716 }
1717 ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_INIT <<
1718 INFINIPATH_IBCC_LINKCMD_SHIFT);
1719 lstate = IPATH_LINKINIT;
1720 break;
1721
1722 case IPATH_IB_LINKARM: 1718 case IPATH_IB_LINKARM:
1723 if (dd->ipath_flags & IPATH_LINKARMED) { 1719 if (dd->ipath_flags & IPATH_LINKARMED) {
1724 ret = 0; 1720 ret = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 4cc0f95ea877..ecf3f7ff7717 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -767,6 +767,7 @@ void ipath_kreceive(struct ipath_portdata *);
767int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned); 767int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned);
768int ipath_reset_device(int); 768int ipath_reset_device(int);
769void ipath_get_faststats(unsigned long); 769void ipath_get_faststats(unsigned long);
770int ipath_wait_linkstate(struct ipath_devdata *, u32, int);
770int ipath_set_linkstate(struct ipath_devdata *, u8); 771int ipath_set_linkstate(struct ipath_devdata *, u8);
771int ipath_set_mtu(struct ipath_devdata *, u16); 772int ipath_set_mtu(struct ipath_devdata *, u16);
772int ipath_set_lid(struct ipath_devdata *, u32, u8); 773int ipath_set_lid(struct ipath_devdata *, u32, u8);
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c
index d98d5f103700..b34b91d3723a 100644
--- a/drivers/infiniband/hw/ipath/ipath_mad.c
+++ b/drivers/infiniband/hw/ipath/ipath_mad.c
@@ -555,10 +555,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
555 /* FALLTHROUGH */ 555 /* FALLTHROUGH */
556 case IB_PORT_DOWN: 556 case IB_PORT_DOWN:
557 if (lstate == 0) 557 if (lstate == 0)
558 if (get_linkdowndefaultstate(dd)) 558 lstate = IPATH_IB_LINKDOWN_ONLY;
559 lstate = IPATH_IB_LINKDOWN_SLEEP;
560 else
561 lstate = IPATH_IB_LINKDOWN;
562 else if (lstate == 1) 559 else if (lstate == 1)
563 lstate = IPATH_IB_LINKDOWN_SLEEP; 560 lstate = IPATH_IB_LINKDOWN_SLEEP;
564 else if (lstate == 2) 561 else if (lstate == 2)
@@ -568,6 +565,8 @@ static int recv_subn_set_portinfo(struct ib_smp *smp,
568 else 565 else
569 goto err; 566 goto err;
570 ipath_set_linkstate(dd, lstate); 567 ipath_set_linkstate(dd, lstate);
568 ipath_wait_linkstate(dd, IPATH_LINKINIT | IPATH_LINKARMED |
569 IPATH_LINKACTIVE, 1000);
571 break; 570 break;
572 case IB_PORT_ARMED: 571 case IB_PORT_ARMED:
573 ipath_set_linkstate(dd, IPATH_IB_LINKARM); 572 ipath_set_linkstate(dd, IPATH_IB_LINKARM);
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index 80dc623cee40..087ed3166479 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -329,8 +329,9 @@ struct ipath_qp *ipath_lookup_qpn(struct ipath_qp_table *qpt, u32 qpn)
329/** 329/**
330 * ipath_reset_qp - initialize the QP state to the reset state 330 * ipath_reset_qp - initialize the QP state to the reset state
331 * @qp: the QP to reset 331 * @qp: the QP to reset
332 * @type: the QP type
332 */ 333 */
333static void ipath_reset_qp(struct ipath_qp *qp) 334static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type)
334{ 335{
335 qp->remote_qpn = 0; 336 qp->remote_qpn = 0;
336 qp->qkey = 0; 337 qp->qkey = 0;
@@ -342,7 +343,7 @@ static void ipath_reset_qp(struct ipath_qp *qp)
342 qp->s_psn = 0; 343 qp->s_psn = 0;
343 qp->r_psn = 0; 344 qp->r_psn = 0;
344 qp->r_msn = 0; 345 qp->r_msn = 0;
345 if (qp->ibqp.qp_type == IB_QPT_RC) { 346 if (type == IB_QPT_RC) {
346 qp->s_state = IB_OPCODE_RC_SEND_LAST; 347 qp->s_state = IB_OPCODE_RC_SEND_LAST;
347 qp->r_state = IB_OPCODE_RC_SEND_LAST; 348 qp->r_state = IB_OPCODE_RC_SEND_LAST;
348 } else { 349 } else {
@@ -414,7 +415,7 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)
414 wc.wr_id = qp->r_wr_id; 415 wc.wr_id = qp->r_wr_id;
415 wc.opcode = IB_WC_RECV; 416 wc.opcode = IB_WC_RECV;
416 wc.status = err; 417 wc.status = err;
417 ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1); 418 ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
418 } 419 }
419 wc.status = IB_WC_WR_FLUSH_ERR; 420 wc.status = IB_WC_WR_FLUSH_ERR;
420 421
@@ -534,7 +535,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
534 535
535 switch (new_state) { 536 switch (new_state) {
536 case IB_QPS_RESET: 537 case IB_QPS_RESET:
537 ipath_reset_qp(qp); 538 ipath_reset_qp(qp, ibqp->qp_type);
538 break; 539 break;
539 540
540 case IB_QPS_ERR: 541 case IB_QPS_ERR:
@@ -647,7 +648,7 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
647 attr->port_num = 1; 648 attr->port_num = 1;
648 attr->timeout = qp->timeout; 649 attr->timeout = qp->timeout;
649 attr->retry_cnt = qp->s_retry_cnt; 650 attr->retry_cnt = qp->s_retry_cnt;
650 attr->rnr_retry = qp->s_rnr_retry; 651 attr->rnr_retry = qp->s_rnr_retry_cnt;
651 attr->alt_port_num = 0; 652 attr->alt_port_num = 0;
652 attr->alt_timeout = 0; 653 attr->alt_timeout = 0;
653 654
@@ -839,7 +840,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
839 goto bail_qp; 840 goto bail_qp;
840 } 841 }
841 qp->ip = NULL; 842 qp->ip = NULL;
842 ipath_reset_qp(qp); 843 ipath_reset_qp(qp, init_attr->qp_type);
843 break; 844 break;
844 845
845 default: 846 default:
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index 459e46e2c016..40f3e37d7adc 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -1196,6 +1196,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
1196 list_move_tail(&qp->timerwait, 1196 list_move_tail(&qp->timerwait,
1197 &dev->pending[dev->pending_index]); 1197 &dev->pending[dev->pending_index]);
1198 spin_unlock(&dev->pending_lock); 1198 spin_unlock(&dev->pending_lock);
1199
1200 if (opcode == OP(RDMA_READ_RESPONSE_MIDDLE))
1201 qp->s_retry = qp->s_retry_cnt;
1202
1199 /* 1203 /*
1200 * Update the RDMA receive state but do the copy w/o 1204 * Update the RDMA receive state but do the copy w/o
1201 * holding the locks and blocking interrupts. 1205 * holding the locks and blocking interrupts.
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h
index 6d2a17f9c1da..92ad73a7fff0 100644
--- a/drivers/infiniband/hw/ipath/ipath_registers.h
+++ b/drivers/infiniband/hw/ipath/ipath_registers.h
@@ -185,7 +185,7 @@
185#define INFINIPATH_IBCC_LINKINITCMD_SLEEP 3 185#define INFINIPATH_IBCC_LINKINITCMD_SLEEP 3
186#define INFINIPATH_IBCC_LINKINITCMD_SHIFT 16 186#define INFINIPATH_IBCC_LINKINITCMD_SHIFT 16
187#define INFINIPATH_IBCC_LINKCMD_MASK 0x3ULL 187#define INFINIPATH_IBCC_LINKCMD_MASK 0x3ULL
188#define INFINIPATH_IBCC_LINKCMD_INIT 1 /* move to 0x11 */ 188#define INFINIPATH_IBCC_LINKCMD_DOWN 1 /* move to 0x11 */
189#define INFINIPATH_IBCC_LINKCMD_ARMED 2 /* move to 0x21 */ 189#define INFINIPATH_IBCC_LINKCMD_ARMED 2 /* move to 0x21 */
190#define INFINIPATH_IBCC_LINKCMD_ACTIVE 3 /* move to 0x31 */ 190#define INFINIPATH_IBCC_LINKCMD_ACTIVE 3 /* move to 0x31 */
191#define INFINIPATH_IBCC_LINKCMD_SHIFT 18 191#define INFINIPATH_IBCC_LINKCMD_SHIFT 18
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 52b1bebfa744..2490b2d79dbb 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -38,6 +38,7 @@
38#include <net/icmp.h> 38#include <net/icmp.h>
39#include <linux/icmpv6.h> 39#include <linux/icmpv6.h>
40#include <linux/delay.h> 40#include <linux/delay.h>
41#include <linux/vmalloc.h>
41 42
42#include "ipoib.h" 43#include "ipoib.h"
43 44
@@ -637,6 +638,7 @@ static inline int post_send(struct ipoib_dev_priv *priv,
637 priv->tx_sge[0].addr = addr; 638 priv->tx_sge[0].addr = addr;
638 priv->tx_sge[0].length = len; 639 priv->tx_sge[0].length = len;
639 640
641 priv->tx_wr.num_sge = 1;
640 priv->tx_wr.wr_id = wr_id | IPOIB_OP_CM; 642 priv->tx_wr.wr_id = wr_id | IPOIB_OP_CM;
641 643
642 return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr); 644 return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr);
@@ -1030,13 +1032,13 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
1030 struct ipoib_dev_priv *priv = netdev_priv(p->dev); 1032 struct ipoib_dev_priv *priv = netdev_priv(p->dev);
1031 int ret; 1033 int ret;
1032 1034
1033 p->tx_ring = kzalloc(ipoib_sendq_size * sizeof *p->tx_ring, 1035 p->tx_ring = vmalloc(ipoib_sendq_size * sizeof *p->tx_ring);
1034 GFP_KERNEL);
1035 if (!p->tx_ring) { 1036 if (!p->tx_ring) {
1036 ipoib_warn(priv, "failed to allocate tx ring\n"); 1037 ipoib_warn(priv, "failed to allocate tx ring\n");
1037 ret = -ENOMEM; 1038 ret = -ENOMEM;
1038 goto err_tx; 1039 goto err_tx;
1039 } 1040 }
1041 memset(p->tx_ring, 0, ipoib_sendq_size * sizeof *p->tx_ring);
1040 1042
1041 p->qp = ipoib_cm_create_tx_qp(p->dev, p); 1043 p->qp = ipoib_cm_create_tx_qp(p->dev, p);
1042 if (IS_ERR(p->qp)) { 1044 if (IS_ERR(p->qp)) {
@@ -1077,6 +1079,7 @@ err_id:
1077 ib_destroy_qp(p->qp); 1079 ib_destroy_qp(p->qp);
1078err_qp: 1080err_qp:
1079 p->qp = NULL; 1081 p->qp = NULL;
1082 vfree(p->tx_ring);
1080err_tx: 1083err_tx:
1081 return ret; 1084 return ret;
1082} 1085}
@@ -1127,7 +1130,7 @@ timeout:
1127 if (p->qp) 1130 if (p->qp)
1128 ib_destroy_qp(p->qp); 1131 ib_destroy_qp(p->qp);
1129 1132
1130 kfree(p->tx_ring); 1133 vfree(p->tx_ring);
1131 kfree(p); 1134 kfree(p);
1132} 1135}
1133 1136
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index f96477a8ca5a..57282048865c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -41,6 +41,7 @@
41#include <linux/init.h> 41#include <linux/init.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/kernel.h> 43#include <linux/kernel.h>
44#include <linux/vmalloc.h>
44 45
45#include <linux/if_arp.h> /* For ARPHRD_xxx */ 46#include <linux/if_arp.h> /* For ARPHRD_xxx */
46 47
@@ -887,13 +888,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
887 goto out; 888 goto out;
888 } 889 }
889 890
890 priv->tx_ring = kzalloc(ipoib_sendq_size * sizeof *priv->tx_ring, 891 priv->tx_ring = vmalloc(ipoib_sendq_size * sizeof *priv->tx_ring);
891 GFP_KERNEL);
892 if (!priv->tx_ring) { 892 if (!priv->tx_ring) {
893 printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n", 893 printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n",
894 ca->name, ipoib_sendq_size); 894 ca->name, ipoib_sendq_size);
895 goto out_rx_ring_cleanup; 895 goto out_rx_ring_cleanup;
896 } 896 }
897 memset(priv->tx_ring, 0, ipoib_sendq_size * sizeof *priv->tx_ring);
897 898
898 /* priv->tx_head, tx_tail & tx_outstanding are already 0 */ 899 /* priv->tx_head, tx_tail & tx_outstanding are already 0 */
899 900
@@ -903,7 +904,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
903 return 0; 904 return 0;
904 905
905out_tx_ring_cleanup: 906out_tx_ring_cleanup:
906 kfree(priv->tx_ring); 907 vfree(priv->tx_ring);
907 908
908out_rx_ring_cleanup: 909out_rx_ring_cleanup:
909 kfree(priv->rx_ring); 910 kfree(priv->rx_ring);
@@ -928,7 +929,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
928 ipoib_ib_dev_cleanup(dev); 929 ipoib_ib_dev_cleanup(dev);
929 930
930 kfree(priv->rx_ring); 931 kfree(priv->rx_ring);
931 kfree(priv->tx_ring); 932 vfree(priv->tx_ring);
932 933
933 priv->rx_ring = NULL; 934 priv->rx_ring = NULL;
934 priv->tx_ring = NULL; 935 priv->tx_ring = NULL;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 2628339e3a99..31a53c5bcb13 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -650,7 +650,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
650 */ 650 */
651 spin_lock(&priv->lock); 651 spin_lock(&priv->lock);
652 652
653 if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || 653 if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags) ||
654 !priv->broadcast || 654 !priv->broadcast ||
655 !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { 655 !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
656 ++dev->stats.tx_dropped; 656 ++dev->stats.tx_dropped;