diff options
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ib.c | 80 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 11 |
2 files changed, 46 insertions, 45 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 9dcb2c9e758a..72626c348174 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
| @@ -669,12 +669,13 @@ int ipoib_ib_dev_open(struct net_device *dev, int flush) | |||
| 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) { |
| @@ -712,9 +713,10 @@ dev_stop: | |||
| 712 | 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); |
| @@ -958,13 +960,27 @@ static inline int update_parent_pkey(struct ipoib_dev_priv *priv) | |||
| 958 | 960 | ||
| 959 | return 1; | 961 | return 1; |
| 960 | } | 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 | } | ||
| 961 | 978 | ||
| 962 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | 979 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, |
| 963 | enum ipoib_flush_level level) | 980 | enum ipoib_flush_level level) |
| 964 | { | 981 | { |
| 965 | struct ipoib_dev_priv *cpriv; | 982 | struct ipoib_dev_priv *cpriv; |
| 966 | struct net_device *dev = priv->dev; | 983 | struct net_device *dev = priv->dev; |
| 967 | u16 new_index; | ||
| 968 | int result; | 984 | int result; |
| 969 | 985 | ||
| 970 | down_read(&priv->vlan_rwsem); | 986 | down_read(&priv->vlan_rwsem); |
| @@ -978,19 +994,20 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
| 978 | 994 | ||
| 979 | up_read(&priv->vlan_rwsem); | 995 | up_read(&priv->vlan_rwsem); |
| 980 | 996 | ||
| 981 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) { | 997 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags) && |
| 982 | /* for non-child devices must check/update the pkey value here */ | 998 | level != IPOIB_FLUSH_HEAVY) { |
| 983 | if (level == IPOIB_FLUSH_HEAVY) { | ||
| 984 | if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) | ||
| 985 | ipoib_pkey_open(priv); | ||
| 986 | else | ||
| 987 | update_parent_pkey(priv); | ||
| 988 | } | ||
| 989 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); | 999 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); |
| 990 | return; | 1000 | return; |
| 991 | } | 1001 | } |
| 992 | 1002 | ||
| 993 | 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 | } | ||
| 994 | 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"); |
| 995 | return; | 1012 | return; |
| 996 | } | 1013 | } |
| @@ -1000,19 +1017,13 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
| 1000 | * (parent) devices should always takes what present in pkey index 0 | 1017 | * (parent) devices should always takes what present in pkey index 0 |
| 1001 | */ | 1018 | */ |
| 1002 | if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { | 1019 | if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { |
| 1003 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) { | 1020 | result = update_child_pkey(priv); |
| 1004 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 1021 | if (result) { |
| 1005 | ipoib_ib_dev_down(dev, 0); | 1022 | /* restart QP only if P_Key index is changed */ |
| 1006 | ipoib_ib_dev_stop(dev, 0); | ||
| 1007 | return; | ||
| 1008 | } | ||
| 1009 | /* restart QP only if P_Key index is changed */ | ||
| 1010 | if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) && | ||
| 1011 | new_index == priv->pkey_index) { | ||
| 1012 | ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n"); | 1023 | ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n"); |
| 1013 | return; | 1024 | return; |
| 1014 | } | 1025 | } |
| 1015 | priv->pkey_index = new_index; | 1026 | |
| 1016 | } else { | 1027 | } else { |
| 1017 | result = update_parent_pkey(priv); | 1028 | result = update_parent_pkey(priv); |
| 1018 | /* restart QP only if P_Key value changed */ | 1029 | /* restart QP only if P_Key value changed */ |
| @@ -1032,8 +1043,12 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
| 1032 | ipoib_ib_dev_down(dev, 0); | 1043 | ipoib_ib_dev_down(dev, 0); |
| 1033 | 1044 | ||
| 1034 | if (level == IPOIB_FLUSH_HEAVY) { | 1045 | if (level == IPOIB_FLUSH_HEAVY) { |
| 1035 | ipoib_ib_dev_stop(dev, 0); | 1046 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
| 1036 | ipoib_ib_dev_open(dev, 0); | 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); | ||
| 1037 | } | 1052 | } |
| 1038 | 1053 | ||
| 1039 | /* | 1054 | /* |
| @@ -1088,15 +1103,4 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) | |||
| 1088 | ipoib_transport_dev_cleanup(dev); | 1103 | ipoib_transport_dev_cleanup(dev); |
| 1089 | } | 1104 | } |
| 1090 | 1105 | ||
| 1091 | void ipoib_pkey_open(struct ipoib_dev_priv *priv) | ||
| 1092 | { | ||
| 1093 | |||
| 1094 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | ||
| 1095 | return; | ||
| 1096 | |||
| 1097 | ipoib_pkey_dev_check_presence(priv->dev); | ||
| 1098 | |||
| 1099 | if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) | ||
| 1100 | ipoib_open(priv->dev); | ||
| 1101 | } | ||
| 1102 | 1106 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 1bf994a96860..217cb77157d8 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -108,14 +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 | 111 | if (ipoib_ib_dev_open(dev, 1)) { | |
| 112 | ipoib_pkey_dev_check_presence(dev); | 112 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) |
| 113 | 113 | return 0; | |
| 114 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) | ||
| 115 | return 0; | ||
| 116 | |||
| 117 | if (ipoib_ib_dev_open(dev, 1)) | ||
| 118 | goto err_disable; | 114 | goto err_disable; |
| 115 | } | ||
| 119 | 116 | ||
| 120 | if (ipoib_ib_dev_up(dev)) | 117 | if (ipoib_ib_dev_up(dev)) |
| 121 | goto err_stop; | 118 | goto err_stop; |
