diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index e029401b5680..f3f3051713ef 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -2061,19 +2061,14 @@ void ib_dispatch_event_clients(struct ib_event *event)
 	up_read(&event->device->event_handler_rwsem);
 }
 
-static int iw_query_port(struct ib_device *device,
-			   u32 port_num,
-			   struct ib_port_attr *port_attr)
+static int iw_query_port(struct ib_device *device, u32 port_num,
+                        struct ib_port_attr *port_attr,
+                        struct net_device *netdev)
 {
 	struct in_device *inetdev;
-	struct net_device *netdev;
 
 	memset(port_attr, 0, sizeof(*port_attr));
 
-	netdev = ib_device_get_netdev(device, port_num);
-	if (!netdev)
-		return -ENODEV;
-
 	port_attr->max_mtu = IB_MTU_4096;
 	port_attr->active_mtu = ib_mtu_int_to_enum(netdev->mtu);
 
@@ -2096,7 +2091,6 @@ static int iw_query_port(struct ib_device *device,
 		rcu_read_unlock();
 	}
 
-	dev_put(netdev);
 	return device->ops.query_port(device, port_num, port_attr);
 }
 
@@ -2134,13 +2128,27 @@ int ib_query_port(struct ib_device *device,
 		  u32 port_num,
 		  struct ib_port_attr *port_attr)
 {
+       struct net_device *netdev = NULL;
+       int ret;
+
 	if (!rdma_is_port_valid(device, port_num))
 		return -EINVAL;
 
+       if (rdma_protocol_iwarp(device, port_num) ||
+           rdma_protocol_roce(device, port_num)) {
+               netdev = ib_device_get_netdev(device, port_num);
+               if (!netdev)
+                       return -ENODEV;
+       }
+
 	if (rdma_protocol_iwarp(device, port_num))
-		return iw_query_port(device, port_num, port_attr);
+               ret = iw_query_port(device, port_num, port_attr, netdev);
 	else
-		return __ib_query_port(device, port_num, port_attr);
+               ret = __ib_query_port(device, port_num, port_attr);
+       if (netdev)
+               dev_put(netdev);
+       return ret;
+
 }
 EXPORT_SYMBOL(ib_query_port);
 
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 473ee0831307..561fe5704fa8 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -1988,11 +1988,11 @@ int ib_get_eth_speed(struct ib_device *dev, u32 port_num, u16 *speed, u8 *width)
 	if (rdma_port_get_link_layer(dev, port_num) != IB_LINK_LAYER_ETHERNET)
 		return -EINVAL;
 
+	rtnl_lock();
 	netdev = ib_device_get_netdev(dev, port_num);
 	if (!netdev)
 		return -ENODEV;
 
-	rtnl_lock();
 	rc = __ethtool_get_link_ksettings(netdev, &lksettings);
 	rtnl_unlock();
 
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
index 75d1407db52d..c5d439bebc24 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -605,6 +605,7 @@ static int rxe_notify(struct notifier_block *not_blk,
 
 	switch (event) {
 	case NETDEV_UNREGISTER:
+		ib_device_set_netdev(&rxe->ib_dev, NULL, 1);
 		ib_unregister_device_queued(&rxe->ib_dev);
 		break;
 	case NETDEV_UP: