diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-14 13:09:05 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-14 13:09:05 -0400 |
| commit | e3b1fd56f175526db42ae94c457f29c2fa810aca (patch) | |
| tree | 3e2948ca44fb7fd5348244c2a83eef864b3110b4 /drivers/infiniband/ulp/ipoib | |
| parent | 0680eb1f485ba5aac2ee02c9f0622239c9a4b16c (diff) | |
| parent | d087f6ad724dfbcdc3df8e0191b80d9d8d839e71 (diff) | |
Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
Pull infiniband/rdma updates from Roland Dreier:
"Main set of InfiniBand/RDMA updates for 3.17 merge window:
- MR reregistration support
- MAD support for RMPP in userspace
- iSER and SRP initiator updates
- ocrdma hardware driver updates
- other fixes..."
* tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (52 commits)
IB/srp: Fix return value check in srp_init_module()
RDMA/ocrdma: report asic-id in query device
RDMA/ocrdma: Update sli data structure for endianness
RDMA/ocrdma: Obtain SL from device structure
RDMA/uapi: Include socket.h in rdma_user_cm.h
IB/srpt: Handle GID change events
IB/mlx5: Use ARRAY_SIZE instead of sizeof/sizeof[0]
IB/mlx4: Use ARRAY_SIZE instead of sizeof/sizeof[0]
RDMA/amso1100: Check for integer overflow in c2_alloc_cq_buf()
IPoIB: Remove unnecessary test for NULL before debugfs_remove()
IB/mad: Add user space RMPP support
IB/mad: add new ioctl to ABI to support new registration options
IB/mad: Add dev_notice messages for various umad/mad registration failures
IB/mad: Update module to [pr|dev]_* style print messages
IB/ipoib: Avoid multicast join attempts with invalid P_key
IB/umad: Update module to [pr|dev]_* style print messages
IB/ipoib: Avoid flushing the workqueue from worker context
IB/ipoib: Use P_Key change event instead of P_Key polling mechanism
IB/ipath: Add P_Key change event support
mlx4_core: Add support for secure-host and SMP firewall
...
Diffstat (limited to 'drivers/infiniband/ulp/ipoib')
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 8 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_fs.c | 6 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 133 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 9 |
4 files changed, 55 insertions, 101 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index c639f90cfda4..3edce617c31b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
| @@ -86,7 +86,6 @@ enum { | |||
| 86 | IPOIB_FLAG_INITIALIZED = 1, | 86 | IPOIB_FLAG_INITIALIZED = 1, |
| 87 | IPOIB_FLAG_ADMIN_UP = 2, | 87 | IPOIB_FLAG_ADMIN_UP = 2, |
| 88 | IPOIB_PKEY_ASSIGNED = 3, | 88 | IPOIB_PKEY_ASSIGNED = 3, |
| 89 | IPOIB_PKEY_STOP = 4, | ||
| 90 | IPOIB_FLAG_SUBINTERFACE = 5, | 89 | IPOIB_FLAG_SUBINTERFACE = 5, |
| 91 | IPOIB_MCAST_RUN = 6, | 90 | IPOIB_MCAST_RUN = 6, |
| 92 | IPOIB_STOP_REAPER = 7, | 91 | IPOIB_STOP_REAPER = 7, |
| @@ -312,7 +311,6 @@ struct ipoib_dev_priv { | |||
| 312 | struct list_head multicast_list; | 311 | struct list_head multicast_list; |
| 313 | struct rb_root multicast_tree; | 312 | struct rb_root multicast_tree; |
| 314 | 313 | ||
| 315 | struct delayed_work pkey_poll_task; | ||
| 316 | struct delayed_work mcast_task; | 314 | struct delayed_work mcast_task; |
| 317 | struct work_struct carrier_on_task; | 315 | struct work_struct carrier_on_task; |
| 318 | struct work_struct flush_light; | 316 | struct work_struct flush_light; |
| @@ -473,10 +471,11 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work); | |||
| 473 | void ipoib_pkey_event(struct work_struct *work); | 471 | void ipoib_pkey_event(struct work_struct *work); |
| 474 | void ipoib_ib_dev_cleanup(struct net_device *dev); | 472 | void ipoib_ib_dev_cleanup(struct net_device *dev); |
| 475 | 473 | ||
| 476 | int ipoib_ib_dev_open(struct net_device *dev); | 474 | int ipoib_ib_dev_open(struct net_device *dev, int flush); |
| 477 | int ipoib_ib_dev_up(struct net_device *dev); | 475 | int ipoib_ib_dev_up(struct net_device *dev); |
| 478 | int ipoib_ib_dev_down(struct net_device *dev, int flush); | 476 | int ipoib_ib_dev_down(struct net_device *dev, int flush); |
| 479 | int ipoib_ib_dev_stop(struct net_device *dev, int flush); | 477 | int ipoib_ib_dev_stop(struct net_device *dev, int flush); |
| 478 | void ipoib_pkey_dev_check_presence(struct net_device *dev); | ||
| 480 | 479 | ||
| 481 | int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); | 480 | int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); |
| 482 | void ipoib_dev_cleanup(struct net_device *dev); | 481 | void ipoib_dev_cleanup(struct net_device *dev); |
| @@ -532,8 +531,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf); | |||
| 532 | 531 | ||
| 533 | void ipoib_setup(struct net_device *dev); | 532 | void ipoib_setup(struct net_device *dev); |
| 534 | 533 | ||
| 535 | void ipoib_pkey_poll(struct work_struct *work); | 534 | void ipoib_pkey_open(struct ipoib_dev_priv *priv); |
| 536 | int ipoib_pkey_dev_delay_open(struct net_device *dev); | ||
| 537 | void ipoib_drain_cq(struct net_device *dev); | 535 | void ipoib_drain_cq(struct net_device *dev); |
| 538 | 536 | ||
| 539 | void ipoib_set_ethtool_ops(struct net_device *dev); | 537 | void ipoib_set_ethtool_ops(struct net_device *dev); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index 50061854616e..6bd5740e2691 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c | |||
| @@ -281,10 +281,8 @@ void ipoib_delete_debug_files(struct net_device *dev) | |||
| 281 | { | 281 | { |
| 282 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 282 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 283 | 283 | ||
| 284 | if (priv->mcg_dentry) | 284 | debugfs_remove(priv->mcg_dentry); |
| 285 | debugfs_remove(priv->mcg_dentry); | 285 | debugfs_remove(priv->path_dentry); |
| 286 | if (priv->path_dentry) | ||
| 287 | debugfs_remove(priv->path_dentry); | ||
| 288 | } | 286 | } |
| 289 | 287 | ||
| 290 | int ipoib_register_debugfs(void) | 288 | int ipoib_register_debugfs(void) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 6a7003ddb0be..72626c348174 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
| @@ -664,17 +664,18 @@ static void ipoib_ib_tx_timer_func(unsigned long ctx) | |||
| 664 | drain_tx_cq((struct net_device *)ctx); | 664 | drain_tx_cq((struct net_device *)ctx); |
| 665 | } | 665 | } |
| 666 | 666 | ||
| 667 | int ipoib_ib_dev_open(struct net_device *dev) | 667 | int ipoib_ib_dev_open(struct net_device *dev, int flush) |
| 668 | { | 668 | { |
| 669 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 669 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 670 | int ret; | 670 | int ret; |
| 671 | 671 | ||
| 672 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &priv->pkey_index)) { | 672 | ipoib_pkey_dev_check_presence(dev); |
| 673 | ipoib_warn(priv, "P_Key 0x%04x not found\n", priv->pkey); | 673 | |
| 674 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 674 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { |
| 675 | ipoib_warn(priv, "P_Key 0x%04x is %s\n", priv->pkey, | ||
| 676 | (!(priv->pkey & 0x7fff) ? "Invalid" : "not found")); | ||
| 675 | return -1; | 677 | return -1; |
| 676 | } | 678 | } |
| 677 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | ||
| 678 | 679 | ||
| 679 | ret = ipoib_init_qp(dev); | 680 | ret = ipoib_init_qp(dev); |
| 680 | if (ret) { | 681 | if (ret) { |
| @@ -705,16 +706,17 @@ int ipoib_ib_dev_open(struct net_device *dev) | |||
| 705 | dev_stop: | 706 | dev_stop: |
| 706 | if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | 707 | if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
| 707 | napi_enable(&priv->napi); | 708 | napi_enable(&priv->napi); |
| 708 | ipoib_ib_dev_stop(dev, 1); | 709 | ipoib_ib_dev_stop(dev, flush); |
| 709 | return -1; | 710 | return -1; |
| 710 | } | 711 | } |
| 711 | 712 | ||
| 712 | static void ipoib_pkey_dev_check_presence(struct net_device *dev) | 713 | void ipoib_pkey_dev_check_presence(struct net_device *dev) |
| 713 | { | 714 | { |
| 714 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 715 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 715 | u16 pkey_index = 0; | ||
| 716 | 716 | ||
| 717 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) | 717 | if (!(priv->pkey & 0x7fff) || |
| 718 | ib_find_pkey(priv->ca, priv->port, priv->pkey, | ||
| 719 | &priv->pkey_index)) | ||
| 718 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 720 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
| 719 | else | 721 | else |
| 720 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 722 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
| @@ -745,14 +747,6 @@ int ipoib_ib_dev_down(struct net_device *dev, int flush) | |||
| 745 | clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags); | 747 | clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags); |
| 746 | netif_carrier_off(dev); | 748 | netif_carrier_off(dev); |
| 747 | 749 | ||
| 748 | /* Shutdown the P_Key thread if still active */ | ||
| 749 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { | ||
| 750 | mutex_lock(&pkey_mutex); | ||
| 751 | set_bit(IPOIB_PKEY_STOP, &priv->flags); | ||
| 752 | cancel_delayed_work_sync(&priv->pkey_poll_task); | ||
| 753 | mutex_unlock(&pkey_mutex); | ||
| 754 | } | ||
| 755 | |||
| 756 | ipoib_mcast_stop_thread(dev, flush); | 750 | ipoib_mcast_stop_thread(dev, flush); |
| 757 | ipoib_mcast_dev_flush(dev); | 751 | ipoib_mcast_dev_flush(dev); |
| 758 | 752 | ||
| @@ -924,7 +918,7 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
| 924 | (unsigned long) dev); | 918 | (unsigned long) dev); |
| 925 | 919 | ||
| 926 | if (dev->flags & IFF_UP) { | 920 | if (dev->flags & IFF_UP) { |
| 927 | if (ipoib_ib_dev_open(dev)) { | 921 | if (ipoib_ib_dev_open(dev, 1)) { |
| 928 | ipoib_transport_dev_cleanup(dev); | 922 | ipoib_transport_dev_cleanup(dev); |
| 929 | return -ENODEV; | 923 | return -ENODEV; |
| 930 | } | 924 | } |
| @@ -966,13 +960,27 @@ static inline int update_parent_pkey(struct ipoib_dev_priv *priv) | |||
| 966 | 960 | ||
| 967 | return 1; | 961 | return 1; |
| 968 | } | 962 | } |
| 963 | /* | ||
| 964 | * returns 0 if pkey value was found in a different slot. | ||
| 965 | */ | ||
| 966 | static inline int update_child_pkey(struct ipoib_dev_priv *priv) | ||
| 967 | { | ||
| 968 | u16 old_index = priv->pkey_index; | ||
| 969 | |||
| 970 | priv->pkey_index = 0; | ||
| 971 | ipoib_pkey_dev_check_presence(priv->dev); | ||
| 972 | |||
| 973 | if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) && | ||
| 974 | (old_index == priv->pkey_index)) | ||
| 975 | return 1; | ||
| 976 | return 0; | ||
| 977 | } | ||
| 969 | 978 | ||
| 970 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | 979 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, |
| 971 | enum ipoib_flush_level level) | 980 | enum ipoib_flush_level level) |
| 972 | { | 981 | { |
| 973 | struct ipoib_dev_priv *cpriv; | 982 | struct ipoib_dev_priv *cpriv; |
| 974 | struct net_device *dev = priv->dev; | 983 | struct net_device *dev = priv->dev; |
| 975 | u16 new_index; | ||
| 976 | int result; | 984 | int result; |
| 977 | 985 | ||
| 978 | down_read(&priv->vlan_rwsem); | 986 | down_read(&priv->vlan_rwsem); |
| @@ -986,16 +994,20 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
| 986 | 994 | ||
| 987 | up_read(&priv->vlan_rwsem); | 995 | up_read(&priv->vlan_rwsem); |
| 988 | 996 | ||
| 989 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) { | 997 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags) && |
| 990 | /* for non-child devices must check/update the pkey value here */ | 998 | level != IPOIB_FLUSH_HEAVY) { |
| 991 | if (level == IPOIB_FLUSH_HEAVY && | ||
| 992 | !test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) | ||
| 993 | update_parent_pkey(priv); | ||
| 994 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); | 999 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); |
| 995 | return; | 1000 | return; |
| 996 | } | 1001 | } |
| 997 | 1002 | ||
| 998 | if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { | 1003 | if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { |
| 1004 | /* interface is down. update pkey and leave. */ | ||
| 1005 | if (level == IPOIB_FLUSH_HEAVY) { | ||
| 1006 | if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) | ||
| 1007 | update_parent_pkey(priv); | ||
| 1008 | else | ||
| 1009 | update_child_pkey(priv); | ||
| 1010 | } | ||
| 999 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_ADMIN_UP not set.\n"); | 1011 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_ADMIN_UP not set.\n"); |
| 1000 | return; | 1012 | return; |
| 1001 | } | 1013 | } |
| @@ -1005,20 +1017,13 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
| 1005 | * (parent) devices should always takes what present in pkey index 0 | 1017 | * (parent) devices should always takes what present in pkey index 0 |
| 1006 | */ | 1018 | */ |
| 1007 | if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { | 1019 | if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { |
| 1008 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) { | 1020 | result = update_child_pkey(priv); |
| 1009 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 1021 | if (result) { |
| 1010 | ipoib_ib_dev_down(dev, 0); | 1022 | /* restart QP only if P_Key index is changed */ |
| 1011 | ipoib_ib_dev_stop(dev, 0); | ||
| 1012 | if (ipoib_pkey_dev_delay_open(dev)) | ||
| 1013 | return; | ||
| 1014 | } | ||
| 1015 | /* restart QP only if P_Key index is changed */ | ||
| 1016 | if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) && | ||
| 1017 | new_index == priv->pkey_index) { | ||
| 1018 | ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n"); | 1023 | ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n"); |
| 1019 | return; | 1024 | return; |
| 1020 | } | 1025 | } |
| 1021 | priv->pkey_index = new_index; | 1026 | |
| 1022 | } else { | 1027 | } else { |
| 1023 | result = update_parent_pkey(priv); | 1028 | result = update_parent_pkey(priv); |
| 1024 | /* restart QP only if P_Key value changed */ | 1029 | /* restart QP only if P_Key value changed */ |
| @@ -1038,8 +1043,12 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
| 1038 | ipoib_ib_dev_down(dev, 0); | 1043 | ipoib_ib_dev_down(dev, 0); |
| 1039 | 1044 | ||
| 1040 | if (level == IPOIB_FLUSH_HEAVY) { | 1045 | if (level == IPOIB_FLUSH_HEAVY) { |
| 1041 | ipoib_ib_dev_stop(dev, 0); | 1046 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
| 1042 | ipoib_ib_dev_open(dev); | 1047 | ipoib_ib_dev_stop(dev, 0); |
| 1048 | if (ipoib_ib_dev_open(dev, 0) != 0) | ||
| 1049 | return; | ||
| 1050 | if (netif_queue_stopped(dev)) | ||
| 1051 | netif_start_queue(dev); | ||
| 1043 | } | 1052 | } |
| 1044 | 1053 | ||
| 1045 | /* | 1054 | /* |
| @@ -1094,54 +1103,4 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) | |||
| 1094 | ipoib_transport_dev_cleanup(dev); | 1103 | ipoib_transport_dev_cleanup(dev); |
| 1095 | } | 1104 | } |
| 1096 | 1105 | ||
| 1097 | /* | ||
| 1098 | * Delayed P_Key Assigment Interim Support | ||
| 1099 | * | ||
| 1100 | * The following is initial implementation of delayed P_Key assigment | ||
| 1101 | * mechanism. It is using the same approach implemented for the multicast | ||
| 1102 | * group join. The single goal of this implementation is to quickly address | ||
| 1103 | * Bug #2507. This implementation will probably be removed when the P_Key | ||
| 1104 | * change async notification is available. | ||
| 1105 | */ | ||
| 1106 | |||
| 1107 | void ipoib_pkey_poll(struct work_struct *work) | ||
| 1108 | { | ||
| 1109 | struct ipoib_dev_priv *priv = | ||
| 1110 | container_of(work, struct ipoib_dev_priv, pkey_poll_task.work); | ||
| 1111 | struct net_device *dev = priv->dev; | ||
| 1112 | |||
| 1113 | ipoib_pkey_dev_check_presence(dev); | ||
| 1114 | |||
| 1115 | if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) | ||
| 1116 | ipoib_open(dev); | ||
| 1117 | else { | ||
| 1118 | mutex_lock(&pkey_mutex); | ||
| 1119 | if (!test_bit(IPOIB_PKEY_STOP, &priv->flags)) | ||
| 1120 | queue_delayed_work(ipoib_workqueue, | ||
| 1121 | &priv->pkey_poll_task, | ||
| 1122 | HZ); | ||
| 1123 | mutex_unlock(&pkey_mutex); | ||
| 1124 | } | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | int ipoib_pkey_dev_delay_open(struct net_device *dev) | ||
| 1128 | { | ||
| 1129 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
| 1130 | |||
| 1131 | /* Look for the interface pkey value in the IB Port P_Key table and */ | ||
| 1132 | /* set the interface pkey assigment flag */ | ||
| 1133 | ipoib_pkey_dev_check_presence(dev); | ||
| 1134 | 1106 | ||
| 1135 | /* P_Key value not assigned yet - start polling */ | ||
| 1136 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { | ||
| 1137 | mutex_lock(&pkey_mutex); | ||
| 1138 | clear_bit(IPOIB_PKEY_STOP, &priv->flags); | ||
| 1139 | queue_delayed_work(ipoib_workqueue, | ||
| 1140 | &priv->pkey_poll_task, | ||
| 1141 | HZ); | ||
| 1142 | mutex_unlock(&pkey_mutex); | ||
| 1143 | return 1; | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | return 0; | ||
| 1147 | } | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 4e675f4fecc9..1310acf6bf92 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -108,11 +108,11 @@ int ipoib_open(struct net_device *dev) | |||
| 108 | 108 | ||
| 109 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); | 109 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); |
| 110 | 110 | ||
| 111 | if (ipoib_pkey_dev_delay_open(dev)) | 111 | if (ipoib_ib_dev_open(dev, 1)) { |
| 112 | return 0; | 112 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) |
| 113 | 113 | return 0; | |
| 114 | if (ipoib_ib_dev_open(dev)) | ||
| 115 | goto err_disable; | 114 | goto err_disable; |
| 115 | } | ||
| 116 | 116 | ||
| 117 | if (ipoib_ib_dev_up(dev)) | 117 | if (ipoib_ib_dev_up(dev)) |
| 118 | goto err_stop; | 118 | goto err_stop; |
| @@ -1379,7 +1379,6 @@ void ipoib_setup(struct net_device *dev) | |||
| 1379 | INIT_LIST_HEAD(&priv->dead_ahs); | 1379 | INIT_LIST_HEAD(&priv->dead_ahs); |
| 1380 | INIT_LIST_HEAD(&priv->multicast_list); | 1380 | INIT_LIST_HEAD(&priv->multicast_list); |
| 1381 | 1381 | ||
| 1382 | INIT_DELAYED_WORK(&priv->pkey_poll_task, ipoib_pkey_poll); | ||
| 1383 | INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task); | 1382 | INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task); |
| 1384 | INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task); | 1383 | INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task); |
| 1385 | INIT_WORK(&priv->flush_light, ipoib_ib_dev_flush_light); | 1384 | INIT_WORK(&priv->flush_light, ipoib_ib_dev_flush_light); |
