aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx4
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/mlx4')
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c33
-rw-r--r--drivers/infiniband/hw/mlx4/main.c35
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
1124static 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
1124static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) 1156static 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
1380err_notif: 1415err_notif: