aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/ipoib
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-12 13:22:49 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-12 13:22:49 -0400
commitfbf8d7106c926d375c76e65cc878f4fa7b91cbc3 (patch)
treee9faf7f8a9ce8da9ad2e2a3f1768a4af414670d4 /drivers/infiniband/ulp/ipoib
parent98f62b7a082e1e9eb762c7329a704316f6e07698 (diff)
parentd4e4ab86bcba5a72779c43dc1459f71fea3d89c8 (diff)
Merge 3.11-rc5 into staging-next
We want the staging fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/infiniband/ulp/ipoib')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c76
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_netlink.c9
3 files changed, 73 insertions, 14 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 2cfa76f5d99e..196b1d13cbcb 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -932,12 +932,47 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port)
932 return 0; 932 return 0;
933} 933}
934 934
935/*
936 * Takes whatever value which is in pkey index 0 and updates priv->pkey
937 * returns 0 if the pkey value was changed.
938 */
939static inline int update_parent_pkey(struct ipoib_dev_priv *priv)
940{
941 int result;
942 u16 prev_pkey;
943
944 prev_pkey = priv->pkey;
945 result = ib_query_pkey(priv->ca, priv->port, 0, &priv->pkey);
946 if (result) {
947 ipoib_warn(priv, "ib_query_pkey port %d failed (ret = %d)\n",
948 priv->port, result);
949 return result;
950 }
951
952 priv->pkey |= 0x8000;
953
954 if (prev_pkey != priv->pkey) {
955 ipoib_dbg(priv, "pkey changed from 0x%x to 0x%x\n",
956 prev_pkey, priv->pkey);
957 /*
958 * Update the pkey in the broadcast address, while making sure to set
959 * the full membership bit, so that we join the right broadcast group.
960 */
961 priv->dev->broadcast[8] = priv->pkey >> 8;
962 priv->dev->broadcast[9] = priv->pkey & 0xff;
963 return 0;
964 }
965
966 return 1;
967}
968
935static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, 969static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
936 enum ipoib_flush_level level) 970 enum ipoib_flush_level level)
937{ 971{
938 struct ipoib_dev_priv *cpriv; 972 struct ipoib_dev_priv *cpriv;
939 struct net_device *dev = priv->dev; 973 struct net_device *dev = priv->dev;
940 u16 new_index; 974 u16 new_index;
975 int result;
941 976
942 mutex_lock(&priv->vlan_mutex); 977 mutex_lock(&priv->vlan_mutex);
943 978
@@ -951,6 +986,10 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
951 mutex_unlock(&priv->vlan_mutex); 986 mutex_unlock(&priv->vlan_mutex);
952 987
953 if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) { 988 if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) {
989 /* for non-child devices must check/update the pkey value here */
990 if (level == IPOIB_FLUSH_HEAVY &&
991 !test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags))
992 update_parent_pkey(priv);
954 ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); 993 ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n");
955 return; 994 return;
956 } 995 }
@@ -961,21 +1000,32 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
961 } 1000 }
962 1001
963 if (level == IPOIB_FLUSH_HEAVY) { 1002 if (level == IPOIB_FLUSH_HEAVY) {
964 if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) { 1003 /* child devices chase their origin pkey value, while non-child
965 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); 1004 * (parent) devices should always takes what present in pkey index 0
966 ipoib_ib_dev_down(dev, 0); 1005 */
967 ipoib_ib_dev_stop(dev, 0); 1006 if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
968 if (ipoib_pkey_dev_delay_open(dev)) 1007 if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) {
1008 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
1009 ipoib_ib_dev_down(dev, 0);
1010 ipoib_ib_dev_stop(dev, 0);
1011 if (ipoib_pkey_dev_delay_open(dev))
1012 return;
1013 }
1014 /* restart QP only if P_Key index is changed */
1015 if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) &&
1016 new_index == priv->pkey_index) {
1017 ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n");
969 return; 1018 return;
1019 }
1020 priv->pkey_index = new_index;
1021 } else {
1022 result = update_parent_pkey(priv);
1023 /* restart QP only if P_Key value changed */
1024 if (result) {
1025 ipoib_dbg(priv, "Not flushing - P_Key value not changed.\n");
1026 return;
1027 }
970 } 1028 }
971
972 /* restart QP only if P_Key index is changed */
973 if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) &&
974 new_index == priv->pkey_index) {
975 ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n");
976 return;
977 }
978 priv->pkey_index = new_index;
979 } 1029 }
980 1030
981 if (level == IPOIB_FLUSH_LIGHT) { 1031 if (level == IPOIB_FLUSH_LIGHT) {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index b6e049a3c7a8..c6f71a88c55c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1461,7 +1461,7 @@ static ssize_t create_child(struct device *dev,
1461 if (sscanf(buf, "%i", &pkey) != 1) 1461 if (sscanf(buf, "%i", &pkey) != 1)
1462 return -EINVAL; 1462 return -EINVAL;
1463 1463
1464 if (pkey < 0 || pkey > 0xffff) 1464 if (pkey <= 0 || pkey > 0xffff || pkey == 0x8000)
1465 return -EINVAL; 1465 return -EINVAL;
1466 1466
1467 /* 1467 /*
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
index 74685936c948..f81abe16cf09 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
@@ -119,6 +119,15 @@ static int ipoib_new_child_link(struct net *src_net, struct net_device *dev,
119 } else 119 } else
120 child_pkey = nla_get_u16(data[IFLA_IPOIB_PKEY]); 120 child_pkey = nla_get_u16(data[IFLA_IPOIB_PKEY]);
121 121
122 if (child_pkey == 0 || child_pkey == 0x8000)
123 return -EINVAL;
124
125 /*
126 * Set the full membership bit, so that we join the right
127 * broadcast group, etc.
128 */
129 child_pkey |= 0x8000;
130
122 err = __ipoib_vlan_add(ppriv, netdev_priv(dev), child_pkey, IPOIB_RTNL_CHILD); 131 err = __ipoib_vlan_add(ppriv, netdev_priv(dev), child_pkey, IPOIB_RTNL_CHILD);
123 132
124 if (!err && data) 133 if (!err && data)