diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx4')
-rw-r--r-- | drivers/infiniband/hw/mlx4/mad.c | 33 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 35 |
2 files changed, 66 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index e98849338a94..318d5bcf821b 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -185,6 +185,10 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad, | |||
185 | { | 185 | { |
186 | struct ib_port_info *pinfo; | 186 | struct ib_port_info *pinfo; |
187 | u16 lid; | 187 | u16 lid; |
188 | __be16 *base; | ||
189 | u32 bn, pkey_change_bitmap; | ||
190 | int i; | ||
191 | |||
188 | 192 | ||
189 | struct mlx4_ib_dev *dev = to_mdev(ibdev); | 193 | struct mlx4_ib_dev *dev = to_mdev(ibdev); |
190 | if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || | 194 | if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || |
@@ -209,8 +213,33 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad, | |||
209 | break; | 213 | break; |
210 | 214 | ||
211 | case IB_SMP_ATTR_PKEY_TABLE: | 215 | case IB_SMP_ATTR_PKEY_TABLE: |
212 | mlx4_ib_dispatch_event(dev, port_num, | 216 | if (!mlx4_is_mfunc(dev->dev)) { |
213 | IB_EVENT_PKEY_CHANGE); | 217 | mlx4_ib_dispatch_event(dev, port_num, |
218 | IB_EVENT_PKEY_CHANGE); | ||
219 | break; | ||
220 | } | ||
221 | |||
222 | bn = be32_to_cpu(((struct ib_smp *)mad)->attr_mod) & 0xFFFF; | ||
223 | base = (__be16 *) &(((struct ib_smp *)mad)->data[0]); | ||
224 | pkey_change_bitmap = 0; | ||
225 | for (i = 0; i < 32; i++) { | ||
226 | pr_debug("PKEY[%d] = x%x\n", | ||
227 | i + bn*32, be16_to_cpu(base[i])); | ||
228 | if (be16_to_cpu(base[i]) != | ||
229 | dev->pkeys.phys_pkey_cache[port_num - 1][i + bn*32]) { | ||
230 | pkey_change_bitmap |= (1 << i); | ||
231 | dev->pkeys.phys_pkey_cache[port_num - 1][i + bn*32] = | ||
232 | be16_to_cpu(base[i]); | ||
233 | } | ||
234 | } | ||
235 | pr_debug("PKEY Change event: port=%d, " | ||
236 | "block=0x%x, change_bitmap=0x%x\n", | ||
237 | port_num, bn, pkey_change_bitmap); | ||
238 | |||
239 | if (pkey_change_bitmap) | ||
240 | mlx4_ib_dispatch_event(dev, port_num, | ||
241 | IB_EVENT_PKEY_CHANGE); | ||
242 | |||
214 | break; | 243 | break; |
215 | 244 | ||
216 | case IB_SMP_ATTR_GUID_INFO: | 245 | case IB_SMP_ATTR_GUID_INFO: |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 3f7f77f93a1c..8e10ec2af7b6 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -1121,6 +1121,38 @@ static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event | |||
1121 | return NOTIFY_DONE; | 1121 | return NOTIFY_DONE; |
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | static void init_pkeys(struct mlx4_ib_dev *ibdev) | ||
1125 | { | ||
1126 | int port; | ||
1127 | int slave; | ||
1128 | int i; | ||
1129 | |||
1130 | if (mlx4_is_master(ibdev->dev)) { | ||
1131 | for (slave = 0; slave <= ibdev->dev->num_vfs; ++slave) { | ||
1132 | for (port = 1; port <= ibdev->dev->caps.num_ports; ++port) { | ||
1133 | for (i = 0; | ||
1134 | i < ibdev->dev->phys_caps.pkey_phys_table_len[port]; | ||
1135 | ++i) { | ||
1136 | ibdev->pkeys.virt2phys_pkey[slave][port - 1][i] = | ||
1137 | /* master has the identity virt2phys pkey mapping */ | ||
1138 | (slave == mlx4_master_func_num(ibdev->dev) || !i) ? i : | ||
1139 | ibdev->dev->phys_caps.pkey_phys_table_len[port] - 1; | ||
1140 | mlx4_sync_pkey_table(ibdev->dev, slave, port, i, | ||
1141 | ibdev->pkeys.virt2phys_pkey[slave][port - 1][i]); | ||
1142 | } | ||
1143 | } | ||
1144 | } | ||
1145 | /* initialize pkey cache */ | ||
1146 | for (port = 1; port <= ibdev->dev->caps.num_ports; ++port) { | ||
1147 | for (i = 0; | ||
1148 | i < ibdev->dev->phys_caps.pkey_phys_table_len[port]; | ||
1149 | ++i) | ||
1150 | ibdev->pkeys.phys_pkey_cache[port-1][i] = | ||
1151 | (i) ? 0 : 0xFFFF; | ||
1152 | } | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1124 | static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) | 1156 | static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) |
1125 | { | 1157 | { |
1126 | char name[32]; | 1158 | char name[32]; |
@@ -1375,6 +1407,9 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
1375 | 1407 | ||
1376 | ibdev->ib_active = true; | 1408 | ibdev->ib_active = true; |
1377 | 1409 | ||
1410 | if (mlx4_is_mfunc(ibdev->dev)) | ||
1411 | init_pkeys(ibdev); | ||
1412 | |||
1378 | return ibdev; | 1413 | return ibdev; |
1379 | 1414 | ||
1380 | err_notif: | 1415 | err_notif: |